Skip to content

Commit

Permalink
update rounds api
Browse files Browse the repository at this point in the history
  • Loading branch information
Hedgefog committed Mar 23, 2023
1 parent 1be0dce commit 3cab818
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 140 deletions.
266 changes: 128 additions & 138 deletions api_rounds.sma
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
#pragma semicolon 1

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

#tryinclude <reapi>

#if defined _reapi_included
#define ROUND_CONTINUE HC_CONTINUE
#define ROUND_SUPERCEDE HC_SUPERCEDE
#define WINSTATUS_TERRORIST WINSTATUS_TERRORISTS
#define WINSTATUS_CT WINSTATUS_CTS
#else
#include <roundcontrol>
#endif

#define PLUGIN "[API] Rounds"
#define AUTHOR "Hedgehog Fog"
#define VERSION "1.0.0"

#define TASKID_ROUNDTIME_EXPIRE 1
#include <reapi>

enum GameState {
GameState_NewRound,
Expand All @@ -30,41 +12,40 @@ enum GameState {
enum _:Hook {
Hook_PluginId,
Hook_FunctionId
}
};

new GameState:g_iGameState;

new g_iFwResult;
new g_iFwNewRound;
new g_iFwRoundStart;
new g_iFwRoundEnd;
new g_iFwRoundExpired;
new g_iFwRoundRestart;
new g_iFwRoundTimerTick;

new GameState:g_iGamestate;
new Float:g_fRoundStartTime;
new Array:g_irgCheckWinConditionHooks;

new Array:g_iCheckWinConditionHooks;
new g_pCvarRoundEndDelay;

public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR);

register_event("HLTV", "OnNewRound", "a", "1=0", "2=0");
register_logevent("OnRoundStart", 2, "1=Round_Start");
register_logevent("OnRoundEnd", 2, "1=Round_End");
register_event("TextMsg", "OnRoundEnd", "a", "2=#Game_will_restart_in");

#if defined _reapi_included
RegisterHookChain(RG_CSGameRules_CheckWinConditions, "OnCheckWinConditions");
#else
RegisterControl(RC_CheckWinConditions, "OnCheckWinConditions");
#endif
register_plugin("[API] Rounds", "2.0.0", "Hedgehog Fog");

register_message(get_user_msgid("RoundTime"), "OnMessage_RoundTime");
register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
RegisterHookChain(RG_CSGameRules_RestartRound, "HC_RestartRound", .post = 0);
RegisterHookChain(RG_CSGameRules_OnRoundFreezeEnd, "HC_OnRoundFreezeEnd_Post", .post = 1);
RegisterHookChain(RG_RoundEnd, "HC_RoundEnd", .post = 1);
RegisterHookChain(RG_CSGameRules_CheckWinConditions, "HC_CheckWinConditions", .post = 0);

g_iFwNewRound = CreateMultiForward("Round_Fw_NewRound", ET_IGNORE);
g_iFwRoundStart = CreateMultiForward("Round_Fw_RoundStart", ET_IGNORE);
g_iFwRoundEnd = CreateMultiForward("Round_Fw_RoundEnd", ET_IGNORE);
g_iFwRoundEnd = CreateMultiForward("Round_Fw_RoundEnd", ET_IGNORE, FP_CELL);
g_iFwRoundExpired = CreateMultiForward("Round_Fw_RoundExpired", ET_IGNORE);
g_iFwRoundRestart = CreateMultiForward("Round_Fw_RoundRestart", ET_IGNORE);
g_iFwRoundTimerTick = CreateMultiForward("Round_Fw_RoundTimerTick", ET_IGNORE);

g_iCheckWinConditionHooks = ArrayCreate(Hook);
g_irgCheckWinConditionHooks = ArrayCreate(Hook);

g_pCvarRoundEndDelay = get_cvar_pointer("mp_round_restart_delay");
}

