From: Oliver Jowett Subject: Re: Events and Ticks > I did some thinking on this very subject over the weekend. First, I don't > think that event-based means you get rid of the cascading loops. You still > have to poll mobs to see if they have events to register. > > So, the aggressive function could work like this: > > [ char_to_room registers a "new person in room" event on the room ] > [ char_to_room registers another "new person in room" event on the room ] > > [ room_event loop ] > we realize that the room has an event pending, so we look at it. Since its > a "new person in room" event, we check for any room reactions (through room > programs) and we pass the message to each character and object in the room. > We also delete any other "new person in room" events, since we've handled > it. > > [ mob_event loop ] > the aggressive mob catches the message and decides that it needs to agress > on a random person. Purge the event. You can use a single global event queue, which means you don't have to run through every room/mob on each pulse. As an example, here's my current event structure: /* Event queueing/dequeueing/etc */ typedef void (*ev_callback)(struct _event *ev); struct _event { union { CHAR_DATA *ch; OBJ_DATA *obj; ROOM_INDEX_DATA *room; } item; /* object/char etc. associated with this */ void *param; /* param for the callback */ ev_callback callback; /* callback to call */ int when; /* when event is going to happen (pulseclock) */ struct _event *next; /* next in priority queue */ struct _event *nextitem; /* next in item queue */ struct _event **start; /* pointer to pointer to start of this sublist */ }; The 'next' pointer goes through a global priority queue of events; the 'nextitem' and 'start' pointers are to maintain a list for each char/room/obj/etc. In char_data (and obj_data, room_index_data, etc) I have: EVENT *events; which is a pointer to the first event concerning this character in the queue; the nextitem pointers then chain through other events concerning it. ch->events->start == &ch->events, so that the event update function can remove an event from the itemlist without knowing the details of the object it's removing it from. > I'm sure that there are better ways to do it, but the main point is simple: > the event-based system waits until the movement cycle is complete before it > starts agressing. Yes, exactly. Oliver -- "The flames are all long gone / But the pain lingers on..."