diff --git a/mp/src/game/server/server_ff.vpc b/mp/src/game/server/server_ff.vpc index 9b9aed90..0509e888 100644 --- a/mp/src/game/server/server_ff.vpc +++ b/mp/src/game/server/server_ff.vpc @@ -31,7 +31,7 @@ $Project "Server (FF)" { $Folder "Game" { - $File "FF\ff_sv_client.cpp" + $File "ff\ff_sv_client.cpp" $File "ff\ff_sv_dll_interface.cpp" $File "ff\ff_sv_dll_interface.h" } diff --git a/mp/src/game/server/team.h b/mp/src/game/server/team.h index f8510771..0ed6d796 100644 --- a/mp/src/game/server/team.h +++ b/mp/src/game/server/team.h @@ -86,8 +86,8 @@ public: CNetworkString( m_szTeamname, MAX_TEAM_NAME_LENGTH ); CNetworkVar( int, m_iScore ); CNetworkVar( int, m_iRoundsWon ); - int m_iDeaths; - + //FF: network deaths cuz scoreboard (and MANY players) care int m_iDeaths; + CNetworkVar( int, m_iDeaths ); // Spawnpoints int m_iLastSpawn; // Index of the last spawnpoint used diff --git a/mp/src/game/shared/ff/ff_sh_gamerules.cpp b/mp/src/game/shared/ff/ff_sh_gamerules.cpp index 16e748b3..f5435798 100644 --- a/mp/src/game/shared/ff/ff_sh_gamerules.cpp +++ b/mp/src/game/shared/ff/ff_sh_gamerules.cpp @@ -28,10 +28,10 @@ #include "iscorer.h" #include "ff_sv_player.h" #include "weapon_hl2mpbasehlmpcombatweapon.h" - #include "team.h" #include "voice_gamemgr.h" #include "ff_sv_dll_interface.h" #include "hl2mp_cvars.h" + #include "ff_sh_team_manager.h" #ifdef DEBUG #include "hl2mp_bot_temp.h" @@ -96,7 +96,7 @@ static const char *s_PreserveEnts[] = "ai_network", "ai_hint", "ff_gamerules", - "team_manager", + "ff_team_manager", "player_manager", "env_soundscape", "env_soundscape_proxy", @@ -113,8 +113,8 @@ static const char *s_PreserveEnts[] = "info_node", "info_target", "info_node_hint", - // FF note, only info_ff_teamspawn is checked for spawnpoints, no fallback anymore "info_ff_teamspawn", + "info_player_start", "info_map_parameters", "keyframe_rope", "move_rope", @@ -174,14 +174,26 @@ static const char *s_PreserveEnts[] = #endif +#ifdef GAME_DLL // NOTE: the indices here must match TEAM_TERRORIST, TEAM_CT, TEAM_SPECTATOR, etc. char *sTeamNames[] = { "Unassigned", "Spectator", - "Combine", - "Rebels", + "Blue", + "Red", + "Yellow", + "Green", + "Custom1", + "Custom2", + "Custom3", + "Custom4", + "Custom5", + "Custom6", + "Custom7", + "Custom8", }; +#endif CFF_SH_Rules::CFF_SH_Rules() { @@ -189,7 +201,7 @@ CFF_SH_Rules::CFF_SH_Rules() // Create the team managers for ( int i = 0; i < ARRAYSIZE( sTeamNames ); i++ ) { - CTeam *pTeam = static_cast(CreateEntityByName( "team_manager" )); + CFF_SH_TeamManager *pTeam = static_cast(CreateEntityByName( "ff_team_manager" )); pTeam->Init( sTeamNames[i], i ); g_Teams.AddToTail( pTeam ); diff --git a/mp/src/game/shared/ff/ff_sh_shareddefs.h b/mp/src/game/shared/ff/ff_sh_shareddefs.h new file mode 100644 index 00000000..f4a03dbd --- /dev/null +++ b/mp/src/game/shared/ff/ff_sh_shareddefs.h @@ -0,0 +1,42 @@ +#ifndef FF_SH_SHAREDDEFS_H +#define FF_SH_SHAREDDEFS_H +#ifdef _WIN32 +#pragma once +#endif + +// FF Team stuff +// note, when ported i switched to an enum so we have our custom team stuff a little more obvious +typedef enum +{ + TEAM_BLUE = 2, + TEAM_RED, + TEAM_YELLOW, + TEAM_GREEN, + TEAM_CUSTOM1, + TEAM_CUSTOM2, + TEAM_CUSTOM3, + TEAM_CUSTOM4, + TEAM_CUSTOM5, + TEAM_CUSTOM6, + TEAM_CUSTOM7, + TEAM_CUSTOM8, + TEAM_COUNT +} FF_TEAM; + + +typedef enum +{ + CLASS_SCOUT = 1, + CLASS_SNIPER, + CLASS_SOLDIER, + CLASS_DEMOMAN, + CLASS_MEDIC, + CLASS_HWGUY, + CLASS_PYRO, + CLASS_SPY, + CLASS_ENGINEER, + CLASS_CIVILIAN, + CLASS_COUNT +} FF_CLASS; + +#endif // FF_SH_SHAREDDEFS_H \ No newline at end of file diff --git a/mp/src/game/shared/ff/ff_sh_team_manager.cpp b/mp/src/game/shared/ff/ff_sh_team_manager.cpp new file mode 100644 index 00000000..53f8f953 --- /dev/null +++ b/mp/src/game/shared/ff/ff_sh_team_manager.cpp @@ -0,0 +1,235 @@ +#include "cbase.h" +#include "ff_sh_team_manager.h" + +#ifdef GAME_DLL +#include "entitylist.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +LINK_ENTITY_TO_CLASS( ff_team_manager, CFF_SH_TeamManager ); + +#ifdef GAME_DLL +//Missing RecvProp for +IMPLEMENT_SERVERCLASS_ST( CFF_SH_TeamManager, DT_FFTeamManager ) + SendPropInt( SENDINFO( m_iAllies ) ), + SendPropInt( SENDINFO( m_iFortPoints ) ), + SendPropArray3( SENDINFO_ARRAY3(m_iClasses), SendPropInt( SENDINFO_ARRAY(m_iClasses), 4 ) ), + SendPropInt( SENDINFO( m_iMaxPlayers ) ), + //SendPropString( SENDINFO( m_szTeamname ) ), already done in base data table + SendPropInt( SENDINFO( m_iDeaths ) ), +END_SEND_TABLE() +#else +IMPLEMENT_CLIENTCLASS_DT( CFF_CL_TeamManager, DT_FFTeamManager, CFF_SV_TeamManager ) + RecvPropInt( RECVINFO( m_iAllies ) ), + RecvPropInt( RECVINFO( m_iFortPoints ) ), + RecvPropArray3( RECVINFO_ARRAY(m_iClasses), RecvPropInt( RECVINFO(m_iClasses[0]))), + RecvPropInt( RECVINFO( m_iMaxPlayers ) ), + //RecvPropString( RECVINFO( m_szTeamname ) ), already done in base data table + RecvPropInt( RECVINFO( m_iDeaths ) ), +END_RECV_TABLE() +#endif + +CFF_SH_TeamManager *GetGlobalFFTeam( int iIndex ) +{ + return (CFF_SH_TeamManager*) GetGlobalTeam( iIndex ); +} + +#ifdef GAME_DLL +//----------------------------------------------------------------------------- +// Purpose: Needed because this is an entity, but should never be used +//----------------------------------------------------------------------------- +void CFF_SH_TeamManager::Init( const char *pName, int iNumber ) +{ + BaseClass::Init( pName, iNumber ); + NetworkProp()->SetUpdateInterval( 0.6f ); // 0.75f + // dexter, tweaked old code that memset directly to use set so the disabled defaults (-1) + // are sent networked in next update + for (int i = 0; i < CLASS_COUNT; i++) + m_iClasses.Set(i, -1); + + m_iAllies = 0; +} + +void CFF_SH_TeamManager::AddDeaths( int iDeaths ) +{ + m_iDeaths += iDeaths; +} + +void CFF_SH_TeamManager::AddFortPoints( int iFortPoints ) +{ + m_iFortPoints += iFortPoints; +} + +void CFF_SH_TeamManager::ClearAllies() +{ + m_iAllies = 0; +} + +void CFF_SH_TeamManager::SetAllies( int iTeam ) +{ + //m_iAllies = iAllies; + m_iAllies |= 1 << iTeam; +} + +void CFF_SH_TeamManager::SetClassLimit( int iClass, int iLimit ) +{ + m_iClassesMap[iClass] = iLimit; + m_iClasses.Set( iClass, iLimit ); + DevMsg( "FF Team manager::SetClassLimit (team='%s') class=%i, limit=%i\n", m_szTeamname.Get(), iClass, iLimit ); +} + +void CFF_SH_TeamManager::SetDeaths( int iDeaths ) +{ + m_iDeaths = iDeaths; +} + +void CFF_SH_TeamManager::SetName( const char *pName ) +{ + if (!pName) + return; + + Q_strncpy( m_szTeamname.GetForModify(), pName, MAX_TEAM_NAME_LENGTH ); +} + +void CFF_SH_TeamManager::SetFortPoints( int iFortPoints ) +{ + m_iFortPoints = iFortPoints; +} + +void CFF_SH_TeamManager::SetTeamLimits( int iTeamLimits ) +{ + m_iMaxPlayers = iTeamLimits; +} + +#endif // GAME_DLL + +int CFF_SH_TeamManager::GetAllies( void ) +{ + return m_iAllies; +} + +int CFF_SH_TeamManager::GetClassLimit ( int iClass ) +{ + if ( iClass < 0 || iClass > CLASS_COUNT ) + return -1; +#ifdef CLIENT_DLL + return m_iClasses[iClass]; +#else + return m_iClasses.Get(iClass); +#endif +} + +int CFF_SH_TeamManager::GetFortPoints( void ) +{ + return m_iFortPoints; +} + +const char *CFF_SH_TeamManager::GetName( void ) +{ +#ifdef CLIENT_DLL + return m_szTeamname; +#else + return m_szTeamname.Get(); +#endif +} + +int CFF_SH_TeamManager::GetTeamLimits( void ) +{ + return m_iMaxPlayers; +} + +#ifdef GAME_DLL + +static void ClassRestrictionChange( IConVar *var, const char *pOldString, float fOldVal ); + +// we gotta do this anyway for other classes to use em directly without having to lookup +ConVar cr_scout( "cr_scout", "0", 0, "Max number of scouts", ClassRestrictionChange ); +ConVar cr_sniper( "cr_sniper", "0", 0, "Max number of snipers", ClassRestrictionChange ); +ConVar cr_soldier( "cr_soldier", "0", 0, "Max number of soldiers", ClassRestrictionChange ); +ConVar cr_demoman( "cr_demoman", "0", 0, "Max number of demoman", ClassRestrictionChange ); +ConVar cr_medic( "cr_medic", "0", 0, "Max number of medic", ClassRestrictionChange ); +ConVar cr_hwguy( "cr_hwguy", "0", 0, "Max number of hwguy", ClassRestrictionChange ); +ConVar cr_pyro( "cr_pyro", "0", 0, "Max number of pyro", ClassRestrictionChange ); +ConVar cr_spy( "cr_spy", "0", 0, "Max number of spy", ClassRestrictionChange ); +ConVar cr_engineer( "cr_engineer", "0", 0, "Max number of engineer", ClassRestrictionChange ); +ConVar cr_civilian( "cr_civilian", "0", 0, "Max number of engineer", ClassRestrictionChange ); + +//static CUtlDict classCvarToIndexDict; +// do this so we can find correct idx to pass to team manager +// (from old CFFTeam::UpdateTeamLimits indices) +static ConVar classRestrictionCvars[] = +{ + cr_scout, + cr_sniper, + cr_soldier, + cr_demoman, + cr_medic, + cr_hwguy, + cr_pyro, + cr_spy, + cr_engineer, + cr_civilian, +}; + +// Need to update the real class limits for this map +static void ClassRestrictionChange( IConVar *var, const char *pOldString, float fOldVal ) +{ + // Update the team limits (skip unassigned and spec, they dont need limits applied ) + for ( int i = TEAM_SPECTATOR + 1; i < g_Teams.Count(); i++ ) + { + CFF_SH_TeamManager *pTeam = GetGlobalFFTeam( i ); + if ( !pTeam ) + return; + + ConVar *conVar = static_cast(var); + if ( !conVar ) + return; + + int idx = -1; + for ( int i = 0; i < CLASS_COUNT; i ++) + { + //if ( conVar == &classRestrictionCvars[i] ) + if ( Q_strcmp( conVar->GetName(), classRestrictionCvars[i].GetName() ) == 0 ) + { + idx = i; + break; + } + } + + if ( idx == -1 ) + return; + + pTeam->SetClassLimit( idx, conVar->GetInt() ); + } +} + + + +#endif // GAME_DLL + +//ConCommand ff_team( "ff_team", +//ConCommand ff_team( "ffdbg_dump_teams", +#if defined (DEBUG) && defined (GAME_DLL) +void DebugSetTeamName_f( const CCommand &args ) +{ + if ( args.ArgC() < 2 ) + return; + + int teamNum = Q_atoi(args.Arg(1)); + const char* newName = args.Arg(2); + if ( teamNum > TEAM_COUNT ) + return; + + CFF_SH_TeamManager *pTeam = GetGlobalFFTeam( teamNum ); + if ( !pTeam ) + return; + DevMsg("Current team name ='%s'\n", pTeam->GetName()); + DevMsg("Setting team name to '%s'..\n", newName); + pTeam->SetName( newName ); + DevMsg("Team name after set ='%s'\n", pTeam->GetName()); +} +ConCommand cc_ffdbg_setteamname("ffdbg_set_team_name", DebugSetTeamName_f); +#endif diff --git a/mp/src/game/shared/ff/ff_sh_team_manager.h b/mp/src/game/shared/ff/ff_sh_team_manager.h new file mode 100644 index 00000000..8c7e6c5d --- /dev/null +++ b/mp/src/game/shared/ff/ff_sh_team_manager.h @@ -0,0 +1,76 @@ +#ifndef FF_SH_TEAM_MANAGER_H +#define FF_SH_TEAM_MANAGER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "ff_sh_shareddefs.h" + +#ifdef GAME_DLL +#include "team.h" +#else +#include "c_team.h" +#define CTeam C_Team +#endif + + +#ifdef CLIENT_DLL + #define CFF_SH_TeamManager CFF_CL_TeamManager +#else + #define CFF_SH_TeamManager CFF_SV_TeamManager +#endif + +class CFF_SH_TeamManager : public CTeam +{ + DECLARE_CLASS( CFF_SH_TeamManager, CTeam ); +#ifdef GAME_DLL + DECLARE_SERVERCLASS(); +#else + DECLARE_CLIENTCLASS(); +#endif + +public: +// variables +#ifdef GAME_DLL + int m_iClassesMap[CLASS_COUNT]; // this is just the map limits + CNetworkVar( int, m_iAllies ); + CNetworkVar( int, m_iFortPoints ); + CNetworkArray( int, m_iClasses, CLASS_COUNT ); // this is the actual limit, needed by the client + CNetworkVar( int, m_iMaxPlayers ); +#else + int m_iAllies; + int m_iFortPoints; + int m_iClasses[CLASS_COUNT]; + int m_iMaxPlayers; +#endif + + // setters / writes +#ifdef GAME_DLL + // Initialization + virtual void Init( const char *pName, int iNumber ); + void AddDeaths( int iDeaths ); + void AddFortPoints( int iFortPoints ); + void ClearAllies(); + void SetAllies( int ); + void SetClassLimit( int, int ); // Set the map's class limit + void SetDeaths( int iDeatsh ); + void SetName( const char *pName ); + void SetFortPoints( int iFortPoints ); + void SetTeamLimits( int ); + //void UpdateLimits( void ); + +#endif // GAME_DLL + + // shared getters + int GetAllies( void ); + int GetClassLimit( int ); + int GetDeaths( void ); + int GetFortPoints( void ); + const char *GetName ( void ); + int GetTeamLimits( void ); +}; + +extern CFF_SH_TeamManager *GetGlobalFFTeam( int iIndex ); + +#endif // FF_SV_TEAM_MANAGER_H \ No newline at end of file diff --git a/mp/src/game/shared/ff/ff_shared.vpc b/mp/src/game/shared/ff/ff_shared.vpc index fa0e663c..2622b189 100644 --- a/mp/src/game/shared/ff/ff_shared.vpc +++ b/mp/src/game/shared/ff/ff_shared.vpc @@ -28,8 +28,10 @@ $Project { $File "$SRCDIR\game\shared\ff\ff_sh_gamerules.cpp" $File "$SRCDIR\game\shared\ff\ff_sh_gamerules.h" + $File "$SRCDIR\game\shared\ff\ff_sh_shareddefs.h" + $File "$SRCDIR\game\shared\ff\ff_sh_team_manager.h" + $File "$SRCDIR\game\shared\ff\ff_sh_team_manager.cpp" } - } // folder structure has to match for remove to work correctly..