rewritten; have not changed interface

should support messages with more than 32 params now
This commit is contained in:
Pavol Marko 2004-02-26 19:04:53 +00:00
parent ce318d366d
commit 3c2107bf1d
2 changed files with 474 additions and 334 deletions

View File

@ -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 );
} }

View File

@ -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__