mirror of
https://github.com/dashr9230/SA-MP.git
synced 2024-12-22 14:37:29 +08:00
5467762720
* Implement `CScriptTimers::Delete(...)` * Update `CNetGame::Process()`
245 lines
5.9 KiB
C++
245 lines
5.9 KiB
C++
|
|
#include "main.h"
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
CScriptTimers::CScriptTimers()
|
|
{
|
|
m_dwTimerCount = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
CScriptTimers::~CScriptTimers()
|
|
{
|
|
DwordTimerMap::iterator itor;
|
|
for (itor = m_Timers.begin(); itor != m_Timers.end(); itor++)
|
|
{
|
|
FreeMem(itor->second);
|
|
SAFE_DELETE(itor->second);
|
|
}
|
|
m_Timers.clear();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void CScriptTimers::FreeMem(ScriptTimer_s* Timer)
|
|
{
|
|
if (Timer->cellParams != NULL)
|
|
{
|
|
free(Timer->cellParams);
|
|
Timer->cellParams = NULL;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void CScriptTimers::DeleteForMode(AMX* pEndedAMX)
|
|
{
|
|
bool bRestart = false;
|
|
DwordTimerMap::iterator itor;
|
|
for (itor = m_Timers.begin(); itor != m_Timers.end(); bRestart?(itor=m_Timers.begin()):(itor++))
|
|
{
|
|
bRestart = false;
|
|
if (itor->second->pAMX == pEndedAMX)
|
|
{
|
|
FreeMem(itor->second);
|
|
SAFE_DELETE(itor->second);
|
|
m_Timers.erase(itor);
|
|
|
|
// Can't continue iteration if a node is deleted, start iteration from start again.
|
|
bRestart = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
DWORD CScriptTimers::New(char* szScriptFunc, int iInterval, BOOL bRepeating, AMX* pAMX)
|
|
{
|
|
m_dwTimerCount++;
|
|
|
|
ScriptTimer_s* NewTimer = new ScriptTimer_s;
|
|
|
|
strncpy(NewTimer->szScriptFunc, szScriptFunc, 255);
|
|
NewTimer->iTotalTime = iInterval;
|
|
NewTimer->iRemainingTime = iInterval;
|
|
NewTimer->bRepeating = bRepeating;
|
|
NewTimer->iParamCount = 0;
|
|
NewTimer->bKilled = false;
|
|
NewTimer->pAMX = pAMX;
|
|
NewTimer->cellParams = NULL;
|
|
|
|
m_Timers.insert(DwordTimerMap::value_type(m_dwTimerCount, NewTimer));
|
|
return m_dwTimerCount;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Same as new only with parameters to be passed to the called function
|
|
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
|
DWORD CScriptTimers::NewEx(char* szScriptFunc, int iInterval, BOOL bRepeating, cell *params, AMX* pAMX)
|
|
{
|
|
m_dwTimerCount++;
|
|
|
|
ScriptTimer_s* NewTimer = new ScriptTimer_s;
|
|
|
|
strncpy(NewTimer->szScriptFunc, szScriptFunc, 255);
|
|
NewTimer->iTotalTime = iInterval;
|
|
NewTimer->iRemainingTime = iInterval;
|
|
NewTimer->bRepeating = bRepeating;
|
|
NewTimer->bKilled = false;
|
|
NewTimer->pAMX = pAMX;
|
|
|
|
cell amx_addr[256];
|
|
|
|
char* szParamList;
|
|
amx_StrParam(pAMX, params[4], szParamList);
|
|
int j, numstr, iOff = 5; // Count, func, interval, repeat, map
|
|
if (szParamList == NULL) j = 0;
|
|
else j = strlen(szParamList);
|
|
numstr = 0;
|
|
while (j)
|
|
{
|
|
j--;
|
|
cell *paddr = NULL;
|
|
if (*(szParamList + j) == 'a')
|
|
{
|
|
int numcells = *get_amxaddr(pAMX, params[j + iOff + 1]);
|
|
if (amx_Allot(pAMX, numcells, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
|
|
{
|
|
memcpy(paddr, get_amxaddr(pAMX, params[j + iOff]), numcells * sizeof (cell));
|
|
numstr++;
|
|
}
|
|
}
|
|
else if (*(szParamList + j) == 's')
|
|
{
|
|
char* szParamText;
|
|
amx_StrParam(pAMX, params[j + iOff], szParamText);
|
|
if (szParamText != NULL && strlen(szParamText) > 0)
|
|
{
|
|
int numcells = strlen(szParamText) + 1;
|
|
if (amx_Allot(pAMX, numcells, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
|
|
{
|
|
amx_SetString(paddr, szParamText, 0, 0, UNLIMITED);
|
|
numstr++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*szParamText = 1;
|
|
*(szParamText + 1) = 0;
|
|
if (amx_Allot(pAMX, 1, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
|
|
{
|
|
amx_SetString(paddr, szParamText, 0, 0, UNLIMITED);
|
|
numstr++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
amx_addr[numstr] = *get_amxaddr(pAMX, params[j + iOff]);
|
|
numstr++;
|
|
}
|
|
}
|
|
void* mem = NULL;
|
|
if (numstr)
|
|
{
|
|
mem = malloc(numstr * sizeof (cell));
|
|
memcpy(mem, &amx_addr, numstr * sizeof (cell));
|
|
NewTimer->cellParams = mem;
|
|
}
|
|
else
|
|
{
|
|
NewTimer->cellParams = NULL;
|
|
}
|
|
NewTimer->iParamCount = numstr;
|
|
|
|
m_Timers.insert(DwordTimerMap::value_type(m_dwTimerCount, NewTimer));
|
|
return m_dwTimerCount;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void CScriptTimers::Delete(DWORD dwTimerId)
|
|
{
|
|
DwordTimerMap::iterator itor;
|
|
itor = m_Timers.find(dwTimerId);
|
|
if (itor != m_Timers.end())
|
|
{
|
|
FreeMem(itor->second);
|
|
SAFE_DELETE(itor->second);
|
|
m_Timers.erase(itor);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void CScriptTimers::Kill(DWORD dwTimerId)
|
|
{
|
|
DwordTimerMap::iterator itor;
|
|
itor = m_Timers.find(dwTimerId);
|
|
if (itor != m_Timers.end())
|
|
{
|
|
itor->second->iRemainingTime = 0;
|
|
itor->second->bKilled = true;
|
|
itor->second->bRepeating = false;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
void CScriptTimers::Process(int iElapsedTime)
|
|
{
|
|
DwordTimerMap::iterator itor;
|
|
CGameMode *pGameMode;
|
|
for (itor = m_Timers.begin(); itor != m_Timers.end(); itor++)
|
|
{
|
|
itor->second->iRemainingTime -= iElapsedTime;
|
|
if (itor->second->iRemainingTime <= 0)
|
|
{
|
|
DwordTimerMap::iterator itor_tmp = ++itor; itor--;
|
|
if (!itor->second->bKilled)
|
|
{
|
|
pGameMode = pNetGame->GetGameMode();
|
|
if (pGameMode)
|
|
{
|
|
int idx;
|
|
AMX* amx = itor->second->pAMX;
|
|
if (amx && !amx_FindPublic(amx, itor->second->szScriptFunc, &idx))
|
|
{
|
|
cell ret;
|
|
int count = itor->second->iParamCount;
|
|
int i = 0;
|
|
if (count > 0)
|
|
{
|
|
cell* pars = (cell*)itor->second->cellParams;
|
|
while (i < count)
|
|
{
|
|
amx_Push(amx, pars[i]);
|
|
i++; // Go forwards to maintain push order
|
|
}
|
|
}
|
|
amx_Exec(amx, &ret, idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (itor->second->bRepeating)
|
|
{
|
|
itor->second->iRemainingTime = itor->second->iTotalTime;
|
|
}
|
|
else
|
|
{
|
|
// Release parameter memory
|
|
FreeMem(itor->second);
|
|
Delete(itor->first);
|
|
}
|
|
itor = itor_tmp;
|
|
}
|
|
if (itor == m_Timers.end()) break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// EOF
|