mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 06:15:37 +03:00
rewritten; have not changed interface
should support messages with more than 32 params now
This commit is contained in:
parent
ce318d366d
commit
3c2107bf1d
@ -1,32 +1,32 @@
|
|||||||
/* AMX Mod X
|
/*
|
||||||
|
* Copyright (c) 2002-2003 Aleksander Naszko, Pavol Marko
|
||||||
*
|
*
|
||||||
* by the AMX Mod X Development Team
|
* This file is part of AMX Mod X.
|
||||||
* originally developed by OLO
|
|
||||||
*
|
*
|
||||||
|
* AMX Mod X is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* AMX Mod X is distributed in the hope that it will be useful, but
|
||||||
* under the terms of the GNU General Public License as published by the
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* your option) any later version.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* You should have received a copy of the GNU General Public License
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
* along with AMX Mod Xod; if not, write to the Free Software Foundation,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
* General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* In addition, as a special exception, the author gives permission to
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
*
|
*
|
||||||
* In addition, as a special exception, the author gives permission to
|
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
||||||
* respects for all of the code used other than the HL Engine and MODs
|
|
||||||
* from Valve. If you modify this file, you may extend this exception
|
|
||||||
* to your version of the file, but you are not obligated to do so. If
|
|
||||||
* you do not wish to do so, delete this exception statement from your
|
|
||||||
* version.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <extdll.h>
|
#include <extdll.h>
|
||||||
@ -35,303 +35,440 @@
|
|||||||
#include "CEvent.h"
|
#include "CEvent.h"
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class EventsMngr
|
// class ClEvent
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
EventsMngr::EventsMngr()
|
|
||||||
{
|
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||||
memset( modMsgsFunCall, 0 , sizeof(modMsgsFunCall) );
|
{
|
||||||
|
m_Plugin = plugin;
|
||||||
|
m_Func = func;
|
||||||
|
|
||||||
|
// flags
|
||||||
|
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||||
|
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||||
|
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||||
|
if (flags & 24)
|
||||||
|
{
|
||||||
|
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||||
|
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Stamp = 0.0f;
|
||||||
|
m_Done = false;
|
||||||
}
|
}
|
||||||
EventsMngr::~EventsMngr()
|
|
||||||
{
|
EventsMngr::ClEvent::~ClEvent()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int EventsMngr::ClEvent::getFunction()
|
||||||
|
{
|
||||||
|
return m_Func;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventsMngr::EventsMngr()
|
||||||
|
{
|
||||||
clearEvents();
|
clearEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventsMngr::ClEvent::ClEvent( CPluginMngr::CPlugin* amxplugin, int function, int flags )
|
EventsMngr::~EventsMngr()
|
||||||
{
|
{
|
||||||
plugin = amxplugin;
|
clearEvents();
|
||||||
func = function;
|
|
||||||
stamp = 0.0;
|
|
||||||
next = 0;
|
|
||||||
done = false;
|
|
||||||
alive=true;
|
|
||||||
dead=true;
|
|
||||||
if ( flags & 24 ){
|
|
||||||
alive=(flags&16)?true:false; //e
|
|
||||||
dead=(flags&8)?true:false; //d
|
|
||||||
}
|
|
||||||
world=(flags&1)?true:false; //a
|
|
||||||
player=(flags&2)?true:false; //b
|
|
||||||
once=(flags&4)?true:false; //c
|
|
||||||
memset(cond,0,sizeof(cond));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventsMngr::ClEvent::registerFilter( char* filter )
|
|
||||||
|
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
|
||||||
{
|
{
|
||||||
if ( filter == 0 ) return;
|
return m_Plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************
|
||||||
|
// class EventsMngr
|
||||||
|
// *****************************************************
|
||||||
|
|
||||||
|
void EventsMngr::ClEvent::registerFilter(char *filter)
|
||||||
|
{
|
||||||
|
// filters (conditions) have the form x&y
|
||||||
|
// x is the param number
|
||||||
|
// & may also be other characters
|
||||||
|
// y is a string or a number
|
||||||
|
if (!filter)
|
||||||
|
return;
|
||||||
|
|
||||||
char* value = filter;
|
char* value = filter;
|
||||||
|
|
||||||
while ( isdigit(*value) )
|
// get the first numbr
|
||||||
|
while (isdigit(*value))
|
||||||
++value;
|
++value;
|
||||||
|
|
||||||
if ( *value == 0 ) return;
|
// end of string => ignore
|
||||||
|
if (!*value)
|
||||||
|
return;
|
||||||
|
|
||||||
cond_t* b = new cond_t;
|
CondMapPair pair;
|
||||||
|
|
||||||
if ( b == 0 ) return;
|
// type character
|
||||||
|
pair.second.type = *value;
|
||||||
b->type = *value;
|
|
||||||
|
|
||||||
|
// set a null here so param id can be recognized later
|
||||||
*value++ = 0;
|
*value++ = 0;
|
||||||
|
|
||||||
b->sValue.set(value);
|
// rest of line
|
||||||
b->fValue = atof(value);
|
pair.second.sValue = value;
|
||||||
b->iValue = atoi(value);
|
pair.second.fValue = atof(value);
|
||||||
|
pair.second.iValue = atoi(value);
|
||||||
|
|
||||||
int i = atoi(filter);
|
// param id
|
||||||
if (i >= 0 && i < MAX_PARSE_VALUES) {
|
pair.first = atoi(filter);
|
||||||
b->next = cond[i];
|
|
||||||
cond[i] = b;
|
m_Conditions.insert(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid)
|
||||||
|
{
|
||||||
|
// validate parameter
|
||||||
|
if (msgid < 0 || msgid >= MAX_AMX_REG_MSG)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ClEvent *event = new ClEvent(plugin, func, flags);
|
||||||
|
if (!event)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
m_Events[msgid].push_back(event);
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index)
|
||||||
|
{
|
||||||
|
if (msg_type < 0 || msg_type > MAX_AMX_REG_MSG)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_ParseNotDone = false;
|
||||||
|
m_Timer = timer;
|
||||||
|
|
||||||
|
// don't parse if nothing to do
|
||||||
|
if (m_Events[msg_type].empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(ClEventVecIter iter = m_Events[msg_type].begin(); iter != m_Events[msg_type].end(); ++iter)
|
||||||
|
{
|
||||||
|
if ((*iter)->m_Done)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(*iter)->m_Plugin->isExecutable((*iter)->m_Func))
|
||||||
|
{
|
||||||
|
(*iter)->m_Done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPlayer)
|
||||||
|
{
|
||||||
|
if (!(*iter)->m_FlagPlayer || (pPlayer->IsAlive() ? !(*iter)->m_FlagAlive : !(*iter)->m_FlagDead ) )
|
||||||
|
{
|
||||||
|
(*iter)->m_Done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(*iter)->m_FlagWorld)
|
||||||
|
{
|
||||||
|
(*iter)->m_Done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*iter)->m_FlagOnce && (*iter)->m_Stamp == (float)(*timer))
|
||||||
|
{
|
||||||
|
(*iter)->m_Done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_ParseNotDone = true;
|
||||||
}
|
}
|
||||||
else delete b;
|
|
||||||
|
if (m_ParseNotDone)
|
||||||
|
{
|
||||||
|
// we don't clear it (performance)
|
||||||
|
if (m_ParseVault.size() < 1)
|
||||||
|
{
|
||||||
|
m_ParseVault.reserve(32); // 32 as default
|
||||||
|
m_ParseVault.push_back(MsgDataVault());
|
||||||
|
}
|
||||||
|
m_ParsePos = 0;
|
||||||
|
m_ParseVault[m_ParsePos].type = MSG_INTEGER;
|
||||||
|
m_ParseVault[m_ParsePos].iValue = index;
|
||||||
|
}
|
||||||
|
m_ParseFun = &m_Events[msg_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
EventsMngr::ClEvent* EventsMngr::registerEvent( CPluginMngr::CPlugin* p, int f, int flags, int pos )
|
void EventsMngr::parseValue(int iValue)
|
||||||
{
|
{
|
||||||
ClEvent* a = new ClEvent( p , f , flags );
|
// not parsing
|
||||||
if ( a == 0 ) return 0;
|
if (!m_ParseNotDone || !m_ParseFun)
|
||||||
ClEvent** end = &modMsgsFunCall[pos];
|
return;
|
||||||
while( *end ) end = &(*end)->next;
|
|
||||||
return *end = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventsMngr::parserInit(int msg_type, float* tim, CPlayer *pPlayer, int index) {
|
// grow if needed
|
||||||
parseNotDone = false;
|
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||||
timer = tim;
|
{
|
||||||
if ( (parseFun = modMsgsFunCall[msg_type]) == 0 ) return;
|
MsgDataVault tmp;
|
||||||
|
m_ParseVault.push_back(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
for(EventsMngr::ClEvent*p=parseFun;p;p=p->next){
|
m_ParseVault[m_ParsePos].type = MSG_INTEGER;
|
||||||
if ( p->done ) continue;
|
m_ParseVault[m_ParsePos].iValue = iValue;
|
||||||
if ( !p->plugin->isExecutable(p->func) ){
|
|
||||||
p->done = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( pPlayer ) {
|
|
||||||
if ( !p->player || ( pPlayer->IsAlive() ? !p->alive : !p->dead ) ) {
|
|
||||||
p->done = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( !p->world ){
|
|
||||||
p->done = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( p->once && p->stamp == (float)(*timer) ){
|
|
||||||
p->done = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
parseNotDone = true;
|
|
||||||
}
|
|
||||||
if ( parseNotDone ) {
|
|
||||||
parseVault[parsePos = 0].type = MSG_INTEGER;
|
|
||||||
parseVault[parsePos].iValue = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// loop through the registered funcs, and decide whether they have to be called
|
||||||
|
bool skip;
|
||||||
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||||
|
{
|
||||||
|
if ((*iter)->m_Done)
|
||||||
|
continue;
|
||||||
|
|
||||||
const char* EventsMngr::getArgString(int a)
|
skip = false;
|
||||||
{
|
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||||
if ( a < 0 || a > parsePos ) return "";
|
if (condIter == (*iter)->m_Conditions.end())
|
||||||
static char var[32];
|
continue;
|
||||||
switch(parseVault[a].type){
|
|
||||||
case MSG_INTEGER:
|
do
|
||||||
sprintf( var, "%d", parseVault[a].iValue );
|
{
|
||||||
return var;
|
switch(condIter->second.type)
|
||||||
case MSG_STRING:
|
{
|
||||||
return parseVault[a].sValue;
|
case '=': if (condIter->second.iValue == iValue) skip=true; break;
|
||||||
default:
|
case '!': if (condIter->second.iValue != iValue) skip=true; break;
|
||||||
sprintf( var, "%g", parseVault[a].fValue );
|
case '&': if (iValue & condIter->second.iValue) skip=true; break;
|
||||||
return var;
|
case '<': if (iValue < condIter->second.iValue) skip=true; break;
|
||||||
|
case '>': if (iValue > condIter->second.iValue) skip=true; break;
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
break;
|
||||||
|
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
(*iter)->m_Done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventsMngr::getArgInteger(int a)
|
void EventsMngr::parseValue(float fValue)
|
||||||
{
|
{
|
||||||
if ( a < 0 || a > parsePos ) return 0;
|
// not parsing
|
||||||
switch(parseVault[a].type){
|
if (!m_ParseNotDone || !m_ParseFun)
|
||||||
case MSG_INTEGER: return parseVault[a].iValue;
|
return;
|
||||||
case MSG_STRING: return atoi(parseVault[a].sValue);
|
|
||||||
default: return (int)parseVault[a].fValue;
|
// grow if needed
|
||||||
|
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||||
|
{
|
||||||
|
MsgDataVault tmp;
|
||||||
|
m_ParseVault.push_back(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ParseVault[m_ParsePos].type = MSG_FLOAT;
|
||||||
|
m_ParseVault[m_ParsePos].fValue = fValue;
|
||||||
|
|
||||||
|
// loop through the registered funcs, and decide whether they have to be called
|
||||||
|
bool skip;
|
||||||
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||||
|
{
|
||||||
|
if ((*iter)->m_Done)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skip = false;
|
||||||
|
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||||
|
if (condIter == (*iter)->m_Conditions.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
switch(condIter->second.type)
|
||||||
|
{
|
||||||
|
case '=': if (condIter->second.fValue == fValue) skip=true; break;
|
||||||
|
case '!': if (condIter->second.fValue != fValue) skip=true; break;
|
||||||
|
case '<': if (fValue < condIter->second.fValue) skip=true; break;
|
||||||
|
case '>': if (fValue > condIter->second.fValue) skip=true; break;
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
break;
|
||||||
|
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
(*iter)->m_Done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float EventsMngr::getArgFloat(int a)
|
void EventsMngr::parseValue(const char *sz)
|
||||||
{
|
{
|
||||||
if ( a < 0 || a > parsePos ) return 0.0f;
|
// not parsing
|
||||||
switch(parseVault[a].type){
|
if (!m_ParseNotDone || !m_ParseFun)
|
||||||
case MSG_INTEGER: return parseVault[a].iValue;
|
return;
|
||||||
case MSG_STRING: return atof(parseVault[a].sValue);
|
|
||||||
default: return parseVault[a].fValue;
|
// grow if needed
|
||||||
|
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||||
|
{
|
||||||
|
MsgDataVault tmp;
|
||||||
|
m_ParseVault.push_back(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ParseVault[m_ParsePos].type = MSG_STRING;
|
||||||
|
m_ParseVault[m_ParsePos].sValue = sz;
|
||||||
|
|
||||||
|
// loop through the registered funcs, and decide whether they have to be called
|
||||||
|
bool skip;
|
||||||
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||||
|
{
|
||||||
|
if ((*iter)->m_Done)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skip = false;
|
||||||
|
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||||
|
if (condIter == (*iter)->m_Conditions.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
switch(condIter->second.type)
|
||||||
|
{
|
||||||
|
case '=': if (!strcmp(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||||
|
case '!': if (!strstr(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||||
|
case '&': if (strstr(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
break;
|
||||||
|
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
(*iter)->m_Done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventsMngr::executeEvents()
|
||||||
|
{
|
||||||
void EventsMngr::executeEvents() {
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#ifdef ENABLEEXEPTIONS
|
#ifdef ENABLEEXEPTIONS
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#endif
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||||
for ( ClEvent*p = parseFun ; p ; p = p->next )
|
|
||||||
{
|
{
|
||||||
|
if ( (*iter)->m_Done )
|
||||||
if ( p->done )
|
|
||||||
{
|
{
|
||||||
p->done = false;
|
(*iter)->m_Done = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->stamp = *timer;
|
(*iter)->m_Stamp = *m_Timer;
|
||||||
|
|
||||||
if ((err = amx_Exec(p->plugin->getAMX(), NULL , p->func , 1,parseVault[0].iValue)) != AMX_ERR_NONE)
|
if ((err = amx_Exec((*iter)->m_Plugin->getAMX(), NULL, (*iter)->m_Func, 1, m_ParseVault.size() ? m_ParseVault[0].iValue : 0)) != AMX_ERR_NONE)
|
||||||
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n",err,p->plugin->getAMX()->curline,p->plugin->getName());
|
{
|
||||||
|
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n", err,
|
||||||
|
(*iter)->m_Plugin->getAMX()->curline, (*iter)->m_Plugin->getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLEEXEPTIONS
|
#ifdef ENABLEEXEPTIONS
|
||||||
}
|
}
|
||||||
catch( ... )
|
catch( ... )
|
||||||
{
|
{
|
||||||
print_srvconsole( "[AMX] fatal error at event execution\n");
|
print_srvconsole( "[AMX] fatal error at event execution\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventsMngr::parseValue(int iValue) {
|
int EventsMngr::getArgNum()
|
||||||
if ( !parseNotDone ) return;
|
|
||||||
parseVault[++parsePos].type = MSG_INTEGER;
|
|
||||||
parseVault[parsePos].iValue = iValue;
|
|
||||||
bool skip;
|
|
||||||
for (ClEvent*p=parseFun;p;p=p->next){
|
|
||||||
if ( p->done || !p->cond[parsePos] ) continue;
|
|
||||||
skip = false;
|
|
||||||
ClEvent::cond_t* a = p->cond[parsePos];
|
|
||||||
do {
|
|
||||||
switch(a->type){
|
|
||||||
case '=': if (a->iValue == iValue) skip=true; break;
|
|
||||||
case '!': if (a->iValue != iValue) skip=true; break;
|
|
||||||
case '&': if (iValue & a->iValue) skip=true; break;
|
|
||||||
case '<': if (iValue < a->iValue) skip=true; break;
|
|
||||||
case '>': if (iValue > a->iValue) skip=true; break;
|
|
||||||
}
|
|
||||||
if (skip) break;
|
|
||||||
} while ( a = a->next );
|
|
||||||
if (skip) continue;
|
|
||||||
p->done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventsMngr::parseValue(float flValue) {
|
|
||||||
if ( !parseNotDone ) return;
|
|
||||||
parseVault[++parsePos].type = MSG_FLOAT;
|
|
||||||
parseVault[parsePos].fValue = flValue;
|
|
||||||
bool skip;
|
|
||||||
for (ClEvent*p=parseFun;p;p=p->next){
|
|
||||||
if ( p->done || !p->cond[parsePos] ) continue;
|
|
||||||
skip = false;
|
|
||||||
ClEvent::cond_t* a = p->cond[parsePos];
|
|
||||||
do {
|
|
||||||
switch(a->type){
|
|
||||||
case '=': if (a->fValue == flValue) skip=true; break;
|
|
||||||
case '!': if (a->fValue != flValue) skip=true; break;
|
|
||||||
case '<': if (flValue < a->fValue) skip=true; break;
|
|
||||||
case '>': if (flValue > a->fValue) skip=true; break;
|
|
||||||
}
|
|
||||||
if (skip) break;
|
|
||||||
} while ( a = a->next );
|
|
||||||
if (skip) continue;
|
|
||||||
p->done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventsMngr::parseValue(const char *sz) {
|
|
||||||
if ( !parseNotDone ) return;
|
|
||||||
parseVault[++parsePos].type = MSG_STRING;
|
|
||||||
parseVault[parsePos].sValue = sz;
|
|
||||||
bool skip;
|
|
||||||
for (ClEvent*p=parseFun;p;p=p->next){
|
|
||||||
if ( p->done || !p->cond[parsePos] ) continue;
|
|
||||||
skip = false;
|
|
||||||
ClEvent::cond_t* a = p->cond[parsePos];
|
|
||||||
do {
|
|
||||||
switch(a->type){
|
|
||||||
case '=': if (!strcmp(sz,a->sValue.str())) skip=true; break;
|
|
||||||
case '!': if (strcmp(sz,a->sValue.str())) skip=true; break;
|
|
||||||
case '&': if (strstr(sz,a->sValue.str())) skip=true; break;
|
|
||||||
}
|
|
||||||
if (skip) break;
|
|
||||||
} while ( a = a->next );
|
|
||||||
if (skip) continue;
|
|
||||||
p->done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventsMngr::clearEvents()
|
|
||||||
{
|
{
|
||||||
for(int i=0;i<MAX_AMX_REG_MSG;++i){
|
return m_ParsePos + 1;
|
||||||
ClEvent**b = &modMsgsFunCall[i];
|
}
|
||||||
while (*b){
|
|
||||||
ClEvent*aa = (*b)->next;
|
const char* EventsMngr::getArgString(int a)
|
||||||
delete *b;
|
{
|
||||||
*b = aa;
|
if ( a < 0 || a > m_ParsePos )
|
||||||
}
|
return "";
|
||||||
|
|
||||||
|
static char var[32];
|
||||||
|
|
||||||
|
switch(m_ParseVault[a].type)
|
||||||
|
{
|
||||||
|
case MSG_INTEGER:
|
||||||
|
sprintf( var, "%d", m_ParseVault[a].iValue );
|
||||||
|
return var;
|
||||||
|
case MSG_STRING:
|
||||||
|
return m_ParseVault[a].sValue;
|
||||||
|
default:
|
||||||
|
sprintf( var, "%g", m_ParseVault[a].fValue );
|
||||||
|
return var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EventsMngr::ClEvent::~ClEvent(){
|
int EventsMngr::getArgInteger(int a)
|
||||||
for(int a = 0; a < MAX_PARSE_VALUES; ++a){
|
{
|
||||||
cond_t** b = &cond[a];
|
if ( a < 0 || a > m_ParsePos )
|
||||||
while(*b){
|
return 0;
|
||||||
cond_t* nn = (*b)->next;
|
|
||||||
delete *b;
|
switch(m_ParseVault[a].type)
|
||||||
*b = nn;
|
{
|
||||||
}
|
case MSG_INTEGER:
|
||||||
|
return m_ParseVault[a].iValue;
|
||||||
|
case MSG_STRING:
|
||||||
|
return atoi(m_ParseVault[a].sValue);
|
||||||
|
default:
|
||||||
|
return (int)m_ParseVault[a].fValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EventsMngr::ClEvent* EventsMngr::getValidEvent(ClEvent* a ) {
|
float EventsMngr::getArgFloat(int a)
|
||||||
while(a){
|
{
|
||||||
if ( a->done ) {
|
if ( a < 0 || a > m_ParsePos )
|
||||||
a->done = false;
|
return 0.0f;
|
||||||
a = a->next;
|
|
||||||
continue;
|
switch(m_ParseVault[a].type)
|
||||||
}
|
{
|
||||||
a->stamp = *timer;
|
case MSG_INTEGER:
|
||||||
return a;
|
return m_ParseVault[a].iValue;
|
||||||
|
case MSG_STRING:
|
||||||
|
return atof(m_ParseVault[a].sValue);
|
||||||
|
default:
|
||||||
|
return m_ParseVault[a].fValue;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventsMngr::getEventId( const char* msg ){
|
void EventsMngr::clearEvents(void)
|
||||||
struct CS_Events {
|
{
|
||||||
|
for (int i = 0; i < MAX_AMX_REG_MSG; ++i)
|
||||||
|
{
|
||||||
|
for (ClEventVecIter iter = m_Events[i].begin(); iter != m_Events[i].end(); ++iter)
|
||||||
|
{
|
||||||
|
if (*iter)
|
||||||
|
delete *iter;
|
||||||
|
}
|
||||||
|
m_Events[i].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int EventsMngr::getEventId(const char* msg)
|
||||||
|
{
|
||||||
|
const struct CS_Events
|
||||||
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
CS_EventsIds id;
|
CS_EventsIds id;
|
||||||
} table[] = {
|
} table[] =
|
||||||
|
{
|
||||||
{ "CS_DeathMsg" , CS_DeathMsg },
|
{ "CS_DeathMsg" , CS_DeathMsg },
|
||||||
// { "CS_RoundEnd" , CS_RoundEnd },
|
// { "CS_RoundEnd" , CS_RoundEnd },
|
||||||
// { "CS_RoundStart" , CS_RoundStart },
|
// { "CS_RoundStart" , CS_RoundStart },
|
||||||
// { "CS_Restart" , CS_Restart },
|
// { "CS_Restart" , CS_Restart },
|
||||||
{ "" , CS_Null }
|
{ "" , CS_Null }
|
||||||
};
|
};
|
||||||
int pos;
|
// if msg is a number, return it
|
||||||
if ( (pos = atoi( msg )) != 0 )
|
int pos = atoi(msg);
|
||||||
|
if (pos != 0)
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
|
// try to find in table first
|
||||||
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
|
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
|
||||||
if ( !strcmp( table[ pos ].name , msg ) )
|
if ( !strcmp( table[ pos ].name , msg ) )
|
||||||
return table[ pos ].id;
|
return table[ pos ].id;
|
||||||
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
|
|
||||||
|
// not found
|
||||||
|
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
|
||||||
}
|
}
|
||||||
|
175
amxmodx/CEvent.h
175
amxmodx/CEvent.h
@ -1,40 +1,43 @@
|
|||||||
/* AMX Mod X
|
/*
|
||||||
|
* Copyright (c) 2002-2003 Aleksander Naszko, Pavol Marko
|
||||||
*
|
*
|
||||||
* by the AMX Mod X Development Team
|
* This file is part of AMX Mod X.
|
||||||
* originally developed by OLO
|
|
||||||
*
|
*
|
||||||
|
* AMX Mod X is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* AMX Mod X is distributed in the hope that it will be useful, but
|
||||||
* under the terms of the GNU General Public License as published by the
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* your option) any later version.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* You should have received a copy of the GNU General Public License
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
* along with AMX Mod Xod; if not, write to the Free Software Foundation,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
* General Public License for more details.
|
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* In addition, as a special exception, the author gives permission to
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
*
|
*
|
||||||
* In addition, as a special exception, the author gives permission to
|
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
||||||
* respects for all of the code used other than the HL Engine and MODs
|
|
||||||
* from Valve. If you modify this file, you may extend this exception
|
|
||||||
* to your version of the file, but you are not obligated to do so. If
|
|
||||||
* you do not wish to do so, delete this exception statement from your
|
|
||||||
* version.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EVENTS_H
|
#ifndef __CEVENTS_H__
|
||||||
#define EVENTS_H
|
#define __CEVENTS_H__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#define MAX_PARSE_VALUES 32
|
|
||||||
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
|
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CS_DEATHMSG = MAX_REG_MSGS,
|
CS_DEATHMSG = MAX_REG_MSGS,
|
||||||
// CS_ROUNDEND,
|
// CS_ROUNDEND,
|
||||||
@ -46,10 +49,10 @@ enum {
|
|||||||
// class EventsMngr
|
// class EventsMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
|
class EventsMngr
|
||||||
class EventsMngr {
|
{
|
||||||
|
enum MsgParamType
|
||||||
enum MsgValueType{
|
{
|
||||||
MSG_INTEGER,
|
MSG_INTEGER,
|
||||||
MSG_FLOAT,
|
MSG_FLOAT,
|
||||||
MSG_STRING,
|
MSG_STRING,
|
||||||
@ -57,7 +60,8 @@ class EventsMngr {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum CS_EventsIds {
|
enum CS_EventsIds
|
||||||
|
{
|
||||||
CS_Null = 0,
|
CS_Null = 0,
|
||||||
CS_DeathMsg = MAX_REG_MSGS, // start from last element
|
CS_DeathMsg = MAX_REG_MSGS, // start from last element
|
||||||
// CS_RoundEnd,
|
// CS_RoundEnd,
|
||||||
@ -65,51 +69,69 @@ public:
|
|||||||
// CS_Restart,
|
// CS_Restart,
|
||||||
};
|
};
|
||||||
|
|
||||||
class iterator;
|
class ClEvent
|
||||||
friend class iterator;
|
{
|
||||||
|
friend class EventsMngr; // events manager may access our private members
|
||||||
|
|
||||||
class ClEvent {
|
int m_Func; // function to be executed
|
||||||
friend class EventsMngr;
|
CPluginMngr::CPlugin *m_Plugin; // the plugin this ClEvent class is assigned to
|
||||||
friend class iterator;
|
|
||||||
CPluginMngr::CPlugin* plugin;
|
// flags
|
||||||
int func;
|
bool m_FlagPlayer;
|
||||||
bool player;
|
bool m_FlagWorld;
|
||||||
bool world;
|
bool m_FlagOnce;
|
||||||
bool once;
|
bool m_FlagDead;
|
||||||
bool done;
|
bool m_FlagAlive;
|
||||||
bool dead;
|
|
||||||
bool alive;
|
float m_Stamp; // for 'once' flag
|
||||||
float stamp;
|
|
||||||
struct cond_t {
|
bool m_Done;
|
||||||
String sValue;
|
|
||||||
|
// conditions
|
||||||
|
struct cond_t
|
||||||
|
{
|
||||||
|
std::string sValue; // value
|
||||||
float fValue;
|
float fValue;
|
||||||
int iValue;
|
int iValue;
|
||||||
int type;
|
int type;
|
||||||
cond_t* next;
|
};
|
||||||
} *cond[MAX_PARSE_VALUES];
|
|
||||||
ClEvent* next;
|
typedef std::pair<int, cond_t> CondMapPair;
|
||||||
ClEvent( CPluginMngr::CPlugin* p, int f, int flags );
|
typedef std::map<int, cond_t> CondMap;
|
||||||
|
typedef CondMap::iterator CondMapIter;
|
||||||
|
|
||||||
|
CondMap m_Conditions;
|
||||||
|
|
||||||
|
// constructors & destructors
|
||||||
|
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||||
~ClEvent();
|
~ClEvent();
|
||||||
public:
|
public:
|
||||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
inline CPluginMngr::CPlugin* getPlugin();
|
||||||
inline int getFunction() { return func; }
|
inline int getFunction();
|
||||||
void registerFilter( char* filter );
|
void registerFilter(char* filter); // add a condition
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MsgDataVault {
|
struct MsgDataVault
|
||||||
|
{
|
||||||
float fValue;
|
float fValue;
|
||||||
int iValue;
|
int iValue;
|
||||||
const char* sValue;
|
const char* sValue;
|
||||||
MsgValueType type;
|
MsgParamType type;
|
||||||
} parseVault[MAX_PARSE_VALUES];
|
};
|
||||||
|
typedef std::vector<MsgDataVault> MsgDataVaultVec;
|
||||||
|
typedef MsgDataVaultVec::iterator MsgDataVaultVecIter;
|
||||||
|
MsgDataVaultVec m_ParseVault;
|
||||||
|
|
||||||
|
typedef std::vector<ClEvent*> ClEventVec;
|
||||||
|
typedef ClEventVec::iterator ClEventVecIter;
|
||||||
|
ClEventVec m_Events[MAX_AMX_REG_MSG];
|
||||||
|
ClEventVec *m_ParseFun; // current Event vector
|
||||||
|
|
||||||
ClEvent* modMsgsFunCall[MAX_AMX_REG_MSG];
|
bool m_ParseNotDone;
|
||||||
ClEvent* parseFun;
|
int m_ParsePos; // is -1 less then args. num.
|
||||||
bool parseNotDone;
|
float* m_Timer;
|
||||||
int parsePos; // is -1 less then args. num.
|
|
||||||
float* timer;
|
|
||||||
ClEvent* getValidEvent(ClEvent* a );
|
ClEvent* getValidEvent(ClEvent* a );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -118,37 +140,18 @@ public:
|
|||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
ClEvent* registerEvent( CPluginMngr::CPlugin* p, int f, int flags, int pos );
|
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
|
||||||
void parserInit(int msg_type, float* timer , CPlayer* target = 0, int index = 0);
|
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
|
||||||
void parseValue(int iValue);
|
void parseValue(int iValue);
|
||||||
void parseValue(float fValue);
|
void parseValue(float fValue);
|
||||||
void parseValue(const char *sz);
|
void parseValue(const char *sz);
|
||||||
void executeEvents();
|
void executeEvents();
|
||||||
inline int getArgNum() { return (parsePos+1); }
|
int getArgNum(); //{ return (parsePos+1); }
|
||||||
const char* getArgString(int a);
|
const char* getArgString(int a);
|
||||||
int getArgInteger(int a);
|
int getArgInteger(int a);
|
||||||
float getArgFloat(int a);
|
float getArgFloat(int a);
|
||||||
void clearEvents(void);
|
void clearEvents(void);
|
||||||
static int getEventId( const char* msg );
|
static int getEventId( const char* msg );
|
||||||
|
|
||||||
|
|
||||||
class iterator {
|
|
||||||
EventsMngr* b;
|
|
||||||
ClEvent* a;
|
|
||||||
public:
|
|
||||||
inline iterator(ClEvent*aa,EventsMngr* bb) : a(aa), b(bb) {}
|
|
||||||
inline iterator& operator++() {
|
|
||||||
a = b->getValidEvent( a->next );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
inline bool operator==(const iterator& c) const { return a == c.a; }
|
|
||||||
inline bool operator!=(const iterator& c) const { return !operator==(c); }
|
|
||||||
ClEvent& operator*() { return *a; }
|
|
||||||
operator bool ( ) const { return a ? true : false; }
|
|
||||||
};
|
|
||||||
inline iterator begin() { return iterator(getValidEvent(parseFun),this); }
|
|
||||||
inline iterator end() { return iterator(0,this); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // #ifdef __CEVENTS_H__
|
||||||
|
|
Loading…
Reference in New Issue
Block a user