Skip to content

Commit 3cab818

Browse files
committed
update rounds api
1 parent 1be0dce commit 3cab818

File tree

2 files changed

+132
-140
lines changed

2 files changed

+132
-140
lines changed

api_rounds.sma

Lines changed: 128 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,7 @@
11
#pragma semicolon 1
22

33
#include <amxmodx>
4-
#include <fakemeta>
5-
#include <hamsandwich>
6-
7-
#tryinclude <reapi>
8-
9-
#if defined _reapi_included
10-
#define ROUND_CONTINUE HC_CONTINUE
11-
#define ROUND_SUPERCEDE HC_SUPERCEDE
12-
#define WINSTATUS_TERRORIST WINSTATUS_TERRORISTS
13-
#define WINSTATUS_CT WINSTATUS_CTS
14-
#else
15-
#include <roundcontrol>
16-
#endif
17-
18-
#define PLUGIN "[API] Rounds"
19-
#define AUTHOR "Hedgehog Fog"
20-
#define VERSION "1.0.0"
21-
22-
#define TASKID_ROUNDTIME_EXPIRE 1
4+
#include <reapi>
235

246
enum GameState {
257
GameState_NewRound,
@@ -30,41 +12,40 @@ enum GameState {
3012
enum _:Hook {
3113
Hook_PluginId,
3214
Hook_FunctionId
33-
}
15+
};
16+
17+
new GameState:g_iGameState;
3418

35-
new g_iFwResult;
3619
new g_iFwNewRound;
3720
new g_iFwRoundStart;
3821
new g_iFwRoundEnd;
3922
new g_iFwRoundExpired;
23+
new g_iFwRoundRestart;
24+
new g_iFwRoundTimerTick;
4025

41-
new GameState:g_iGamestate;
42-
new Float:g_fRoundStartTime;
26+
new Array:g_irgCheckWinConditionHooks;
4327

44-
new Array:g_iCheckWinConditionHooks;
28+
new g_pCvarRoundEndDelay;
4529

4630
public plugin_init() {
47-
register_plugin(PLUGIN, VERSION, AUTHOR);
48-
49-
register_event("HLTV", "OnNewRound", "a", "1=0", "2=0");
50-
register_logevent("OnRoundStart", 2, "1=Round_Start");
51-
register_logevent("OnRoundEnd", 2, "1=Round_End");
52-
register_event("TextMsg", "OnRoundEnd", "a", "2=#Game_will_restart_in");
53-
54-
#if defined _reapi_included
55-
RegisterHookChain(RG_CSGameRules_CheckWinConditions, "OnCheckWinConditions");
56-
#else
57-
RegisterControl(RC_CheckWinConditions, "OnCheckWinConditions");
58-
#endif
31+
register_plugin("[API] Rounds", "2.0.0", "Hedgehog Fog");
5932

60-
register_message(get_user_msgid("RoundTime"), "OnMessage_RoundTime");
33+
register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
34+
RegisterHookChain(RG_CSGameRules_RestartRound, "HC_RestartRound", .post = 0);
35+
RegisterHookChain(RG_CSGameRules_OnRoundFreezeEnd, "HC_OnRoundFreezeEnd_Post", .post = 1);
36+
RegisterHookChain(RG_RoundEnd, "HC_RoundEnd", .post = 1);
37+
RegisterHookChain(RG_CSGameRules_CheckWinConditions, "HC_CheckWinConditions", .post = 0);
6138

6239
g_iFwNewRound = CreateMultiForward("Round_Fw_NewRound", ET_IGNORE);
6340
g_iFwRoundStart = CreateMultiForward("Round_Fw_RoundStart", ET_IGNORE);
64-
g_iFwRoundEnd = CreateMultiForward("Round_Fw_RoundEnd", ET_IGNORE);
41+
g_iFwRoundEnd = CreateMultiForward("Round_Fw_RoundEnd", ET_IGNORE, FP_CELL);
6542
g_iFwRoundExpired = CreateMultiForward("Round_Fw_RoundExpired", ET_IGNORE);
43+
g_iFwRoundRestart = CreateMultiForward("Round_Fw_RoundRestart", ET_IGNORE);
44+
g_iFwRoundTimerTick = CreateMultiForward("Round_Fw_RoundTimerTick", ET_IGNORE);
6645

67-
g_iCheckWinConditionHooks = ArrayCreate(Hook);
46+
g_irgCheckWinConditionHooks = ArrayCreate(Hook);
47+
48+
g_pCvarRoundEndDelay = get_cvar_pointer("mp_round_restart_delay");
6849
}
6950

7051
public plugin_natives() {
@@ -79,166 +60,175 @@ public plugin_natives() {
7960
}
8061

8162
public plugin_destroy() {
82-
ArrayDestroy(g_iCheckWinConditionHooks);
63+
ArrayDestroy(g_irgCheckWinConditionHooks);
8364
}
8465

85-
/*--------------------------------[ Natives ]--------------------------------*/
66+
public server_frame() {
67+
static Float:flTime;
68+
flTime = get_gametime();
8669

87-
public Native_DispatchWin(iPluginId, iArgc) {
88-
new iTeam = get_param(1);
89-
new Float:fDelay = get_param_f(2);
90-
DispatchWin(iTeam, fDelay);
91-
}
70+
static Float:flNextPeriodicThink;
71+
flNextPeriodicThink = get_member_game(m_tmNextPeriodicThink);
9272

93-
public Native_GetTime(iPluginId, iArgc) {
94-
return GetTime();
95-
}
73+
if (flNextPeriodicThink < flTime) {
74+
static bool:bFreezePeriod;
75+
bFreezePeriod = get_member_game(m_bFreezePeriod);
9676

97-
public Native_SetTime(iPluginId, iArgc) {
98-
new iTime = get_param(1);
99-
SetTime(iTime);
77+
ExecuteForward(g_iFwRoundTimerTick);
78+
79+
static iRoundTimeSecs;
80+
iRoundTimeSecs = get_member_game(m_iRoundTimeSecs);
81+
82+
static Float:flStartTime;
83+
flStartTime = get_member_game(m_fRoundStartTimeReal);
84+
85+
static Float:flEndTime;
86+
flEndTime = flStartTime + float(iRoundTimeSecs);
87+
88+
if (!bFreezePeriod) {
89+
if (flTime >= flEndTime) {
90+
ExecuteForward(g_iFwRoundExpired);
91+
}
92+
}
93+
}
10094
}
10195

102-
public Native_GetTimeLeft(iPluginId, iArgc) {
103-
return GetTimeLeft();
96+
public HC_RestartRound() {
97+
if (!get_member_game(m_bCompleteReset)) {
98+
// g_iGameState = GameState_NewRound;
99+
// ExecuteForward(g_iFwNewRound);
100+
} else {
101+
ExecuteForward(g_iFwRoundRestart);
102+
}
104103
}
105104

106-
public bool:Native_IsRoundStarted(iPluginId, iArgc) {
107-
return g_iGamestate > GameState_NewRound;
105+
public HC_OnRoundFreezeEnd_Post() {
106+
g_iGameState = GameState_RoundStarted;
107+
ExecuteForward(g_iFwRoundStart);
108108
}
109109

110-
public bool:Native_IsRoundEnd(iPluginId, iArgc) {
111-
return g_iGamestate == GameState_RoundEnd;
110+
public Event_NewRound() {
111+
g_iGameState = GameState_NewRound;
112+
ExecuteForward(g_iFwNewRound);
112113
}
113114

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

118-
new hook[Hook];
119-
hook[Hook_PluginId] = iPluginId;
120-
hook[Hook_FunctionId] = get_func_id(szFunctionName, iPluginId);
118+
switch (iStatus) {
119+
case WINSTATUS_TERRORISTS: iWinTeam = TEAM_TERRORIST;
120+
case WINSTATUS_CTS: iWinTeam = TEAM_CT;
121+
case WINSTATUS_DRAW: iWinTeam = TEAM_SPECTATOR;
122+
}
121123

122-
ArrayPushArray(g_iCheckWinConditionHooks, hook);
123-
}
124+
g_iGameState = GameState_RoundEnd;
124125

125-
/*--------------------------------[ Hooks ]--------------------------------*/
126+
ExecuteForward(g_iFwRoundEnd, _, _:iWinTeam);
127+
}
126128

127-
public OnCheckWinConditions() {
128-
new size = ArraySize(g_iCheckWinConditionHooks);
129+
public HC_CheckWinConditions() {
130+
new iSize = ArraySize(g_irgCheckWinConditionHooks);
129131

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

134136
if (callfunc_begin_i(hook[Hook_FunctionId], hook[Hook_PluginId]) == 1) {
135137
if (callfunc_end() > PLUGIN_CONTINUE) {
136-
return ROUND_SUPERCEDE;
138+
return HC_SUPERCEDE;
137139
}
138140
}
139141
}
140142

141-
return ROUND_CONTINUE;
143+
return HC_CONTINUE;
142144
}
143145

144-
public OnNewRound() {
145-
g_iGamestate = GameState_NewRound;
146-
ExecuteForward(g_iFwNewRound, g_iFwResult);
146+
public Native_DispatchWin(iPluginId, iArgc) {
147+
new iTeam = get_param(1);
148+
new Float:flDelay = get_param_f(2);
149+
DispatchWin(iTeam, flDelay);
147150
}
148151

149-
public OnRoundStart() {
150-
g_iGamestate = GameState_RoundStarted;
151-
g_fRoundStartTime = get_gametime();
152-
UpdateRoundTime();
153-
ExecuteForward(g_iFwRoundStart, g_iFwResult);
152+
public Native_GetTime(iPluginId, iArgc) {
153+
return get_member_game(m_iRoundTimeSecs);
154154
}
155155

156-
public OnRoundEnd() {
157-
g_iGamestate = GameState_RoundEnd;
158-
remove_task(TASKID_ROUNDTIME_EXPIRE);
159-
ExecuteForward(g_iFwRoundEnd, g_iFwResult);
156+
public Native_SetTime(iPluginId, iArgc) {
157+
new iTime = get_param(1);
158+
SetTime(iTime);
160159
}
161160

162-
public OnRoundTimeExpired() {
163-
ExecuteForward(g_iFwRoundExpired, g_iFwResult);
161+
public Native_GetTimeLeft(iPluginId, iArgc) {
162+
return GetTimeLeft();
164163
}
165164

166-
public OnMessage_RoundTime() {
167-
if (g_iGamestate == GameState_NewRound) {
168-
return PLUGIN_CONTINUE;
169-
}
170-
171-
set_msg_arg_int(1, ARG_SHORT, GetTimeLeft());
165+
public bool:Native_IsRoundStarted(iPluginId, iArgc) {
166+
return g_iGameState > GameState_NewRound;
167+
}
172168

173-
return PLUGIN_CONTINUE;
169+
public bool:Native_IsRoundEnd(iPluginId, iArgc) {
170+
return g_iGameState == GameState_RoundEnd;
174171
}
175172

176-
/*--------------------------------[ Methods ]--------------------------------*/
173+
public Native_HookCheckWinConditions(iPluginId, iArgc) {
174+
new szFunctionName[32];
175+
get_string(1, szFunctionName, charsmax(szFunctionName));
177176

178-
DispatchWin(iTeam, Float:fDelay) {
179-
if (g_iGamestate == GameState_RoundEnd) {
177+
new hook[Hook];
178+
hook[Hook_PluginId] = iPluginId;
179+
hook[Hook_FunctionId] = get_func_id(szFunctionName, iPluginId);
180+
181+
ArrayPushArray(g_irgCheckWinConditionHooks, hook);
182+
}
183+
184+
DispatchWin(iTeam, Float:flDelay = -1.0) {
185+
if (g_iGameState == GameState_RoundEnd) {
180186
return;
181187
}
182188

183189
if (iTeam < 1 || iTeam > 3) {
184190
return;
185191
}
186192

187-
new any:iWinstatus = WINSTATUS_DRAW;
193+
if (flDelay < 0.0) {
194+
flDelay = g_pCvarRoundEndDelay ? get_pcvar_float(g_pCvarRoundEndDelay) : 5.0;
195+
}
196+
197+
new WinStatus:iWinstatus = WINSTATUS_DRAW;
188198
if (iTeam == 1) {
189-
iWinstatus = WINSTATUS_TERRORIST;
199+
iWinstatus = WINSTATUS_TERRORISTS;
190200
} else if (iTeam == 2) {
191-
iWinstatus = WINSTATUS_CT;
201+
iWinstatus = WINSTATUS_CTS;
192202
}
193203

194-
#if defined _reapi_included
195-
new ScenarioEventEndRound:iEvent = ROUND_END_DRAW;
196-
if (iTeam == 1) {
197-
iEvent = ROUND_TERRORISTS_WIN;
198-
} else if (iTeam == 2) {
199-
iEvent = ROUND_CTS_WIN;
200-
}
201-
202-
rg_round_end(fDelay, iWinstatus, iEvent);
203-
rg_update_teamscores(iTeam == 2 ? 1 : 0, iTeam == 1 ? 1 : 0);
204-
#else
205-
RoundEndForceControl(iWinstatus, fDelay);
206-
#endif
207-
}
204+
new ScenarioEventEndRound:iEvent = ROUND_END_DRAW;
205+
if (iTeam == 1) {
206+
iEvent = ROUND_TERRORISTS_WIN;
207+
} else if (iTeam == 2) {
208+
iEvent = ROUND_CTS_WIN;
209+
}
208210

209-
GetTime() {
210-
#if defined _reapi_included
211-
return get_member_game(m_iRoundTime);
212-
#else
213-
return get_pgame_int(m_iRoundTime);
214-
#endif
211+
rg_round_end(flDelay, iWinstatus, iEvent, _, _, true);
212+
rg_update_teamscores(iTeam == 2 ? 1 : 0, iTeam == 1 ? 1 : 0);
215213
}
216214

217215
SetTime(iTime) {
218-
#if defined _reapi_included
219-
set_member_game(m_iRoundTime, iTime);
220-
set_member_game(m_fRoundStartTime, g_fRoundStartTime);
221-
#else
222-
set_pgame_int(m_iRoundTime, iTime);
223-
set_pgame_float(m_fRoundCount, g_fRoundStartTime);
224-
#endif
216+
new Float:flStartTime = get_member_game(m_fRoundStartTimeReal);
225217

226-
UpdateRoundTime();
227-
}
218+
set_member_game(m_iRoundTime, iTime);
219+
set_member_game(m_iRoundTimeSecs, iTime);
220+
set_member_game(m_fRoundStartTime, flStartTime);
228221

229-
GetTimeLeft() {
230-
return floatround(g_fRoundStartTime + float(GetTime()) - get_gametime());
222+
UpdateTimer(0, GetTimeLeft());
231223
}
232224

233-
UpdateRoundTime() {
234-
new iTimeLeft = GetTimeLeft();
235-
236-
RountTimeMessage(0, iTimeLeft);
237-
remove_task(TASKID_ROUNDTIME_EXPIRE);
238-
set_task(float(iTimeLeft), "OnRoundTimeExpired", TASKID_ROUNDTIME_EXPIRE);
225+
GetTimeLeft() {
226+
new Float:flStartTime = get_member_game(m_fRoundStartTimeReal);
227+
new iTime = get_member_game(m_iRoundTimeSecs);
228+
return floatround(flStartTime + float(iTime) - get_gametime());
239229
}
240230

241-
stock RountTimeMessage(iClient, iTime) {
231+
UpdateTimer(iClient, iTime) {
242232
static iMsgId = 0;
243233
if(!iMsgId) {
244234
iMsgId = get_user_msgid("RoundTime");

include/api_rounds.inc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#if defined _api_rounds_included
22
#endinput
33
#endif
4-
#define _api_round_included
4+
#define _api_rounds_included
55

66
#pragma reqlib api_rounds
77

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

1616
forward Round_Fw_NewRound();
1717
forward Round_Fw_RoundStart();
18-
forward Round_Fw_RoundEnd();
18+
forward Round_Fw_RoundEnd(iWinnerTeam);
1919
forward Round_Fw_RoundExpired();
20+
forward Round_Fw_RoundRestart();
21+
forward Round_Fw_RoundTimerTick();

0 commit comments

Comments
 (0)