Skip to content

Commit

Permalink
Add util for default round win reason
Browse files Browse the repository at this point in the history
Fixed correct callout and graphics for winning team when knife-round ends
Get rid of Timer_PostKnife
Always reset g_HasKnifeRoundStarted when loading configs or maps
  • Loading branch information
nickdnk committed Aug 13, 2022
1 parent ad4155e commit 68784d9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 28 deletions.
72 changes: 47 additions & 25 deletions scripting/get5.sp
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,11 @@ public void OnPluginStart() {

/** Hooks **/
HookEvent("cs_win_panel_match", Event_MatchOver);
HookEvent("cs_win_panel_round", Event_RoundWinPanel, EventHookMode_Pre);
HookEvent("player_connect_full", Event_PlayerConnectFull);
HookEvent("player_disconnect", Event_PlayerDisconnect);
HookEvent("player_spawn", Event_PlayerSpawn);
HookEvent("round_end", Event_RoundEnd);
HookEvent("round_end", Event_RoundEnd, EventHookMode_Pre);
HookEvent("round_freeze_end", Event_FreezeEnd);
HookEvent("round_prestart", Event_RoundPreStart);
HookEvent("round_start", Event_RoundStart);
Expand Down Expand Up @@ -813,6 +814,7 @@ public void OnMapStart() {
}

g_ReadyTimeWaitingUsed = 0;
g_HasKnifeRoundStarted = false;

if (g_WaitingForRoundBackup) {
ChangeState(Get5State_Warmup);
Expand Down Expand Up @@ -1369,6 +1371,15 @@ public Action Event_RoundPreStart(Event event, const char[] name, bool dontBroad
ChangeState(Get5State_Live);
}

if (g_GameState == Get5State_WaitingForKnifeRoundDecision && !InWarmup()) {
// Ensures that round end after knife sends players directly into warmup.
// This immediately triggers another Event_RoundPreStart, so we can return here and avoid writing backup twice.
LogDebug("Changed to warmup post knife.");
ExecCfg(g_WarmupCfgCvar);
EnsureIndefiniteWarmup();
return Plugin_Continue;
}

Stats_ResetRoundValues();

// We need this for events that fire after the map ends, such as grenades detonating (or someone
Expand All @@ -1383,6 +1394,7 @@ public Action Event_RoundPreStart(Event event, const char[] name, bool dontBroad
if (g_GameState >= Get5State_Warmup) {
WriteBackup();
}
return Plugin_Continue;
}

public Action Event_FreezeEnd(Event event, const char[] name, bool dontBroadcast) {
Expand Down Expand Up @@ -1493,21 +1505,19 @@ public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcas
EventLogger_LogAndDeleteEvent(startEvent);
}

public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
LogDebug("Event_RoundEnd");
if (g_DoingBackupRestoreNow || g_WaitingForRoundBackup) {
return;
}

public Action Event_RoundWinPanel(Event event, const char[] name, bool dontBroadcast) {
LogDebug("Event_RoundWinPanel");
if (g_GameState == Get5State_KnifeRound && g_HasKnifeRoundStarted) {
g_HasKnifeRoundStarted = false;

ChangeState(Get5State_WaitingForKnifeRoundDecision);
CreateTimer(1.0, Timer_PostKnife);
if (g_KnifeChangedCvars != INVALID_HANDLE) {
RestoreCvars(g_KnifeChangedCvars, true);
}

int ctAlive = CountAlivePlayersOnTeam(CS_TEAM_CT);
int tAlive = CountAlivePlayersOnTeam(CS_TEAM_T);
int winningCSTeam = CS_TEAM_NONE;
int winningCSTeam;
if (ctAlive > tAlive) {
winningCSTeam = CS_TEAM_CT;
} else if (tAlive > ctAlive) {
Expand All @@ -1520,11 +1530,8 @@ public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
} else if (tHealth > ctHealth) {
winningCSTeam = CS_TEAM_T;
} else {
if (GetRandomFloat(0.0, 1.0) < 0.5) {
winningCSTeam = CS_TEAM_CT;
} else {
winningCSTeam = CS_TEAM_T;
}
winningCSTeam = GetRandomFloat(0.0, 1.0) < 0.5 ? CS_TEAM_CT : CS_TEAM_T;
LogDebug("Randomized knife winner to side %d", winningCSTeam);
}
}

Expand All @@ -1535,8 +1542,31 @@ public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
FormatChatCommand(formattedSwapCommand, sizeof(formattedSwapCommand), "!swap");
Get5_MessageToAll("%t", "WaitingForEnemySwapInfoMessage", g_FormattedTeamNames[g_KnifeWinnerTeam], formattedStayCommand, formattedSwapCommand);

if (g_TeamTimeToKnifeDecisionCvar.FloatValue > 0)
CreateTimer(g_TeamTimeToKnifeDecisionCvar.FloatValue, Timer_ForceKnifeDecision);
if (g_TeamTimeToKnifeDecisionCvar.FloatValue > 0) {
CreateTimer(g_TeamTimeToKnifeDecisionCvar.FloatValue, Timer_ForceKnifeDecision, TIMER_FLAG_NO_MAPCHANGE);
}

// This ensures that the correct graphic is displayed in-game for the winning team, as CTs will always win if the
// clock runs out. It also ensures that the reason displayed is correct, i.e. just "win" and no "won because clock
// ran down".
event.SetInt("final_event", ConvertCSTeamToDefaultWinReason(winningCSTeam));
}
return Plugin_Continue;
}

public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
LogDebug("Event_RoundEnd");
if (g_DoingBackupRestoreNow || g_WaitingForRoundBackup) {
return Plugin_Continue;
}

if (g_GameState == Get5State_WaitingForKnifeRoundDecision && g_KnifeWinnerTeam != Get5Team_None) {
int winningCSTeam = Get5TeamToCSTeam(g_KnifeWinnerTeam);
// Event_RoundWinPanel is called before Event_RoundEnd, so that event handles knife winner.
// We override this event only to have the correct audio callout in the game.
event.SetInt("winner", winningCSTeam);
event.SetInt("reason", ConvertCSTeamToDefaultWinReason(winningCSTeam));
return Plugin_Continue;
}

if (g_GameState == Get5State_Live) {
Expand Down Expand Up @@ -1619,6 +1649,7 @@ public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)

EventLogger_LogAndDeleteEvent(roundEndEvent);
}
return Plugin_Continue;
}

