diff --git a/mp/src/game/client/c_playerresource.cpp b/mp/src/game/client/c_playerresource.cpp index 80bd3a5b..21386193 100644 --- a/mp/src/game/client/c_playerresource.cpp +++ b/mp/src/game/client/c_playerresource.cpp @@ -12,6 +12,7 @@ #ifdef FF #include "ff_sh_gamerules.h" #include "ff_sh_shareddefs.h" +#include "ff_cl_info_ff_team_manager.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -61,17 +62,17 @@ C_PlayerResource::C_PlayerResource() memset( m_iHealth, 0, sizeof( m_iHealth ) ); m_szUnconnectedName = 0; - for ( int i=0; i= MAX_TEAMS ) - { - Assert( false ); - static Color blah; - return blah; - } - else - { + static Color teamColor; + teamColor = COLOR_GREY; + + if ( index < 0 || index > FF_TEAM_LAST ) + return teamColor; + + if( index < FF_TEAM_ONE ) return m_Colors[index]; - } + + CFF_CL_InfoFFTeamManager *pTeam = dynamic_cast(GetGlobalTeam( index )); + if( !pTeam ) + return teamColor; + + color32 c = pTeam->m_clrTeamColor; + teamColor = Color(c.r, c.g, c.b, 255); + return teamColor; } //----------------------------------------------------------------------------- diff --git a/mp/src/game/client/c_playerresource.h b/mp/src/game/client/c_playerresource.h index 31b89d5d..7433b468 100644 --- a/mp/src/game/client/c_playerresource.h +++ b/mp/src/game/client/c_playerresource.h @@ -15,6 +15,7 @@ #include "const.h" #include "c_baseentity.h" #include +#include "ff_sh_shareddefs.h" // FF: --> hlstriker: Added #define PLAYER_UNCONNECTED_NAME "unconnected" #define PLAYER_ERROR_NAME "ERRORNAME" @@ -69,7 +70,7 @@ protected: int m_iTeam[MAX_PLAYERS+1]; bool m_bAlive[MAX_PLAYERS+1]; int m_iHealth[MAX_PLAYERS+1]; - Color m_Colors[MAX_TEAMS]; + Color m_Colors[FF_TEAM_LAST+1]; string_t m_szUnconnectedName; }; diff --git a/mp/src/game/client/client_ff.vpc b/mp/src/game/client/client_ff.vpc index 18879d58..1fe35826 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;$SRCDIR\game\shared\ff;$THIRDPARTYDIR\lua;$THIRDPARTYDIR" + $AdditionalIncludeDirectories "$BASE;.\ff;.\ff\entities;$SRCDIR\game\shared\ff;$THIRDPARTYDIR\lua;$THIRDPARTYDIR" $PreprocessorDefinitions "$BASE;FF;FF_CLIENT_DLL;SOURCE_2013;GLOWS_ENABLE" } } @@ -65,6 +65,8 @@ $Project "Client (FF)" } $Folder "Entities" { + $File "ff\entities\ff_cl_info_ff_team_manager.cpp" + $File "ff\entities\ff_cl_info_ff_team_manager.h" $File "ff\entities\ff_cl_info_ff_weapon_spawner.cpp" } } diff --git a/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.cpp b/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.cpp new file mode 100644 index 00000000..e03dcce7 --- /dev/null +++ b/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.cpp @@ -0,0 +1,12 @@ +#include "cbase.h" +#include "ff_cl_info_ff_team_manager.h" + + +LINK_ENTITY_TO_CLASS( info_ff_team_manager, CFF_CL_InfoFFTeamManager ); + +IMPLEMENT_CLIENTCLASS_DT(CFF_CL_InfoFFTeamManager, DT_FF_InfoFFTeamManager, CFF_SV_InfoFFTeamManager) + RecvPropInt( RECVINFO( m_iAllies ) ), + RecvPropInt( RECVINFO( m_iMaxPlayers ) ), + RecvPropInt( RECVINFO( m_clrTeamColor ) ), + RecvPropArray3( RECVINFO_ARRAY(m_iClassLimits), RecvPropInt( RECVINFO( m_iClassLimits[0] ) ) ), +END_RECV_TABLE() diff --git a/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.h b/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.h new file mode 100644 index 00000000..7731952e --- /dev/null +++ b/mp/src/game/client/ff/entities/ff_cl_info_ff_team_manager.h @@ -0,0 +1,25 @@ +#pragma once + +#ifndef FF_CL_INFO_FF_TEAM_MANAGER_H +#define FF_CL_INFO_FF_TEAM_MANAGER_H + +#include "cbase.h" +#include "c_team.h" +#include "ff_sh_shareddefs.h" + + +class CFF_CL_InfoFFTeamManager : public C_Team +{ +public: + DECLARE_CLASS( CFF_CL_InfoFFTeamManager, C_Team ); + DECLARE_CLIENTCLASS(); + + CFF_CL_InfoFFTeamManager() {} + + int m_iAllies; + int m_iMaxPlayers; + color32 m_clrTeamColor; + int m_iClassLimits[FF_CLASS_COUNT]; +}; + +#endif // FF_CL_INFO_FF_TEAM_MANAGER_H diff --git a/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp b/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp index efe7bc44..db6fc10b 100644 --- a/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp +++ b/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp @@ -11,14 +11,21 @@ public: { m_angles.y = RandomFloat(0.0f, 359.0f); m_bDirection = RandomInt(0, 1); + m_nCurAlpha = 255; } - void Spawn(); - void ClientThink(); + void Spawn(); + void ClientThink(); + unsigned char GetClientSideFade(); + void OnDataChanged(DataUpdateType_t updateType); + void OnPreDataChanged(DataUpdateType_t updateType); private: QAngle m_angles; bool m_bDirection; + int m_nCurAlpha; // NOTE: This isn't an unsigned char because when adding it can go over 255 and overflow which messes our calculations up. + + int m_bOldEffects; }; @@ -28,6 +35,35 @@ IMPLEMENT_CLIENTCLASS_DT(CFF_CL_InfoFFWeaponSpawner, DT_FF_InfoFFWeaponSpawner, END_RECV_TABLE() +void CFF_CL_InfoFFWeaponSpawner::OnPreDataChanged(DataUpdateType_t updateType) +{ + BaseClass::OnPreDataChanged(updateType); + m_bOldEffects = GetEffects(); +} + +void CFF_CL_InfoFFWeaponSpawner::OnDataChanged(DataUpdateType_t updateType) +{ + BaseClass::OnDataChanged(updateType); + if(updateType != DATA_UPDATE_DATATABLE_CHANGED) + return; + + if(!(GetEffects() & EF_NODRAW) && GetEffects() != m_bOldEffects) + m_nCurAlpha = 0; +} + +unsigned char CFF_CL_InfoFFWeaponSpawner::GetClientSideFade() +{ + m_nCurAlpha += RoundFloatToInt((255.0f / 0.27f) * gpGlobals->frametime); + if(m_nCurAlpha > 255) + m_nCurAlpha = 255; + + unsigned char alpha = BaseClass::GetClientSideFade(); + if(alpha < m_nCurAlpha) + return alpha; + + return m_nCurAlpha; +} + void CFF_CL_InfoFFWeaponSpawner::Spawn() { SetNextClientThink(CLIENT_THINK_ALWAYS); diff --git a/mp/src/game/client/ff/ff_cl_player.cpp b/mp/src/game/client/ff/ff_cl_player.cpp index 46fce071..382b1595 100644 --- a/mp/src/game/client/ff/ff_cl_player.cpp +++ b/mp/src/game/client/ff/ff_cl_player.cpp @@ -29,11 +29,13 @@ IMPLEMENT_CLIENTCLASS_DT(CFF_CL_Player, DT_FF_Player, CFF_SV_Player) RecvPropInt( RECVINFO( m_iSpawnInterpCounter ) ), RecvPropInt( RECVINFO( m_iPlayerSoundType) ), - RecvPropBool( RECVINFO( m_fIsWalking ) ), + //RecvPropBool( RECVINFO( m_fIsWalking ) ), + RecvPropFloat( RECVINFO( m_flNextJumpTimeForDouble ) ), END_RECV_TABLE() BEGIN_PREDICTION_DATA( CFF_CL_Player ) - DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + //DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + //DEFINE_PRED_FIELD( m_flNextJumpTimeForDouble, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), END_PREDICTION_DATA() #define HL2_WALK_SPEED 150 diff --git a/mp/src/game/client/ff/ff_cl_player.h b/mp/src/game/client/ff/ff_cl_player.h index acfab38c..0d379fca 100644 --- a/mp/src/game/client/ff/ff_cl_player.h +++ b/mp/src/game/client/ff/ff_cl_player.h @@ -127,6 +127,9 @@ private: CNetworkVar( FFPlayerState, m_iPlayerState ); bool m_fIsWalking; + +public: + float m_flNextJumpTimeForDouble; }; inline CFF_CL_Player *ToFFPlayer( CBaseEntity *pEntity ) diff --git a/mp/src/game/client/hl2mp/ui/hl2mpclientscoreboard.cpp b/mp/src/game/client/hl2mp/ui/hl2mpclientscoreboard.cpp index 11fc862c..2afbac3a 100644 --- a/mp/src/game/client/hl2mp/ui/hl2mpclientscoreboard.cpp +++ b/mp/src/game/client/hl2mp/ui/hl2mpclientscoreboard.cpp @@ -335,16 +335,19 @@ void CHL2MPClientScoreBoardDialog::InitScoreboardSections() if ( FFRules()->IsTeamplay() ) { - // add the team sections - // FF TODO: how do into dynamic teams - AddSection( TYPE_TEAM, FF_TEAM_ONE ); - AddSection( TYPE_TEAM, FF_TEAM_TWO ); + for( int i=0; iGetTeamNumber() < FF_TEAM_ONE || g_Teams[i]->GetTeamNumber() > FF_TEAM_LAST ) + continue; + + AddSection( TYPE_TEAM, g_Teams[i]->GetTeamNumber() ); + } } else { - AddSection( TYPE_TEAM, TEAM_UNASSIGNED ); + AddSection( TYPE_TEAM, FF_TEAM_UNASSIGNED ); } - AddSection( TYPE_TEAM, TEAM_SPECTATOR ); + AddSection( TYPE_SPECTATORS, FF_TEAM_SPECTATE ); } //----------------------------------------------------------------------------- @@ -366,7 +369,7 @@ void CHL2MPClientScoreBoardDialog::UpdateTeamInfo() } // update the team sections in the scoreboard - for ( int i = TEAM_SPECTATOR; i < TEAM_MAXCOUNT; i++ ) + for ( int i = FF_TEAM_SPECTATE; i <= FF_TEAM_LAST; i++ ) { wchar_t *teamName = NULL; int sectionID = 0; @@ -497,20 +500,13 @@ void CHL2MPClientScoreBoardDialog::AddSection(int teamType, int teamNumber) int CHL2MPClientScoreBoardDialog::GetSectionFromTeamNumber( int teamNumber ) { - // FF hacked in, need to do proper scoreboard - switch ( teamNumber ) - { - case FF_TEAM_ONE: - return SCORESECTION_COMBINE; - case FF_TEAM_TWO: - return SCORESECTION_REBELS; - case TEAM_SPECTATOR: - return SCORESECTION_SPECTATOR; - case FF_TEAM_UNASSIGNED: - return SCORESECTION_FREEFORALL; + if( teamNumber >= FF_TEAM_ONE && teamNumber <= FF_TEAM_LAST ) + return teamNumber - 1; - } - return SCORESECTION_FREEFORALL; + if( teamNumber == FF_TEAM_SPECTATE ) + return FF_TEAM_LAST; + + return FF_TEAM_LAST + 1; } //----------------------------------------------------------------------------- diff --git a/mp/src/game/server/baseanimating.h b/mp/src/game/server/baseanimating.h index 9dec53d2..4d89d557 100644 --- a/mp/src/game/server/baseanimating.h +++ b/mp/src/game/server/baseanimating.h @@ -15,6 +15,7 @@ #include "studio.h" #include "datacache/idatacache.h" #include "tier0/threadtools.h" +#include "ff_sv_base_ff_goal.h" // FF: --> hlstriker: Added struct animevent_t; @@ -26,10 +27,10 @@ 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 CBaseEntity +class CBaseAnimating : public CFF_SV_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. { public: - DECLARE_CLASS( CBaseAnimating, CBaseEntity ); + DECLARE_CLASS( CBaseAnimating, CFF_SV_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. CBaseAnimating(); ~CBaseAnimating(); diff --git a/mp/src/game/server/basetoggle.h b/mp/src/game/server/basetoggle.h index 259fa275..c6c1db98 100644 --- a/mp/src/game/server/basetoggle.h +++ b/mp/src/game/server/basetoggle.h @@ -10,11 +10,12 @@ #pragma once #include "baseentity.h" +#include "ff_sv_base_ff_goal.h" // FF: --> hlstriker: Added -class CBaseToggle : public CBaseEntity +class CBaseToggle : public CFF_SV_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. { - DECLARE_CLASS( CBaseToggle, CBaseEntity ); + DECLARE_CLASS( CBaseToggle, CFF_SV_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. public: CBaseToggle(); diff --git a/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.cpp b/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.cpp new file mode 100644 index 00000000..8c731bce --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.cpp @@ -0,0 +1,27 @@ +#include "cbase.h" +#include "ff_sv_base_ff_goal.h" + + +// Don't link this class to an entity. This class is only to be for inheritance. +//LINK_ENTITY_TO_CLASS( base_ff_goal, CFF_SV_BaseFFGoal ); + +BEGIN_DATADESC( CFF_SV_BaseFFGoal ) +END_DATADESC() + + +bool CanActivateGoal(CBasePlayer *pActivator) +{ + // TODO: Check to see if this player needs to be on a certain team to activate this goal. + // --> + + // TODO: Check to see if this player needs to be a certain class to activate this goal. + // --> + + // TODO: Check to see if this player needs to own a certain item_ff_goal. + // --> + + // TODO: Check to see if this player needs to NOT own a certain item_ff_goal. + // --> + + return true; +} \ No newline at end of file diff --git a/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.h b/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.h new file mode 100644 index 00000000..d8c2cdb6 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_base_ff_goal.h @@ -0,0 +1,23 @@ +#pragma once + +#ifndef FF_SV_BASE_FF_GOAL_H +#define FF_SV_BASE_FF_GOAL_H + +#include "ff_sv_teamcheck_target.h" + + +class CFF_SV_BaseFFGoal : public CFF_SV_TeamcheckTarget +{ +public: + DECLARE_CLASS( CFF_SV_BaseFFGoal, CFF_SV_TeamcheckTarget ); + DECLARE_DATADESC(); + + CFF_SV_BaseFFGoal() + { + } + +private: + bool CanActivateGoal(CBasePlayer *pActivator); +}; + +#endif // FF_SV_BASE_FF_GOAL_H diff --git a/mp/src/game/server/ff/entities/ff_sv_env_ff_message.cpp b/mp/src/game/server/ff/entities/ff_sv_env_ff_message.cpp new file mode 100644 index 00000000..1c170fb9 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_env_ff_message.cpp @@ -0,0 +1,170 @@ +#include "cbase.h" +#include "ff_sv_env_ff_message.h" +#include "ff_sv_util.h" + + +LINK_ENTITY_TO_CLASS( env_ff_message, CFF_SV_EnvFFMessage ); + +BEGIN_DATADESC( CFF_SV_EnvFFMessage ) + // Keyfields. + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToAll, FIELD_STRING, "msg_to_all" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToActivator, FIELD_STRING, "msg_to_activator" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToNonActivator, FIELD_STRING, "msg_to_non_activator" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToActivatorsTeams, FIELD_STRING, "msg_to_activators_teams" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToNonActivatorsTeams, FIELD_STRING, "msg_to_non_activators_teams" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToOwnerTeams, FIELD_STRING, "msg_to_owner_teams" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToNonOwnerTeams, FIELD_STRING, "msg_to_non_owner_teams" ), + + // Inputs. + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgAll", Input_ShowMsgAll ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgActivator", Input_ShowMsgActivator ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgNonActivator", Input_ShowMsgNonActivator ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgActivatorTeams", Input_ShowMsgActivatorTeams ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgNonActivatorTeams", Input_ShowMsgNonActivatorTeams ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgOwnerTeams", Input_ShowMsgOwnerTeams ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgNonOwnerTeams", Input_ShowMsgNonOwnerTeams ), +END_DATADESC() + + +void CFF_SV_EnvFFMessage::Input_ShowMessages( inputdata_t &inputdata ) +{ + // TODO: + DevMsg("Implement Input_ShowMessages\n"); + return; + + // TODO: We need to make an array of all players connected, and when we send a message to one of them we need to remove them from the array so they can't have a lower priority msg sent to them. + + // Priority: activator, (activator teams, non activator team), (owner teams, non owner teams), non activator, all + CRecipientFilter filter; + CBasePlayer *pActivator = dynamic_cast(inputdata.pActivator); + + if( pActivator ) + { + // Message to activator. + if( m_iszMessageToActivator != NULL_STRING ) + { + filter.AddRecipient(pActivator); + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivator) ); + return; + } + + // Message to activator teams. + if( m_iszMessageToActivatorsTeams != NULL_STRING ) + { + filter.AddRecipientsByTeam( pActivator->GetTeam() ); + + // TODO: Add allied teams. + // --> + + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivatorsTeams) ); + return; + } + + // Message to non-activator teams. + if( m_iszMessageToNonActivatorsTeams != NULL_STRING ) + { + filter.AddAllPlayers(); + filter.RemoveRecipientsByTeam( pActivator->GetTeam() ); + + // TODO: Remove allied teams. + // --> + + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToNonActivatorsTeams) ); + return; + } + } + + // TODO: Implement owner teams and non-owner teams when goals are finished. + // --> + + if( m_iszMessageToNonActivator != NULL_STRING ) + { + // + } +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgAll( inputdata_t &inputdata ) +{ + if( !m_iszMessageToAll ) + return; + + FF_UTIL_HudMessageAll( -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToAll) ); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgActivator( inputdata_t &inputdata ) +{ + if( !m_iszMessageToActivator ) + return; + + CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); + if( !pPlayer ) + return; + + CRecipientFilter filter; + filter.AddRecipient( pPlayer ); + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivator) ); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgNonActivator( inputdata_t &inputdata ) +{ + if( !m_iszMessageToNonActivator ) + return; + + CRecipientFilter filter; + filter.AddAllPlayers(); + + CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); + if( pPlayer ) + filter.RemoveRecipient(pPlayer); + + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToNonActivator) ); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgActivatorTeams( inputdata_t &inputdata ) +{ + if( !m_iszMessageToActivatorsTeams ) + return; + + CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); + if( !pPlayer ) + return; + + CRecipientFilter filter; + filter.AddRecipientsByTeam( pPlayer->GetTeam() ); + + // TODO: Add allied teams. + // --> + + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivatorsTeams) ); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgNonActivatorTeams( inputdata_t &inputdata ) +{ + if( !m_iszMessageToNonActivatorsTeams ) + return; + + CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); + if( !pPlayer ) + return; + + CRecipientFilter filter; + filter.AddAllPlayers(); + filter.RemoveRecipientsByTeam( pPlayer->GetTeam() ); + + // TODO: Remove allied teams. + // --> + + FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToNonActivatorsTeams) ); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgOwnerTeams( inputdata_t &inputdata ) +{ + // TODO: Need goal entity implemented first. + DevMsg("Implement Input_ShowMsgOwnerTeams\n"); +} + +void CFF_SV_EnvFFMessage::Input_ShowMsgNonOwnerTeams( inputdata_t &inputdata ) +{ + // TODO: Need goal entity implemented first. + DevMsg("Implement Input_ShowMsgNonOwnerTeams\n"); +} diff --git a/mp/src/game/server/ff/entities/ff_sv_env_ff_message.h b/mp/src/game/server/ff/entities/ff_sv_env_ff_message.h new file mode 100644 index 00000000..95eb6b01 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_env_ff_message.h @@ -0,0 +1,44 @@ +#pragma once + +#ifndef FF_SV_ENV_FF_MESSAGE_H +#define FF_SV_ENV_FF_MESSAGE_H + + +class CFF_SV_EnvFFMessage : public CBaseEntity +{ +public: + DECLARE_CLASS( CFF_SV_EnvFFMessage, CBaseEntity ); + DECLARE_DATADESC(); + + CFF_SV_EnvFFMessage() + { + m_clrMesssage.r = 200; + m_clrMesssage.g = 200; + m_clrMesssage.b = 200; + m_clrMesssage.a = 255; + } + +private: + color32 m_clrMesssage; + + string_t m_iszMessageToAll; + string_t m_iszMessageToActivator; + string_t m_iszMessageToNonActivator; + string_t m_iszMessageToActivatorsTeams; + string_t m_iszMessageToNonActivatorsTeams; + string_t m_iszMessageToOwnerTeams; + string_t m_iszMessageToNonOwnerTeams; + + void Input_ShowMsgAll( inputdata_t &inputdata ); + void Input_ShowMsgActivator( inputdata_t &inputdata ); + void Input_ShowMsgNonActivator( inputdata_t &inputdata ); + void Input_ShowMsgActivatorTeams( inputdata_t &inputdata ); + void Input_ShowMsgNonActivatorTeams( inputdata_t &inputdata ); + void Input_ShowMsgOwnerTeams( inputdata_t &inputdata ); + void Input_ShowMsgNonOwnerTeams( inputdata_t &inputdata ); + + void Input_ShowMessages( inputdata_t &inputdata ); +}; + + +#endif // FF_SV_ENV_FF_MESSAGE_H diff --git a/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.cpp b/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.cpp new file mode 100644 index 00000000..68c94a25 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.cpp @@ -0,0 +1,122 @@ +#include "cbase.h" +#include "ff_sv_info_ff_team_manager.h" + + +LINK_ENTITY_TO_CLASS( info_ff_team_manager, CFF_SV_InfoFFTeamManager ); + +BEGIN_DATADESC( CFF_SV_InfoFFTeamManager ) + // Keyfields. + DEFINE_KEYFIELD_NOT_SAVED( m_iTeamNum, FIELD_INTEGER, "team_num" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszTeamName, FIELD_STRING, "team_name" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iMaxPlayers, FIELD_INTEGER, "maxplayers" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iszAllies, FIELD_STRING, "allies" ), + DEFINE_KEYFIELD_NOT_SAVED( m_clrTeamColor, FIELD_COLOR32, "team_color" ), + + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_SCOUT], FIELD_INTEGER, "max_scout" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_SNIPER], FIELD_INTEGER, "max_sniper" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_SOLDIER], FIELD_INTEGER, "max_soldier" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_DEMOMAN], FIELD_INTEGER, "max_demoman" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_MEDIC], FIELD_INTEGER, "max_medic" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_HWGUY], FIELD_INTEGER, "max_hwguy" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_PYRO], FIELD_INTEGER, "max_pyro" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_SPY], FIELD_INTEGER, "max_spy" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_ENGINEER], FIELD_INTEGER, "max_engineer" ), + DEFINE_KEYFIELD_NOT_SAVED( m_iClassLimits[FF_CLASS_CIVILIAN], FIELD_INTEGER, "max_civilian" ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CFF_SV_InfoFFTeamManager, DT_FF_InfoFFTeamManager ) + SendPropInt( SENDINFO( m_iAllies ) ), + SendPropInt( SENDINFO( m_iMaxPlayers ) ), + SendPropInt( SENDINFO( m_clrTeamColor ) ), + SendPropArray3( SENDINFO_ARRAY3( m_iClassLimits ), SendPropInt( SENDINFO_ARRAY( m_iClassLimits ) ) ), +END_SEND_TABLE() + + +void CFF_SV_InfoFFTeamManager::Spawn() +{ + // Increase the team number by 1 since FF_TEAM_ONE actually has the value of 2. + m_iTeamNum++; + + if( m_iTeamNum < FF_TEAM_ONE || m_iTeamNum > FF_TEAM_LAST ) + return; + + // Make sure this team number doesn't already exist in the teams list. + for( int i=0; iGetTeamNumber() == m_iTeamNum ) + return; + } + + if( m_iszTeamName != NULL_STRING ) + SetTeamName( STRING(m_iszTeamName) ); + + CUtlVector allies; + Q_SplitString( STRING(m_iszAllies), ",", allies ); + + int iAllyTeam; + for( int i=0; i FF_TEAM_LAST ) + continue; + + m_iAllies |= FF_TEAM_BITS[iAllyTeam]; + } + + BaseClass::Init( STRING(m_iszTeamName), m_iTeamNum ); + g_Teams.AddToTail( this ); +} + +void CFF_SV_InfoFFTeamManager::SetTeamName( const char *pTeamName ) +{ + if( !pTeamName ) + return; + + Q_strncpy( m_szTeamname.GetForModify(), pTeamName, MAX_TEAM_NAME_LENGTH ); +} + +bool CFF_SV_InfoFFTeamManager::TryChangeTeam( CFF_SV_Player &pPlayer, int iNewTeam ) +{ + if( iNewTeam == FF_TEAM_AUTO_ASSIGN ) + iNewTeam = GetAutoAssignTeam(); + + if ( iNewTeam < FF_TEAM_SPECTATE || iNewTeam > FF_TEAM_LAST ) + return false; + + int iCurrentTeam = pPlayer.GetTeamNumber(); + if ( iCurrentTeam == iNewTeam ) + return false; + + // Make sure this team exists. + CFF_SV_InfoFFTeamManager *pTeam = dynamic_cast(GetGlobalTeam( iNewTeam )); + if( !pTeam ) + return false; + + // Make sure this team isn't full. + if( pTeam->IsTeamFull() ) + return false; + + // TODO: Lua player_switchteam predicate here. + // --> + + // refactored this, so each step of the process is seperate chunks, + // since so much per-class state is handled in each + pPlayer.PreChangeTeam( iCurrentTeam, iNewTeam ); + pPlayer.ChangeTeam( iNewTeam ); + pPlayer.PostChangeTeam( iCurrentTeam, iNewTeam ); + return true; +} + +int CFF_SV_InfoFFTeamManager::GetAutoAssignTeam() +{ + // TODO: Implement the auto assign code. + return FF_TEAM_ONE; +} + +bool CFF_SV_InfoFFTeamManager::IsTeamFull() +{ + // TODO: Implement this. + // --> + + return false; +} \ No newline at end of file diff --git a/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.h b/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.h new file mode 100644 index 00000000..6872b5ee --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_team_manager.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef FF_SV_INFO_FF_TEAM_MANAGER_H +#define FF_SV_INFO_FF_TEAM_MANAGER_H + +#include "team.h" +#include "ff_sh_shareddefs.h" +#include "ff_sv_player.h" + + +class CFF_SV_InfoFFTeamManager : public CTeam +{ +public: + DECLARE_CLASS( CFF_SV_InfoFFTeamManager, CTeam ); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CFF_SV_InfoFFTeamManager() + { + m_iAllies = 0; + m_iTeamNum = 0; + } + + void Spawn( void ); + void SetTeamName( const char *pTeamName ); + bool IsTeamFull( void ); + + CNetworkVar( int, m_iAllies ); + CNetworkArray( int, m_iClassLimits, FF_CLASS_COUNT ); + CNetworkVar( int, m_iMaxPlayers ); + CNetworkColor32( m_clrTeamColor ); + + string_t m_iszTeamName; + string_t m_iszAllies; + + static bool TryChangeTeam( CFF_SV_Player &pPlayer, int iNewTeam ); + static int GetAutoAssignTeam(); +}; + + +#endif // FF_SV_INFO_FF_TEAM_MANAGER_H diff --git a/mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.cpp b/mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.cpp similarity index 57% rename from mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.cpp rename to mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.cpp index 7bcd729a..5f267f42 100644 --- a/mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.cpp +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.cpp @@ -1,11 +1,11 @@ #include "cbase.h" #include "ff_sh_util.h" -#include "ff_sv_point_ff_teamcheck.h" +#include "ff_sv_info_ff_teamcheck.h" -LINK_ENTITY_TO_CLASS( point_ff_teamcheck, CFF_SV_PointFFTeamCheck ); +LINK_ENTITY_TO_CLASS( info_ff_teamcheck, CFF_SV_InfoFFTeamCheck ); -BEGIN_DATADESC( CFF_SV_PointFFTeamCheck ) +BEGIN_DATADESC( CFF_SV_InfoFFTeamCheck ) // Keyfields. DEFINE_KEYFIELD_NOT_SAVED( m_iTeamsAllowed, FIELD_INTEGER, "teams_allowed" ), @@ -15,17 +15,17 @@ BEGIN_DATADESC( CFF_SV_PointFFTeamCheck ) END_DATADESC() -void CFF_SV_PointFFTeamCheck::InputSetTeamsAllowed( inputdata_t &inputdata ) +void CFF_SV_InfoFFTeamCheck::InputSetTeamsAllowed( inputdata_t &inputdata ) { m_iTeamsAllowed = inputdata.value.Int(); } -void CFF_SV_PointFFTeamCheck::InputSwapTeams( inputdata_t &inputdata ) +void CFF_SV_InfoFFTeamCheck::InputSwapTeams( inputdata_t &inputdata ) { m_iTeamsAllowed = ~m_iTeamsAllowed; } -bool CFF_SV_PointFFTeamCheck::IsTeamAllowed(int iTeamNum) +bool CFF_SV_InfoFFTeamCheck::IsTeamAllowed(int iTeamNum) { if(!m_iTeamsAllowed) return true; diff --git a/mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.h b/mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.h new file mode 100644 index 00000000..86958b58 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_teamcheck.h @@ -0,0 +1,27 @@ +#pragma once + +#ifndef FF_SV_INFO_FF_TEAMCHECK_H +#define FF_SV_INFO_FF_TEAMCHECK_H + + +class CFF_SV_InfoFFTeamCheck : public CBaseEntity +{ +public: + DECLARE_CLASS( CFF_SV_InfoFFTeamCheck, CBaseEntity ); + DECLARE_DATADESC(); + + CFF_SV_InfoFFTeamCheck() + { + } + + bool IsTeamAllowed(int iTeamNum); + +private: + void InputSetTeamsAllowed( inputdata_t &inputdata ); + void InputSwapTeams( inputdata_t &inputdata ); + + int m_iTeamsAllowed; +}; + + +#endif // FF_SV_INFO_FF_TEAMCHECK_H 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 9571aca8..9fed82cc 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 @@ -4,10 +4,10 @@ #include "ammodef.h" -class CFF_SV_InfoFFWeaponSpawner : public CFF_SV_TeamcheckTarget +class CFF_SV_InfoFFWeaponSpawner : public CBaseAnimating { public: - DECLARE_CLASS( CFF_SV_InfoFFWeaponSpawner, CFF_SV_TeamcheckTarget ); + DECLARE_CLASS( CFF_SV_InfoFFWeaponSpawner, CBaseAnimating ); DECLARE_DATADESC(); DECLARE_SERVERCLASS(); @@ -17,12 +17,14 @@ public: SetThink(NULL); } - void Spawn( void ); - void ForceNextSpawn( void ); - void SetWait( void ); - void ThinkNextSpawn( void ); + void Spawn( void ); + void Precache( void ); + void ForceNextSpawn( void ); + void SetWait( void ); + void ThinkNextSpawn( void ); + int UpdateTransmitState( void ); - void OnTouch( CBaseEntity *pOther ); + void OnTouch( CBaseEntity *pOther ); private: int m_iWeaponsAllowed; @@ -61,8 +63,27 @@ IMPLEMENT_SERVERCLASS_ST( CFF_SV_InfoFFWeaponSpawner, DT_FF_InfoFFWeaponSpawner END_SEND_TABLE() +#define SOUND_AMMO_PICKUP "Player.PickupWeapon" +#define SOUND_WEAPON_RESPAWN "weapons/physcannon/physcannon_drop.wav" + + +void CFF_SV_InfoFFWeaponSpawner::Precache( void ) +{ + PrecacheScriptSound(SOUND_AMMO_PICKUP); + PrecacheScriptSound(SOUND_WEAPON_RESPAWN); + BaseClass::Precache(); +} + +int CFF_SV_InfoFFWeaponSpawner::UpdateTransmitState() +{ + // We have to call this since EF_NODRAW will set it to FL_EDICT_DONTSEND. + return FL_EDICT_PVSCHECK; +} + void CFF_SV_InfoFFWeaponSpawner::Spawn() { + Precache(); + m_iNumInArray = 0; for(int iWeaponNum=0; iWeaponNumMaxCarry(m_hWeapon->GetPrimaryAmmoType()) + m_hWeapon->GetMaxClip1() ) * m_fGiveAmmoScale; CBaseCombatWeapon *pOwnedWeapon = pPlayer->Weapon_OwnsThisType(m_hWeapon->GetName()); @@ -136,6 +155,20 @@ void CFF_SV_InfoFFWeaponSpawner::OnTouch( CBaseEntity *pOther ) pOwnedWeapon->m_iClip1 = pOwnedWeapon->GetMaxClip1(); } */ + else + { + // Play ammo pickup sound only if they already own the weapon. + CRecipientFilter filter; + filter.AddRecipientsByPVS(GetAbsOrigin()); + filter.MakeReliable(); + + EmitSound_t params; + params.m_pSoundName = SOUND_AMMO_PICKUP; + params.m_SoundLevel = SNDLVL_80dB; + + if(filter.GetRecipientCount()) + EmitSound(filter, ENTINDEX(this), params); + } // Put the rest of the ammo in their reserve. if(ammoToGive > 0) @@ -144,6 +177,9 @@ void CFF_SV_InfoFFWeaponSpawner::OnTouch( CBaseEntity *pOther ) m_hWeapon->SetLocalOrigin( pPlayer->GetLocalOrigin() ); m_hWeapon->Touch(pPlayer); m_hWeapon = NULL; + + // Wait to respawn. + SetWait(); } void CFF_SV_InfoFFWeaponSpawner::SetWait() @@ -210,6 +246,16 @@ void CFF_SV_InfoFFWeaponSpawner::ForceNextSpawn() RemoveEffects(EF_NODRAW); SetTouch( &CFF_SV_InfoFFWeaponSpawner::OnTouch ); + + // Play respawn sound. + CRecipientFilter filter; + filter.AddRecipientsByPVS(GetAbsOrigin()); + filter.MakeReliable(); + + EmitSound_t params; + params.m_pSoundName = SOUND_WEAPON_RESPAWN; + params.m_SoundLevel = SNDLVL_IDLE; + EmitSound(filter, ENTINDEX(this), params); } void CFF_SV_InfoFFWeaponSpawner::DeletePreviousWeapon() 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 91e9e1f5..50d81e4b 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,12 +1,11 @@ #include "cbase.h" -#include "ff_sv_util.h" #include "ff_sv_teamcheck_target.h" -class CFF_SV_ItemFFGoal : public CFF_SV_TeamcheckTarget +class CFF_SV_ItemFFGoal : public CBaseAnimating { public: - DECLARE_CLASS( CFF_SV_ItemFFGoal, CFF_SV_TeamcheckTarget ); + DECLARE_CLASS( CFF_SV_ItemFFGoal, CBaseAnimating ); DECLARE_DATADESC(); CFF_SV_ItemFFGoal() @@ -46,12 +45,10 @@ private: float m_fActiveTime; // How long to stay in the active state. float m_fActiveDelay; // How long to wait before going in the active state. + // TODO: These probably don't need to be EHANDLEs unless we network them... EHANDLE m_hGoalActivator; // The player that activated this goal (this is not always the owner). EHANDLE m_hGoalOwner; // The player that owns this goal (this is not always the activator). - string_t m_iszActivatedMsgToAll; // The message sent to everyone when the goal is activated. - string_t m_iszActivatedMsgToOwner; // The message sent to the owner when the goal is activated. - string_t m_iszSoundName; }; @@ -65,9 +62,6 @@ BEGIN_DATADESC( CFF_SV_ItemFFGoal ) DEFINE_KEYFIELD_NOT_SAVED( m_fActiveTime, FIELD_FLOAT, "active_time" ), DEFINE_KEYFIELD_NOT_SAVED( m_fActiveDelay, FIELD_FLOAT, "active_delay" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszActivatedMsgToAll, FIELD_STRING, "msg_activated_to_all" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszActivatedMsgToOwner, FIELD_STRING, "msg_activated_to_owner" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszSoundName, FIELD_SOUNDNAME, "sound" ), // Goal touch functions. @@ -188,13 +182,6 @@ void CFF_SV_ItemFFGoal::ThinkDoActive() { AddEffects( EF_NODRAW ); - CBasePlayer *pActivator = dynamic_cast(m_hGoalActivator.Get()); - if( pActivator ) - { - color32 color = {200, 200, 200, 255}; - FF_UTIL_HudMessageFormat( pActivator, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, color, color, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszActivatedMsgToOwner) ); - } - if( m_iszSoundName.ToCStr()[0] ) { CRecipientFilter filter; @@ -203,8 +190,10 @@ void CFF_SV_ItemFFGoal::ThinkDoActive() EmitSound_t params; params.m_pSoundName = m_iszSoundName.ToCStr(); + params.m_SoundLevel = SNDLVL_NORM; - EmitSound( filter, ENTINDEX(this), params ); + if( filter.GetRecipientCount() ) + EmitSound( filter, ENTINDEX(this), params ); } // Start setting inactive. diff --git a/mp/src/game/server/ff/entities/ff_sv_point_ff_message.cpp b/mp/src/game/server/ff/entities/ff_sv_point_ff_message.cpp deleted file mode 100644 index 42ada3a9..00000000 --- a/mp/src/game/server/ff/entities/ff_sv_point_ff_message.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "cbase.h" -#include "ff_sv_util.h" - - -class CFF_SV_PointFFMessage : public CBaseEntity -{ -public: - DECLARE_CLASS( CFF_SV_PointFFMessage, CBaseEntity ); - DECLARE_DATADESC(); - - CFF_SV_PointFFMessage() - { - m_clrMesssage.r = 200; - m_clrMesssage.g = 200; - m_clrMesssage.b = 200; - m_clrMesssage.a = 255; - } - -private: - color32 m_clrMesssage; - - string_t m_iszMessageToAll; - string_t m_iszMessageToActivator; - string_t m_iszMessageToNonActivator; - string_t m_iszMessageToActivatorsTeams; - string_t m_iszMessageToNonActivatorsTeam; - - void Input_ShowMsgAll( inputdata_t &inputdata ); - void Input_ShowMsgActivator( inputdata_t &inputdata ); - void Input_ShowMsgNonActivator( inputdata_t &inputdata ); - void Input_ShowMsgActivatorTeam( inputdata_t &inputdata ); - void Input_ShowMsgNonActivatorTeam( inputdata_t &inputdata ); - - void ShowDefaultMessage( CRecipientFilter &filter ); -}; - - -LINK_ENTITY_TO_CLASS( point_ff_message, CFF_SV_PointFFMessage ); - -BEGIN_DATADESC( CFF_SV_PointFFMessage ) - // Goal keyfields. - DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToAll, FIELD_STRING, "msg_to_all" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToActivator, FIELD_STRING, "msg_to_activator" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToNonActivator, FIELD_STRING, "msg_to_non_activator" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToActivatorsTeams, FIELD_STRING, "msg_to_activators_team" ), - DEFINE_KEYFIELD_NOT_SAVED( m_iszMessageToNonActivatorsTeam, FIELD_STRING, "msg_to_non_activators_team" ), - - // Goal inputs. - DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgAll", Input_ShowMsgAll ), - DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgActivator", Input_ShowMsgActivator ), - DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgNonActivator", Input_ShowMsgNonActivator ), - DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgActivatorTeam", Input_ShowMsgActivatorTeam ), - DEFINE_INPUTFUNC( FIELD_VOID, "ShowMsgNonActivatorTeam", Input_ShowMsgNonActivatorTeam ), -END_DATADESC() - - -void CFF_SV_PointFFMessage::ShowDefaultMessage( CRecipientFilter &filter ) -{ - if( !m_iszMessageToAll ) - return; - - FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToAll) ); -} - -void CFF_SV_PointFFMessage::Input_ShowMsgAll( inputdata_t &inputdata ) -{ - if( !m_iszMessageToAll ) - return; - - FF_UTIL_HudMessageAll( -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToAll) ); -} - -void CFF_SV_PointFFMessage::Input_ShowMsgActivator( inputdata_t &inputdata ) -{ - CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); - if( !pPlayer ) - return; - - CRecipientFilter filter; - filter.AddRecipient( pPlayer ); - - if( !m_iszMessageToActivator ) - { - ShowDefaultMessage( filter ); - return; - } - - FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivator) ); -} - -void CFF_SV_PointFFMessage::Input_ShowMsgNonActivator( inputdata_t &inputdata ) -{ - CRecipientFilter filter; - filter.AddAllPlayers(); - - CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); - if( pPlayer ) - filter.RemoveRecipient(pPlayer); - - if( !m_iszMessageToNonActivator ) - { - ShowDefaultMessage( filter ); - return; - } - - FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToNonActivator) ); -} - -void CFF_SV_PointFFMessage::Input_ShowMsgActivatorTeam( inputdata_t &inputdata ) -{ - CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); - if( !pPlayer ) - return; - - CRecipientFilter filter; - filter.AddRecipientsByTeam( pPlayer->GetTeam() ); - - if( !m_iszMessageToActivatorsTeams ) - { - ShowDefaultMessage( filter ); - return; - } - - FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToActivatorsTeams) ); -} - -void CFF_SV_PointFFMessage::Input_ShowMsgNonActivatorTeam( inputdata_t &inputdata ) -{ - CBasePlayer *pPlayer = dynamic_cast(inputdata.pActivator); - if( !pPlayer ) - return; - - CRecipientFilter filter; - filter.AddAllPlayers(); - filter.RemoveRecipientsByTeam( pPlayer->GetTeam() ); - - if( !m_iszMessageToNonActivatorsTeam ) - { - ShowDefaultMessage( filter ); - return; - } - - FF_UTIL_HudMessage( filter, -1.0f, 0.7f, HUD_EFFECT_FADE_IN_OUT, m_clrMesssage, m_clrMesssage, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszMessageToNonActivatorsTeam) ); -} diff --git a/mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.h b/mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.h deleted file mode 100644 index 046b4788..00000000 --- a/mp/src/game/server/ff/entities/ff_sv_point_ff_teamcheck.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifndef FF_SV_POINT_FF_TEAMCHECK_H -#define FF_SV_POINT_FF_TEAMCHECK_H - - -class CFF_SV_PointFFTeamCheck : public CBaseEntity -{ -public: - DECLARE_CLASS( CFF_SV_PointFFTeamCheck, CBaseEntity ); - DECLARE_DATADESC(); - - CFF_SV_PointFFTeamCheck() - { - } - - bool IsTeamAllowed(int iTeamNum); - -private: - void InputSetTeamsAllowed( inputdata_t &inputdata ); - void InputSwapTeams( inputdata_t &inputdata ); - - int m_iTeamsAllowed; -}; - - -#endif // FF_SV_POINT_FF_TEAMCHECK_H diff --git a/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.cpp b/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.cpp index 71bb22e0..42c7b9ef 100644 --- a/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.cpp +++ b/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.cpp @@ -1,5 +1,5 @@ #include "cbase.h" -#include "ff_sv_point_ff_teamcheck.h" +#include "ff_sv_info_ff_teamcheck.h" #include "ff_sv_teamcheck_target.h" @@ -17,7 +17,7 @@ bool CFF_SV_TeamcheckTarget::IsTeamAllowed( int iTeamNum ) if( !m_iszTeamTarget ) return true; - CFF_SV_PointFFTeamCheck *pEnt = dynamic_cast( gEntList.FindEntityByName( NULL, m_iszTeamTarget ) ); + CFF_SV_InfoFFTeamCheck *pEnt = dynamic_cast( gEntList.FindEntityByName( NULL, m_iszTeamTarget ) ); if( !pEnt ) return true; diff --git a/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.h b/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.h index e243a36c..3d4724f1 100644 --- a/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.h +++ b/mp/src/game/server/ff/entities/ff_sv_teamcheck_target.h @@ -3,12 +3,13 @@ #ifndef FF_SV_TEAMCHECK_TARGET_H #define FF_SV_TEAMCHECK_TARGET_H +#include "ff_sv_env_ff_message.h" -// NOTE: We might just have to delete this entity and place all the code in CBaseEntity. Unless we find a way to derive from multiple classes. -class CFF_SV_TeamcheckTarget : public CBaseAnimating + +class CFF_SV_TeamcheckTarget : public CFF_SV_EnvFFMessage { public: - DECLARE_CLASS( CFF_SV_TeamcheckTarget, CBaseAnimating ); + DECLARE_CLASS( CFF_SV_TeamcheckTarget, CFF_SV_EnvFFMessage ); DECLARE_DATADESC(); CFF_SV_TeamcheckTarget() diff --git a/mp/src/game/server/ff/ff_sv_player.cpp b/mp/src/game/server/ff/ff_sv_player.cpp index cfee8537..2a72b8a1 100644 --- a/mp/src/game/server/ff/ff_sv_player.cpp +++ b/mp/src/game/server/ff/ff_sv_player.cpp @@ -25,7 +25,7 @@ #include "SoundEmitterSystem/isoundemittersystembase.h" #include "ilagcompensationmanager.h" -#include "ff_sh_team_manager.h" +#include "ff_sv_info_ff_team_manager.h" // Don't alias here @@ -63,6 +63,7 @@ IMPLEMENT_SERVERCLASS_ST(CFF_SV_Player, DT_FF_Player) // SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ), // SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ), + SendPropFloat( SENDINFO( m_flNextJumpTimeForDouble) ), END_SEND_TABLE() BEGIN_DATADESC( CFF_SV_Player ) @@ -844,15 +845,15 @@ void CFF_SV_Player::ChangeTeam( int iTeam ) bool bKill = false; - if ( FFRules()->IsTeamplay() != true && iTeam != TEAM_SPECTATOR ) + if ( FFRules()->IsTeamplay() != true && iTeam != FF_TEAM_SPECTATE ) { //don't let them try to join combine or rebels during deathmatch. - iTeam = TEAM_UNASSIGNED; + iTeam = FF_TEAM_UNASSIGNED; } if ( FFRules()->IsTeamplay() == true ) { - if ( iTeam != GetTeamNumber() && GetTeamNumber() != TEAM_UNASSIGNED ) + if ( iTeam != GetTeamNumber() && GetTeamNumber() != FF_TEAM_UNASSIGNED ) { bKill = true; } @@ -871,7 +872,7 @@ void CFF_SV_Player::ChangeTeam( int iTeam ) SetPlayerModel(); } - if ( iTeam == TEAM_SPECTATOR ) + if ( iTeam == FF_TEAM_SPECTATE ) { RemoveAllItems( true ); @@ -889,7 +890,7 @@ bool CFF_SV_Player::ClientCommand( const CCommand &args ) if( FStrEq(args[0], "spectate") ) { if( ShouldRunRateLimitedCommand(args) ) - CFF_SH_TeamManager::HandlePlayerTeamCommand( *this, FF_TEAM_SPECTATE ); + CFF_SV_InfoFFTeamManager::TryChangeTeam( *this, FF_TEAM_SPECTATE ); return true; } @@ -901,7 +902,10 @@ bool CFF_SV_Player::ClientCommand( const CCommand &args ) int iNewTeam = Q_atoi(args[1]) + 1; if( iNewTeam >= FF_TEAM_ONE ) - CFF_SH_TeamManager::HandlePlayerTeamCommand( *this, iNewTeam ); + { + if( CFF_SV_InfoFFTeamManager::TryChangeTeam( *this, iNewTeam ) ) + DevMsg("Changing to team %i\n", iNewTeam); + } return true; } diff --git a/mp/src/game/server/ff/ff_sv_player.h b/mp/src/game/server/ff/ff_sv_player.h index 148e5ead..fb2d47df 100644 --- a/mp/src/game/server/ff/ff_sv_player.h +++ b/mp/src/game/server/ff/ff_sv_player.h @@ -143,6 +143,8 @@ public: void PostChangeTeam( int iOldTeam, int iNewTeam ); void KillPlayer( void ); + + CNetworkVar( float, m_flNextJumpTimeForDouble ); private: CNetworkQAngle( m_angEyeAngles ); diff --git a/mp/src/game/server/server_ff.vpc b/mp/src/game/server/server_ff.vpc index 03f24c64..58d3ae89 100644 --- a/mp/src/game/server/server_ff.vpc +++ b/mp/src/game/server/server_ff.vpc @@ -42,13 +42,18 @@ $Project "Server (FF)" } $Folder "Entities" { - $File "ff\entities\ff_sv_item_ff_goal.cpp" - $File "ff\entities\ff_sv_point_ff_teamcheck.cpp" - $File "ff\entities\ff_sv_point_ff_teamcheck.h" - $File "ff\entities\ff_sv_teamcheck_target.h" - $File "ff\entities\ff_sv_teamcheck_target.cpp" - $File "ff\entities\ff_sv_point_ff_message.cpp" + $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/server/team.cpp b/mp/src/game/server/team.cpp index 97df8c5b..4c221f5f 100644 --- a/mp/src/game/server/team.cpp +++ b/mp/src/game/server/team.cpp @@ -57,6 +57,8 @@ LINK_ENTITY_TO_CLASS( team_manager, CTeam ); //----------------------------------------------------------------------------- // Purpose: Get a pointer to the specified team manager //----------------------------------------------------------------------------- +// FF: --> hlstriker: Added own version because it should not be checking the index. +/* CTeam *GetGlobalTeam( int iIndex ) { if ( iIndex < 0 || iIndex >= GetNumberOfTeams() ) @@ -64,6 +66,23 @@ CTeam *GetGlobalTeam( int iIndex ) return g_Teams[ iIndex ]; } +*/ + +CTeam *GetGlobalTeam( int iTeamNum ) +{ + CTeam *pTeam = NULL; + for( int i=0; iGetTeamNumber() != iTeamNum ) + continue; + + pTeam = g_Teams[i]; + break; + } + + return pTeam; +} +// FF: <-- //----------------------------------------------------------------------------- // Purpose: Get the number of team managers diff --git a/mp/src/game/server/team.h b/mp/src/game/server/team.h index 0ed6d796..a430de49 100644 --- a/mp/src/game/server/team.h +++ b/mp/src/game/server/team.h @@ -95,7 +95,7 @@ public: }; extern CUtlVector< CTeam * > g_Teams; -extern CTeam *GetGlobalTeam( int iIndex ); +extern CTeam *GetGlobalTeam( int iNewTeam ); // FF: hlstriker --> Changed iIndex to iNewTeam. extern int GetNumberOfTeams( void ); #endif // TEAM_H diff --git a/mp/src/game/server/util.cpp b/mp/src/game/server/util.cpp index 0848b5fe..e4413674 100644 --- a/mp/src/game/server/util.cpp +++ b/mp/src/game/server/util.cpp @@ -1034,6 +1034,9 @@ void UTIL_HudMessage( CBasePlayer *pToPlayer, const hudtextparms_t &textparms, c // FF --> hlstriker: Added void UTIL_HudMessage( CRecipientFilter &filter, const hudtextparms_t &textparms, const char *pMessage ) { + if(!filter.GetRecipientCount()) + return; + filter.MakeReliable(); UserMessageBegin( filter, "HudMsg" ); diff --git a/mp/src/game/shared/basecombatweapon_shared.cpp b/mp/src/game/shared/basecombatweapon_shared.cpp index c0a0bd02..4854000e 100644 --- a/mp/src/game/shared/basecombatweapon_shared.cpp +++ b/mp/src/game/shared/basecombatweapon_shared.cpp @@ -728,6 +728,8 @@ void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner ) { m_OnPlayerPickup.FireOutput(pNewOwner, this); + // FF --> hlstriker: Commented to use code below. + /* // Play the pickup sound for 1st-person observers CRecipientFilter filter; for ( int i=1; i <= gpGlobals->maxClients; ++i ) @@ -742,6 +744,17 @@ void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner ) { CBaseEntity::EmitSound( filter, pNewOwner->entindex(), "Player.PickupWeapon" ); } + */ + // FF <-- + + // FF --> hlstriker: Play the pickup sound for everyone in PVS instead (not to player that picked up though). + CRecipientFilter filter; + filter.AddRecipientsByPVS( GetAbsOrigin() ); + filter.RemoveRecipient( dynamic_cast(pNewOwner) ); + + if( filter.GetRecipientCount() ) + CBaseEntity::EmitSound( filter, pNewOwner->entindex(), "Player.PickupWeapon" ); + // FF <-- // Robin: We don't want to delete weapons the player has picked up, so // clear the name of the weapon. This prevents wildcards that are meant diff --git a/mp/src/game/shared/ff/ff_sh_gamemovement.cpp b/mp/src/game/shared/ff/ff_sh_gamemovement.cpp index 95d1b466..bec44181 100644 --- a/mp/src/game/shared/ff/ff_sh_gamemovement.cpp +++ b/mp/src/game/shared/ff/ff_sh_gamemovement.cpp @@ -365,9 +365,6 @@ bool CFF_SH_GameMovement::DoDoubleJump( float &flJumpSpeed ) CFF_SH_Player *pFFPlayer = ToFFPlayer(player); Assert(pFFPlayer); - // FF TODO: Move this back into player - static float m_flNextJumpTimeForDouble = 0.0f; - bool bDidDoubleJump = false; // FF TODO: Port the stuff that is needed for this code /* @@ -375,7 +372,7 @@ bool CFF_SH_GameMovement::DoDoubleJump( float &flJumpSpeed ) if( ffplayer->m_bCanDoubleJump && !ffplayer->IsStaticBuilding() ) { */ - float flElapsed = m_flNextJumpTimeForDouble - gpGlobals->curtime; + float flElapsed = pFFPlayer->m_flNextJumpTimeForDouble - gpGlobals->curtime; if (flElapsed > 0 && flElapsed < 0.4f) { @@ -392,7 +389,7 @@ bool CFF_SH_GameMovement::DoDoubleJump( float &flJumpSpeed ) //ffplayer->m_bCanDoubleJump = false; } - m_flNextJumpTimeForDouble = gpGlobals->curtime + 0.5f; + pFFPlayer->m_flNextJumpTimeForDouble = gpGlobals->curtime + 0.5f; /* } */ diff --git a/mp/src/game/shared/ff/ff_sh_gamerules.cpp b/mp/src/game/shared/ff/ff_sh_gamerules.cpp index f92a3354..3c1fc982 100644 --- a/mp/src/game/shared/ff/ff_sh_gamerules.cpp +++ b/mp/src/game/shared/ff/ff_sh_gamerules.cpp @@ -31,7 +31,8 @@ #include "voice_gamemgr.h" #include "ff_sv_dll_interface.h" #include "hl2mp_cvars.h" - #include "ff_sh_team_manager.h" + //#include "ff_sh_team_manager.h" + #include "ff_sv_info_ff_team_manager.h" #include #ifdef DEBUG @@ -186,7 +187,7 @@ char *sTeamNames[] = void CFF_SH_Rules::AddTeam( const char *pTeamName, const int iNum ) { - CFF_SH_TeamManager *pTeam = static_cast(CreateEntityByName( "ff_team_manager" )); + CFF_SV_InfoFFTeamManager *pTeam = static_cast(CreateEntityByName( "info_ff_team_manager" )); if ( pTeam ) { pTeam->Init( pTeamName, iNum ); @@ -197,12 +198,12 @@ void CFF_SH_Rules::AddTeam( const char *pTeamName, const int iNum ) // add a new team and use next available unused team number void CFF_SH_Rules::AddTeam( const char *pTeamName ) { - CFF_SH_TeamManager *pTeam = static_cast(CreateEntityByName( "ff_team_manager" )); + CFF_SV_InfoFFTeamManager *pTeam = static_cast(CreateEntityByName( "info_ff_team_manager" )); if ( !pTeam ) return; int iNum = 0; - + for ( int i = 0; i < g_Teams.Count(); ++i ) iNum = max ( g_Teams[i]->GetTeamNumber(), iNum ); @@ -242,8 +243,8 @@ CFF_SH_Rules::CFF_SH_Rules() AddTeam( "Unassigned", FF_TEAM_UNASSIGNED ); AddTeam( "Spectators", FF_TEAM_SPECTATE ); - AddTeam( "Badass guys" ); - AddTeam( "COol dudes" ); + //AddTeam( "Badass guys" ); + //AddTeam( "COol dudes" ); // Dexter: slammed this to always true instead of the cvar for now //m_bTeamPlayEnabled = teamplay.GetBool(); @@ -271,7 +272,7 @@ const FFViewVectors* CFF_SH_Rules::GetFFViewVectors()const { return &g_FFViewVectors; } - + CFF_SH_Rules::~CFF_SH_Rules( void ) { #ifndef CLIENT_DLL diff --git a/mp/src/game/shared/ff/ff_sh_shareddefs.h b/mp/src/game/shared/ff/ff_sh_shareddefs.h index db0a70c1..202d7e27 100644 --- a/mp/src/game/shared/ff/ff_sh_shareddefs.h +++ b/mp/src/game/shared/ff/ff_sh_shareddefs.h @@ -63,7 +63,6 @@ enum FF_TEAM FF_TEAM_LAST = FF_TEAM_THIRTYONE }; -// if you really want to use int here dont forget 31 is the sign bit const int FF_TEAM_BITS[] = { 0, 0, (1<<0), (1<<1), (1<<2), @@ -75,6 +74,7 @@ const int FF_TEAM_BITS[] = (1<<28), (1<<29), (1<<30) }; + enum FF_WEAPON { FF_WEAPON_PISTOL = 0, diff --git a/mp/src/game/shared/ff/ff_sh_team_manager.cpp b/mp/src/game/shared/ff/ff_sh_team_manager.cpp index 74b3d2e7..3ae14b86 100644 --- a/mp/src/game/shared/ff/ff_sh_team_manager.cpp +++ b/mp/src/game/shared/ff/ff_sh_team_manager.cpp @@ -98,8 +98,8 @@ void CFF_SH_TeamManager::Init( const char *pName, int iNumber ) { BaseClass::Init( pName, iNumber ); NetworkProp()->SetUpdateInterval( 0.75f ); - memset( &m_iClasses, -1, sizeof( m_iClasses ) ); - m_iAllies = 0; + memset( &m_iClasses, -1, sizeof( m_iClasses ) ); + m_iAllies = 0; } void CFF_SH_TeamManager::AddDeaths( int iDeaths ) @@ -248,7 +248,16 @@ bool CFF_SH_TeamManager::HandlePlayerTeamCommand( CFF_SV_Player &pPlayer, int iN return false; // Make sure this team exists. - CFF_SH_TeamManager *pTeam = GetGlobalFFTeam( iNewTeam ); + CFF_SH_TeamManager *pTeam = NULL; + for( int i=0; iGetTeamNumber() != iNewTeam ) + continue; + + pTeam = dynamic_cast(g_Teams[i]); + break; + } + if( !pTeam ) { // non active team or something fucked