/**************************************************************************
* File: mud_event.c Part of tbaMUD *
* Usage: Handling of the mud event system *
* *
* By Vatiken. Copyright 2012 by Joseph Arnusch *
**************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "db.h"
#include "dg_event.h"
#include "constants.h"
#include "comm.h" /* For access to the game pulse */
#include "mud_event.h"
/* Global List */
struct list_data * world_events = NULL;
/* The mud_event_index[] is merely a tool for organizing events, and giving
* them a "const char *" name to help in potential debugging */
struct mud_event_list mud_event_index[] = {
{ "Null" , NULL , -1 }, /* eNULL */
{ "Protocol" , get_protocols , EVENT_DESC }, /* ePROTOCOLS */
{ "Whirlwind" , event_whirlwind, EVENT_CHAR } /* eWHIRLWIND */
};
/* init_events() is the ideal function for starting global events. This
* might be the case if you were to move the contents of heartbeat() into
* the event system */
void init_events(void)
{
/* Allocate Event List */
world_events = create_list();
}
/* event_countdown() is used for events which are to be used as a countdown...
* go figure eh? This could be useful for skills which have an extended cooldown,
* like "lay on hands" once every 24 hours. Simply add an event to the
* mud_event_index[] such as:
* { "Lay on hands" , event_countdown, EVENT_CHAR }
* and then add the event after a successful skill call:
* attach_mud_event(new_mud_event(eLAYONHANDS, ch, NULL), 24 * SECS_PER_MUD_HOUR);
* and then add something like this is your skill function:
* if (char_has_mud_event(ch, eLAYONHANDS)) {
* send_to_char(ch, "You must wait a full 24 hours before re-using this skill.\r\n");
* return;
* }
* The bottom switch() is for any post-event actions, like telling the character they can
* now access their skill again.
*/
EVENTFUNC(event_countdown)
{
struct mud_event_data * pMudEvent;
struct char_data * ch = NULL;
pMudEvent = (struct mud_event_data * ) event_obj;
switch (mud_event_index[pMudEvent->iId].iEvent_Type) {
case EVENT_CHAR:
ch = (struct char_data * ) pMudEvent->pStruct;
break;
default:
break;
}
switch (pMudEvent->iId) {
default:
break;
}
return 0;
}
/* As of 3.63, there are only global, descriptor, and character events. This
* is due to the potential scope of the necessary debugging if events were
* included with rooms, objects, spells or any other structure type. Adding
* events to these other systems should be just as easy as adding the current
* library was, and should be available in a future release. - Vat */
void attach_mud_event(struct mud_event_data *pMudEvent, long time)
{
struct event * pEvent;
struct descriptor_data * d;
struct char_data * ch;
pEvent = event_create(mud_event_index[pMudEvent->iId].func, pMudEvent, time);
pEvent->isMudEvent = TRUE;
pMudEvent->pEvent = pEvent;
switch (mud_event_index[pMudEvent->iId].iEvent_Type) {
case EVENT_WORLD:
add_to_list(pEvent, world_events);
break;
case EVENT_DESC:
d = (struct descriptor_data *) pMudEvent->pStruct;
add_to_list(pEvent, d->events);
break;
case EVENT_CHAR:
ch = (struct char_data *) pMudEvent->pStruct;
add_to_list(pEvent, ch->events);
break;
}
}
struct mud_event_data *new_mud_event(event_id iId, void *pStruct, char *sVariables)
{
struct mud_event_data *pMudEvent;
char *varString;
CREATE(pMudEvent, struct mud_event_data, 1);
varString = (sVariables != NULL) ? strdup(sVariables) : NULL;
pMudEvent->iId = iId;
pMudEvent->pStruct = pStruct;
pMudEvent->sVariables = varString;
pMudEvent->pEvent = NULL;
return (pMudEvent);
}
void free_mud_event(struct mud_event_data *pMudEvent)
{
struct descriptor_data * d;
struct char_data * ch;
switch (mud_event_index[pMudEvent->iId].iEvent_Type) {
case EVENT_WORLD:
remove_from_list(pMudEvent->pEvent, world_events);
break;
case EVENT_DESC:
d = (struct descriptor_data *) pMudEvent->pStruct;
remove_from_list(pMudEvent->pEvent, d->events);
break;
case EVENT_CHAR:
ch = (struct char_data *) pMudEvent->pStruct;
remove_from_list(pMudEvent->pEvent, ch->events);
break;
}
if (pMudEvent->sVariables != NULL)
free(pMudEvent->sVariables);
pMudEvent->pEvent->event_obj = NULL;
free(pMudEvent);
}
struct mud_event_data * char_has_mud_event(struct char_data * ch, event_id iId)
{
struct event * pEvent;
struct mud_event_data * pMudEvent;
bool found = FALSE;
if (ch->events->iSize == 0)
return NULL;
simple_list(NULL);
while ((pEvent = (struct event *) simple_list(ch->events)) != NULL) {
if (!pEvent->isMudEvent)
continue;
pMudEvent = (struct mud_event_data * ) pEvent->event_obj;
if (pMudEvent->iId == iId) {
found = TRUE;
break;
}
}
simple_list(NULL);
if (found)
return (pMudEvent);
return NULL;
}