public void SwapSides() {
Expand Down Expand Up @@ -1673,15 +1704,6 @@ public void StartGame(bool knifeRound) {
}
}

public Action Timer_PostKnife(Handle timer) {
if (g_KnifeChangedCvars != INVALID_HANDLE) {
RestoreCvars(g_KnifeChangedCvars, true);
}

ExecCfg(g_WarmupCfgCvar);
EnsureIndefiniteWarmup();
}

public void ChangeState(Get5State state) {
g_GameStateCvar.IntValue = view_as<int>(state);

Expand Down
8 changes: 5 additions & 3 deletions scripting/get5/kniferounds.sp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public void EndKnifeRound(bool swap) {

ChangeState(Get5State_GoingLive);
CreateTimer(3.0, StartGoingLive, _, TIMER_FLAG_NO_MAPCHANGE);

g_KnifeWinnerTeam = Get5Team_None;
}

static bool AwaitingKnifeDecision(int client) {
Expand All @@ -96,18 +98,18 @@ static bool AwaitingKnifeDecision(int client) {

public Action Command_Stay(int client, int args) {
if (AwaitingKnifeDecision(client)) {
EndKnifeRound(false);
Get5_MessageToAll("%t", "TeamDecidedToStayInfoMessage",
g_FormattedTeamNames[g_KnifeWinnerTeam]);
EndKnifeRound(false);
}
return Plugin_Handled;
}

public Action Command_Swap(int client, int args) {
if (AwaitingKnifeDecision(client)) {
EndKnifeRound(true);
Get5_MessageToAll("%t", "TeamDecidedToSwapInfoMessage",
g_FormattedTeamNames[g_KnifeWinnerTeam]);
EndKnifeRound(true);
} else if (g_GameState == Get5State_Warmup && g_InScrimMode &&
GetClientMatchTeam(client) == Get5Team_1) {
PerformSideSwap(true);
Expand Down Expand Up @@ -142,8 +144,8 @@ public Action Command_T(int client, int args) {

public Action Timer_ForceKnifeDecision(Handle timer) {
if (g_GameState == Get5State_WaitingForKnifeRoundDecision) {
EndKnifeRound(false);
Get5_MessageToAll("%t", "TeamLostTimeToDecideInfoMessage",
g_FormattedTeamNames[g_KnifeWinnerTeam]);
EndKnifeRound(false);
}
}
1 change: 1 addition & 0 deletions scripting/get5/matchconfig.sp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) {
}

g_ReadyTimeWaitingUsed = 0;
g_HasKnifeRoundStarted = false;

g_MapNumber = 0;
g_RoundNumber = -1;
Expand Down
8 changes: 8 additions & 0 deletions scripting/get5/util.sp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ stock int SumHealthOfTeam(int team) {
return sum;
}

stock int ConvertCSTeamToDefaultWinReason(int side) {
// This maps to https://github.com/VSES/SourceEngine2007/blob/master/se2007/game/shared/cstrike/cs_gamerules.h, which
// is the regular CSRoundEndReason + 1.
return view_as<int>(side == CS_TEAM_CT ? CSRoundEnd_CTWin : CSRoundEnd_TerroristWin) + 1;
}

/**
* Switches and respawns a player onto a new team.
*/
Expand Down Expand Up @@ -227,8 +233,10 @@ stock bool InFreezeTime() {

stock void EnsureIndefiniteWarmup() {
if (!InWarmup()) {
LogDebug("EnsureIndefiniteWarmup: Not in warmup; calling StartWarmup()");
StartWarmup();
} else {
LogDebug("EnsureIndefiniteWarmup: Already in warmup; setting indefinite");
ServerCommand("mp_warmup_pausetimer 1");
ServerCommand("mp_do_warmup_period 1");
ServerCommand("mp_warmup_pausetimer 1");
Expand Down

0 comments on commit 68784d9

Please sign in to comment.