Пример #1
0
/* function   :: heartbeat()
 * arguments  :: none
 * ======================================================
 * This function is called once per game pulse, and it will
 * check the queue, and execute any pending events, which
 * has been enqueued to execute at this specific time.
 */
void heartbeat()
{
  EVENT_DATA *event;
  ITERATOR Iter;

  /* current_bucket should be global, it is also used in enqueue_event
   * to figure out what bucket to place the new event in.
   */
  current_bucket = (current_bucket + 1) % MAX_EVENT_HASH;

  AttachIterator(&Iter, eventqueue[current_bucket]);
  while ((event = (EVENT_DATA *) NextInList(&Iter)) != NULL)
  {
    /* Here we use the event->passes integer, to keep track of
     * how many times we have ignored this event.
     */
    if (event->passes-- > 0) continue;

    /* execute event and extract if needed. We assume that all
     * event functions are of the following prototype
     *
     * bool event_function ( EVENT_DATA *event );
     *
     * Any event returning TRUE is not dequeued, it is assumed
     * that the event has dequeued itself.
     */
    if (!((*event->fun)(event)))
      dequeue_event(event);
  }
  DetachIterator(&Iter);
}
Пример #2
0
void save_id_handler( ID_HANDLER *handler )
{
   FILE *fp;
   ITERATOR Iter;
   I_ID *id;
   char location[MAX_BUFFER];

   mud_printf( location, "../system/%s.handler", id_handler_names[handler->type] );
   if( ( fp = fopen( location, "w" ) ) == NULL )
   {
      bug( "%s: unable to open file to write: %s", __FUNCTION__, location );
      return;
   }

   fwrite_id_handler( handler, fp );

   AttachIterator( &Iter, handler->free_ids );
   while( ( id = (I_ID *)NextInList(&Iter) ) != NULL )
      fwrite_i_id( id, fp );
   DetachIterator( &Iter );

   fprintf( fp, "%s\n", FILE_TERMINATOR );
   fclose( fp );
   return;
}
Пример #3
0
/* utility */
ID_HANDLER *get_id_handler( int type )
{
   ID_HANDLER *handler = NULL;
   ITERATOR Iter;

   AttachIterator( &Iter, id_handlers );
   while( ( handler = (ID_HANDLER *)NextInList( &Iter ) ) != NULL )
      if( handler->type == type )
         break;
   DetachIterator( &Iter );
   return handler;
}
Пример #4
0
/* function   :: strip_event_mobile()
 * arguments  :: the mobile and the type of event
 * ======================================================
 * This function will dequeue all events of a given type
 * from the given mobile.
 */
void strip_event_mobile(D_MOBILE *dMob, int type)
{
  EVENT_DATA *event;
  ITERATOR Iter;

  AttachIterator(&Iter, dMob->events);
  while ((event = (EVENT_DATA *) NextInList(&Iter)) != NULL)
  {
    if (event->type == type)
      dequeue_event(event);
  }
  DetachIterator(&Iter);
}
Пример #5
0
/* function   :: strip_event_socket()
 * arguments  :: the socket and the type of event
 * ======================================================
 * This function will dequeue all events of a given type
 * from the given socket.
 */
