1.1 --- a/core/TimerSys.cpp Wed Sep 12 23:37:00 2007 +0000
1.2 +++ b/core/TimerSys.cpp Thu Sep 13 00:33:56 2007 +0000
1.3 @@ -35,9 +35,13 @@
1.4 #include "sourcemm_api.h"
1.5 #include "frame_hooks.h"
1.6
1.7 +SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallback, SH_NOATTRIB, false, ConVar *, const char *);
1.8 +
1.9 TimerSystem g_Timers;
1.10 float g_fUniversalTime = 0.0f;
1.11 +float g_fMapStartTime = 0.0f;
1.12 const float *g_pUniversalTime = &g_fUniversalTime;
1.13 +ConVar *mp_timelimit = NULL;
1.14
1.15 ConVar sm_time_adjustment("sm_time_adjustment", "0", 0, "Adjusts the server time in seconds");
1.16
1.17 @@ -56,6 +60,84 @@
1.18 return val;
1.19 }
1.20
1.21 +class DefaultMapTimer :
1.22 + public IMapTimer,
1.23 + public SMGlobalClass
1.24 +{
1.25 +public:
1.26 + DefaultMapTimer()
1.27 + {
1.28 + m_bInUse = false;
1.29 + }
1.30 +
1.31 + int GetMapTimeLimit()
1.32 + {
1.33 + return mp_timelimit->GetInt();
1.34 + }
1.35 +
1.36 + void SetMapTimerStatus(bool enabled)
1.37 + {
1.38 + if (enabled && !m_bInUse)
1.39 + {
1.40 + Enable();
1.41 + }
1.42 + else if (!enabled && m_bInUse)
1.43 + {
1.44 + Disable();
1.45 + }
1.46 + m_bInUse = enabled;
1.47 + }
1.48 +
1.49 + bool GetMapTimeLeft(int *time_left)
1.50 + {
1.51 + if (GetMapTimeLimit() == 0)
1.52 + {
1.53 + return false;
1.54 + }
1.55 +
1.56 + *time_left = (int)((g_fMapStartTime + mp_timelimit->GetInt() * 60.0f) - g_fUniversalTime);
1.57 +
1.58 + return true;
1.59 + }
1.60 +
1.61 + void ExtendMapTimeLimit(int extra_time)
1.62 + {
1.63 + extra_time /= 60;
1.64 +
1.65 + if (extra_time == 0)
1.66 + {
1.67 + mp_timelimit->SetValue(0);
1.68 + return;
1.69 + }
1.70 +
1.71 + mp_timelimit->SetValue(mp_timelimit->GetInt() + extra_time);
1.72 + }
1.73 +
1.74 + void GlobalChangeCallback(ConVar *pVar, const char *old_value)
1.75 + {
1.76 + if (pVar != mp_timelimit)
1.77 + {
1.78 + return;
1.79 + }
1.80 +
1.81 + g_Timers.MapTimeLimitExtended(atoi(old_value) * 60, pVar->GetInt() * 60);
1.82 + }
1.83 +
1.84 +private:
1.85 + void Enable()
1.86 + {
1.87 + SH_ADD_HOOK_MEMFUNC(ICvar, CallGlobalChangeCallback, icvar, this, &DefaultMapTimer::GlobalChangeCallback, false);
1.88 + }
1.89 +
1.90 + void Disable()
1.91 + {
1.92 + SH_REMOVE_HOOK_MEMFUNC(ICvar, CallGlobalChangeCallback, icvar, this, &DefaultMapTimer::GlobalChangeCallback, false);
1.93 + }
1.94 +
1.95 +private:
1.96 + bool m_bInUse;
1.97 +} s_DefaultMapTimer;
1.98 +
1.99 void ITimer::Initialize(ITimedEvent *pCallbacks, float fInterval, float fToExec, void *pData, int flags)
1.100 {
1.101 m_Listener = pCallbacks;
1.102 @@ -69,7 +151,7 @@
1.103
1.104 TimerSystem::TimerSystem()
1.105 {
1.106 - m_fnTimeLeft = NULL;
1.107 + m_pMapTimer = NULL;
1.108 m_bHasMapTickedYet = false;
1.109 m_fLastTickedTime = 0.0f;
1.110 m_LastExecTime = 0.0f;
1.111 @@ -91,8 +173,19 @@
1.112 m_pOnGameFrame = g_Forwards.CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
1.113 }
1.114
1.115 +void TimerSystem::OnSourceModGameInitialized()
1.116 +{
1.117 + mp_timelimit = icvar->FindVar("mp_timelimit");
1.118 +
1.119 + if (m_pMapTimer == NULL && mp_timelimit != NULL)
1.120 + {
1.121 + SetMapTimer(&s_DefaultMapTimer);
1.122 + }
1.123 +}
1.124 +
1.125 void TimerSystem::OnSourceModShutdown()
1.126 {
1.127 + SetMapTimer(NULL);
1.128 g_Forwards.ReleaseForward(m_pOnGameFrame);
1.129 }
1.130
1.131 @@ -118,7 +211,11 @@
1.132 }
1.133
1.134 m_fLastTickedTime = gpGlobals->curtime;
1.135 - m_bHasMapTickedYet = true;
1.136 + if (!m_bHasMapTickedYet)
1.137 + {
1.138 + g_fMapStartTime = g_fUniversalTime;
1.139 + m_bHasMapTickedYet = true;
1.140 + }
1.141
1.142 if (g_fUniversalTime - m_LastExecTime >= 0.1)
1.143 {
1.144 @@ -154,25 +251,6 @@
1.145 }
1.146 }
1.147
1.148 - if (m_fnTimeLeft != NULL && m_MapEndTimers.size())
1.149 - {
1.150 - float time_left = m_fnTimeLeft();
1.151 - for (iter=m_MapEndTimers.begin(); iter!=m_MapEndTimers.end();)
1.152 - {
1.153 - pTimer = (*iter);
1.154 - if ((*iter)->m_Interval < time_left)
1.155 - {
1.156 - pTimer->m_InExec = true;
1.157 - pTimer->m_Listener->OnTimer(pTimer, pTimer->m_pData);
1.158 - pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
1.159 - iter = m_MapEndTimers.erase(iter);
1.160 - m_FreeTimers.push(pTimer);
1.161 - } else {
1.162 - break;
1.163 - }
1.164 - }
1.165 - }
1.166 -
1.167 ResultType res;
1.168 for (iter=m_LoopTimers.begin(); iter!=m_LoopTimers.end(); )
1.169 {
1.170 @@ -203,12 +281,6 @@
1.171 TimerIter iter;
1.172 float to_exec = GetSimulatedTime() + fInterval;
1.173
1.174 - if ((flags & TIMER_FLAG_BEFORE_MAP_END)
1.175 - && m_fnTimeLeft == NULL)
1.176 - {
1.177 - return NULL;
1.178 - }
1.179 -
1.180 if (m_FreeTimers.empty())
1.181 {
1.182 pTimer = new ITimer;
1.183 @@ -225,40 +297,26 @@
1.184 goto return_timer;
1.185 }
1.186
1.187 - if (flags & TIMER_FLAG_BEFORE_MAP_END)
1.188 + if (m_SingleTimers.size() >= 1)
1.189 {
1.190 - for (iter=m_MapEndTimers.begin(); iter!=m_MapEndTimers.end(); iter++)
1.191 - {
1.192 - if (fInterval >= (*iter)->m_Interval)
1.193 - {
1.194 - m_MapEndTimers.insert(iter, pTimer);
1.195 - goto return_timer;
1.196 - }
1.197 - }
1.198 -
1.199 - m_MapEndTimers.push_back(pTimer);
1.200 - } else {
1.201 - if (m_SingleTimers.size() >= 1)
1.202 + iter = --m_SingleTimers.end();
1.203 + if ((*iter)->m_ToExec <= to_exec)
1.204 {
1.205 - iter = --m_SingleTimers.end();
1.206 - if ((*iter)->m_ToExec <= to_exec)
1.207 - {
1.208 - goto normal_insert_end;
1.209 - }
1.210 + goto normal_insert_end;
1.211 }
1.212 -
1.213 - for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
1.214 + }
1.215 +
1.216 + for (iter=m_SingleTimers.begin(); iter!=m_SingleTimers.end(); iter++)
1.217 + {
1.218 + if ((*iter)->m_ToExec >= to_exec)
1.219 {
1.220 - if ((*iter)->m_ToExec >= to_exec)
1.221 - {
1.222 - m_SingleTimers.insert(iter, pTimer);
1.223 - goto return_timer;
1.224 - }
1.225 + m_SingleTimers.insert(iter, pTimer);
1.226 + goto return_timer;
1.227 }
1.228 + }
1.229
1.230 normal_insert_end:
1.231 - m_SingleTimers.push_back(pTimer);
1.232 - }
1.233 + m_SingleTimers.push_back(pTimer);
1.234
1.235 return_timer:
1.236 return pTimer;
1.237 @@ -279,12 +337,7 @@
1.238 if (!(pTimer->m_Flags & TIMER_FLAG_REPEAT))
1.239 {
1.240 pTimer->m_Listener->OnTimerEnd(pTimer, pTimer->m_pData);
1.241 - if (pTimer->m_Flags & TIMER_FLAG_BEFORE_MAP_END)
1.242 - {
1.243 - m_MapEndTimers.remove(pTimer);
1.244 - } else {
1.245 - m_SingleTimers.remove(pTimer);
1.246 - }
1.247 + m_SingleTimers.remove(pTimer);
1.248 m_FreeTimers.push(pTimer);
1.249 } else {
1.250 if ((res != Pl_Stop) && !pTimer->m_KillMe)
1.251 @@ -321,8 +374,6 @@
1.252 if (pTimer->m_Flags & TIMER_FLAG_REPEAT)
1.253 {
1.254 m_LoopTimers.remove(pTimer);
1.255 - } else if (pTimer->m_Flags & TIMER_FLAG_BEFORE_MAP_END) {
1.256 - m_MapEndTimers.remove(pTimer);
1.257 } else {
1.258 m_SingleTimers.remove(pTimer);
1.259 }
1.260 @@ -354,15 +405,6 @@
1.261 }
1.262 }
1.263
1.264 - if (real_mapchange)
1.265 - {
1.266 - for (iter=m_MapEndTimers.begin(); iter!=m_MapEndTimers.end(); iter++)
1.267 - {
1.268 - pTimer = (*iter);
1.269 - s_tokill.push(pTimer);
1.270 - }
1.271 - }
1.272 -
1.273 while (!s_tokill.empty())
1.274 {
1.275 KillTimer(s_tokill.front());
1.276 @@ -370,10 +412,34 @@
1.277 }
1.278 }
1.279
1.280 -SM_TIMELEFT_FUNCTION TimerSystem::SetTimeLeftFunction(SM_TIMELEFT_FUNCTION fn)
1.281 +IMapTimer *TimerSystem::SetMapTimer(IMapTimer *pTimer)
1.282 {
1.283 - SM_TIMELEFT_FUNCTION old = m_fnTimeLeft;
1.284 - m_fnTimeLeft = fn;
1.285 + IMapTimer *old = m_pMapTimer;
1.286 +
1.287 + m_pMapTimer = pTimer;
1.288 +
1.289 + if (m_pMapTimer)
1.290 + {
1.291 + m_pMapTimer->SetMapTimerStatus(true);
1.292 + }
1.293 +
1.294 + if (old)
1.295 + {
1.296 + old->SetMapTimerStatus(false);
1.297 + }
1.298 +
1.299 return old;
1.300 }
1.301
1.302 +IMapTimer *TimerSystem::GetMapTimer()
1.303 +{
1.304 + return m_pMapTimer;
1.305 +}
1.306 +
1.307 +void TimerSystem::MapTimeLimitExtended(int old_limit, int new_limit)
1.308 +{
1.309 + if (old_limit == new_limit)
1.310 + {
1.311 + return;
1.312 + }
1.313 +}