public plugin_natives() {
Expand All @@ -79,166 +60,175 @@ public plugin_natives() {
}

public plugin_destroy() {
ArrayDestroy(g_iCheckWinConditionHooks);
ArrayDestroy(g_irgCheckWinConditionHooks);
}

/*--------------------------------[ Natives ]--------------------------------*/
public server_frame() {
static Float:flTime;
flTime = get_gametime();

public Native_DispatchWin(iPluginId, iArgc) {
new iTeam = get_param(1);
new Float:fDelay = get_param_f(2);
DispatchWin(iTeam, fDelay);
}
static Float:flNextPeriodicThink;
flNextPeriodicThink = get_member_game(m_tmNextPeriodicThink);

public Native_GetTime(iPluginId, iArgc) {
return GetTime();
}
if (flNextPeriodicThink < flTime) {
static bool:bFreezePeriod;
bFreezePeriod = get_member_game(m_bFreezePeriod);

public Native_SetTime(iPluginId, iArgc) {
new iTime = get_param(1);
SetTime(iTime);
ExecuteForward(g_iFwRoundTimerTick);

static iRoundTimeSecs;
iRoundTimeSecs = get_member_game(m_iRoundTimeSecs);

static Float:flStartTime;
flStartTime = get_member_game(m_fRoundStartTimeReal);

static Float:flEndTime;
flEndTime = flStartTime + float(iRoundTimeSecs);

if (!bFreezePeriod) {
if (flTime >= flEndTime) {
ExecuteForward(g_iFwRoundExpired);
}
}
}
}

public Native_GetTimeLeft(iPluginId, iArgc) {
return GetTimeLeft();
public HC_RestartRound() {
if (!get_member_game(m_bCompleteReset)) {
// g_iGameState = GameState_NewRound;
// ExecuteForward(g_iFwNewRound);
} else {
ExecuteForward(g_iFwRoundRestart);
}
}

public bool:Native_IsRoundStarted(iPluginId, iArgc) {
return g_iGamestate > GameState_NewRound;
public HC_OnRoundFreezeEnd_Post() {
g_iGameState = GameState_RoundStarted;
ExecuteForward(g_iFwRoundStart);
}

public bool:Native_IsRoundEnd(iPluginId, iArgc) {
return g_iGamestate == GameState_RoundEnd;
public Event_NewRound() {
g_iGameState = GameState_NewRound;
ExecuteForward(g_iFwNewRound);
}

public Native_HookCheckWinConditions(iPluginId, iArgc) {
static szFunctionName[32];
get_string(1, szFunctionName, charsmax(szFunctionName));
public HC_RoundEnd(WinStatus:iStatus, ScenarioEventEndRound:iEvent, Float:flDelay) {
new TeamName:iWinTeam = TEAM_UNASSIGNED;

new hook[Hook];
hook[Hook_PluginId] = iPluginId;
hook[Hook_FunctionId] = get_func_id(szFunctionName, iPluginId);
switch (iStatus) {
case WINSTATUS_TERRORISTS: iWinTeam = TEAM_TERRORIST;
case WINSTATUS_CTS: iWinTeam = TEAM_CT;
case WINSTATUS_DRAW: iWinTeam = TEAM_SPECTATOR;
}

ArrayPushArray(g_iCheckWinConditionHooks, hook);
}
g_iGameState = GameState_RoundEnd;

/*--------------------------------[ Hooks ]--------------------------------*/
ExecuteForward(g_iFwRoundEnd, _, _:iWinTeam);
}

public OnCheckWinConditions() {
new size = ArraySize(g_iCheckWinConditionHooks);
public HC_CheckWinConditions() {
new iSize = ArraySize(g_irgCheckWinConditionHooks);

for (new i = 0; i < size; ++i) {
for (new i = 0; i < iSize; ++i) {
static hook[_:Hook];
ArrayGetArray(g_iCheckWinConditionHooks, i, hook);
ArrayGetArray(g_irgCheckWinConditionHooks, i, hook);

if (callfunc_begin_i(hook[Hook_FunctionId], hook[Hook_PluginId]) == 1) {
if (callfunc_end() > PLUGIN_CONTINUE) {
return ROUND_SUPERCEDE;
return HC_SUPERCEDE;
}
}
}

return ROUND_CONTINUE;
return HC_CONTINUE;
}

public OnNewRound() {
g_iGamestate = GameState_NewRound;
ExecuteForward(g_iFwNewRound, g_iFwResult);
public Native_DispatchWin(iPluginId, iArgc) {
new iTeam = get_param(1);
new Float:flDelay = get_param_f(2);
DispatchWin(iTeam, flDelay);
}

public OnRoundStart() {
g_iGamestate = GameState_RoundStarted;
g_fRoundStartTime = get_gametime();
UpdateRoundTime();
ExecuteForward(g_iFwRoundStart, g_iFwResult);
public Native_GetTime(iPluginId, iArgc) {
return get_member_game(m_iRoundTimeSecs);
}

public OnRoundEnd() {
g_iGamestate = GameState_RoundEnd;
remove_task(TASKID_ROUNDTIME_EXPIRE);
ExecuteForward(g_iFwRoundEnd, g_iFwResult);
public Native_SetTime(iPluginId, iArgc) {
new iTime = get_param(1);
SetTime(iTime);
}

public OnRoundTimeExpired() {
ExecuteForward(g_iFwRoundExpired, g_iFwResult);
public Native_GetTimeLeft(iPluginId, iArgc) {
return GetTimeLeft();
}

public OnMessage_RoundTime() {
if (g_iGamestate == GameState_NewRound) {
return PLUGIN_CONTINUE;
}

set_msg_arg_int(1, ARG_SHORT, GetTimeLeft());
public bool:Native_IsRoundStarted(iPluginId, iArgc) {
return g_iGameState > GameState_NewRound;
}

return PLUGIN_CONTINUE;
public bool:Native_IsRoundEnd(iPluginId, iArgc) {
return g_iGameState == GameState_RoundEnd;
}

/*--------------------------------[ Methods ]--------------------------------*/
public Native_HookCheckWinConditions(iPluginId, iArgc) {
new szFunctionName[32];
get_string(1, szFunctionName, charsmax(szFunctionName));

DispatchWin(iTeam, Float:fDelay) {
if (g_iGamestate == GameState_RoundEnd) {
new hook[Hook];
hook[Hook_PluginId] = iPluginId;
hook[Hook_FunctionId] = get_func_id(szFunctionName, iPluginId);

ArrayPushArray(g_irgCheckWinConditionHooks, hook);
}

DispatchWin(iTeam, Float:flDelay = -1.0) {
if (g_iGameState == GameState_RoundEnd) {
return;
}

if (iTeam < 1 || iTeam > 3) {
return;
}

new any:iWinstatus = WINSTATUS_DRAW;
if (flDelay < 0.0) {
flDelay = g_pCvarRoundEndDelay ? get_pcvar_float(g_pCvarRoundEndDelay) : 5.0;
}

new WinStatus:iWinstatus = WINSTATUS_DRAW;
if (iTeam == 1) {
iWinstatus = WINSTATUS_TERRORIST;
iWinstatus = WINSTATUS_TERRORISTS;
} else if (iTeam == 2) {
iWinstatus = WINSTATUS_CT;
iWinstatus = WINSTATUS_CTS;
}

#if defined _reapi_included
new ScenarioEventEndRound:iEvent = ROUND_END_DRAW;
if (iTeam == 1) {
iEvent = ROUND_TERRORISTS_WIN;
} else if (iTeam == 2) {
iEvent = ROUND_CTS_WIN;
}

rg_round_end(fDelay, iWinstatus, iEvent);
rg_update_teamscores(iTeam == 2 ? 1 : 0, iTeam == 1 ? 1 : 0);
#else
RoundEndForceControl(iWinstatus, fDelay);
#endif
}
new ScenarioEventEndRound:iEvent = ROUND_END_DRAW;
if (iTeam == 1) {
iEvent = ROUND_TERRORISTS_WIN;
} else if (iTeam == 2) {
iEvent = ROUND_CTS_WIN;
}

GetTime() {
#if defined _reapi_included
return get_member_game(m_iRoundTime);
#else
return get_pgame_int(m_iRoundTime);
#endif
rg_round_end(flDelay, iWinstatus, iEvent, _, _, true);
rg_update_teamscores(iTeam == 2 ? 1 : 0, iTeam == 1 ? 1 : 0);
}

SetTime(iTime) {
#if defined _reapi_included
set_member_game(m_iRoundTime, iTime);
set_member_game(m_fRoundStartTime, g_fRoundStartTime);
#else
set_pgame_int(m_iRoundTime, iTime);
set_pgame_float(m_fRoundCount, g_fRoundStartTime);
#endif
new Float:flStartTime = get_member_game(m_fRoundStartTimeReal);

UpdateRoundTime();
}
set_member_game(m_iRoundTime, iTime);
set_member_game(m_iRoundTimeSecs, iTime);
set_member_game(m_fRoundStartTime, flStartTime);

GetTimeLeft() {
return floatround(g_fRoundStartTime + float(GetTime()) - get_gametime());
UpdateTimer(0, GetTimeLeft());
}

UpdateRoundTime() {
new iTimeLeft = GetTimeLeft();

RountTimeMessage(0, iTimeLeft);
remove_task(TASKID_ROUNDTIME_EXPIRE);
set_task(float(iTimeLeft), "OnRoundTimeExpired", TASKID_ROUNDTIME_EXPIRE);
GetTimeLeft() {
new Float:flStartTime = get_member_game(m_fRoundStartTimeReal);
new iTime = get_member_game(m_iRoundTimeSecs);
return floatround(flStartTime + float(iTime) - get_gametime());
}

stock RountTimeMessage(iClient, iTime) {
UpdateTimer(iClient, iTime) {
static iMsgId = 0;
if(!iMsgId) {
iMsgId = get_user_msgid("RoundTime");
Expand Down
6 changes: 4 additions & 2 deletions include/api_rounds.inc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if defined _api_rounds_included
#endinput
#endif
#define _api_round_included
#define _api_rounds_included

#pragma reqlib api_rounds

Expand All @@ -15,5 +15,7 @@ native Round_HookCheckWinConditions(szFunction[]);

forward Round_Fw_NewRound();
forward Round_Fw_RoundStart();
forward Round_Fw_RoundEnd();
forward Round_Fw_RoundEnd(iWinnerTeam);
forward Round_Fw_RoundExpired();
forward Round_Fw_RoundRestart();
forward Round_Fw_RoundTimerTick();

0 comments on commit 3cab818

Please sign in to comment.