Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

db.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
00003  *  Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe.    *
00004  *                                                                         *
00005  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
00006  *  Chastain, Michael Quan, and Mitchell Tse.                              *
00007  *                                                                         *
00008  *  In order to use any part of this Merc Diku Mud, you must comply with   *
00009  *  both the original Diku license in 'license.doc' as well the Merc       *
00010  *  license in 'license.txt'.  In particular, you may not remove either of *
00011  *  these copyright notices.                                               *
00012  *                                                                         *
00013  *  Much time and thought has gone into this software and you are          *
00014  *  benefitting.  We hope that you share your changes too.  What goes      *
00015  *  around, comes around.                                                  *
00016  **************************************************************************/
00017 
00018 /***************************************************************************
00019  *   ROM 2.4 is copyright 1993-1998 Russ Taylor                            *
00020  *   ROM has been brought to you by the ROM consortium                     *
00021  *       Russ Taylor (rtaylor@hypercube.org)                               *
00022  *       Gabrielle Taylor (gtaylor@hypercube.org)                          *
00023  *       Brian Moore (zump@rom.org)                                        *
00024  *   By using this code, you have agreed to follow the terms of the        *
00025  *   ROM license, in the file Rom24/doc/rom.license                        *
00026  **************************************************************************/
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <ctype.h>
00032 #include <time.h>
00033 #if defined(macintosh)
00034 #include <types.h>
00035 #else
00036 #include <sys/types.h>
00037 #include <sys/time.h>
00038 #include <sys/resource.h>
00039 #endif
00040 
00041 #include "merc.h"
00042 #include "db.h"
00043 #include "recycle.h"
00044 #include "music.h"
00045 #include "tables.h"
00046 #include "lookup.h"
00047 #include "olc.h"
00048 
00049 #if !defined(macintosh)
00050 extern int _filbuf args ((FILE *));
00051 #endif
00052 
00053 #if !defined(OLD_RAND)
00054 #if !defined(linux)
00055 #if !defined(QMFIXES)
00056 long random ();
00057 #endif
00058 #endif
00059 #if !defined(QMFIXES)
00060 void srandom (unsigned int);
00061 #endif
00062 int getpid ();
00063 time_t time (time_t * tloc);
00064 #endif
00065 
00066 
00067 /* externals for counting purposes */
00068 extern OBJ_DATA *obj_free;
00069 extern CHAR_DATA *char_free;
00070 extern DESCRIPTOR_DATA *descriptor_free;
00071 extern PC_DATA *pcdata_free;
00072 extern AFFECT_DATA *affect_free;
00073 
00074 /*
00075  * Globals.
00076  */
00077 HELP_DATA *help_first;
00078 HELP_DATA *help_last;
00079 
00080 HELP_AREA *had_list;
00081 
00082 SHOP_DATA *shop_first;
00083 SHOP_DATA *shop_last;
00084 
00085 NOTE_DATA *note_free;
00086 NOTE_DATA *note_list;
00087 
00088 MPROG_CODE *mprog_list;
00089 //CRS          crs_info;
00090 char bug_buf[2 * MAX_INPUT_LENGTH];
00091 CHAR_DATA *char_list;
00092 char *help_greeting;
00093 char log_buf[2 * MAX_INPUT_LENGTH];
00094 KILL_DATA kill_table[MAX_LEVEL];
00095 OBJ_DATA *object_list;
00096 TIME_INFO_DATA time_info;
00097 WEATHER_DATA weather_info;
00098 unsigned long int r_count=0; // Rooms
00099 unsigned long int m_count=0; // Mobs
00100 unsigned long int o_count=0; // Objects
00101 unsigned long int reset_count=0; // Resets
00102 unsigned long int s_count=0; // Shops
00103 unsigned long int h_count=0; // helps
00104 unsigned long int so_count=0;
00105 unsigned long int skill_count=0;
00106 unsigned long int v_count=0;
00107 sh_int gsn_backstab;
00108 sh_int gsn_dodge;
00109 sh_int gsn_envenom;
00110 sh_int gsn_hide;
00111 sh_int gsn_peek;
00112 sh_int gsn_pick_lock;
00113 sh_int gsn_sneak;
00114 sh_int gsn_steal;
00115 
00116 sh_int gsn_disarm;
00117 sh_int gsn_enhanced_damage;
00118 sh_int gsn_kick;
00119 sh_int gsn_dragonbash;
00120 sh_int gsn_parry;
00121 sh_int gsn_rescue;
00122 sh_int gsn_second_attack;
00123 sh_int gsn_third_attack;
00124 
00125 sh_int gsn_blindness;
00126 sh_int gsn_charm_person;
00127 sh_int gsn_curse;
00128 sh_int gsn_invis;
00129 sh_int gsn_mass_invis;
00130 sh_int gsn_poison;
00131 sh_int gsn_plague;
00132 sh_int gsn_sleep;
00133 sh_int gsn_sanctuary;
00134 sh_int gsn_fly;
00135 /* new gsns */
00136 
00137 sh_int gsn_axe;
00138 sh_int gsn_dagger;
00139 sh_int gsn_flail;
00140 sh_int gsn_mace;
00141 sh_int gsn_polearm;
00142 sh_int gsn_shield_block;
00143 sh_int gsn_spear;
00144 sh_int gsn_sword;
00145 sh_int gsn_whip;
00146 
00147 sh_int gsn_bash;
00148 sh_int gsn_berserk;
00149 sh_int gsn_dirt;
00150 sh_int gsn_hand_to_hand;
00151 sh_int gsn_trip;
00152 
00153 sh_int gsn_fast_healing;
00154 sh_int gsn_haggle;
00155 sh_int gsn_lore;
00156 sh_int gsn_meditation;
00157 
00158 sh_int gsn_scrolls;
00159 sh_int gsn_staves;
00160 sh_int gsn_wands;
00161 sh_int gsn_recall;
00162 sh_int gsn_tailor;
00163 sh_int gsn_blacksmith;
00164 sh_int gsn_fourth_attack;
00165 sh_int gsn_fifth_attack;
00166 sh_int gsn_dual_wield;
00167 sh_int gsn_riding;
00168 sh_int gsn_advanced_riding;
00169 sh_int gsn_side_kick;
00170 sh_int gsn_mudcoat;
00171 
00172 /*
00173  * Locals.
00174  */
00175 MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH];
00176 OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
00177 ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH];
00178 char *string_hash[MAX_KEY_HASH];
00179 
00180 AREA_DATA *area_first;
00181 AREA_DATA *area_last;
00182 AREA_DATA *current_area;
00183 
00184 char *string_space;
00185 char *top_string;
00186 char str_empty[1];
00187 
00188 int top_affect;
00189 int top_area;
00190 int top_ed;
00191 int top_exit;
00192 int top_help;
00193 int top_mob_index;
00194 int top_obj_index;
00195 int top_reset;
00196 int top_room;
00197 int top_shop;
00198 int top_vnum_room;                /* OLC */
00199 int top_vnum_mob;                /* OLC */
00200 int top_vnum_obj;                /* OLC */
00201 int top_mprog_index;            /* OLC */
00202 int mobile_count = 0;
00203 int newmobs = 0;
00204 int newobjs = 0;
00205 
00206 
00207 /*
00208  * Memory management.
00209  * Increase MAX_STRING if you have too.
00210  * Tune the others only if you understand what you're doing.
00211  */
00212 //#define            MAX_STRING    22826240
00213 //:#define            MAX_PERM_BLOCK    131072
00214 #define            MAX_MEM_LIST    11
00215 
00216 //void *rgFreeList[MAX_MEM_LIST];
00217 //const int rgSizeList[MAX_MEM_LIST] = {
00218 //    16, 32, 64, 128, 256, 1024, 2048, 4096, 8192, 16384, 32768 - 64
00219 //};
00220 
00221 int nAllocString;
00222 int sAllocString;
00223 //int nAllocPerm;
00224 //int sAllocPerm;
00225 
00226 
00227 
00228 /*
00229  * Semi-locals.
00230  */
00231 bool fBootDb;
00232 FILE *fpArea;
00233 char strArea[MAX_INPUT_LENGTH];
00234 
00235 
00236 
00237 /*
00238  * Local booting procedures.
00239 */
00240 void init_mm args ((void));
00241 void load_area args ((FILE * fp));
00242 void new_load_area args ((FILE * fp));    /* OLC */
00243 void load_helps args ((FILE * fp, char *fname));
00244 void load_old_mob args ((FILE * fp));
00245 void load_mobiles args ((FILE * fp));
00246 void load_old_obj args ((FILE * fp));
00247 void load_objects args ((FILE * fp));
00248 void load_resets args ((FILE * fp));
00249 void load_rooms args ((FILE * fp));
00250 void load_shops args ((FILE * fp));
00251 void load_socials args ((FILE * fp));
00252 void load_specials args ((FILE * fp));
00253 void load_bans args ((void));
00254 void load_mobprogs args ((FILE * fp));
00255 void    load_notes  args( ( void ) );
00256 void fix_exits args ((void));
00257 void fix_mobprogs args ((void));
00258 
00259 void reset_area args ((AREA_DATA * pArea));
00260 
00261 /*
00262  * Big mama top level function.
00263  */
00264 void boot_db ()
00265 {
00266 
00267     /*
00268      * Init some data space stuff.
00269      */
00270     {
00271      //   if ((string_space = calloc (1, MAX_STRING)) == NULL)
00272        // {
00273          //   bug ("Boot_db: can't alloc %d string space.", MAX_STRING);
00274        //     exit (1);
00275        // }
00276        strspace_alloc();
00277         top_string = string_space;
00278         fBootDb = TRUE;
00279     }
00280 
00281     /*
00282      * Init random number generator.
00283      */
00284     {
00285         init_mm ();
00286     }
00287 
00288     /*
00289      * Set time and weather.
00290      */
00291     {
00292         long lhour, lday, lmonth;
00293     send_to_all_copyover("Loading weather ");
00294         lhour = (current_time - 650336715) / (PULSE_TICK / PULSE_PER_SECOND);
00295         time_info.hour = lhour % 24;
00296         lday = lhour / 24;
00297         time_info.day = lday % 35;
00298         lmonth = lday / 35;
00299         time_info.month = lmonth % 17;
00300         time_info.year = lmonth / 17;
00301 
00302         if (time_info.hour < 5)
00303             weather_info.sunlight = SUN_DARK;
00304         else if (time_info.hour < 6)
00305             weather_info.sunlight = SUN_RISE;
00306         else if (time_info.hour < 19)
00307             weather_info.sunlight = SUN_LIGHT;
00308         else if (time_info.hour < 20)
00309             weather_info.sunlight = SUN_SET;
00310         else
00311             weather_info.sunlight = SUN_DARK;
00312 
00313         weather_info.change = 0;
00314         weather_info.mmhg = 960;
00315         if (time_info.month >= 7 && time_info.month <= 12)
00316             weather_info.mmhg += number_range (1, 50);
00317         else
00318             weather_info.mmhg += number_range (1, 80);
00319 
00320         if (weather_info.mmhg <= 980)
00321             weather_info.sky = SKY_LIGHTNING;
00322         else if (weather_info.mmhg <= 1000)
00323             weather_info.sky = SKY_RAINING;
00324         else if (weather_info.mmhg <= 1020)
00325             weather_info.sky = SKY_CLOUDY;
00326         else
00327             weather_info.sky = SKY_CLOUDLESS;
00328 
00329     }
00330     send_to_all_copyover(" Done.\n\r");
00331 
00332 {
00333    //crs_info.status = 0;
00334    //crs_info.who = &str_empty[0];
00335    //crs_info.reason = &str_empty[0];
00336    //crs_info.timer = -1;
00337  }   
00338 /*
00339      * Assign gsn's for skills which have them.
00340      */
00341     {
00342         int sn;
00343 
00344         for (sn = 0; sn < MAX_SKILL; sn++)
00345         {
00346             if (skill_table[sn].pgsn != NULL)
00347                 *skill_table[sn].pgsn = sn;
00348         }
00349     }
00350     send_to_all_copyover("Loading classes  "); 
00351     load_classes();
00352     
00353     send_to_all_copyover("Loading BTS's Game Settings  ");
00354     load_game_conf();
00355     send_to_all_copyover("\bDone.\n\r");
00356     send_to_all_copyover("Loading Kingdom Data  ");
00357     load_kingdom_data();
00358     send_to_all_copyover("\bDone.\n\r");
00359     send_to_all_copyover("Loading Clan Data  ");
00360     load_clan_data();
00361     send_to_all_copyover("\bDone.\n\r");
00362     /*
00363      * Read in all the area files.
00364      */
00365     {
00366         FILE *fpList;
00367     send_to_all_copyover( "Loading area files  "); twiddle();
00368         if ((fpList = fopen (AREA_LIST, "r")) == NULL)
00369         {
00370             perror (AREA_LIST);
00371             exit (1);
00372         }
00373 
00374         for (;;)
00375         {
00376             
00377         
00378         strcpy (strArea, fread_word (fpList));
00379             if (strArea[0] == '$')
00380                 break;
00381 
00382             if (strArea[0] == '-')
00383             {
00384                 fpArea = stdin;
00385             }
00386             else
00387             {
00388                 if ((fpArea = fopen (strArea, "r")) == NULL)
00389                 {
00390                     perror (strArea);
00391                     exit (1);
00392                 }
00393             }
00394 
00395             current_area = NULL;
00396 
00397             for (;;)
00398             {
00399                 char *word;
00400 
00401                 if (fread_letter (fpArea) != '#')
00402                 {
00403                     bug ("Boot_db: # not found.", 0);
00404                     exit (1);
00405                 }
00406 
00407                 word = fread_word (fpArea);
00408 
00409                 if (word[0] == '$')
00410                     break;
00411                 else if (!str_cmp (word, "AREA")) {
00412                     load_area (fpArea);
00413                 }
00414                 /* OLC */
00415                 else if (!str_cmp (word, "AREADATA"))
00416                     new_load_area (fpArea);
00417                 else if (!str_cmp (word, "HELPS"))
00418                     load_helps (fpArea, strArea);
00419                 else if (!str_cmp (word, "MOBOLD"))
00420                     load_old_mob (fpArea);
00421                 else if (!str_cmp (word, "MOBILES"))
00422                     load_mobiles (fpArea);
00423                 else if (!str_cmp (word, "MOBPROGS"))
00424                     load_mobprogs (fpArea);
00425                 else if (!str_cmp (word, "OBJOLD"))
00426                     load_old_obj (fpArea);
00427                 else if (!str_cmp (word, "OBJECTS"))
00428                     load_objects (fpArea);
00429                 else if (!str_cmp (word, "RESETS"))
00430                     load_resets (fpArea);
00431                 else if (!str_cmp (word, "ROOMS"))
00432                     load_rooms (fpArea);
00433                 else if (!str_cmp (word, "SHOPS"))
00434                     load_shops (fpArea);
00435                 else if (!str_cmp (word, "SOCIALS"))
00436                     load_socials (fpArea);
00437                 else if (!str_cmp (word, "SPECIALS"))
00438                     load_specials (fpArea);
00439                 else
00440                 {
00441                     bug ("Boot_db: bad section name.", 0);
00442                     exit (1);
00443                 }
00444             }
00445 
00446             if (fpArea != stdin)
00447                 fclose (fpArea);
00448             fpArea = NULL;
00449         }
00450         fclose (fpList);
00451     send_to_all_copyover("\bDone.\n\r");
00452     }
00453 
00454     /*
00455      * Fix up exits.
00456      * Declare db booting over.
00457      * Reset all areas once.
00458      * Load up the songs, notes and ban files.
00459      */
00460     {
00461         send_to_all_copyover("Fixing exits  ");
00462     fix_exits ();
00463         fix_mobprogs ();
00464         fBootDb = FALSE;
00465         convert_objects ();        /* ROM OLC */
00466         send_to_all_copyover("\bDone.\n\rUpdating areas  ");
00467     area_update ();
00468     //  load_boards();
00469     //  save_notes();
00470         send_to_all_copyover("\bDone.\n\rLoading vehicles  ");
00471     load_vehicles();
00472     send_to_all_copyover("Loading banned sites  ");
00473     load_bans ();
00474         load_songs ();
00475     send_to_all_copyover("\bDone.\n\r");
00476     send_to_all_copyover("Loading notes  ");
00477     load_notes();
00478     send_to_all_copyover("\bDone.\n\r");
00479     send_to_all_copyover("Loading disabled commands  ");
00480     load_disabled();
00481     load_enhanced_disable();
00482     
00483     send_to_all_copyover("\bDone.\n\r");
00484 
00485 
00486     }
00487     
00488 return;
00489 }
00490 
00491 
00492 
00493 /*
00494  * Snarf an 'area' header line.
00495  */
00496 void load_area (FILE * fp)
00497 {
00498     AREA_DATA *pArea;
00499     send_to_all_copyover("Loading areas into BTS "); 
00500     pArea = alloc_perm (sizeof (*pArea));
00501     pArea->file_name = fread_string (fp);
00502 
00503     /* Pretty up the log a little */
00504     logf("Loading area %s", pArea->file_name);
00505 
00506     pArea->area_flags = AREA_LOADING;    /* OLC */
00507     pArea->security = 9;        /* OLC *//* 9 -- Hugin */
00508     pArea->builders = str_dup ("None");    /* OLC */
00509     pArea->vnum = top_area;        /* OLC */
00510 
00511     pArea->name = fread_string (fp);
00512     pArea->credits = fread_string (fp);
00513     pArea->min_vnum = fread_number (fp);
00514     pArea->max_vnum = fread_number (fp);
00515     pArea->age = 15;
00516     pArea->nplayer = 0;
00517     pArea->r_used =0;
00518     pArea->empty = FALSE;
00519 
00520     if (!area_first)
00521         area_first = pArea;
00522     if (area_last)
00523     {
00524         area_last->next = pArea;
00525         REMOVE_BIT (area_last->area_flags, AREA_LOADING);    /* OLC */
00526     }
00527     area_last = pArea;
00528     pArea->next = NULL;
00529     current_area = pArea;
00530 
00531     top_area++;
00532     send_to_all_copyover("Done.\n\r");
00533     return;
00534 }
00535 
00536 /*
00537  * OLC
00538  * Use these macros to load any new area formats that you choose to
00539  * support on your MUD.  See the new_load_area format below for
00540  * a short example.
00541  */
00542 #if defined(KEY)
00543 #undef KEY
00544 #endif
00545 
00546 #define KEY( literal, field, value )                \
00547                 if ( !str_cmp( word, literal ) )    \
00548                 {                                   \
00549                     field  = value;                 \
00550                     fMatch = TRUE;                  \
00551                     break;                          \
00552                                 }
00553 
00554 #define SKEY( string, field )                       \
00555                 if ( !str_cmp( word, string ) )     \
00556                 {                                   \
00557                     free_string( field );           \
00558                     field = fread_string( fp );     \
00559                     fMatch = TRUE;                  \
00560                     break;                          \
00561                                 }
00562 
00563 
00564 
00565 /* OLC
00566  * Snarf an 'area' header line.   Check this format.  MUCH better.  Add fields
00567  * too.
00568  *
00569  * #AREAFILE
00570  * Name   { All } Locke    Newbie School~
00571  * Repop  A teacher pops in the room and says, 'Repop coming!'~
00572  * Recall 3001
00573  * End
00574  */
00575 void new_load_area (FILE * fp)
00576 {
00577     AREA_DATA *pArea;
00578     char *word;
00579     bool fMatch;
00580 //   send_to_all_copyover("Loading new areas ");
00581     pArea = alloc_perm (sizeof (*pArea));
00582     pArea->age = 15;
00583     pArea->nplayer = 0;
00584     pArea->file_name = str_dup (strArea);
00585     pArea->vnum = top_area;
00586     pArea->name = str_dup ("New Area");
00587     pArea->builders = str_dup ("");
00588     pArea->security = 9;        /* 9 -- Hugin */
00589     pArea->min_vnum = 0;
00590     pArea->max_vnum = 0;
00591     pArea->area_flags = 0;
00592 /*  pArea->recall       = ROOM_VNUM_TEMPLE;        ROM OLC */
00593 
00594     for (;;)
00595     {
00596     
00597         word = feof (fp) ? "End" : fread_word (fp);
00598         fMatch = FALSE;
00599 
00600         switch (UPPER (word[0]))
00601         {
00602             case 'N':
00603                 SKEY ("Name", pArea->name);
00604                 break;
00605             case 'S':
00606                 KEY ("Security", pArea->security, fread_number (fp));
00607                 break;
00608             case 'V':
00609                 if (!str_cmp (word, "VNUMs"))
00610                 {
00611                     pArea->min_vnum = fread_number (fp);
00612                     pArea->max_vnum = fread_number (fp);
00613                 }
00614                 break;
00615             case 'E':
00616                 if (!str_cmp (word, "End"))
00617                 {
00618                     fMatch = TRUE;
00619                     if (area_first == NULL)
00620                         area_first = pArea;
00621                     if (area_last != NULL)
00622                         area_last->next = pArea;
00623                     area_last = pArea;
00624                     pArea->next = NULL;
00625                     current_area = pArea;
00626                     top_area++;
00627 
00628                     return;
00629                 }
00630                 break;
00631             case 'B':
00632                 SKEY ("Builders", pArea->builders);
00633                 break;
00634             case 'C':
00635                 SKEY ("Credits", pArea->credits);
00636         SKEY ("Cont", pArea->cont);
00637                 break;
00638         }
00639     }
00640 //send_to_all_copyover("Done.\n\r");
00641 }
00642 
00643 /*
00644  * Sets vnum range for area using OLC protection features.
00645  */
00646 void assign_area_vnum (int vnum)
00647 {
00648     if (area_last->min_vnum == 0 || area_last->max_vnum == 0)
00649         area_last->min_vnum = area_last->max_vnum = vnum;
00650     if (vnum != URANGE (area_last->min_vnum, vnum, area_last->max_vnum))
00651     {
00652         if (vnum < area_last->min_vnum)
00653             area_last->min_vnum = vnum;
00654         else
00655             area_last->max_vnum = vnum;
00656     }
00657     return;
00658 }
00659 
00660 /*
00661  * Snarf a help section.
00662  */
00663 void load_helps (FILE * fp, char *fname)
00664 {
00665     HELP_DATA *pHelp;
00666     int level;
00667     char *keyword;
00668     //send_to_all_copyover("Loading help files ");
00669     for (;;)
00670     {
00671         HELP_AREA *had;
00672 
00673         level = fread_number (fp);
00674         keyword = fread_string (fp);
00675 
00676         if (keyword[0] == '$')
00677             break;
00678 
00679         if (!had_list)
00680         {
00681             had = new_had ();
00682             had->filename = str_dup (fname);
00683             had->area = current_area;
00684             if (current_area)
00685                 current_area->helps = had;
00686             had_list = had;
00687         }
00688         else if (str_cmp (fname, had_list->filename))
00689         {
00690             had = new_had ();
00691             had->filename = str_dup (fname);
00692             had->area = current_area;
00693             if (current_area)
00694                 current_area->helps = had;
00695             had->next = had_list;
00696             had_list = had;
00697         }
00698         else
00699             had = had_list;
00700 
00701         pHelp = new_help ();
00702         pHelp->level = level;
00703         pHelp->keyword = keyword;
00704         pHelp->text = fread_string (fp);
00705 
00706         if (!str_cmp (pHelp->keyword, "greeting"))
00707             help_greeting = pHelp->text;
00708 
00709         if (help_first == NULL)
00710             help_first = pHelp;
00711         if (help_last != NULL)
00712             help_last->next = pHelp;
00713 
00714         help_last = pHelp;
00715         pHelp->next = NULL;
00716 
00717         if (!had->first)
00718             had->first = pHelp;
00719         if (!had->last)
00720             had->last = pHelp;
00721 
00722         //had->last->next_area = pHelp;
00723         had->last = pHelp;
00724     h_count+=1;
00725         //pHelp->next_area = NULL;
00726 
00727         top_help++;
00728     }
00729 //send_to_all_copyover ("Done.\n\r");
00730     return;
00731 }
00732 
00733 
00734 
00735 /*
00736  * Snarf a mob section.  old style 
00737  */
00738 void load_old_mob (FILE * fp)
00739 {
00740     MOB_INDEX_DATA *pMobIndex;
00741     /* for race updating */
00742     int race;
00743     char name[MAX_STRING_LENGTH];
00744 
00745     if (!area_last)
00746     {                            /* OLC */
00747         bug ("Load_mobiles: no #AREA seen yet.", 0);
00748         exit (1);
00749     }
00750 
00751     for (;;)
00752     {
00753         int vnum;
00754         char letter;
00755         int iHash;
00756 
00757         letter = fread_letter (fp);
00758         if (letter != '#')
00759         {
00760             bug ("Load_mobiles: # not found.", 0);
00761             exit (1);
00762         }
00763 
00764         vnum = fread_number (fp);
00765         if (vnum == 0)
00766             break;
00767 
00768         fBootDb = FALSE;
00769         if (get_mob_index (vnum) != NULL)
00770         {
00771             bug ("Load_mobiles: vnum %d duplicated.", vnum);
00772             exit (1);
00773         }
00774         fBootDb = TRUE;
00775 
00776         pMobIndex = alloc_perm (sizeof (*pMobIndex));
00777         pMobIndex->vnum = vnum;
00778         pMobIndex->area = area_last;    /* OLC */
00779         pMobIndex->new_format = FALSE;
00780         pMobIndex->player_name = fread_string (fp);
00781         pMobIndex->short_descr = fread_string (fp);
00782         pMobIndex->long_descr = fread_string (fp);
00783         pMobIndex->description = fread_string (fp);
00784 
00785         pMobIndex->long_descr[0] = UPPER (pMobIndex->long_descr[0]);
00786         pMobIndex->description[0] = UPPER (pMobIndex->description[0]);
00787 
00788         pMobIndex->act = fread_flag (fp) | ACT_IS_NPC;
00789         pMobIndex->affected_by = fread_flag (fp);
00790         pMobIndex->pShop = NULL;
00791         pMobIndex->alignment = fread_number (fp);
00792         letter = fread_letter (fp);
00793         pMobIndex->level = fread_number (fp);
00794 
00795         /*
00796          * The unused stuff is for imps who want to use the old-style
00797          * stats-in-files method.
00798          */
00799         fread_number (fp);        /* Unused */
00800         fread_number (fp);        /* Unused */
00801         fread_number (fp);        /* Unused */
00802         /* 'd'      */ fread_letter (fp);
00803         /* Unused */
00804         fread_number (fp);        /* Unused */
00805         /* '+'      */ fread_letter (fp);
00806         /* Unused */
00807         fread_number (fp);        /* Unused */
00808         fread_number (fp);        /* Unused */
00809         /* 'd'      */ fread_letter (fp);
00810         /* Unused */
00811         fread_number (fp);        /* Unused */
00812         /* '+'      */ fread_letter (fp);
00813         /* Unused */
00814         fread_number (fp);        /* Unused */
00815         pMobIndex->wealth = fread_number (fp) / 20;
00816         /* xp can't be used! */ fread_number (fp);
00817         /* Unused */
00818         pMobIndex->start_pos = fread_number (fp);    /* Unused */
00819         pMobIndex->default_pos = fread_number (fp);    /* Unused */
00820 
00821         if (pMobIndex->start_pos < POS_SLEEPING)
00822             pMobIndex->start_pos = POS_STANDING;
00823         if (pMobIndex->default_pos < POS_SLEEPING)
00824             pMobIndex->default_pos = POS_STANDING;
00825 
00826         /*
00827          * Back to meaningful values.
00828          */
00829         pMobIndex->sex = fread_number (fp);
00830 
00831         /* compute the race BS */
00832         one_argument (pMobIndex->player_name, name);
00833 
00834         if (name[0] == '\0' || (race = race_lookup (name)) == 0)
00835         {
00836             /* fill in with blanks */
00837             pMobIndex->race = race_lookup ("human");
00838             pMobIndex->off_flags =
00839                 OFF_DODGE | OFF_DISARM | OFF_TRIP | ASSIST_VNUM;
00840             pMobIndex->imm_flags = 0;
00841             pMobIndex->res_flags = 0;
00842             pMobIndex->vuln_flags = 0;
00843             pMobIndex->form =
00844                 FORM_EDIBLE | FORM_SENTIENT | FORM_BIPED | FORM_MAMMAL;
00845             pMobIndex->parts =
00846                 PART_HEAD | PART_ARMS | PART_LEGS | PART_HEART | PART_BRAINS |
00847                 PART_GUTS;
00848         }
00849         else
00850         {
00851             pMobIndex->race = race;
00852             pMobIndex->off_flags =
00853                 OFF_DODGE | OFF_DISARM | OFF_TRIP | ASSIST_RACE |
00854                 race_table[race].off;
00855             pMobIndex->imm_flags = race_table[race].imm;
00856             pMobIndex->res_flags = race_table[race].res;
00857             pMobIndex->vuln_flags = race_table[race].vuln;
00858             pMobIndex->form = race_table[race].form;
00859             pMobIndex->parts = race_table[race].parts;
00860         }
00861 
00862         if (letter != 'S')
00863         {
00864             bug ("Load_mobiles: vnum %d non-S.", vnum);
00865             exit (1);
00866         }
00867 
00868         convert_mobile (pMobIndex);    /* ROM OLC */
00869 
00870         iHash = vnum % MAX_KEY_HASH;
00871         pMobIndex->next = mob_index_hash[iHash];
00872         mob_index_hash[iHash] = pMobIndex;
00873         top_mob_index++;
00874         top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob;    /* OLC */
00875         assign_area_vnum (vnum);    /* OLC */
00876         kill_table[URANGE (0, pMobIndex->level, MAX_LEVEL - 1)].number++;
00877     m_count+=1;
00878     }
00879 
00880     return;
00881 }
00882 
00883 /*
00884  * Snarf an obj section.  old style 
00885  */
00886 void load_old_obj (FILE * fp)
00887 {
00888     OBJ_INDEX_DATA *pObjIndex;
00889 
00890     if (!area_last)
00891     {                            /* OLC */
00892         bug ("Load_objects: no #AREA seen yet.", 0);
00893         exit (1);
00894     }
00895 
00896     for (;;)
00897     {
00898         int vnum;
00899         char letter;
00900         int iHash;
00901 
00902         letter = fread_letter (fp);
00903         if (letter != '#')
00904         {
00905             bug ("Load_objects: # not found.", 0);
00906             exit (1);
00907         }
00908 
00909         vnum = fread_number (fp);
00910         if (vnum == 0)
00911             break;
00912 
00913         fBootDb = FALSE;
00914         if (get_obj_index (vnum) != NULL)
00915         {
00916             bug ("Load_objects: vnum %d duplicated.", vnum);
00917             exit (1);
00918         }
00919         fBootDb = TRUE;
00920 
00921         pObjIndex = alloc_perm (sizeof (*pObjIndex));
00922         pObjIndex->vnum = vnum;
00923         pObjIndex->area = area_last;    /* OLC */
00924         pObjIndex->new_format = FALSE;
00925         pObjIndex->reset_num = 0;
00926         pObjIndex->name = fread_string (fp);
00927         pObjIndex->short_descr = fread_string (fp);
00928         pObjIndex->description = fread_string (fp);
00929         /* Action description */ fread_string (fp);
00930 
00931         pObjIndex->short_descr[0] = LOWER (pObjIndex->short_descr[0]);
00932         pObjIndex->description[0] = UPPER (pObjIndex->description[0]);
00933         pObjIndex->material = str_dup ("");
00934 
00935         pObjIndex->item_type = fread_number (fp);
00936         pObjIndex->extra_flags = fread_flag (fp);
00937         pObjIndex->wear_flags = fread_flag (fp);
00938         pObjIndex->value[0] = fread_number (fp);
00939         pObjIndex->value[1] = fread_number (fp);
00940         pObjIndex->value[2] = fread_number (fp);
00941         pObjIndex->value[3] = fread_number (fp);
00942         pObjIndex->value[4] = 0;
00943         pObjIndex->level = 0;
00944         pObjIndex->condition = 100;
00945         pObjIndex->weight = fread_number (fp);
00946         pObjIndex->cost = fread_number (fp);    /* Unused */
00947         /* Cost per day */ fread_number (fp);
00948 
00949 
00950         if (pObjIndex->item_type == ITEM_WEAPON)
00951         {
00952             if (is_name ("two", pObjIndex->name)
00953                 || is_name ("two-handed", pObjIndex->name)
00954                 || is_name ("claymore", pObjIndex->name))
00955                 SET_BIT (pObjIndex->value[4], WEAPON_TWO_HANDS);
00956         }
00957 
00958         for (;;)
00959         {
00960             char letter;
00961 
00962             letter = fread_letter (fp);
00963 
00964             if (letter == 'A')
00965             {
00966                 AFFECT_DATA *paf;
00967 
00968                 paf = alloc_perm (sizeof (*paf));
00969                 paf->where = TO_OBJECT;
00970                 paf->type = -1;
00971                 paf->level = 20;    /* RT temp fix */
00972                 paf->duration = -1;
00973                 paf->location = fread_number (fp);
00974                 paf->modifier = fread_number (fp);
00975                 paf->bitvector = 0;
00976                 paf->next = pObjIndex->affected;
00977                 pObjIndex->affected = paf;
00978                 top_affect++;
00979             }
00980 
00981             else if (letter == 'E')
00982             {
00983                 EXTRA_DESCR_DATA *ed;
00984 
00985                 ed = alloc_perm (sizeof (*ed));
00986                 ed->keyword = fread_string (fp);
00987                 ed->description = fread_string (fp);
00988                 ed->next = pObjIndex->extra_descr;
00989                 pObjIndex->extra_descr = ed;
00990                 top_ed++;
00991             }
00992 
00993             else
00994             {
00995                 ungetc (letter, fp);
00996                 break;
00997             }
00998         }
00999 
01000         /* fix armors */
01001         if (pObjIndex->item_type == ITEM_ARMOR)
01002         {
01003             pObjIndex->value[1] = pObjIndex->value[0];
01004             pObjIndex->value[2] = pObjIndex->value[1];
01005         }
01006 
01007         /*
01008          * Translate spell "slot numbers" to internal "skill numbers."
01009          */
01010         switch (pObjIndex->item_type)
01011         {
01012             case ITEM_PILL:
01013             case ITEM_POTION:
01014             case ITEM_SCROLL:
01015                 pObjIndex->value[1] = slot_lookup (pObjIndex->value[1]);
01016                 pObjIndex->value[2] = slot_lookup (pObjIndex->value[2]);
01017                 pObjIndex->value[3] = slot_lookup (pObjIndex->value[3]);
01018                 pObjIndex->value[4] = slot_lookup (pObjIndex->value[4]);
01019                 break;
01020 
01021             case ITEM_STAFF:
01022             case ITEM_WAND:
01023                 pObjIndex->value[3] = slot_lookup (pObjIndex->value[3]);
01024                 break;
01025         }
01026 
01027         iHash = vnum % MAX_KEY_HASH;
01028         pObjIndex->next = obj_index_hash[iHash];
01029         obj_index_hash[iHash] = pObjIndex;
01030         top_obj_index++;
01031         top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj;    /* OLC */
01032         assign_area_vnum (vnum);    /* OLC */
01033     o_count+=1;
01034     }
01035 
01036     return;
01037 }
01038 
01039 /*
01040  * Adds a reset to a room.  OLC
01041  * Similar to add_reset in olc.c
01042  */
01043 void new_reset (ROOM_INDEX_DATA * pR, RESET_DATA * pReset)
01044 {
01045     RESET_DATA *pr;
01046 
01047     if (!pR)
01048         return;
01049 
01050     pr = pR->reset_last;
01051 
01052     if (!pr)
01053     {
01054         pR->reset_first = pReset;
01055         pR->reset_last = pReset;
01056     }
01057     else
01058     {
01059         pR->reset_last->next = pReset;
01060         pR->reset_last = pReset;
01061         pR->reset_last->next = NULL;
01062     }
01063 
01064 /*    top_reset++; no estamos asignando memoria!!!! */
01065 
01066     return;
01067 }
01068 
01069 /*
01070  * Snarf a reset section.
01071  */
01072 void load_resets (FILE * fp)
01073 {
01074     RESET_DATA *pReset;
01075     EXIT_DATA *pexit;
01076     ROOM_INDEX_DATA *pRoomIndex;
01077     int rVnum = -1;
01078 //send_to_all_copyover("Loading resets ");
01079     if (!area_last)
01080     {
01081         bug ("Load_resets: no #AREA seen yet.", 0);
01082         exit (1);
01083     }
01084 
01085     for (;;)
01086     {
01087         char letter;
01088 
01089         if ((letter = fread_letter (fp)) == 'S')
01090             break;
01091 
01092         if (letter == '*')
01093         {
01094             fread_to_eol (fp);
01095             continue;
01096         }
01097 
01098         pReset = new_reset_data ();
01099     reset_count+=1;
01100         pReset->command = letter;
01101         /* if_flag */ fread_number (fp);
01102         pReset->arg1 = fread_number (fp);
01103         pReset->arg2 = fread_number (fp);
01104         pReset->arg3 = (letter == 'G' || letter == 'R')
01105             ? 0 : fread_number (fp);
01106         pReset->arg4 = (letter == 'P' || letter == 'M')
01107             ? fread_number (fp) : 0;
01108         fread_to_eol (fp);
01109 
01110         switch (pReset->command)
01111         {
01112             case 'M':
01113             case 'O':
01114                 rVnum = pReset->arg3;
01115                 break;
01116 
01117             case 'P':
01118             case 'G':
01119             case 'E':
01120                 break;
01121 
01122             case 'D':
01123                 pRoomIndex = get_room_index ((rVnum = pReset->arg1));
01124                 if (pReset->arg2 < 0
01125                     || pReset->arg2 >= MAX_DIR
01126                     || !pRoomIndex
01127                     || !(pexit = pRoomIndex->exit[pReset->arg2])
01128                     || !IS_SET (pexit->rs_flags, EX_ISDOOR))
01129                 {
01130                     bugf ("Load_resets: 'D': exit %d, room %d not door.",
01131                           pReset->arg2, pReset->arg1);
01132                     exit (1);
01133                 }
01134 
01135                 switch (pReset->arg3)
01136                 {
01137                     default:
01138                         bug ("Load_resets: 'D': bad 'locks': %d.",
01139                              pReset->arg3);
01140                         break;
01141                     case 0:
01142                         break;
01143                     case 1:
01144                         SET_BIT (pexit->rs_flags, EX_CLOSED);
01145                         SET_BIT (pexit->exit_info, EX_CLOSED);
01146                         break;
01147                     case 2:
01148                         SET_BIT (pexit->rs_flags, EX_CLOSED | EX_LOCKED);
01149                         SET_BIT (pexit->exit_info, EX_CLOSED | EX_LOCKED);
01150                         break;
01151                 }
01152                 break;
01153 
01154             case 'R':
01155                 rVnum = pReset->arg1;
01156                 break;
01157         }
01158 
01159         if (rVnum == -1)
01160         {
01161             bugf ("load_resets : rVnum == -1");
01162             exit (1);
01163         }
01164 
01165         if (pReset->command != 'D')
01166             new_reset (get_room_index (rVnum), pReset);
01167         else
01168             free_reset_data (pReset);
01169     }
01170 //  send_to_all_copyover("Done.\n\r");
01171     return;
01172 }
01173 
01174 /*
01175  * Snarf a room section.
01176  */
01177 void load_rooms (FILE * fp)
01178 {
01179     ROOM_INDEX_DATA *pRoomIndex;
01180 //send_to_all_copyover("Loading rooms ");
01181     if (area_last == NULL)
01182     {
01183         bug ("Load_resets: no #AREA seen yet.", 0);
01184         exit (1);
01185     }
01186 
01187     for (;;)
01188     {
01189         int vnum;
01190         char letter;
01191         int door;
01192         int iHash;
01193     
01194 
01195         letter = fread_letter (fp);
01196         if (letter != '#')
01197         {
01198             bug ("Load_rooms: # not found.", 0);
01199             exit (1);
01200         }
01201 
01202         vnum = fread_number (fp);
01203         if (vnum == 0)
01204             break;
01205 
01206         fBootDb = FALSE;
01207         if (get_room_index (vnum) != NULL)
01208         {
01209             bug ("Load_rooms: vnum %d duplicated.", vnum);
01210             exit (1);
01211         }
01212         fBootDb = TRUE;
01213 
01214         pRoomIndex = alloc_perm (sizeof (*pRoomIndex));
01215     //RoomIndex = alloc_perm (pRoomIndex);
01216         pRoomIndex->owner = str_dup ("");
01217         pRoomIndex->people = NULL;
01218         pRoomIndex->contents = NULL;
01219         pRoomIndex->extra_descr = NULL;
01220         pRoomIndex->area = area_last;
01221         pRoomIndex->vnum = vnum;
01222         pRoomIndex->name = fread_string (fp);
01223 
01224     pRoomIndex->travel_route = fread_number(fp);
01225     pRoomIndex->travel_type = fread_number(fp);
01226     pRoomIndex->travel_state = fread_number(fp);
01227         pRoomIndex->description = fread_string(fp);
01228     pRoomIndex->night_description = fread_string(fp);
01229     /* Area number */ fread_number (fp);
01230         pRoomIndex->room_flags = fread_flag (fp);
01231       /*if ((pRoomIndex->room_flags_extra = fread_flag(fp)))
01232     {
01233     }*/
01234 
01235 pRoomIndex->room_flags_extra = fread_flag (fp);
01236     /* horrible hack */
01237         if (3000 <= vnum && vnum < 3400)
01238             SET_BIT (pRoomIndex->room_flags, ROOM_LAW);
01239         pRoomIndex->sector_type = fread_number (fp);
01240         pRoomIndex->light = 0;
01241         for (door = 0; door <= 9; door++)
01242             pRoomIndex->exit[door] = NULL;
01243 
01244         /* defaults */
01245         pRoomIndex->heal_rate = 100;
01246         pRoomIndex->mana_rate = 100;
01247 
01248         for (;;)
01249         {
01250             letter = fread_letter (fp);
01251         twiddle();
01252 
01253             if (letter == 'S')
01254                 break;
01255 
01256             if (letter == 'H')    /* healing room */
01257                 pRoomIndex->heal_rate = fread_number (fp);
01258 
01259             else if (letter == 'M')    /* mana room */
01260                 pRoomIndex->mana_rate = fread_number (fp);
01261 
01262             else if (letter == 'C')
01263             {                    /* clan */
01264                 if (pRoomIndex->clan)
01265                 {
01266                     bug ("Load_rooms: duplicate clan fields.", 0);
01267                     exit (1);
01268                 }
01269                 pRoomIndex->clan = clan_lookup (fread_string (fp));
01270             }
01271 
01272 
01273             else if (letter == 'D')
01274             {
01275                 EXIT_DATA *pexit;
01276                 int locks;
01277 
01278                 door = fread_number (fp);
01279                 if (door < 0 || door > 9)
01280                 {
01281                     bug ("Fread_rooms: vnum %d has bad door number.", vnum);
01282                     exit (1);
01283                 }
01284 
01285                 pexit = alloc_perm (sizeof (*pexit));
01286                 pexit->description = fread_string (fp);
01287                 pexit->keyword = fread_string (fp);
01288                 pexit->exit_info = 0;
01289                 pexit->rs_flags = 0;    /* OLC */
01290                 locks = fread_number (fp);
01291                 pexit->key = fread_number (fp);
01292                 pexit->u1.vnum = fread_number (fp);
01293                 pexit->orig_door = door;    /* OLC */
01294 
01295                 switch (locks)
01296                 {
01297                     case 1:
01298                         pexit->exit_info = EX_ISDOOR;
01299                         pexit->rs_flags = EX_ISDOOR;
01300                         break;
01301                     case 2:
01302                         pexit->exit_info = EX_ISDOOR | EX_PICKPROOF;
01303                         pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF;
01304                         break;
01305                     case 3:
01306                         pexit->exit_info = EX_ISDOOR | EX_NOPASS;
01307                         pexit->rs_flags = EX_ISDOOR | EX_NOPASS;
01308                         break;
01309                     case 4:
01310                         pexit->exit_info =
01311                             EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
01312                         pexit->rs_flags =
01313                             EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
01314                         break;
01315                 }
01316 
01317                 pRoomIndex->exit[door] = pexit;
01318                 top_exit++;
01319             }
01320             else if (letter == 'E')
01321             {
01322                 EXTRA_DESCR_DATA *ed;
01323 
01324                 ed = alloc_perm (sizeof (*ed));
01325                 ed->keyword = fread_string (fp);
01326                 ed->