core/TimerSys.cpp
changeset 1414 bb258bffc7df
parent 1412 a2ca3d22dd71
child 1415 edf4efe5707c
     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 +}