/**************************************************************************/ // obdb.cpp - reads in area files etc /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with all the licenses * * in licenses.txt... In particular, you may not remove this copyright * * notice. * *************************************************************************** * >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. * * >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to * * you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), * * Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) * * >> Oblivion 1.2 is copyright 1996 Wes Wagner * **************************************************************************/ #include "include.h" // dawn standard includes #include "areas.h" #include "db.h" #include "clan.h" #include "olc.h" extern int flag_lookup args((const char *name, const struct flag_type *flag_table)); void apply_area_vnum_offset(int *old_vnum); /**************************************************************************/ // Snarf a room section. void load_rooms( FILE *fp, int version ) { ROOM_INDEX_DATA *pRoomIndex; if ( area_last == NULL ) { bug("Load_rooms: no #AREA seen yet."); exit_error( 1 , "load_rooms", "no #AREA seen yet"); } for ( ; ; ) { vn_int vnum; char letter; int door; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug("Load_rooms: # not found."); exit_error( 1 , "load_rooms", "# not found"); } vnum = fread_number( fp ); if ( vnum == 0 ) break; vnum+= area_last->vnum_offset; // check for a duplicate room number fBootDb = false; ROOM_INDEX_DATA *dup_room_index=get_room_index( vnum ); if ( dup_room_index) { bugf( "Load_rooms: vnum %d duplicated with room from areafile '%s'.", vnum, dup_room_index->area?dup_room_index->area->file_name:"unknown"); exit_error( 1 , "load_rooms", "Duplicate vnum"); } fBootDb = true; last_vnum = vnum; // backup the last vnum for gdb use pRoomIndex = new_room_index(); pRoomIndex->area = area_last; pRoomIndex->vnum = vnum; pRoomIndex->name = fread_string( fp ); pRoomIndex->description = fread_string( fp ); if (str_len(pRoomIndex->description)>MSL-4) { bugf("load_rooms: description of room %d is %d characters!!! (more than %d)", (int)last_vnum, str_len(pRoomIndex->description), MSL-4); exit_error( 1 , "load_rooms", "too many characters in room description"); } fread_number( fp ); // just a 0 - padding, not really used pRoomIndex->room_flags = fread_flag( fp ); if(AREA_IMPORT_FORMAT(AIF_FORMAT3)){ fread_number( fp ); // read in a room affects flag - not used on dawn } pRoomIndex->sector_type = fread_number( fp ); if(AREA_IMPORT_FORMAT(AIF_FORMAT2)){ areaimport_room_flags_format2(fp, version, pRoomIndex); }else{ // AIF_STOCK - the default areaimport_room_flags_stock(fp, version, pRoomIndex); } pRoomIndex->light = 0; for ( door = 0; door < MAX_DIR; door++ ){ pRoomIndex->exit[door] = NULL; } // defaults pRoomIndex->heal_rate = 100; pRoomIndex->mana_rate = 100; // check vnum fits in area vnum range if ( vnum < pRoomIndex->area->min_vnum + pRoomIndex->area->vnum_offset) { bugf("Room with Vnum %d is less than area %s <%s> vnum %d!", vnum, pRoomIndex->area->name, pRoomIndex->area->file_name, pRoomIndex->area->min_vnum ); } if ( vnum > pRoomIndex->area->max_vnum + pRoomIndex->area->vnum_offset) { bugf("Room with Vnum %d is greater than area %s <%s> vnum %d!", vnum, pRoomIndex->area->name, pRoomIndex->area->file_name, pRoomIndex->area->max_vnum ); } for ( ; ; ) { letter = fread_letter( fp ); if ( letter == 'S' ) break; if ( letter == 'H'){ // healing room pRoomIndex->heal_rate = fread_number(fp); }else if ( letter == 'M'){ // mana room pRoomIndex->mana_rate = fread_number(fp); }else if ( letter == 'C'){ // clan if (pRoomIndex->clan) { bug("Load_rooms: duplicate clan fields."); exit_error( 1 , "load_rooms", "duplicate clan fields"); } pRoomIndex->clan = clan_slookup(fread_string(fp)); }else if ( AREA_IMPORT_FORMAT(AIF_FORMAT3) && (letter=='c' || letter=='s' || letter=='R') ) { // AREA_IMPORT_FORMAT3 only stuff if(letter == 'c' ){ // format3 class restriction system fread_string(fp); }else if(letter == 's' ){ // format3 sex based restriction system fread_number(fp); }else if(letter == 'R' ){ // format3 race based restriction system fread_string(fp); } }else if ( UPPER(letter) == 'X' ){ // MSP Room sound pRoomIndex->msp_sound = fread_string( fp ); }else if (UPPER(letter) == 'D'){ EXIT_DATA *pexit; door = fread_number( fp ); if ( door < 0 || door >=MAX_DIR ) { bugf( "load_rooms: vnum %d has bad door number.", vnum ); exit_error( 1 , "load_rooms", "bad door numbers"); } pexit = (EXIT_DATA *)alloc_perm( sizeof(*pexit) ); pexit->description = fread_string( fp ); pexit->keyword = fread_string( fp ); if(version==1){ int locks= fread_number( fp ); switch ( locks ) { case 1: pexit->rs_flags = EX_ISDOOR; break; case 2: pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF; break; case 3: pexit->rs_flags = EX_ISDOOR | EX_NOPASS; break; case 4: pexit->rs_flags = EX_ISDOOR|EX_NOPASS|EX_PICKPROOF; break; } }else{ pexit->rs_flags = fread_flag( fp ); } pexit->key = fread_number( fp ); pexit->u1.vnum = fread_number( fp ); apply_area_vnum_offset(&pexit->u1.vnum); pexit->exit_info=pexit->rs_flags; pRoomIndex->exit[door] = pexit; top_exit++; } else if ( UPPER(letter) == 'E' ) { EXTRA_DESCR_DATA *ed; ed = (EXTRA_DESCR_DATA *)alloc_perm( sizeof(*ed) ); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); ed->next = pRoomIndex->extra_descr; pRoomIndex->extra_descr = ed; top_ed++; } else if (UPPER(letter) == 'O') { if (pRoomIndex->owner[0] != '\0') { bug("Load_rooms: duplicate owner."); exit_error( 1 , "load_rooms", "duplicate owner"); } pRoomIndex->owner = fread_string(fp); } else if ( letter == 'F' ) { room_echo_data *re= new_room_echo(); re->firsthour = fread_number( fp ); re->lasthour = fread_number( fp ); int lowroll = fread_number( fp ); int highroll = fread_number( fp ); re->percentage = UMAX(highroll,lowroll)-UMIN(highroll,lowroll); re->echotext = fread_string( fp ); re->next = pRoomIndex->echoes; pRoomIndex->echoes= re; } else { bugf( "Load_rooms: vnum %d has flag '%c' which is not 'DESOF'.", vnum, letter ); exit_error( 1 , "load_rooms", "invalid flag"); } } iHash = vnum % MAX_KEY_HASH; pRoomIndex->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoomIndex; top_room++; top_vnum_room = top_vnum_room < vnum ? vnum : top_vnum_room; assign_area_vnum( vnum ); } return; } /**************************************************************************/ void load_object_values( FILE *fp, int version, OBJ_INDEX_DATA *pObjIndex) { assertp(fp); switch(pObjIndex->item_type) { case ITEM_WEAPON: pObjIndex->value[0] = weapontype(fread_word(fp)); pObjIndex->value[1] = fread_number(fp); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = attack_lookup(fread_word(fp)); pObjIndex->value[4] = fread_flag(fp); break; case ITEM_CAULDRON: case ITEM_CONTAINER: case ITEM_FLASK: case ITEM_MORTAR: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = fread_flag(fp); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = fread_number(fp); pObjIndex->value[4] = fread_number(fp); break; case ITEM_DRINK_CON: case ITEM_FOUNTAIN: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = fread_number(fp); pObjIndex->value[2] = liq_lookup(fread_word(fp)); if(version<2){ pObjIndex->value[3] = fread_number(fp); }else{ pObjIndex->value[3] = fread_flag(fp); } pObjIndex->value[4] = fread_number(fp); break; case ITEM_PARCHMENT: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = fread_number(fp); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = language_safe_lookup(fread_word( fp ))->unique_id; pObjIndex->value[4] = fread_number(fp); break; case ITEM_INSTRUMENT: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = fread_number(fp); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = fread_number(fp); pObjIndex->value[4] = fread_number(fp); break; case ITEM_WAND: case ITEM_STAFF: case ITEM_POULTICE: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = fread_number(fp); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = skill_lookup(fread_word(fp)); pObjIndex->value[4] = fread_number(fp); break; case ITEM_POTION: case ITEM_PILL: case ITEM_SCROLL: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = skill_lookup(fread_word(fp)); pObjIndex->value[2] = skill_lookup(fread_word(fp)); pObjIndex->value[3] = skill_lookup(fread_word(fp)); pObjIndex->value[4] = skill_lookup(fread_word(fp)); { int snr=skill_lookup("reserved"); if(snr!=-1){ // convert reserved into -1 for(int i=1; i<5; i++){ if(pObjIndex->value[i]==snr){ pObjIndex->value[i]=-1; } } } } break; case ITEM_COMPONENT: pObjIndex->value[0] = fread_number(fp); pObjIndex->value[1] = skill_lookup(fread_word(fp)); pObjIndex->value[2] = fread_number(fp); pObjIndex->value[3] = fread_number(fp); pObjIndex->value[4] = fread_number(fp); break; default: pObjIndex->value[0] = fread_flag( fp ); pObjIndex->value[1] = fread_flag( fp ); pObjIndex->value[2] = fread_flag( fp ); pObjIndex->value[3] = fread_flag( fp ); pObjIndex->value[4] = fread_flag( fp ); break; } } /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/