void strip_event_socket(D_SOCKET *dSock, int type)
{
  EVENT_DATA *event;
  ITERATOR Iter;

  AttachIterator(&Iter, dSock->events);
  while ((event = (EVENT_DATA *) NextInList(&Iter)) != NULL)
  {
    if (event->type == type)
      dequeue_event(event);
  }
  DetachIterator(&Iter);
}
Пример #6
0
static void link_exits()
{
   D_ROOM *r, *d; //room and destination room
   D_EXIT *e; //the exit we're linking in the room
   ITERATOR iterRoom, iterExit; //iterators for rooms and exits
   
   if( room_list == NULL )
   {
      bug( "ERROR: Global room list does not exist. Aborting game!!" );
      exit(1);
   }
   
   AttachIterator( &iterRoom, room_list );//iterate through all the rooms in the game
   while( ( r = (D_ROOM*)NextInList( &iterRoom ) ) != NULL ) 
   {
      if( r->exits )
      {
         AttachIterator( &iterExit, r->exits ); //iterate through each room's exits
         while( ( e = (D_EXIT*)NextInList(&iterExit ) ) != NULL )
         {
            if( e->dest ) continue;//If it's already linked, skip it
            if( ( d = frbv( e->destVnum ) ) == NULL )
            {
               bug( "Error: Attempting to link exit to room that does not exist( Room: %i Exit: %s to room %i.)", r->vnum, e->name, e->destVnum );
               continue;
            }
            e->dest = d;
         }
         DetachIterator( &iterExit );
      }
      else
      {
         bug( "Error: Room created with unallocated exit list. Correcting now..." );
         r->exits = AllocList();
      }
   }
   DetachIterator( &iterRoom );
   return;
}
Пример #7
0
I_ID *check_free( ID_HANDLER *handler )
{
   ITERATOR Iter;
   I_ID *id;

   if( SizeOfList( handler->free_ids ) <= 0 )
      return NULL;

   AttachIterator( &Iter, handler->free_ids );
   id = NextInList( &Iter );
   DetachFromList( id, handler->free_ids );
   DetachIterator( &Iter );
   return id;
}
Пример #8
0
/* function   :: event_isset_mobile()
 * arguments  :: the mobile and the type of event
 * ======================================================
 * This function checks to see if a given type of event
 * is enqueued/attached to a given mobile, and if it is,
 * it will return a pointer to this event.
 */
EVENT_DATA *event_isset_mobile(D_MOBILE *dMob, int type)
{
  EVENT_DATA *event;
  ITERATOR Iter;

  AttachIterator(&Iter, dMob->events);
  while ((event = (EVENT_DATA *) NextInList(&Iter)) != NULL)
  {
    if (event->type == type)
      break;
  }
  DetachIterator(&Iter);

  return event;
}
Пример #9
0
/* function   :: event_isset_socket()
 * arguments  :: the socket and the type of event
 * ======================================================
 * This function checks to see if a given type of event
 * is enqueued/attached to a given socket, and if it is,
 * it will return a pointer to this event.
 */
