?? db.c
字號:
/***************************************************************************
* 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. *
***************************************************************************/
#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"
#if !defined(macintosh)
extern int _filbuf args( (FILE *) );
#endif
/*
* Globals.
*/
HELP_DATA * help_first;
HELP_DATA * help_last;
SHOP_DATA * shop_first;
SHOP_DATA * shop_last;
CHAR_DATA * char_free;
EXTRA_DESCR_DATA * extra_descr_free;
NOTE_DATA * note_free;
OBJ_DATA * obj_free;
PC_DATA * pcdata_free;
char bug_buf [2*MAX_INPUT_LENGTH];
CHAR_DATA * char_list;
char * help_greeting;
char log_buf [2*MAX_INPUT_LENGTH];
KILL_DATA kill_table [MAX_LEVEL];
NOTE_DATA * note_list;
OBJ_DATA * object_list;
TIME_INFO_DATA time_info;
WEATHER_DATA weather_info;
sh_int gsn_backstab;
sh_int gsn_dodge;
sh_int gsn_hide;
sh_int gsn_peek;
sh_int gsn_pick_lock;
sh_int gsn_sneak;
sh_int gsn_steal;
sh_int gsn_disarm;
sh_int gsn_enhanced_damage;
sh_int gsn_kick;
sh_int gsn_parry;
sh_int gsn_rescue;
sh_int gsn_second_attack;
sh_int gsn_third_attack;
sh_int gsn_blindness;
sh_int gsn_charm_person;
sh_int gsn_curse;
sh_int gsn_invis;
sh_int gsn_mass_invis;
sh_int gsn_poison;
sh_int gsn_sleep;
/*
* Psionicist gsn's.
*/
int gsn_chameleon;
int gsn_domination;
int gsn_heighten;
int gsn_shadow;
/*
* Locals.
*/
MOB_INDEX_DATA * mob_index_hash [MAX_KEY_HASH];
OBJ_INDEX_DATA * obj_index_hash [MAX_KEY_HASH];
ROOM_INDEX_DATA * room_index_hash [MAX_KEY_HASH];
char * string_hash [MAX_KEY_HASH];
AREA_DATA * area_first;
AREA_DATA * area_last;
char * string_space;
char * top_string;
char str_empty [1];
int top_affect;
int top_area;
int top_ed;
int top_exit;
int top_help;
int top_mob_index;
int top_obj_index;
int top_reset;
int top_room;
int top_shop;
/*
* MOBprogram locals
*/
int mprog_name_to_type args( ( char* name ) );
MPROG_DATA * mprog_file_read args( ( char* f, MPROG_DATA* mprg,
MOB_INDEX_DATA *pMobIndex ) );
void load_mobprogs args( ( FILE* fp ) );
void mprog_read_programs args( ( FILE* fp,
MOB_INDEX_DATA *pMobIndex ) );
// Windows version locals
int fIgnoreUnconnected = TRUE;
/*
* Memory management.
* Increase MAX_STRING if you have too.
* Tune the others only if you understand what you're doing.
*/
#define MAX_STRING 1750000
#define MAX_PERM_BLOCK 131072
#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
};
int nAllocString;
int sAllocString;
int nAllocPerm;
int sAllocPerm;
/*
* Semi-locals.
*/
bool fBootDb;
FILE * fpArea;
char strArea[MAX_INPUT_LENGTH];
/*
* Local booting procedures.
*/
void init_mm args( ( void ) );
void load_area args( ( FILE *fp ) );
void load_helps args( ( FILE *fp ) );
void load_mobiles args( ( FILE *fp ) );
void load_objects args( ( FILE *fp ) );
void load_resets args( ( FILE *fp ) );
void load_rooms args( ( FILE *fp ) );
void load_shops args( ( FILE *fp ) );
void load_specials args( ( FILE *fp ) );
void load_notes args( ( void ) );
void fix_exits args( ( void ) );
void reset_area args( ( AREA_DATA * pArea ) );
/*
* Big mama top level function.
*/
void boot_db( void )
{
/*
* 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 );
}
top_string = string_space;
fBootDb = TRUE;
}
/*
* Init random number generator.
*/
{
init_mm( );
}
/*
* Set time and weather.
*/
{
long lhour, lday, lmonth;
lhour = (current_time - 650336715)
/ (PULSE_TICK / PULSE_PER_SECOND);
time_info.hour = lhour % 24;
lday = lhour / 24;
time_info.day = lday % 35;
lmonth = lday / 35;
time_info.month = lmonth % 17;
time_info.year = lmonth / 17;
if ( time_info.hour < 5 ) weather_info.sunlight = SUN_DARK;
else if ( time_info.hour < 6 ) weather_info.sunlight = SUN_RISE;
else if ( time_info.hour < 19 ) weather_info.sunlight = SUN_LIGHT;
else if ( time_info.hour < 20 ) weather_info.sunlight = SUN_SET;
else weather_info.sunlight = SUN_DARK;
weather_info.change = 0;
weather_info.mmhg = 960;
if ( time_info.month >= 7 && time_info.month <=12 )
weather_info.mmhg += number_range( 1, 50 );
else
weather_info.mmhg += number_range( 1, 80 );
if ( weather_info.mmhg <= 980 ) weather_info.sky = SKY_LIGHTNING;
else if ( weather_info.mmhg <= 1000 ) weather_info.sky = SKY_RAINING;
else if ( weather_info.mmhg <= 1020 ) weather_info.sky = SKY_CLOUDY;
else weather_info.sky = SKY_CLOUDLESS;
}
/*
* 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 )
{
perror( AREA_LIST );
exit( 1 );
}
for ( ; ; )
{
strcpy( strArea, fread_word( fpList ) );
if ( strArea[0] == '$' )
break;
if ( strArea[0] == '-' )
{
fpArea = stdin;
}
else
{
if ( ( fpArea = fopen( strArea, "r" ) ) == NULL )
{
perror( strArea );
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);
else if ( !str_cmp( word, "HELPS" ) ) load_helps (fpArea);
else if ( !str_cmp( word, "MOBILES" ) ) load_mobiles (fpArea);
else if ( !str_cmp( word, "MOBPROGS" ) ) load_mobprogs(fpArea);
else if ( !str_cmp( word, "OBJECTS" ) ) load_objects (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
{
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.
* Set the MOBtrigger.
*/
{
fix_exits( );
fBootDb = FALSE;
area_update( );
load_notes( );
MOBtrigger = TRUE;
}
return;
}
/*
* Snarf an 'area' header line.
*/
void load_area( FILE *fp )
{
AREA_DATA *pArea;
pArea = alloc_perm( sizeof(*pArea) );
pArea->reset_first = NULL;
pArea->reset_last = NULL;
pArea->name = fread_string( fp );
pArea->age = 15;
pArea->nplayer = 0;
if ( area_first == NULL )
area_first = pArea;
if ( area_last != NULL )
area_last->next = pArea;
area_last = pArea;
pArea->next = NULL;
top_area++;
return;
}
/*
* Snarf a help section.
*/
void load_helps( FILE *fp )
{
HELP_DATA *pHelp;
for ( ; ; )
{
pHelp = alloc_perm( sizeof(*pHelp) );
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;
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 = alloc_perm( sizeof(*pMobIndex) );
pMobIndex->vnum = vnum;
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_number( fp ) | ACT_IS_NPC;
pMobIndex->affected_by = fread_number( fp );
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->cargo = 0; // @@@ ### Needed?
if ( letter != 'S' )
{
bug( "Load_mobiles: vnum %d non-S.", vnum );
exit( 1 );
}
letter=fread_letter(fp);
if (letter=='>')
{
ungetc(letter,fp);
mprog_read_programs(fp,pMobIndex);
}
else ungetc(letter,fp);
iHash = vnum % MAX_KEY_HASH;
pMobIndex->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMobIndex;
top_mob_index++;
kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++;
}
return;
}
/*
* Snarf an obj section.
*/
void load_objects( FILE *fp )
{
OBJ_INDEX_DATA *pObjIndex;
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 = alloc_perm( sizeof(*pObjIndex) );
pObjIndex->vnum = vnum;
pObjIndex->name = fread_string( fp );
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_number( fp );
pObjIndex->wear_flags = fread_number( 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 */
/* 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 = alloc_perm( sizeof(*paf) );
paf->type = -1;
paf->duration = -1;
paf->location = fread_number( fp );
paf->modifier = fread_number( fp );
paf->bitvector = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -