static bool load_area_mobiles( lua_State *L, D_AREA *area ) { int numMob = 0, i = 0; D_MOBILE *mob; if( !L || !area ) return FALSE; lua_getglobal( L, "mobiles" ); if( !lua_istable( L, -1 ) ) { bug( "Error: 'mobiles' is not a valid table.\n" ); return FALSE; } //numMob = lua_len( L, -1 ); lua_len( L, -1 ); numMob = luaL_checknumber( L, -1 ); lua_pop( L, 1 ); for( i = 1; i <= numMob; i++ ) { lua_rawgeti( L, -1, i ); if( ( mob = load_mobile( L ) ) == NULL ) { bug( "Error: Unable to allocate memory for new mobile." ); return FALSE; } AttachToList( mob, npc_list ); AttachToList( mob, area->mobiles ); lua_pop( L, 1 ); } return TRUE; }
static bool load_area_objects( lua_State *L, D_AREA *area ) { int numObj = 0, i = 0; D_OBJ *obj; if( !L || !area ) return FALSE; lua_getglobal( L, "objects" ); if( !lua_istable( L, -1 ) ) { bug( "Error: 'objects' is not a valid table.\n" ); return FALSE; } //numObj = lua_len( L, -1 ); lua_len( L, -1 ); numObj = luaL_checknumber( L, -1 ); lua_pop( L, 1 ); for( i = 1; i <= numObj; i++ ) { lua_rawgeti( L, -1, i ); if( ( obj = load_object( L ) ) == NULL ) { bug( "Error: Unable to allocate memory for new object." ); return FALSE; } AttachToList( obj, obj_list ); AttachToList( obj, area->objects ); lua_pop( L, 1 ); } return TRUE; }
/* function :: add_event_game() * arguments :: the event and the delay * ====================================================== * This funtion attaches an event to the list og game * events, and makes sure it's enqueued with the correct * delay time. */ void add_event_game(EVENT_DATA *event, int delay) { /* check to see if the event has a type */ if (event->type == EVENT_NONE) { bug("add_event_game: no type."); return; } /* check to see of the event has a callback function */ if (event->fun == NULL) { bug("add_event_game: event type %d has no callback function.", event->type); return; } /* set the correct variables for this event */ event->ownertype = EVENT_OWNER_GAME; /* attach the event to the gamelist */ AttachToList(event, global_events); /* attempt to enqueue the event */ if (enqueue_event(event, delay) == FALSE) bug("add_event_game: event type %d failed to be enqueued.", event->type); }
/* function :: add_event_socket() * arguments :: the event, the owner and the delay * ====================================================== * This function attaches an event to a socket, and sets * all the correct values, and makes sure it is enqueued * into the event queue. */ void add_event_socket(EVENT_DATA *event, D_SOCKET *dSock, int delay) { /* check to see if the event has a type */ if (event->type == EVENT_NONE) { bug("add_event_socket: no type."); return; } /* check to see of the event has a callback function */ if (event->fun == NULL) { bug("add_event_socket: event type %d has no callback function.", event->type); return; } /* set the correct variables for this event */ event->ownertype = EVENT_OWNER_DSOCKET; event->owner.dSock = dSock; /* attach the event to the sockets local list */ AttachToList(event, dSock->events); /* attempt to enqueue the event */ if (enqueue_event(event, delay) == FALSE) bug("add_event_socket: event type %d failed to be enqueued.", event->type); }
/* function :: enqueue_event() * arguments :: the event to enqueue and the delay time. * ====================================================== * This function takes an event which has _already_ been * linked locally to it's owner, and places it in the * event queue, thus making it execute in the given time. */ bool enqueue_event(EVENT_DATA *event, int game_pulses) { int bucket, passes; /* check to see if the event has been attached to an owner */ if (event->ownertype == EVENT_UNOWNED) { bug("enqueue_event: event type %d with no owner.", event->type); return FALSE; } /* An event must be enqueued into the future */ if (game_pulses < 1) game_pulses = 1; /* calculate which bucket to put the event in, * and how many passes the event must stay in the queue. */ bucket = (game_pulses + current_bucket) % MAX_EVENT_HASH; passes = game_pulses / MAX_EVENT_HASH; /* let the event store this information */ event->passes = passes; event->bucket = bucket; /* attach the event in the queue */ AttachToList(event, eventqueue[bucket]); /* success */ return TRUE; }
/* function :: add_event_mobile() * arguments :: the event, the owner and the delay * ====================================================== * This function attaches an event to a mobile, and sets * all the correct values, and makes sure it is enqueued * into the event queue. */ void add_event_mobile(EVENT_DATA *event, D_MOBILE *dMob, int delay) { /* check to see if the event has a type */ if (event->type == EVENT_NONE) { bug("add_event_mobile: no type."); return; } /* check to see of the event has a callback function */ if (event->fun == NULL) { bug("add_event_mobile: event type %d has no callback function.", event->type); return; } /* set the correct variables for this event */ event->ownertype = EVENT_OWNER_DMOB; event->owner.dMob = dMob; /* attach the event to the mobiles local list */ AttachToList(event, dMob->events); /* attempt to enqueue the event */ if (enqueue_event(event, delay) == FALSE) bug("add_event_mobile: event type %d failed to be enqueued.", event->type); }
static bool load_room_resets( lua_State *L, D_ROOM *room ) { int num, i; D_RESET *r; if( !L || !room ) return FALSE; lua_pushstring( L, "resets" ); lua_gettable( L, -2 ); lua_len( L, -1 ); num = luaL_checknumber( L, -1 ); lua_pop( L, 1 ); for( i = 1; i <= num; i++ ) //iterate through the resets { lua_rawgeti( L, -1, i ); if( ( r = load_reset( L ) ) == NULL ) { bug( "Error: Unable to allocate memory for new reset." ); return FALSE; } AttachToList( r, room->resets ); //attach it to the room's reset list lua_pop( L, 1 ); } return TRUE; }
static bool load_area_rooms( lua_State *L, D_AREA *area ) { int numRooms, i; D_ROOM *room; if( !L || !area ) return FALSE; lua_getglobal( L, "rooms" ); if( !lua_istable( L, -1 ) ) { bug( "Error: 'rooms' is not a valid table.\n" ); //if an area doesn't have rooms then fail the load return FALSE; } //numRooms = lua_len( L, -1 ); lua_len( L, -1 ); numRooms= luaL_checknumber( L, -1 ); lua_pop( L, 1 ); for( i = 1; i <= numRooms; i++ ) //iterate through the rooms { lua_rawgeti( L, -1, i ); if( ( room = load_room( L ) ) == NULL ) { bug( "Error: Unable to allocate memory for new room." ); return FALSE; } AttachToList( room, area->rooms ); //attach it to the area's room list lua_pop( L, 1 ); } return TRUE; }
bool load_id_handler( ID_HANDLER *handler ) { FILE *fp; I_ID *id; char *word; char location[MAX_BUFFER]; bool found, done = FALSE; mud_printf( location, "../handlers/%s.handler", id_handler_names[handler->type] ); if( ( fp = fopen( location, "r" ) ) == NULL ) { bug( "%s: unable to open file to read: %s", __FUNCTION__, location ); return FALSE; } word = ( feof( fp ) ? FILE_TERMINATOR : fread_word( fp ) ); if( strcmp( word, "#IDHANDLER" ) ) { bug( "%s: %s not started with proper tag.", __FUNCTION__, location ); return FALSE; } while( !done ) { found = FALSE; switch( word[1] ) { case 'O': if( !strcasecmp( word, "EOF" ) ) {done = TRUE; found = TRUE; break; } break; case 'I': if( !strcmp( word, "#IDHANDLER" ) ) { found = TRUE; fread_id_handler( handler, fp ); break; } if( !strcmp( word, "#I_ID" ) ) { found = TRUE; id = fread_i_id( fp ); AttachToList( id, handler->free_ids ); break; } break; } if( !found ) { bug( "%s: word key not known, %s", __FUNCTION__, word ); return FALSE; } if( !done ) word = ( feof( fp ) ? FILE_TERMINATOR : fread_word( fp ) ); } fclose( fp ); return TRUE; }
void move_mob( D_MOBILE *dMob, const char *dir ) { D_EXIT *exit; if( !dMob || !dir ) return; if( !dMob->room ) { bug( "Error: Player (%s) without room. Sending to the void...", dMob->name ); dMob->room = frbv( 1 );//default to the void if they don't have a room assigned to them if( !dMob->room ) //if the void doesn't even exist... { bug( "Error: Can Not Find The Void Room!" ); return; } } exit = febn( dir, dMob->room->exits ); if( !exit || !exit->dest ) { if( exit && !exit->dest ) bug( "Error: Exit with non-existent room in room %i.", dMob->room->vnum ); text_to_mobile( dMob, "Alas, you can not go that way.\r\n" ); return; } switch( exit->state ) { case STATE_OPEN: case STATE_DOOR_OPEN: case STATE_DOOR_OPEN_BROKEN: { break; } case STATE_DOOR_CLOSED: case STATE_DOOR_CLOSED_BROKEN: case STATE_DOOR_CLOSED_LOCKED: { text_to_mobile( dMob, "The %s is closed.\r\n", exit->desc ); return; } default: { bug( "Exit \'%s\' in invalid state in room %i.", exit->name, dMob->room->vnum ); return; } } DetachFromList( dMob, dMob->room->mobiles ); dMob->room = exit->dest; AttachToList( dMob, dMob->room->mobiles ); cmd_look( dMob, "" ); return; }
static D_ROOM *load_room( lua_State *L ) { D_ROOM *r; D_EXIT *e; int i=0, numExits=0; if( !L ) return NULL; if( ( r = new_room() ) == NULL ) { return NULL; } lua_pushstring( L, "vnum" ); lua_gettable( L, -2 ); r->vnum = (int)luaL_checknumber( L, -1 ); lua_pop( L, 1 ); lua_pushstring( L, "name" ); lua_gettable( L, -2 ); r->name = strdup( luaL_checkstring( L, -1 ) ); lua_pop( L, 1 ); lua_pushstring( L, "desc" ); lua_gettable( L, -2 ); r->desc = strdup( luaL_checkstring( L, -1 ) ); lua_pop( L, 1 ); lua_pushstring( L, "exits" ); lua_gettable( L, -2 ); //numExits = lua_len( L, -1 ); lua_len( L, -1 ); numExits = luaL_checknumber( L, -1 ); lua_pop( L, 1 ); for( i = 1; i <= numExits; i++ ) //iterate through the exits { lua_rawgeti( L, -1, i ); if( ( e = load_exit( L ) ) == NULL ) { bug( "Error: Unable to allocate memory for new exit." ); continue; } AttachToList( e, r->exits ); //attach it to the room's exit list lua_pop( L, 1 ); } lua_pop( L, 1 ); load_room_resets( L, r ); lua_pop( L, 1 ); return r; }
inline int socket_addState( lua_State *L ) { D_SOCKET *socket; SOCKET_STATE *state; DAVLUACM_SOCKET_NIL( socket, L ); if( ( state = (SOCKET_STATE *)check_meta( L, 2, "State.meta" ) ) == NULL ) { bug( "%s: cannot add non-State.meta to socket states.", __FUNCTION__ ); lua_pushnil( L ); return 1; } AttachToList( socket->states ); lua_pushnumber( L, SizeOfList( socket->states ) ); return 1; }
bool load_id_handlers( void ) { int x; ID_HANDLER *handler; for( x = 0; x < MAX_STRUCT; x++ ) { handler = init_id_handler( x ); if( !load_id_handler( handler ) ) { free_id_handler( handler ); bug( "%s: could not load %s id handler.", __FUNCTION__, id_handler_names[x] ); return FALSE; } AttachToList( handler, id_handlers ); } return TRUE; }
static void load_room_objects_resets( lua_State *L, D_RESET *r ) { int vnum; int num; int i; D_OBJ *o; if( !L || !r ) { bug( "Calling load_area_objects_resets with NULL arguments" ); return; } lua_pushstring( L, "inside" ); lua_gettable( L, -2 ); if( lua_isnil( L, -1 ) ) { //do nothing } else if( !lua_istable( L, -1 ) ) { bug( "Error: 'inside' is not a valid table.\n" ); return; } else { num = lua_len( L, -1 ); for( i = 1; i <= num; i++ ) //iterate through the rooms { lua_rawgeti( L, -1, i ); vnum = luaL_checknumber( L, -1 ); if( ( o = fobv( vnum ) ) == NULL ) { bug( "Reset references object vnum %i, which does not exist.", vnum ); continue; } AttachToList( o, obj->in ); lua_pop( L, 1 );//the vnum of the contained object } } lua_pop( L, 1 );//the 'in' table lua_getglobal( L, "on" ); if( lua_isnil( L, -1 ) ) { //do nothing } else if( !lua_istable( L, -1 ) ) { bug( "Error: 'on' is not a valid table.\n" ); return; } else { num = lua_len( L, -1 ); for( i = 1; i <= num; i++ ) //iterate through the rooms { lua_rawgeti( L, -1, i ); vnum = luaL_checknumber( L, -1 ); if( ( o = fobv( vnum ) ) == NULL ) { bug( "Reset references object vnum %i, which does not exist.", vnum ); continue; } AttachToList( o, obj->on ); lua_pop( L, 1 );//the vnum of the contained object } } lua_pop( L, 1 );//the 'on' table lua_getglobal( L, "under" ); if( lua_isnil( L, -1 ) ) { //do nothing } else if( !lua_istable( L, -1 ) ) { bug( "Error: 'under' is not a valid table.\n" ); return; } else { num = lua_len( L, -1 ); for( i = 1; i <= num; i++ ) //iterate through the rooms { lua_rawgeti( L, -1, i ); vnum = luaL_checknumber( L, -1 ); if( ( o = fobv( vnum ) ) == NULL ) { bug( "Reset references object vnum %i, which does not exist.", vnum ); continue; } AttachToList( o, obj->under ); lua_pop( L, 1 );//the vnum of the contained object } } lua_pop( L, 1 );//the 'under' table return; }
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; }