/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #include <glib.h> #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <merc.h> #include <tables.h> #include <recycle.h> #if !defined(macintosh) extern int _filbuf args( (FILE *) ); #endif extern char * help_greeting; extern HELP_DATA * help_first; extern HELP_DATA * help_last; extern int flag_lookup args((const char *name, const struct flag_type *flag_table)); extern TIME_INFO_DATA time_info; extern WEATHER_DATA weather_info[SECT_MAX]; /* * Locals. */ extern MOB_INDEX_DATA * mob_index_hash [MAX_KEY_HASH]; extern OBJ_INDEX_DATA * obj_index_hash [MAX_KEY_HASH]; extern ROOM_INDEX_DATA * room_index_hash [MAX_KEY_HASH]; extern char * string_hash [MAX_KEY_HASH]; extern AREA_DATA * area_first; extern AREA_DATA * area_last; extern AREA_DATA * current_area; extern DUMMY_ARG * dummy_free; extern DUMMY_ARG * dummy_list; extern char strArea[MAX_INPUT_LENGTH]; extern FILE * fpArea; extern int top_affect; extern int top_area; extern int top_rt; extern int top_ed; extern int top_exit; extern int top_help; extern int top_mob_index; extern int top_obj_index; extern int top_reset; extern int top_room; extern int top_shop; extern int top_vnum_mob; extern int top_vnum_room; extern int top_vnum_obj; /* * Memory management. * Increase MAX_STRING if you have too. * Tune the others only if you understand what you're doing. #define MAX_STRING 1048576 #define MAX_STRING 1572864 #define MAX_STRING 3413120 */ #define MAX_STRING 3413120 //#define MAX_PERM_BLOCK 131072 /* Taken out and put in the merc.h for Optimazation - Spiral * #define MAX_MEM_LIST 11 */ /* void * rgFreeList [MAX_MEM_LIST]; const int rgSizeList [MAX_MEM_LIST] = { 16, 32, 64, 128, 256, 1024, 2048, 4096, 8192, 16384, 32768-64 }; */ /* * Semi-locals. */ extern bool fBootDb; /* * Local booting procedures. */ void init_mm args( ( void ) ); void load_area args( ( FILE *fp, char Save_Area[MAX_INPUT_LENGTH] ) ); void new_load_area args( ( FILE *fp ) ); void load_helps args( ( FILE *fp ) ); void load_mobiles args( ( FILE *fp ) ); void load_mobiles_new args( ( FILE *fp ) ); void load_mobiles_rom args( ( FILE *fp ) ); void load_objects args( ( FILE *fp ) ); void load_objects_new args( ( FILE *fp ) ); void load_resets args( ( FILE *fp ) ); void load_rooms args( ( FILE *fp ) ); void load_shops args( ( FILE *fp ) ); void load_socials args( ( FILE *fp ) ); void load_riddles args( ( FILE *fp ) ); void load_xsocials args( ( FILE *fp ) ); void load_specials args( ( FILE *fp ) ); void load_mobprogs args( ( FILE *fp ) ); void fix_mobprogs args( ( void ) ); void fix_exits args( ( void ) ); void reset_area args( ( AREA_DATA * pArea ) ); extern long flag_convert args( (char letter ) ); void load_bans args( ( void ) ); extern char * string_space; extern int top_mprog_index; extern char str_empty [1]; extern char * string_hash [MAX_KEY_HASH]; extern bool fBootDb; extern int thread_count; bool copyover_start; /* player loading error correction */ bool Player_Load; bool Player_Error; /* Global Spiralsoft shit */ int copyover_time; bool copyover_set; bool fCopyOver; int read_build() { int build = 0; FILE *fpList; if ( ( fpList = fopen( BUILD_FILE, "r" ) ) == NULL ) return 0; build = fread_number(fpList); fclose(fpList); return build; } /* * Big mama top level function. */ void boot_db( void ) { /* * Declare the lists... */ object_free = NULL; obj_free = NULL; /* * Init some data space stuff. */ { /* if ( ( string_space = calloc( 1, MAX_STRING ) ) == NULL ) { bug( "Boot_db: can't alloc %d string space.", MAX_STRING ); exit( 1 ); } */ fBootDb = TRUE; } /* * Init random number generator. */ { init_mm( ); } /* * Set time and weather. */ { long lhour, lday, lmonth; int sect; lhour = (current_time - 650336715) / (PULSE_TICK / PULSE_PER_SECOND); time_info.hour = lhour % 24; time_info.half_hour = 0; lday = lhour / 24; time_info.day = lday % 35; lmonth = lday / 35; time_info.month = lmonth % 17; time_info.year = lmonth / 17; for ( sect = 0 ; sect < SECT_MAX ; sect++) { if ( time_info.hour < 5 ) weather_info[sect].sunlight = SUN_DARK; else if ( time_info.hour < 6 ) weather_info[sect].sunlight = SUN_RISE; else if ( time_info.hour < 19 ) weather_info[sect].sunlight = SUN_LIGHT; else if ( time_info.hour < 20 ) weather_info[sect].sunlight = SUN_SET; else weather_info[sect].sunlight = SUN_DARK; weather_info[sect].change = 0; weather_info[sect].mmhg = 960; if ( time_info.month >= 7 && time_info.month <=12 ) weather_info[sect].mmhg += number_range( 1, 50 ); else weather_info[sect].mmhg += number_range( 1, 80 ); if ( weather_info[sect].mmhg <= 980 ) weather_info[sect].sky = SKY_LIGHTNING; else if ( weather_info[sect].mmhg <= 1000 ) weather_info[sect].sky = SKY_RAINING; else if ( weather_info[sect].mmhg <= 1020 ) weather_info[sect].sky = SKY_CLOUDY; else weather_info[sect].sky = SKY_CLOUDLESS; } } /* initalize the obj,mob varbiles*/ mudsetting->total_mobiles_created = 0; mudsetting->total_objects_created = 0; mudsetting->mobiles_created = 0; mudsetting->Objects_Recycled_HEAP = 0; mudsetting->objects_created = 0; mudsetting->objects_recycled = 0; mudsetting->last_proc_logged = 0; mudsetting->Mobiles_Recycle = 0; mudsetting->Mobiles_Recycle_Heap = 0; mudsetting->Mobiles_New = 0; mudsetting->high_mobile_vnum = 0; mudsetting->build = read_build(); /* * Assign gsn's for skills which have them. */ { int sn; for ( sn = 0; sn < MAX_SKILL; sn++ ) { if ( skill_table[sn].pgsn != NULL ) *skill_table[sn].pgsn = sn; } } /* * Read in all the area files. */ { FILE *fpList; if ( ( fpList = fopen( AREA_LIST, "r" ) ) == NULL ) { bug( AREA_LIST, 0 ); exit( 1 ); } for ( ; ; ) { str_cpy( strArea, fread_word( fpList ) ); if ( strArea[0] == '$' ) break; if ( strArea[0] == '-' ) { fpArea = stdin; } else { if ( ( fpArea = fopen( strArea, "r" ) ) == NULL ) { bug( strArea, 0 ); exit( 1 ); } } for ( ; ; ) { char *word; if ( fread_letter( fpArea ) != '#' ) { bug( "Boot_db: # not found.", 0 ); exit( 1 ); } word = fread_word( fpArea ); if ( word[0] == '$' ) break; else if ( !str_cmp( word, "AREA" ) ) load_area (fpArea,strArea); else if ( !str_cmp( word, "AREADATA" ) ) new_load_area (fpArea); else if ( !str_cmp( word, "HELPS" ) ) load_helps (fpArea); else if ( !str_cmp( word, "MOBILES" ) ) load_mobiles (fpArea); else if ( !str_cmp( word, "MOBILES_NEW" ) ) load_mobiles_new (fpArea); else if ( !str_cmp( word, "MOBILES_ROM" ) ) load_mobiles_rom (fpArea); else if ( !str_cmp( word, "OBJECTS" ) ) load_objects (fpArea); else if ( !str_cmp( word, "OBJECTS_NEW" ) ) load_objects_new (fpArea); else if ( !str_cmp( word, "RESETS" ) ) load_resets (fpArea); else if ( !str_cmp( word, "ROOMS" ) ) load_rooms (fpArea); else if ( !str_cmp( word, "SHOPS" ) ) load_shops (fpArea); else if ( !str_cmp( word, "SPECIALS" ) ) load_specials(fpArea); else if ( !str_cmp( word, "SOCIALS" ) ) load_socials (fpArea); else if ( !str_cmp( word, "XSOCIALS" ) ) load_xsocials (fpArea); else if ( !str_cmp( word, "RIDDLES" ) ) load_riddles (fpArea); else if ( !str_cmp( word, "MOBPROGS" ) ) load_mobprogs(fpArea); else { bug( "Boot_db: bad section name.", 0 ); exit( 1 ); } } if ( fpArea != stdin ) fclose( fpArea ); fpArea = NULL; } fclose( fpList ); } /* * Fix up exits. * Declare db booting over. * Reset all areas once. * Load up the notes file. */ { fix_exits( ); fix_mobprogs( ); fBootDb = FALSE; area_update( ); load_boards( ); load_bans( ); riddle_number = number_range(1,riddle_max); } /* * Rotain's Clan Table Read Settings */ /* clan_table_read(); artifact_table_read();*/ if (fCopyOver) copyover_recover(); return; } /* * Snarf an 'area' header line. */ void load_area( FILE *fp, char Save_Area[MAX_INPUT_LENGTH] ) { AREA_DATA *pArea; pArea = g_chunk_new (AREA_DATA, AreaID_mem_chunk);; pArea->reset_first = NULL; pArea->reset_last = NULL; pArea->name = fread_string( fp ); pArea->file_name = g_strdup(Save_Area); pArea->age = 15; pArea->security = 9; pArea->nplayer = 0; pArea->vnum = top_area; pArea->empty = FALSE; if ( area_first == NULL ) area_first = pArea; if ( area_last ) { area_last->next = pArea; } area_last = pArea; pArea->next = NULL; current_area = pArea; top_area++; return; } /* * OLC * Use these macros to load any new area formats that you choose to * support on your MUD. See the new_load_area format below for * a short example. */ #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } #define SKEY( string, field ) \ if ( !str_cmp( word, string ) ) \ { \ field = fread_string( fp ); \ fMatch = TRUE; \ break; \ } /* OLC * Snarf an 'area' header line. Check this format. MUCH better. Add fields * too. * * #AREAFILE * Name { All } Locke Newbie School~ * Repop A teacher pops in the room and says, 'Repop coming!'~ * Recall 3001 * End */ void new_load_area( FILE *fp ) { AREA_DATA *pArea; char *word; bool fMatch; pArea = g_chunk_new (AREA_DATA, AreaID_mem_chunk); pArea->age = 15; pArea->nplayer = 0; pArea->file_name = g_strdup( strArea ); pArea->vnum = top_area; pArea->name = g_strdup( "New Area" ); pArea->builders = g_strdup( "" ); pArea->security = 9; /* 9 -- Hugin */ pArea->min_vnum = 0; pArea->max_vnum = 0; pArea->empty = FALSE; pArea->area_flags = 0; /* pArea->recall = ROOM_VNUM_TEMPLE; ROM OLC */ for ( ; ; ) { word = feof( fp ) ? (char *)"End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case 'N': SKEY( "Name", pArea->name ); break; case 'S': KEY( "Security", pArea->security, fread_number( fp ) ); break; case 'V': if ( !str_cmp( word, "VNUMs" ) ) { pArea->min_vnum = fread_number( fp ); pArea->max_vnum = fread_number( fp ); } break; case 'E': if ( !str_cmp( word, "End" ) ) { fMatch = TRUE; if ( area_first == NULL ) area_first = pArea; if ( area_last != NULL ) area_last->next = pArea; area_last = pArea; pArea->next = NULL; current_area = pArea; top_area++; return; } break; case 'B': SKEY( "Builders", pArea->builders ); break; case 'C': SKEY( "Credits", pArea->credits ); break; } } } /* * Sets vnum range for area using OLC protection features. */ void assign_area_vnum( int vnum ) { if ( area_last->min_vnum == 0 || area_last->max_vnum == 0 ) area_last->min_vnum = area_last->max_vnum = vnum; if ( vnum != URANGE( area_last->min_vnum, vnum, area_last->max_vnum ) ) { if ( vnum < area_last->min_vnum ) area_last->min_vnum = vnum; else area_last->max_vnum = vnum; } return; } /* * Snarf a help section. */ void load_helps( FILE *fp ) { HELP_DATA *pHelp; for ( ; ; ) { pHelp = g_chunk_new (HELP_DATA, HelpID_mem_chunk); pHelp->level = fread_number( fp ); pHelp->keyword = fread_string( fp ); if ( pHelp->keyword[0] == '$' ) break; pHelp->text = fread_string( fp ); if ( !str_cmp( pHelp->keyword, "greeting" ) ) help_greeting = pHelp->text; if ( help_first == NULL ) help_first = pHelp; if ( help_last != NULL ) help_last->next = pHelp; help_last = pHelp; pHelp->next = NULL; top_help++; } return; } /* * Snarf a mob section. */ void load_mobiles( FILE *fp ) { MOB_INDEX_DATA *pMobIndex; char letter2; if ( !area_last ) { bug("LoadoBh: no area seen yet.", 0); exit(1); } for ( ; ; ) { sh_int vnum; char letter; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_mobiles: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_mob_index( vnum ) != NULL ) { bug( "Load_mobiles: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pMobIndex = g_chunk_new (MOB_INDEX_DATA, MobID_mem_chunk); pMobIndex->vnum = vnum; pMobIndex->area = area_last; pMobIndex->player_name = fread_string( fp ); pMobIndex->short_descr = fread_string( fp ); pMobIndex->long_descr = fread_string( fp ); pMobIndex->description = fread_string( fp ); pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]); pMobIndex->description[0] = UPPER(pMobIndex->description[0]); pMobIndex->act = fread_flag( fp ) | ACT_IS_NPC; if ( IS_SET(pMobIndex->act,ACT_DEAD)) REMOVE_BIT(pMobIndex->act,ACT_DEAD); pMobIndex->affected_by = fread_flag( fp ); pMobIndex->mob_con = fread_flag( fp ); pMobIndex->itemaffect = 0; pMobIndex->spec_fun = NULL; pMobIndex->pShop = NULL; pMobIndex->alignment = fread_number( fp ); letter = fread_letter( fp ); pMobIndex->level = number_fuzzy( fread_number( fp ) ); /* * The unused stuff is for imps who want to use the old-style * stats-in-files method. */ pMobIndex->hitroll = fread_number( fp ); /* Unused */ pMobIndex->ac = fread_number( fp ); /* Unused */ pMobIndex->hitnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->hitsizedice = fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ pMobIndex->hitplus = fread_number( fp ); /* Unused */ pMobIndex->damnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->damsizedice = fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ pMobIndex->damplus = fread_number( fp ); /* Unused */ pMobIndex->gold = fread_number( fp ); /* Unused */ /* xp can't be used! */ fread_number( fp ); /* Unused */ /* position */ fread_number( fp ); /* Unused */ /* start pos */ fread_number( fp ); /* Unused */ /* * Back to meaningful values. */ pMobIndex->sex = fread_number( fp ); pMobIndex->added = fread_number( fp ); pMobIndex->mprogs = NULL; pMobIndex->mprog_flags = 0; pMobIndex->mob_fight = fread_number( fp ); pMobIndex->sphere_spaffect = fread_number( fp ); pMobIndex->count = 0; /* if ( letter != 'S' ) { bug( "Load_mobiles: vnum %d non-S.", vnum ); exit( 1 ); } */ for ( ; ; ) { letter2 = fread_letter( fp ); if ( letter2 == 'M' ) { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = new_mprog(); word = fread_word( fp ); if ( !(trigger = flag_lookup( word, mprog_flags )) ) { bug("MOBprogs: invalid trigger.",0); exit(1); } SET_BIT( pMobIndex->mprog_flags, trigger ); pMprog->trig_type = trigger; pMprog->vnum = fread_number( fp ); pMprog->trig_phrase = g_string_append(pMprog->trig_phrase,fread_string( fp )); pMprog->next = pMobIndex->mprogs; pMobIndex->mprogs = pMprog; } else { ungetc(letter2,fp); break; } } iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; assign_area_vnum( vnum ); kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++; if (vnum > mudsetting->high_mobile_vnum) mudsetting->high_mobile_vnum = vnum; } return; } /* * Snarf an obj section. */ void load_objects( FILE *fp ) { OBJ_INDEX_DATA *pObjIndex; if ( !area_last ) { bug("LoadoBh: no area seen yet.", 0); exit(1); } for ( ; ; ) { sh_int vnum; char letter; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_objects: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_obj_index( vnum ) != NULL ) { bug( "Load_objects: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pObjIndex = g_chunk_new (OBJ_INDEX_DATA, ObjID_mem_chunk); pObjIndex->vnum = vnum; pObjIndex->name = fread_string( fp ); pObjIndex->area = area_last; pObjIndex->short_descr = fread_string( fp ); pObjIndex->description = fread_string( fp ); /* Action description */ fread_string( fp ); pObjIndex->short_descr[0] = LOWER(pObjIndex->short_descr[0]); pObjIndex->description[0] = UPPER(pObjIndex->description[0]); pObjIndex->item_type = fread_number( fp ); pObjIndex->extra_flags = fread_flag( fp ); pObjIndex->wear_flags = fread_flag( fp ); 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->weight = fread_number( fp ); pObjIndex->cost = fread_number( fp ); /* Unused */ pObjIndex->affected = 0; pObjIndex->extra_descr = 0; pObjIndex->chpoweron = &str_empty[0];; pObjIndex->chpoweroff = &str_empty[0];; pObjIndex->chpoweruse = &str_empty[0];; pObjIndex->victpoweron = &str_empty[0];; pObjIndex->victpoweroff = &str_empty[0];; pObjIndex->victpoweruse = &str_empty[0];; pObjIndex->mprogs = NULL; pObjIndex->mprog_flags = 0; pObjIndex->spectype = 0; pObjIndex->specpower = 0; /* Cost per day */ fread_number( fp ); /* if ( pObjIndex->item_type == ITEM_POTION ) SET_BIT(pObjIndex->extra_flags, ITEM_NODROP); */ for ( ; ; ) { char letter; letter = fread_letter( fp ); if ( letter == 'A' ) { AFFECT_DATA *paf; paf = g_chunk_new (AFFECT_DATA, affect_mem_chunk); paf->type = -1; paf->duration = -1; paf->location = fread_number( fp ); paf->modifier = fread_number( fp ); paf->bitvector = 0; paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if ( letter == 'E' ) { EXTRA_DESCR_DATA *ed; ed = g_chunk_new (EXTRA_DESCR_DATA, extra_desc_mem_chunk); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); ed->next = pObjIndex->extra_descr; pObjIndex->extra_descr = ed; top_ed++; } else if ( letter == 'M' ) { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = new_mprog(); word = fread_word( fp ); if ( !(trigger = flag_lookup( word, mprog_obj_flags )) ) { bug("MUDprogs: invalid trigger.",0); exit(1); } SET_BIT( pObjIndex->mprog_flags, trigger ); pMprog->trig_type = trigger; pMprog->vnum = fread_number( fp ); pMprog->trig_phrase = g_string_assign(pMprog->trig_phrase,fread_string( fp )); pMprog->next = pObjIndex->mprogs; pObjIndex->mprogs = pMprog; } else if ( letter == 'Q' ) { pObjIndex->chpoweron = fread_string( fp ); pObjIndex->chpoweroff = fread_string( fp ); pObjIndex->chpoweruse = fread_string( fp ); pObjIndex->victpoweron = fread_string( fp ); pObjIndex->victpoweroff = fread_string( fp ); pObjIndex->victpoweruse = fread_string( fp ); pObjIndex->spectype = fread_number( fp ); pObjIndex->specpower = fread_number( fp ); } else { ungetc( letter, fp ); break; } } /* * Translate spell "slot numbers" to internal "skill numbers." */ switch ( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pObjIndex->value[1] = slot_lookup( pObjIndex->value[1] ); pObjIndex->value[2] = slot_lookup( pObjIndex->value[2] ); pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; case ITEM_STAFF: case ITEM_WAND: pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; } iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; assign_area_vnum( vnum ); top_obj_index++; } return; } void new_reset( ROOM_INDEX_DATA *pR, RESET_DATA *pReset ) { if ( !pR ) return; pR->reset_list = g_slist_append(pR->reset_list,pReset); top_reset++; return; } extern GMemChunk *reset_mem_chunk; /* * Snarf a reset section. */ void load_resets( FILE *fp ) { RESET_DATA *pReset; int iLastRoom = 0; int iLastObj = 0; if ( area_last == NULL ) { bug( "Load_resets: no #AREA seen yet.", 0 ); exit( 1 ); } for ( ; ; ) { ROOM_INDEX_DATA *pRoomIndex; EXIT_DATA *pexit; OBJ_INDEX_DATA *temp_index; char letter; if ( ( letter = fread_letter( fp ) ) == 'S' ) break; if ( letter == '*' ) { fread_to_eol( fp ); continue; } pReset = new_reset_data(); pReset->command = letter; /* if_flag */ fread_number( fp ); pReset->arg1 = fread_number( fp ); pReset->arg2 = fread_number( fp ); pReset->arg3 = (letter == 'G' || letter == 'R') ? 0 : fread_number( fp ); fread_to_eol( fp ); /* * Validate parameters. * We're calling the index functions for the side effect. */ switch ( letter ) { default: bug( "Load_resets: bad command '%c'.", letter ); exit( 1 ); break; case 'M': get_mob_index ( pReset->arg1 ); if ( ( pRoomIndex = get_room_index ( pReset->arg3 ) ) != NULL ) { new_reset( pRoomIndex, pReset ); iLastRoom = pReset->arg3; } break; case 'O': temp_index = get_obj_index ( pReset->arg1 ); temp_index->reset_num++; if ( ( pRoomIndex = get_room_index ( pReset->arg3 ) ) ) { new_reset( pRoomIndex, pReset ); iLastObj = pReset->arg3; } break; case 'P': temp_index = get_obj_index ( pReset->arg1 ); temp_index->reset_num++; get_obj_index ( pReset->arg3 ); get_obj_index ( pReset->arg1 ); if ( ( pRoomIndex = get_room_index ( iLastObj ) ) ) { new_reset( pRoomIndex, pReset ); } break; case 'G': case 'E': temp_index = get_obj_index ( pReset->arg1 ); temp_index->reset_num++; if ( ( pRoomIndex = get_room_index ( iLastRoom ) ) ) { new_reset( pRoomIndex, pReset ); iLastObj = iLastRoom; } break; case 'D': pRoomIndex = get_room_index( pReset->arg1 ); if ( pReset->arg2 < 0 || pReset->arg2 > 5 || !pRoomIndex || !(pexit = pRoomIndex->exit[pReset->arg2]) ) { bug( "Load_resets: 'D': exit %d not door.", pReset->arg2 ); exit(1); } if (!IS_SET( pexit->rs_flags, EX_ISDOOR)) SET_BIT(pexit->rs_flags,EX_ISDOOR); switch ( pReset->arg3 ) { default: bug( "Load_resets: 'D': bad 'locks': %d." , pReset->arg3); case 0: break; case 1: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED ); break; case 2: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED ); break; case 3: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_PASSPROOF ); break; case 4: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_PICKPROOF ); break; case 5: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_NOPASS|EX_PICKPROOF ); break; } /* * By calling new_reset we are assigning reset data for doors. * This data is not used in updating the game any longer. But * displaying resets in this manner may be to your liking. * I have left the code here so you may do so. Uncomment data in * display_resets in olc.c if you wish to do this. * * new_reset( pRoomIndex, pReset ); * * End Resets Comment. */ break; case 'R': pRoomIndex = get_room_index( pReset->arg1 ); if ( pReset->arg2 < 0 || pReset->arg2 > 6 ) { bug( "Load_resets: 'R': bad exit %d.", pReset->arg2 ); exit( 1 ); } if ( pRoomIndex ) new_reset( pRoomIndex, pReset ); break; } /* if ( area_last->reset_first == NULL ) area_last->reset_first = pReset; if ( area_last->reset_last != NULL ) area_last->reset_last->next = pReset; area_last->reset_last = pReset; */ top_reset++; } return; } extern GMemChunk *exit_mem_chunk; extern GMemChunk *extradata_mem_chunk; extern GMemChunk *roomtext_mem_chunk; /* * Snarf a room section. */ void load_rooms( FILE *fp ) { ROOM_INDEX_DATA *pRoomIndex; if ( area_last == NULL ) { bug( "Load_resets: no #AREA seen yet.", 0 ); exit( 1 ); } for ( ; ; ) { sh_int vnum; char letter; int door; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_rooms: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_room_index( vnum ) != NULL ) { bug( "Load_rooms: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pRoomIndex = g_chunk_new (ROOM_INDEX_DATA, RoomID_mem_chunk); pRoomIndex->people = NULL; pRoomIndex->contents = NULL; pRoomIndex->extra_descr = NULL; pRoomIndex->mprog_flags = 0; pRoomIndex->area = area_last; pRoomIndex->vnum = vnum; pRoomIndex->affected_by = 0; pRoomIndex->affected = NULL; pRoomIndex->name = fread_string( fp ); pRoomIndex->mprogs = NULL; pRoomIndex->description = fread_string( fp ); /* Area number */ fread_number( fp ); pRoomIndex->room_flags = fread_flag( fp ); if (IS_SET(pRoomIndex->room_flags,ROOM_PRIVATE)) REMOVE_BIT(pRoomIndex->room_flags,ROOM_PRIVATE); pRoomIndex->sector_type = fread_number( fp ); pRoomIndex->light = 0; pRoomIndex->blood = 0; pRoomIndex->roomtext = NULL; pRoomIndex->reset_list = NULL; for ( door = 0; door <= 4; door++ ) { pRoomIndex->track[door] = g_string_new(""); pRoomIndex->track_dir[door] = 0; } for ( door = 0; door <= 5; door++ ) pRoomIndex->exit[door] = NULL; for ( ; ; ) { letter = fread_letter( fp ); if ( letter == 'S' ) break; if ( letter == 'D' ) { EXIT_DATA *pexit; int locks; door = fread_number( fp ); if ( door < 0 || door > 5 ) { bug( "Fread_rooms: vnum %d has bad door number.", vnum ); exit( 1 ); } pexit = new_exit(); pexit->description = fread_string( fp ); pexit->keyword = fread_string( fp ); pexit->exit_info = 0; locks = fread_number( fp ); pexit->key = fread_number( fp ); pexit->vnum = fread_number( fp ); pexit->orig_door = door; switch ( locks ) { case 0: break; case 1: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED ); break; case 2: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED ); break; case 3: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_PASSPROOF ); break; case 4: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_PICKPROOF ); break; case 5: SET_BIT( pexit->rs_flags, EX_ISDOOR|EX_CLOSED|EX_LOCKED|EX_NOPASS|EX_PICKPROOF ); break; } if ( pexit->vnum != 0 ) { pRoomIndex->exit[door] = pexit; top_exit++; } } else if ( letter == 'E' ) { EXTRA_DESCR_DATA *ed; ed = g_chunk_new (EXTRA_DESCR_DATA, extradata_mem_chunk); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); ed->next = pRoomIndex->extra_descr; pRoomIndex->extra_descr = ed; top_ed++; } else if ( letter == 'M' ) { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = new_mprog(); word = fread_word( fp ); if ( !(trigger = flag_lookup( word, mprog_room_flags )) ) { bug("MUDprogs: invalid trigger.",0); exit(1); } SET_BIT( pRoomIndex->mprog_flags, trigger ); pMprog->trig_type = trigger; pMprog->vnum = fread_number( fp ); pMprog->trig_phrase = g_string_assign(pMprog->trig_phrase,fread_string( fp )); pMprog->next = pRoomIndex->mprogs; pRoomIndex->mprogs = pMprog; } else if ( letter == 'T' ) { ROOMTEXT_DATA *rt; rt = g_chunk_new (ROOMTEXT_DATA, roomtext_mem_chunk); rt->input = fread_string( fp ); rt->output = fread_string( fp ); rt->choutput = fread_string( fp ); rt->name = fread_string( fp ); rt->type = fread_number( fp ); rt->power = fread_number( fp ); rt->mob = fread_number( fp ); rt->next = pRoomIndex->roomtext; pRoomIndex->roomtext = rt; top_rt++; } else { bug( "Load_rooms: vnum %d has flag not 'DES'.", vnum ); exit( 1 ); } } iHash = vnum % MAX_KEY_HASH; pRoomIndex->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoomIndex; assign_area_vnum( vnum ); top_room++; } return; } extern GMemChunk *shop_mem_chunk; /* * Snarf a shop section. */ void load_shops( FILE *fp ) { SHOP_DATA *pShop; for ( ; ; ) { MOB_INDEX_DATA *pMobIndex; int iTrade; pShop = new_shop(); pShop->keeper = fread_number( fp ); if ( pShop->keeper == 0 ) break; for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ ) pShop->buy_type[iTrade] = fread_number( fp ); pShop->profit_buy = fread_number( fp ); pShop->profit_sell = fread_number( fp ); pShop->open_hour = fread_number( fp ); pShop->close_hour = fread_number( fp ); fread_to_eol( fp ); pMobIndex = get_mob_index( pShop->keeper ); pMobIndex->pShop = pShop; if ( shop_first == NULL ) shop_first = pShop; if ( shop_last != NULL ) shop_last->next = pShop; shop_last = pShop; pShop->next = NULL; top_shop++; } return; } /* * Snarf spec proc declarations. */ void load_specials( FILE *fp ) { for ( ; ; ) { MOB_INDEX_DATA *pMobIndex; char letter; switch ( letter = fread_letter( fp ) ) { default: bug( "Load_specials: letter '%c' not *MS.", letter ); exit( 1 ); case 'S': return; case '*': break; case 'M': pMobIndex = get_mob_index ( fread_number ( fp ) ); pMobIndex->spec_fun = spec_lookup ( fread_word ( fp ) ); if ( pMobIndex->spec_fun == 0 ) { bug( "Load_specials: 'M': vnum %d.", pMobIndex->vnum ); exit( 1 ); } break; } fread_to_eol( fp ); } } /* * Translate all room exits from virtual to real. * Has to be done after all rooms are read in. * Check for bad reverse exits. */ void fix_exits( void ) { extern const sh_int rev_dir []; char buf[MAX_STRING_LENGTH]; ROOM_INDEX_DATA *pRoomIndex; ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; int iHash; int door; for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex != NULL; pRoomIndex = pRoomIndex->next ) { bool fexit; fexit = FALSE; for ( door = 0; door <= 5; door++ ) { if ( ( pexit = pRoomIndex->exit[door] ) != NULL ) { fexit = TRUE; if ( pexit->vnum <= 0 ) pexit->to_room = NULL; else pexit->to_room = get_room_index( pexit->vnum ); } } if ( !fexit ) SET_BIT( pRoomIndex->room_flags, ROOM_NO_MOB ); } } for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex != NULL; pRoomIndex = pRoomIndex->next ) { for ( door = 0; door <= 5; door++ ) { if ( ( pexit = pRoomIndex->exit[door] ) != NULL && ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL && pexit_rev->to_room != pRoomIndex ) { sprintf( buf, "Fix_exits: %d:%d -> %d:%d -> %d.", pRoomIndex->vnum, door, to_room->vnum, rev_dir[door], (pexit_rev->to_room == NULL) ? 0 : pexit_rev->to_room->vnum ); /* bug( buf, 0 ); */ } } } } return; } extern GMemChunk *pmprog_mem_chunk; /* * Load mobprogs section */ void load_mobprogs( FILE *fp ) { MPROG_CODE *pMprog; if ( area_last == NULL ) { bug( "Load_mobprogs: no #AREA seen yet.", 0 ); exit( 1 ); } for ( ; ; ) { sh_int vnum; char letter; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_mobprogs: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_mprog_index( vnum ) != NULL ) { bug( "Load_mobprogs: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pMprog = new_mpcode(); pMprog->vnum = vnum; pMprog->code = g_string_assign(pMprog->code,fread_string( fp )); if ( mprog_list == NULL ) mprog_list = pMprog; else { pMprog->next = mprog_list; mprog_list = pMprog; } top_mprog_index++; } return; } /* * Translate mobprog vnums pointers to real code */ void fix_mobprogs( void ) { MOB_INDEX_DATA *pMobIndex; ROOM_INDEX_DATA *pRoomIndex; OBJ_INDEX_DATA *pObjIndex; MPROG_LIST *list; MPROG_CODE *prog; int iHash; for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for ( pMobIndex = mob_index_hash[iHash]; pMobIndex != NULL; pMobIndex = pMobIndex->next ) { for( list = pMobIndex->mprogs; list != NULL; list = list->next ) { if ( ( prog = get_mprog_index( list->vnum ) ) != NULL ) list->code = prog->code; else { bug( "Fix_mobprogs: code vnum %d not found.", list->vnum ); exit( 1 ); } } } for ( pObjIndex = obj_index_hash[iHash]; pObjIndex != NULL; pObjIndex = pObjIndex->next ) { for( list = pObjIndex->mprogs; list != NULL; list = list->next ) { if ( ( prog = get_mprog_index( list->vnum ) ) != NULL ) list->code = prog->code; else { bug( "Fix_mobprogs: code vnum %d not found.", list->vnum ); exit( 1 ); } } } for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex != NULL; pRoomIndex = pRoomIndex->next ) { for( list = pRoomIndex->mprogs; list != NULL; list = list->next ) { if (list->vnum == 0) continue; if ( ( prog = get_mprog_index( list->vnum ) ) != NULL ) list->code = prog->code; else { bug( "Fix_mobprogs: code vnum %d not found.", list->vnum ); exit( 1 ); } } } } } /* * Repopulate areas periodically. */ void area_update( void ) { AREA_DATA *pArea; for ( pArea = area_first; pArea != NULL; pArea = pArea->next ) { CHAR_DATA *pch; if ( ++pArea->age < 3 ) continue; /* * Check for PC's. */ if ( pArea->nplayer > 0 && pArea->age == 15 - 1 ) { for ( pch = char_list; pch != NULL; pch = pch->next ) { if ( !IS_NPC(pch) && IS_AWAKE(pch) && pch->in_room != NULL && pch->in_room->area == pArea ) { send_to_char( "You hear an agonized scream in the distance.\n\r", pch ); } } } /* * Check age and reset. * Note: Mud School resets every 3 minutes (not 15). */ if ( pArea->nplayer == 0 || pArea->age >= 15 ) { ROOM_INDEX_DATA *pRoomIndex; reset_area( pArea ); pArea->age = number_range( 0, 3 ); pRoomIndex = get_room_index( ROOM_VNUM_SCHOOL ); if ( pRoomIndex != NULL && pArea == pRoomIndex->area ) pArea->age = 15 - 3; } } logchan("Areas Reset!",NULL,NULL,WIZ_RESETS,0,LEVEL_IMMORTAL); return; } char *fread_string_eol( FILE *fp ) { static bool char_special[256-EOF]; GString *plast; char *shared_string = NULL; char c; int count = 0; if ( char_special[EOF-EOF] != TRUE ) { char_special[EOF - EOF] = TRUE; char_special['\n' - EOF] = TRUE; char_special['\r' - EOF] = TRUE; } plast = g_string_new(""); /* * Skip blanks. * Read first char. */ do { c = getc( fp ); } while ( isspace(c) ); plast = g_string_append_c(plast,c); if ( plast->str[count] == '\n') return &str_empty[0]; for ( ;; ) { c = getc(fp); switch (c) { default: break; case EOF: { c = getc(fp); shared_string = g_string_chunk_insert_const(LurfStringChunk,plast->str); g_string_free(plast,TRUE); return shared_string; } case '\n': case '\r': { c = getc(fp); shared_string = g_string_chunk_insert_const(LurfStringChunk,plast->str); g_string_free(plast,TRUE); return shared_string; } } plast = g_string_append_c(plast,c); } } extern int riddle_max; extern int riddle_number; extern struct riddle_type riddle_table[MAX_RIDDLE]; void load_riddles( FILE *fp) { struct riddle_type riddle; int riddle_count = 0; char * temp; for ( ; ; ) { riddle.clue = NULL; riddle.clue_do = NULL; riddle.riddle = NULL; riddle.answer = NULL; riddle.answer_do = NULL; temp = fread_word(fp); if (!strcmp(temp,"#")) { riddle_max = riddle_count; return; } riddle_count++; riddle.riddle = fread_string(fp); riddle.clue = fread_string(fp); riddle.clue_do = fread_string(fp); riddle.answer = fread_string(fp); riddle.answer_do = fread_string(fp); riddle_table[riddle_count] = riddle; } } /* values for db2.c */ extern int social_count; extern int xsocial_count; extern struct social_type social_table[MAX_SOCIALS]; extern struct xsocial_type xsocial_table[MAX_SOCIALS]; /* snarf a socials file */ void load_socials( FILE *fp) { for ( ; ; ) { struct social_type social; char *temp; /* clear social */ social.char_no_arg = NULL; social.others_no_arg = NULL; social.char_found = NULL; social.others_found = NULL; social.vict_found = NULL; social.char_not_found = NULL; social.char_auto = NULL; social.others_auto = NULL; temp = fread_word(fp); if (!strcmp(temp,"#0")) return; /* done */ #if defined(social_debug) else fprintf(stderr,"%s\n\r",temp); #endif str_cpy(social.name,temp); fread_to_eol(fp); temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.char_no_arg = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.char_no_arg = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.others_no_arg = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.others_no_arg = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.char_found = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.char_found = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.others_found = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.others_found = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.vict_found = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.vict_found = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.char_not_found = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.char_not_found = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.char_auto = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.char_auto = temp; temp = fread_string_eol(fp); if (!strcmp(temp,"$")) social.others_auto = NULL; else if (!strcmp(temp,"#")) { social_table[social_count] = social; social_count++; continue; } else social.others_auto = temp; social_table[social_count] = social; social_count++; } return; } void load_xsocials( FILE *fp) { for ( ; ; ) { struct xsocial_type xsocial; char *temp; /* clear social */ xsocial.char_no_arg = NULL; xsocial.others_no_arg = NULL; xsocial.char_found = NULL; xsocial.others_found = NULL; xsocial.vict_found = NULL; xsocial.char_auto = NULL; xsocial.others_auto = NULL; xsocial.gender = 0; xsocial.stage = 0; xsocial.position = 0; xsocial.self = 0; xsocial.other = 0; xsocial.chance = FALSE; temp = fread_string( fp); if (!strcmp(temp,"endofthisfile")) { xsocial.name = NULL; xsocial_table[xsocial_count] = xsocial; return; } xsocial.name = temp; xsocial.char_no_arg = fread_string(fp); xsocial.others_no_arg = fread_string(fp); xsocial.char_found = fread_string(fp); xsocial.others_found = fread_string(fp); xsocial.vict_found = fread_string(fp); xsocial.char_auto = fread_string(fp); xsocial.gender = fread_number( fp ); xsocial.stage = fread_number( fp ); xsocial.position = fread_number( fp ); xsocial.self = fread_number( fp ); xsocial.other = fread_number( fp ); temp = fread_word( fp ); if (!strcmp(temp,"TRUE")) xsocial.chance = TRUE; else xsocial.chance = FALSE; xsocial.msp = fread_string( fp ); fread_to_eol(fp); xsocial_table[xsocial_count] = xsocial; xsocial_count++; } return; } void load_mobiles_rom( FILE *fp ) { MOB_INDEX_DATA *pMobIndex; char letter2; if ( !area_last ) { bug("LoadoBh: no area seen yet.", 0); exit(1); } for ( ; ; ) { sh_int vnum; char letter; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_mobiles: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_mob_index( vnum ) != NULL ) { bug( "Load_mobiles: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pMobIndex = g_chunk_new (MOB_INDEX_DATA, MobID_mem_chunk); pMobIndex->vnum = vnum; pMobIndex->area = area_last; pMobIndex->player_name = fread_string( fp ); pMobIndex->short_descr = fread_string( fp ); pMobIndex->long_descr = fread_string( fp ); pMobIndex->description = fread_string( fp ); fread_string( fp ); /* Junk Read */ pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]); pMobIndex->description[0] = UPPER(pMobIndex->description[0]); pMobIndex->act = fread_flag( fp ) | ACT_IS_NPC; if ( IS_SET(pMobIndex->act,ACT_DEAD)) REMOVE_BIT(pMobIndex->act,ACT_DEAD); pMobIndex->affected_by = fread_flag( fp ); pMobIndex->itemaffect = 0; pMobIndex->pShop = NULL; pMobIndex->alignment = fread_number( fp ); letter = fread_number( fp ); pMobIndex->level = number_fuzzy( fread_number( fp ) ); /* * The unused stuff is for imps who want to use the old-style * stats-in-files method. */ pMobIndex->hitroll = fread_number( fp ); /* Unused */ //pMobIndex->ac = fread_number( fp ); /* Unused */ pMobIndex->hitnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->hitsizedice = fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ pMobIndex->hitplus = fread_number( fp ); /* Unused */ pMobIndex->damnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->damsizedice = fread_number( fp ); /* Unused */ /* + */ fread_letter( fp ); /* Unused */ fread_number( fp ); fread_number( fp ); /* 'd' */ fread_letter( fp ); /* Unused */ /*pMobIndex->damsizedice*/ fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ /*pMobIndex->damsizedice*/ fread_number( fp ); /* Unused */ /*pMobIndex->gold*/ fread_word( fp ); /* Unused */ /* xp can't be used! */ fread_number( fp ); /* Unused */ /* position */ fread_number( fp ); /* Unused */ /* start pos */ fread_number( fp ); /* Unused */ /* * Back to meaningful values. */ pMobIndex->sex = fread_number( fp ); fread_flag( fp ); /*this is something*/ fread_flag( fp ); fread_flag( fp ); fread_flag( fp ); fread_word( fp ); fread_word( fp ); fread_word( fp ); fread_number( fp ); pMobIndex->added = fread_number( fp ); pMobIndex->mob_fight = fread_flag( fp ); fread_word( fp ); fread_number( fp ); //pMobIndex->sphere_spaffect = fread_number( fp ); /* if ( letter != 'S' ) { bug( "Load_mobiles: vnum %d non-S.", vnum ); exit( 1 ); } */ for ( ; ; ) { letter2 = fread_letter( fp ); if ( letter2 == 'M' ) { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = new_mprog(); word = fread_word( fp ); if ( !(trigger = flag_lookup( word, mprog_flags )) ) { bug("MOBprogs: invalid trigger.",0); exit(1); } SET_BIT( pMobIndex->mprog_flags, trigger ); pMprog->trig_type = trigger; pMprog->vnum = fread_number( fp ); pMprog->trig_phrase = g_string_assign(pMprog->trig_phrase,fread_string( fp )); pMprog->next = pMobIndex->mprogs; pMobIndex->mprogs = pMprog; } else { ungetc(letter2,fp); break; } } iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; assign_area_vnum( vnum ); kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++; } return; } void load_objects_new( FILE *fp ) { OBJ_INDEX_DATA *pObjIndex; if ( !area_last ) { bug("LoadoBh: no area seen yet.", 0); exit(1); } for ( ; ; ) { sh_int vnum; char letter; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_objects: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_obj_index( vnum ) != NULL ) { bug( "Load_objects: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pObjIndex = g_chunk_new (OBJ_INDEX_DATA, ObjID_mem_chunk); pObjIndex->vnum = vnum; pObjIndex->name = fread_string( fp ); pObjIndex->area = area_last; pObjIndex->short_descr = fread_string( fp ); pObjIndex->description = fread_string( fp ); /* Action description */ fread_string( fp ); pObjIndex->short_descr[0] = LOWER(pObjIndex->short_descr[0]); pObjIndex->description[0] = UPPER(pObjIndex->description[0]); pObjIndex->item_type = fread_number( fp ); pObjIndex->extra_flags = fread_flag( fp ); pObjIndex->wear_flags = fread_flag( fp ); switch(pObjIndex->item_type) { case ITEM_WEAPON: 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_flag(fp); break; case ITEM_CONTAINER: 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] = fread_number(fp); pObjIndex->value[3] = fread_number(fp); //pObjIndex->value[4] = fread_number(fp); break; case ITEM_WAND: case ITEM_STAFF: 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)); 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; } pObjIndex->weight = fread_number( fp ); pObjIndex->cost = fread_number( fp ); /* Unused */ pObjIndex->affected = 0; pObjIndex->extra_descr = 0; pObjIndex->chpoweron = &str_empty[0];; pObjIndex->chpoweroff = &str_empty[0];; pObjIndex->chpoweruse = &str_empty[0];; pObjIndex->victpoweron = &str_empty[0];; pObjIndex->victpoweroff = &str_empty[0];; pObjIndex->victpoweruse = &str_empty[0];; pObjIndex->spectype = 0; pObjIndex->specpower = 0; /* Cost per day */ fread_number( fp ); fread_flag(fp); /* if ( pObjIndex->item_type == ITEM_POTION ) SET_BIT(pObjIndex->extra_flags, ITEM_NODROP); */ for ( ; ; ) { char letter; letter = fread_letter( fp ); if ( letter == 'A' ) { AFFECT_DATA *paf; paf = g_chunk_new (AFFECT_DATA, affect_mem_chunk); paf->type = -1; paf->duration = -1; paf->location = fread_number( fp ); paf->modifier = fread_number( fp ); paf->bitvector = 0; paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if ( letter == 'E' ) { EXTRA_DESCR_DATA *ed; ed = g_chunk_new (EXTRA_DESCR_DATA, extra_desc_mem_chunk); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); ed->next = pObjIndex->extra_descr; pObjIndex->extra_descr = ed; top_ed++; } else if ( letter == 'Q' ) { pObjIndex->chpoweron = fread_string( fp ); pObjIndex->chpoweroff = fread_string( fp ); pObjIndex->chpoweruse = fread_string( fp ); pObjIndex->victpoweron = fread_string( fp ); pObjIndex->victpoweroff = fread_string( fp ); pObjIndex->victpoweruse = fread_string( fp ); pObjIndex->spectype = fread_number( fp ); pObjIndex->specpower = fread_number( fp ); } else { ungetc( letter, fp ); break; } } /* * Translate spell "slot numbers" to internal "skill numbers." */ switch ( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pObjIndex->value[1] = slot_lookup( pObjIndex->value[1] ); pObjIndex->value[2] = slot_lookup( pObjIndex->value[2] ); pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; case ITEM_STAFF: case ITEM_WAND: pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; } iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; assign_area_vnum( vnum ); top_obj_index++; } return; } void load_mobiles_new( FILE *fp ) { MOB_INDEX_DATA *pMobIndex; char letter2; if ( !area_last ) { bug("LoadoBh: no area seen yet.", 0); exit(1); } for ( ; ; ) { sh_int vnum; char letter; int iHash; letter = fread_letter( fp ); if ( letter != '#' ) { bug( "Load_mobiles: # not found.", 0 ); exit( 1 ); } vnum = fread_number( fp ); if ( vnum == 0 ) break; fBootDb = FALSE; if ( get_mob_index( vnum ) != NULL ) { bug( "Load_mobiles: vnum %d duplicated.", vnum ); exit( 1 ); } fBootDb = TRUE; pMobIndex = g_chunk_new (MOB_INDEX_DATA, MobID_mem_chunk); pMobIndex->vnum = vnum; pMobIndex->area = area_last; pMobIndex->player_name = fread_string( fp ); pMobIndex->short_descr = fread_string( fp ); pMobIndex->long_descr = fread_string( fp ); pMobIndex->description = fread_string( fp ); pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]); pMobIndex->description[0] = UPPER(pMobIndex->description[0]); pMobIndex->act = fread_flag( fp ) | ACT_IS_NPC; if ( IS_SET(pMobIndex->act,ACT_DEAD)) REMOVE_BIT(pMobIndex->act,ACT_DEAD); pMobIndex->affected_by = fread_flag( fp ); pMobIndex->itemaffect = 0; pMobIndex->pShop = NULL; pMobIndex->alignment = fread_number( fp ); letter = fread_letter( fp ); pMobIndex->level = number_fuzzy( fread_number( fp ) ); /* * The unused stuff is for imps who want to use the old-style * stats-in-files method. */ pMobIndex->hitroll = fread_number( fp ); /* Unused */ pMobIndex->ac = fread_number( fp ); /* Unused */ pMobIndex->hitnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->hitsizedice = fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ pMobIndex->hitplus = fread_number( fp ); /* Unused */ pMobIndex->damnodice = fread_number( fp ); /* Unused */ /* 'd' */ fread_letter( fp ); /* Unused */ pMobIndex->damsizedice = fread_number( fp ); /* Unused */ /* '+' */ fread_letter( fp ); /* Unused */ pMobIndex->damplus = fread_number( fp ); /* Unused */ /*pMobIndex->gold = fread_number( fp );*/ /* Unused */ /* xp can't be used! */ fread_number( fp ); /* Unused */ /* position */ fread_number( fp ); /* Unused */ /* start pos */ fread_number( fp ); /* Unused */ /* * Back to meaningful values. */ //pMobIndex->sex = fread_number( fp ); pMobIndex->added = fread_number( fp ); pMobIndex->mob_fight = fread_number( fp ); /* xp can't be used! */ fread_number( fp ); /* Unused */ /* position */ fread_number( fp ); /* Unused */ /* start pos */ fread_number( fp ); /* Unused */ /*pMobIndex->sphere_spaffect = fread_number( fp );*/ /* if ( letter != 'S' ) { bug( "Load_mobiles: vnum %d non-S.", vnum ); exit( 1 ); } */ for ( ; ; ) { letter2 = fread_letter( fp ); if ( letter2 == 'M' ) { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = new_mprog(); word = fread_word( fp ); if ( !(trigger = flag_lookup( word, mprog_flags )) ) { bug("MOBprogs: invalid trigger.",0); exit(1); } SET_BIT( pMobIndex->mprog_flags, trigger ); pMprog->trig_type = trigger; pMprog->vnum = fread_number( fp ); pMprog->trig_phrase = g_string_assign(pMprog->trig_phrase,fread_string( fp )); pMprog->next = pMobIndex->mprogs; pMobIndex->mprogs = pMprog; } else { ungetc(letter2,fp); break; } } iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; assign_area_vnum( vnum ); kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++; } return; }