Skip to content

Commit

Permalink
Add start of game ready up mechanic
Browse files Browse the repository at this point in the history
* A (not enabled by default) ready up mechanic that will only start a
  game if the players ready match the defined threshold (default to
  5v5)
* Allows to override the limit if desired, although for either scenarios
  will still require equal amount of players between Jinrai and NSF
* New native player commands to set/unset ready state, configure
  override limit, and check players not ready
* The override limit will reset to false when players drops below threshold
* Automatic intermission can be turned off with the ready-up feature on
* HUD round state fixed to just directly take the const wchar_t strings
  and therefore no need for ANSI->WCHAR conversions
* Make sure round wins and XPs are resetting on non-intermission to ready
* Only functional during idle state, other state shouldn't be able to
  interact or/and activate ready-up feature
* Player commands
    * !ready - For the player to signal they're ready to play
    * !unready - For the player to signal they're not ready to play
    * !overridelimit - A player to signal in behalf of everyone that
      they'll be playing over the stated limit
    * !playersnotready - Prints the players that are not ready and give
      info on why it's not starting
* ConVars
    * neo_sv_readyup_lobby - 0 by default, toggles the ready-up feature
    * neo_sv_readyup_teamplayersthres - 5 by default, the exact amount
      of players to ready-up and participate to start a game
    * neo_sv_readyup_skipwarmup - 1 by default, if ready-up feature is
      on and this is enabled, skip warmup state
    * neo_sv_readyup_autointermission - 0 by default, if disabled will
      not automatically enter intermission when the match ends
* fixes #218
  • Loading branch information
nullsystem committed Oct 12, 2024
1 parent dccc1a4 commit d93bbd3
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 22 deletions.
20 changes: 10 additions & 10 deletions mp/src/game/client/neo/ui/neo_hud_round_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ CNEOHud_RoundState::CNEOHud_RoundState(const char *pElementName, vgui::Panel *pa
: CHudElement(pElementName)
, Panel(parent, pElementName)
{
m_pWszStatusUnicode = L"";
SetAutoDelete(true);

if (parent)
Expand Down Expand Up @@ -203,29 +204,28 @@ void CNEOHud_RoundState::ApplySchemeSettings(vgui::IScheme* pScheme)
SetBounds(0, Y_POS, res.w, res.h);
}

extern ConVar neo_sv_readyup_lobby;

void CNEOHud_RoundState::UpdateStateForNeoHudElementDraw()
{
float roundTimeLeft = NEORules()->GetRoundRemainingTime();
const NeoRoundStatus roundStatus = NEORules()->GetRoundStatus();
const bool inSuddenDeath = NEORules()->RoundIsInSuddenDeath();
const bool inMatchPoint = NEORules()->RoundIsMatchPoint();

const char *prefixStr = (roundStatus == NeoRoundStatus::Warmup) ? "Warmup" : "";
m_pWszStatusUnicode = (roundStatus == NeoRoundStatus::Warmup) ? L"Warmup" : L"";
if (roundStatus == NeoRoundStatus::Idle) {
prefixStr = "Waiting for players";
m_pWszStatusUnicode = neo_sv_readyup_lobby.GetBool() ? L"Waiting for players to ready up" : L"Waiting for players";
}
else if (inSuddenDeath)
{
prefixStr = "Sudden death";
m_pWszStatusUnicode = L"Sudden death";
}
else if (inMatchPoint)
{
prefixStr = "Match point";
m_pWszStatusUnicode = L"Match point";
}
char szStatusANSI[24] = {};
V_sprintf_safe(szStatusANSI, "%s", prefixStr);
memset(m_wszStatusUnicode, 0, sizeof(m_wszStatusUnicode)); // NOTE (nullsystem): Clear it or get junk after warmup ends
g_pVGuiLocalize->ConvertANSIToUnicode(szStatusANSI, m_wszStatusUnicode, sizeof(m_wszStatusUnicode));
m_iStatusUnicodeSize = V_wcslen(m_pWszStatusUnicode);

// Update steam images
if (gpGlobals->curtime > m_iNextAvatarUpdate) {
Expand Down Expand Up @@ -376,9 +376,9 @@ void CNEOHud_RoundState::DrawNeoHudElement()
surface()->DrawPrintText(m_wszRoundUnicode, 9);

// Draw round status
surface()->GetTextSize(m_hOCRSmallFont, m_wszStatusUnicode, fontWidth, fontHeight);
surface()->GetTextSize(m_hOCRSmallFont, m_pWszStatusUnicode, fontWidth, fontHeight);
surface()->DrawSetTextPos(m_iXpos - (fontWidth / 2), m_iBoxYEnd);
surface()->DrawPrintText(m_wszStatusUnicode, 24);
surface()->DrawPrintText(m_pWszStatusUnicode, m_iStatusUnicodeSize);

const int localPlayerTeam = GetLocalPlayerTeam();
const int localPlayerIndex = GetLocalPlayerIndex();
Expand Down
3 changes: 2 additions & 1 deletion mp/src/game/client/neo/ui/neo_hud_round_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ class CNEOHud_RoundState : public CNEOHud_ChildElement, public CHudElement, publ
wchar_t m_wszLeftTeamScore[3] = {};
wchar_t m_wszRightTeamScore[3] = {};
wchar_t m_wszPlayersAliveUnicode[9] = {};
wchar_t m_wszStatusUnicode[24] = {};
const wchar_t *m_pWszStatusUnicode = nullptr;
int m_iStatusUnicodeSize = 0;
wchar_t m_wszGameTypeDescription[MAX_GAME_TYPE_OBJECTIVE_LENGTH] = {};
char szGameTypeDescription[MAX_GAME_TYPE_OBJECTIVE_LENGTH] = {};

Expand Down
5 changes: 5 additions & 0 deletions mp/src/game/server/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

#ifdef NEO
#include "neo_player.h"
#include "neo_gamerules.h"
#endif

// memdbgon must be the last include file in a .cpp file!!!
Expand Down Expand Up @@ -276,6 +277,10 @@ void Host_Say( edict_t *pEdict, const CCommand &args, bool teamonly )

Q_strncat( text, p, sizeof( text ), COPY_ALL_CHARACTERS );
Q_strncat( text, "\n", sizeof( text ), COPY_ALL_CHARACTERS );

#ifdef NEO
static_cast<CNEORules *>(g_pGameRules)->CheckChatCommand(static_cast<CNEO_Player *>(pPlayer), p);
#endif

// loop through all players
// Start with the first player.
Expand Down
Loading

0 comments on commit d93bbd3

Please sign in to comment.