/***************************************************************************
* 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;
}