EVENT_DATA *event_isset_socket(D_SOCKET *dSock, int type)
{
  EVENT_DATA *event;
  ITERATOR Iter;

  AttachIterator(&Iter, dSock->events);
  while ((event = (EVENT_DATA *) NextInList(&Iter)) != NULL)
  {
    if (event->type == type)
      break;
  }
  DetachIterator(&Iter);

  return event;
}
Пример #10
0
/* deletion */
void free_id_handler( ID_HANDLER *handler )
{
   I_ID *id;
   ITERATOR Iter;

   /* no other pointers to free at the moment */
   DetachFromList( handler, id_handlers );
   AttachIterator( &Iter, handler->free_ids );
   while ( ( id = (I_ID *)NextInList(&Iter) ) == NULL )
      free_i_id( id );
   DetachIterator( &Iter );

   free( handler ); /*free the memory alotted for the handler*/
   return;
}
Пример #11
0
bool event_game_tick(EVENT_DATA *event)
{
   ITERATOR Iter;
   ENTITY_INSTANCE *instance;

   AttachIterator(&Iter, eInstances_list);
   while ((instance = (ENTITY_INSTANCE *) NextInList(&Iter)) != NULL)
      text_to_entity( instance, "Tick! The event queue is working.\r\n" );
   DetachIterator(&Iter);

   event = alloc_event();
   event->fun = &event_game_tick;
   event->type = EVENT_GAME_TICK;
   add_event_game(event, 10 * 60 * PULSES_PER_SECOND);

   return FALSE;
}
Пример #12
0
bool event_instance_lua_callback( EVENT_DATA *event )
{
   ENTITY_INSTANCE *instance = (ENTITY_INSTANCE *)event->owner;
   ENTITY_INSTANCE *arg_entity;
   void *content;
   ITERATOR Iter;
   int ret, counter = 0;

   prep_stack( get_frame_script_path( instance->framework ), event->argument );
   if( SizeOfList( event->lua_args ) > 0 )
   {
      AttachIterator( &Iter, event->lua_args );
      while( ( content = NextInList( &Iter ) ) != NULL )
      {
         switch( tolower( event->lua_cypher[counter++] ) )
         {
            case 's':
               lua_pushstring( lua_handle, (const char *)content );
               break;
            case 'n':
               lua_pushnumber( lua_handle, *((int *)content) );
               break;
            case 'i':
               if( ( arg_entity = get_active_instance_by_id( *((int *)content ) ) ) == NULL )
               {
                  bug( "%s: instance with ID:%d is no longer active.", __FUNCTION__, *((int *)content ) );
                  lua_pushnil( lua_handle );
                  break;
               }
               push_instance( arg_entity, lua_handle );
               break;
         }
      }
      DetachIterator( &Iter );
   }
   if( ( ret = lua_pcall( lua_handle, strlen( event->lua_cypher ), LUA_MULTRET, 0 ) ) )
      bug( "%s: ret %d: path: %s\r\n - error message: %s.", __FUNCTION__, ret, get_frame_script_path( instance->framework ), lua_tostring( lua_handle, -1 ) );

   return FALSE;
}
Пример #13
0
//The world list is just a file with a line-by-line list of all the areas
//in the game.
void load_world()
{
   FILE *fp;
   ITERATOR iter;
   D_AREA *area;
   char buf[MAX_BUFFER];
   
   area_loader = luaL_newstate();
   luaL_openlibs( area_loader );
   
   log_string( "Loading World" );
   
   if( ( fp = fopen( "../areas/list.are", "r" ) ) == NULL )
   {
      log_string( "FATAL ERROR: Area List (areas/list.are) does not exist!" );
      abort();
      return;
   }
   
   while( !feof( fp ) )
   {
      fgets( buf, MAX_BUFFER, fp );
      buf[strlen(buf)-1] = '\0'; //fgets includes the newline in the read, so we kill it here.
      if( !strcasecmp( buf, "END" ) )
         break;
      load_area( buf );
   }  
   fclose( fp );
   link_exits();
   
   AttachIterator( &iter, area_list );
   while( ( area = (D_AREA*)NextInList( &iter ) ) != NULL )
      reset_area( area );
   DetachIterator( &iter );
   
   return;
}
Пример #14
0
void reset_area( D_AREA *area )
{
   ITERATOR it,rIt; // it = room iterator, rIt = reset iterator
   D_OBJ *o;
   D_RESET *reset;
   D_MOBILE *m;
   D_ROOM *room;
   
   AttachIterator( &it, area->rooms );
   while( ( room = (D_ROOM*)NextInList( &it ) ) != NULL )
   {
      AttachIterator( &rIt, room->resets );
      while( ( reset = (D_RESET*)NextInList(&rIt) ) != NULL )
      {
         switch( reset->type )
         {
            default:
            {
               bug( "Invalid reset type %c.", reset->type );
               break;
            }
            case 'o':
            case 'O':
            {
                //if the reset has already fired once we need to see if the object
                //is still there, if its not, make a new one.
               if( reset->ptr )
               {
                  //if object is still there skip this reset
                  if( IsInList( reset->ptr, room->objects ) ) 
                     continue;
               }
               if( ( o = clone_obj( fobv( reset->vnum ) ) ) == NULL )
               {
                  bug( "Reset calls for object vnum %i which does not exist.", reset->vnum );
                  continue;
               }
               AttachToList( o, room->objects );
               //does the reset reference any subresets (contained objects)?
               if( reset->nest && SizeOfList( reset->nest ) > 0 )
               {
               }
               
               o->reset = reset;
               reset->ptr = o;
               break;
            }
            case 'm':
            case 'M':
            {
               if( reset->ptr )
               {
                  if( IsInList( reset->ptr, npc_list ) )
                     continue;
               }
               if( ( m = clone_npc( fmbv( reset->vnum ) ) ) == NULL )
               {
                  bug( "Reset calls for NPC vnum %i which does not exist.", reset->vnum );
                  continue;
               }
               AttachToList( m, room->mobiles );
               m->npc_data->reset = reset;
               reset->ptr = m;
               break;
            }
         }
      }
      DetachIterator( &rIt );
   }
   DetachIterator( &it );
   return;
}