home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / db.c < prev    next >
C/C++ Source or Header  |  1991-03-01  |  49KB  |  2,288 lines

  1. /**************************************************************************
  2. *  file: db.c , Database module.                          Part of DIKUMUD *
  3. *  Usage: Loading/Saving chars, booting world, resetting etc.             *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ***************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <time.h>
  11.  
  12. #include "structs.h"
  13. #include "utils.h"
  14. #include "db.h"
  15. #include "comm.h"
  16. #include "handler.h"
  17. #include "limits.h"
  18.  
  19. #define NEW_ZONE_SYSTEM
  20.  
  21. /**************************************************************************
  22. *  declarations of most of the 'global' variables                         *
  23. ************************************************************************ */
  24.  
  25. struct room_data *world;              /* dyn alloc'ed array of rooms     */
  26. int top_of_world = 0;                 /* ref to the top element of world */
  27. struct obj_data  *object_list = 0;    /* the global linked list of obj's */
  28. struct char_data *character_list = 0; /* global l-list of chars          */
  29.  
  30. struct zone_data *zone_table;         /* table of reset data             */
  31. int top_of_zone_table = 0;
  32. struct message_list fight_messages[MAX_MESSAGES]; /* fighting messages   */
  33. struct player_index_element *player_table = 0; /* index to player file   */
  34. int top_of_p_table = 0;               /* ref to top of table             */
  35. int top_of_p_file = 0;
  36.  
  37. char credits[MAX_STRING_LENGTH];      /* the Credits List                */
  38. char news[MAX_STRING_LENGTH];            /* the news                        */
  39. char motd[MAX_STRING_LENGTH];         /* the messages of today           */
  40. char help[MAX_STRING_LENGTH];         /* the main help page              */
  41. char info[MAX_STRING_LENGTH];         /* the info text                   */
  42. char wizlist[MAX_STRING_LENGTH];      /* the wizlist                     */
  43.  
  44.  
  45. FILE *mob_f,                          /* file containing mob prototypes  */
  46.      *obj_f,                          /* obj prototypes                  */
  47.      *help_fl;                        /* file for help texts (HELP <kwd>)*/
  48.  
  49. struct index_data *mob_index;         /* index table for mobile file     */
  50. struct index_data *obj_index;         /* index table for object file     */
  51. struct help_index_element *help_index = 0;
  52.  
  53. int top_of_mobt = 0;                  /* top of mobile index table       */
  54. int top_of_objt = 0;                  /* top of object index table       */
  55. int top_of_helpt;                     /* top of help index table         */
  56.  
  57. struct time_info_data time_info;    /* the infomation about the time   */
  58. struct weather_data weather_info;    /* the infomation about the weather */
  59.  
  60.  
  61.  
  62.  
  63. /* local procedures */
  64. void boot_zones(void);
  65. void setup_dir(FILE *fl, int room, int dir);
  66. void allocate_room(int new_top);
  67. void boot_world(void);
  68. struct index_data *generate_indices(FILE *fl, int *top);
  69. void build_player_index(void);
  70. void char_to_store(struct char_data *ch, struct char_file_u *st);
  71. void store_to_char(struct char_file_u *st, struct char_data *ch);
  72. int is_empty(int zone_nr);
  73. void reset_zone(int zone);
  74. int file_to_string(char *name, char *buf);
  75. void renum_world(void);
  76. void renum_zone_table(void);
  77. void reset_time(void);
  78. void clear_char(struct char_data *ch);
  79.  
  80. /* external refs */
  81. extern struct descriptor_data *descriptor_list;
  82. void load_messages(void);
  83. void weather_and_time ( int mode );
  84. void assign_command_pointers ( void );
  85. void assign_spell_pointers ( void );
  86. void log(char *str);
  87. int dice(int number, int size);
  88. int number(int from, int to);
  89. void boot_social_messages(void);
  90. void boot_pose_messages(void);
  91. void update_obj_file(void); /* In reception.c */
  92. struct help_index_element *build_help_index(FILE *fl, int *num);
  93.  
  94.  
  95. /*************************************************************************
  96. *  routines for booting the system                                       *
  97. *********************************************************************** */
  98.  
  99.  
  100. /* body of the booting system */
  101. void boot_db(void)
  102. {
  103.     int i;
  104.     extern int no_specials;
  105.  
  106.     log("Boot db -- BEGIN.");
  107.  
  108.     log("Resetting the game time:");
  109.     reset_time();
  110.  
  111.     log("Reading newsfile, credits, help-page, info and motd.");
  112.     file_to_string(NEWS_FILE, news);
  113.     file_to_string(CREDITS_FILE, credits);
  114.     file_to_string(MOTD_FILE, motd);
  115.     file_to_string(HELP_PAGE_FILE, help);
  116.     file_to_string(INFO_FILE, info);
  117.     file_to_string(WIZLIST_FILE, wizlist);
  118.  
  119.     log("Opening mobile, object and help files.");
  120.     if (!(mob_f = fopen(MOB_FILE, "r")))
  121.     {
  122.         perror("boot");
  123.         exit(0);
  124.     }
  125.  
  126.     if (!(obj_f = fopen(OBJ_FILE, "r")))
  127.     {
  128.         perror("boot");
  129.         exit(0);
  130.     }
  131.     if (!(help_fl = fopen(HELP_KWRD_FILE, "r")))
  132.       log("   Could not open help file.");
  133.     else 
  134.         help_index = build_help_index(help_fl, &top_of_helpt);
  135.  
  136.  
  137.     log("Loading zone table.");
  138.     boot_zones();
  139.  
  140.     log("Loading rooms.");
  141.     boot_world();
  142.     log("Renumbering rooms.");
  143.     renum_world();
  144.  
  145.     log("Generating index tables for mobile and object files.");
  146.     mob_index = generate_indices(mob_f, &top_of_mobt);
  147.     obj_index = generate_indices(obj_f, &top_of_objt);
  148.             
  149.     log("Renumbering zone table.");
  150.     renum_zone_table();
  151.  
  152.     log("Generating player index.");
  153.     build_player_index();
  154.  
  155.     log("Loading fight messages.");
  156.     load_messages();
  157.  
  158.     log("Loading social messages.");
  159.     boot_social_messages();
  160.  
  161.   log("Loading pose messages.");
  162.     boot_pose_messages();
  163.  
  164.     log("Assigning function pointers:");
  165.     if (!no_specials)
  166.     {
  167.         log("   Mobiles.");
  168.         assign_mobiles();
  169.         log("   Objects.");
  170.         assign_objects();
  171.         log("   Room.");
  172.         assign_rooms();
  173.     }
  174.  
  175.     log("   Commands.");    
  176.     assign_command_pointers();
  177.     log("   Spells.");
  178.     assign_spell_pointers();
  179.  
  180.     log("Updating characters with saved items:");
  181.     update_obj_file();
  182.  
  183.     for (i = 0; i <= top_of_zone_table; i++)
  184.     {
  185.         fprintf(stderr, "Performing boot-time reset of %s (rooms %d-%d).\n",
  186.             zone_table[i].name,
  187.             (i ? (zone_table[i - 1].top + 1) : 0),
  188.             zone_table[i].top);
  189.         reset_zone(i);
  190.     }
  191.  
  192.     reset_q.head = reset_q.tail = 0;
  193.  
  194.     log("Boot db -- DONE.");
  195. }
  196.  
  197.  
  198. /* reset the time in the game from file */
  199. void reset_time(void)
  200. {
  201.     char buf[MAX_STRING_LENGTH];
  202.     struct time_info_data mud_time;
  203.  
  204.     long beginning_of_time = 650336715;
  205.  
  206.     struct time_info_data mud_time_passed(time_t t2, time_t t1);
  207.  
  208.     time_info = mud_time_passed(time(0), beginning_of_time);
  209.  
  210. /*
  211.     FILE *f1;
  212.     long current_time;
  213.     long last_time;
  214.     long diff_time;
  215.     long diff_hours;
  216.  
  217.     if (!(f1 = fopen(TIME_FILE, "r")))
  218.     {
  219.         perror("reset time");
  220.         exit(0);
  221.     }
  222.  
  223.     fscanf(f1, "#\n");
  224.  
  225.     fscanf(f1, "%D\n", &last_time);
  226.     fscanf(f1, "%d\n", &last_time_info.hours);
  227.     fscanf(f1, "%d\n", &last_time_info.day);
  228.     fscanf(f1, "%d\n", &last_time_info.month);
  229.     fscanf(f1, "%d\n", &last_time_info.year);
  230.  
  231.     fclose(f1);
  232.  
  233.     sprintf(buf,"   Last Gametime: %dH %dD %dM %dY.",
  234.             last_time_info.hours, last_time_info.day,
  235.             last_time_info.month, last_time_info.year);
  236.     log(buf);
  237.  
  238.     current_time = time(0);
  239.     diff_time = current_time - last_time;
  240.  
  241.     sprintf(buf,"   Time since last shutdown: %d.", diff_time);
  242.     log(buf);
  243.  
  244.     time_info.hours = last_time_info.hours;
  245.     time_info.day   = last_time_info.day;
  246.     time_info.month = last_time_info.month;
  247.     time_info.year  = last_time_info.year;
  248.  
  249.     diff_hours = diff_time/SECS_PER_MUD_HOUR;
  250.     diff_time = diff_time % SEC_PR_HOUR;
  251.     
  252.     sprintf(buf,"   Real time lack : %d sec.", diff_time);
  253.     log(buf);
  254.  
  255.     for(;diff_hours > 0; diff_hours--) 
  256.         weather_and_time(0);
  257.  
  258. */
  259.  
  260.     switch(time_info.hours){
  261.         case 0 :
  262.         case 1 :
  263.         case 2 :
  264.         case 3 :
  265.         case 4 : 
  266.         {
  267.             weather_info.sunlight = SUN_DARK;
  268.             break;
  269.         }
  270.         case 5 :
  271.         {
  272.             weather_info.sunlight = SUN_RISE;
  273.             break;
  274.         }
  275.         case 6 :
  276.         case 7 :
  277.         case 8 :
  278.         case 9 :
  279.         case 10 :
  280.         case 11 :
  281.         case 12 :
  282.         case 13 :
  283.         case 14 :
  284.         case 15 :
  285.         case 16 :
  286.         case 17 :
  287.         case 18 :
  288.         case 19 :
  289.         case 20 :
  290.         {
  291.             weather_info.sunlight = SUN_LIGHT;
  292.             break;
  293.         }
  294.         case 21 :
  295.         {
  296.             weather_info.sunlight = SUN_SET;
  297.             break;
  298.         }
  299.         case 22 :
  300.         case 23 :
  301.         default :
  302.         {
  303.             weather_info.sunlight = SUN_DARK;
  304.             break;
  305.         }
  306.     }
  307.  
  308.     sprintf(buf,"   Current Gametime: %dH %dD %dM %dY.",
  309.             time_info.hours, time_info.day,
  310.             time_info.month, time_info.year);
  311.     log(buf);
  312.  
  313.     weather_info.pressure = 960;
  314.     if ((time_info.month>=7)&&(time_info.month<=12))
  315.         weather_info.pressure += dice(1,50);
  316.     else
  317.         weather_info.pressure += dice(1,80);
  318.  
  319.     weather_info.change = 0;
  320.  
  321.     if (weather_info.pressure<=980)
  322.         weather_info.sky = SKY_LIGHTNING;
  323.     else if (weather_info.pressure<=1000)
  324.         weather_info.sky = SKY_RAINING;
  325.     else if (weather_info.pressure<=1020)
  326.         weather_info.sky = SKY_CLOUDY;
  327.     else weather_info.sky = SKY_CLOUDLESS;
  328. }
  329.  
  330.  
  331.  
  332. /* update the time file */
  333. void update_time(void)
  334. {
  335.     FILE *f1;
  336.     extern struct time_info_data time_info;
  337.     long current_time;
  338.  
  339.     return;
  340.  
  341.  
  342.     if (!(f1 = fopen(TIME_FILE, "w")))
  343.     {
  344.         perror("update time");
  345.         exit(0);
  346.     }
  347.  
  348.     current_time = time(0);
  349.     log("Time update.");
  350.  
  351.     fprintf(f1, "#\n");
  352.  
  353.     fprintf(f1, "%d\n", current_time);
  354.     fprintf(f1, "%d\n", time_info.hours);
  355.     fprintf(f1, "%d\n", time_info.day);
  356.     fprintf(f1, "%d\n", time_info.month);
  357.     fprintf(f1, "%d\n", time_info.year);
  358.  
  359.     fclose(f1);
  360. }
  361.  
  362.  
  363.  
  364. /* generate index table for the player file */
  365. void build_player_index(void)
  366. {
  367.     int nr = -1, i;
  368.     struct char_file_u dummy;
  369.     FILE *fl;
  370.  
  371.     if (!(fl = fopen(PLAYER_FILE, "rb+")))
  372.     {
  373.         perror("build player index");
  374.         exit(0);
  375.     }
  376.  
  377.     for (; !feof(fl);)
  378.     {
  379.         fread(&dummy, sizeof(struct char_file_u), 1, fl);
  380.         if (!feof(fl))   /* new record */
  381.         {
  382.             /* Create new entry in the list */
  383.             if (nr == -1) {
  384.                 CREATE(player_table, 
  385.                        struct player_index_element, 1);
  386.                 nr = 0;
  387.             }    else {
  388.                 if (!(player_table = (struct player_index_element *)
  389.                     realloc(player_table, (++nr + 1) *
  390.                     sizeof(struct player_index_element))))
  391.                 {
  392.                     perror("generate index");
  393.                     exit(0);
  394.                 }
  395.             }
  396.         
  397.             player_table[nr].nr = nr;
  398.  
  399.             CREATE(player_table[nr].name, char,
  400.                strlen(dummy.name) + 1);
  401.             for (i = 0; *(player_table[nr].name + i) = 
  402.                LOWER(*(dummy.name + i)); i++);
  403.         }
  404.     }
  405.  
  406.     fclose(fl);
  407.  
  408.     top_of_p_table = nr;
  409.  
  410.     top_of_p_file = top_of_p_table;
  411. }
  412.     
  413.  
  414.  
  415.  
  416.  
  417.  
  418. /* generate index table for object or monster file */
  419. struct index_data *generate_indices(FILE *fl, int *top)
  420. {
  421.     int i = 0;
  422.     struct index_data *index;
  423.     long pos;
  424.     char buf[82];
  425.  
  426.     rewind(fl);
  427.  
  428.     for (;;)
  429.     {
  430.         if (fgets(buf, 81, fl))
  431.         {
  432.             if (*buf == '#')
  433.             {
  434.                 /* allocate new cell */
  435.                 
  436.                 if (!i)                         /* first cell */
  437.                     CREATE(index, struct index_data, 1);
  438.                 else
  439.                     if (!(index = 
  440.                         (struct index_data*) realloc(index, 
  441.                         (i + 1) * sizeof(struct index_data))))
  442.                     {
  443.                         perror("load indices");
  444.                         exit(0);
  445.                      }
  446.                 sscanf(buf, "#%d", &index[i].virtual);
  447.                 index[i].pos = ftell(fl);
  448.                 index[i].number = 0;
  449.                 index[i].func = 0;
  450.                 i++;
  451.             }
  452.             else 
  453.                 if (*buf == '$')    /* EOF */
  454.                     break;
  455.         }
  456.         else
  457.         {
  458.             perror("generate indices");
  459.             exit(0);
  460.         }
  461.     }
  462.     *top = i - 2;
  463.     return(index);
  464. }
  465.  
  466.  
  467.  
  468.  
  469. /* load the rooms */
  470. void boot_world(void)
  471. {
  472.     FILE *fl;
  473.     int room_nr = 0, zone = 0, dir_nr, virtual_nr, flag, tmp;
  474.     char *temp, chk[50];
  475.     struct extra_descr_data *new_descr;
  476.  
  477.     world = 0;
  478.     character_list = 0;
  479.     object_list = 0;
  480.     
  481.     if (!(fl = fopen(WORLD_FILE, "r")))
  482.     {
  483.         perror("fopen");
  484.         log("boot_world: could not open world file.");
  485.         exit(0);
  486.     }
  487.  
  488.     do
  489.     {
  490.         fscanf(fl, " #%d\n", &virtual_nr);
  491.  
  492.         temp = fread_string(fl);
  493.         if (flag = (*temp != '$'))    /* a new record to be read */
  494.         {
  495.             allocate_room(room_nr);
  496.             world[room_nr].number = virtual_nr;
  497.             world[room_nr].name = temp;
  498.             world[room_nr].description = fread_string(fl);
  499.  
  500.             if (top_of_zone_table >= 0)
  501.             {
  502.                 fscanf(fl, " %*d ");
  503.  
  504.                 /* OBS: Assumes ordering of input rooms */
  505.  
  506.                 if (world[room_nr].number <= (zone ? zone_table[zone-1].top : -1))
  507.                 {
  508.                     fprintf(stderr, "Room nr %d is below zone %d.\n",
  509.                         room_nr, zone);
  510.                     exit(0);
  511.                 }
  512.                 while (world[room_nr].number > zone_table[zone].top)
  513.                     if (++zone > top_of_zone_table)
  514.                     {
  515.                         fprintf(stderr, "Room %d is outside of any zone.\n",
  516.                             virtual_nr);
  517.                         exit(0);
  518.                     }
  519.                 world[room_nr].zone = zone;
  520.             }
  521.             fscanf(fl, " %d ", &tmp);
  522.             world[room_nr].room_flags = tmp;
  523.             fscanf(fl, " %d ", &tmp);
  524.             world[room_nr].sector_type = tmp;
  525.  
  526.             world[room_nr].funct = 0;
  527.             world[room_nr].contents = 0;
  528.             world[room_nr].people = 0;
  529.             world[room_nr].light = 0; /* Zero light sources */
  530.  
  531.             for (tmp = 0; tmp <= 5; tmp++)
  532.                 world[room_nr].dir_option[tmp] = 0;
  533.  
  534.             world[room_nr].ex_description = 0;
  535.  
  536.             for (;;)
  537.             {
  538.                 fscanf(fl, " %s \n", chk);
  539.  
  540.                 if (*chk == 'D')  /* direction field */
  541.                     setup_dir(fl, room_nr, atoi(chk + 1));
  542.                 else if (*chk == 'E')  /* extra description field */
  543.                 {
  544.                     CREATE(new_descr, struct extra_descr_data, 1);
  545.                     new_descr->keyword = fread_string(fl);
  546.                     new_descr->description = fread_string(fl);
  547.                     new_descr->next = world[room_nr].ex_description;
  548.                     world[room_nr].ex_description = new_descr;
  549.                 }
  550.                 else if (*chk == 'S')    /* end of current room */
  551.                     break;
  552.             }
  553.                         
  554.             room_nr++;
  555.           }
  556.     }
  557.     while (flag);
  558.  
  559.     free(temp);    /* cleanup the area containing the terminal $  */
  560.  
  561.     fclose(fl);
  562.     top_of_world = --room_nr;
  563. }
  564.  
  565.  
  566.  
  567.  
  568.  
  569. void allocate_room(int new_top)
  570. {
  571.     struct room_data *new_world;
  572.  
  573.     if (new_top)
  574.     { 
  575.         if (!(new_world = (struct room_data *) 
  576.             realloc(world, (new_top + 1) * sizeof(struct room_data))))
  577.         {
  578.             perror("alloc_room");
  579.             exit(0);
  580.         } 
  581.     }
  582.     else
  583.         CREATE(new_world, struct room_data, 1);
  584.  
  585.     world = new_world;
  586. }
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593. /* read direction data */
  594. void setup_dir(FILE *fl, int room, int dir)
  595. {
  596.     int tmp;
  597.  
  598.     CREATE(world[room].dir_option[dir], 
  599.         struct room_direction_data, 1);
  600.  
  601.     world[room].dir_option[dir]->general_description =
  602.         fread_string(fl);
  603.     world[room].dir_option[dir]->keyword = fread_string(fl);
  604.  
  605.     fscanf(fl, " %d ", &tmp);
  606.     if (tmp == 1)
  607.         world[room].dir_option[dir]->exit_info = EX_ISDOOR;
  608.     else if (tmp == 2)
  609.         world[room].dir_option[dir]->exit_info = EX_ISDOOR | EX_PICKPROOF;
  610.     else
  611.         world[room].dir_option[dir]->exit_info = 0;
  612.  
  613.     fscanf(fl, " %d ", &tmp);
  614.     world[room].dir_option[dir]->key = tmp;
  615.  
  616.     fscanf(fl, " %d ", &tmp);
  617.     world[room].dir_option[dir]->to_room = tmp;
  618. }
  619.  
  620.  
  621.  
  622.  
  623. void renum_world(void)
  624. {
  625.     register int room, door;
  626.  
  627.     for (room = 0; room <= top_of_world; room++)
  628.         for (door = 0; door <= 5; door++)
  629.             if (world[room].dir_option[door])
  630.          if (world[room].dir_option[door]->to_room != NOWHERE)
  631.              world[room].dir_option[door]->to_room =
  632.                  real_room(world[room].dir_option[door]->to_room);
  633. }
  634.  
  635.  
  636. #ifdef NEW_ZONE_SYSTEM
  637.  
  638. void renum_zone_table(void)
  639. {
  640.     int zone, comm;
  641.  
  642.     for (zone = 0; zone <= top_of_zone_table; zone++)
  643.         for (comm = 0; zone_table[zone].cmd[comm].command != 'S'; comm++)
  644.             switch(zone_table[zone].cmd[comm].command)
  645.             {
  646.                 case 'M':
  647.                     zone_table[zone].cmd[comm].arg1 =
  648.                         real_mobile(zone_table[zone].cmd[comm].arg1);
  649.                     zone_table[zone].cmd[comm].arg3 = 
  650.                         real_room(zone_table[zone].cmd[comm].arg3);
  651.                 break;
  652.                 case 'O':
  653.                     zone_table[zone].cmd[comm].arg1 = 
  654.                         real_object(zone_table[zone].cmd[comm].arg1);
  655.                     if (zone_table[zone].cmd[comm].arg3 != NOWHERE)
  656.                         zone_table[zone].cmd[comm].arg3 =
  657.                         real_room(zone_table[zone].cmd[comm].arg3);
  658.                 break;
  659.                 case 'G':
  660.                     zone_table[zone].cmd[comm].arg1 =
  661.                         real_object(zone_table[zone].cmd[comm].arg1);
  662.                 break;
  663.                 case 'E':
  664.                     zone_table[zone].cmd[comm].arg1 =
  665.                         real_object(zone_table[zone].cmd[comm].arg1);
  666.                 break;
  667.                 case 'P':
  668.                     zone_table[zone].cmd[comm].arg1 =
  669.                         real_object(zone_table[zone].cmd[comm].arg1);
  670.                     zone_table[zone].cmd[comm].arg3 =
  671.                         real_object(zone_table[zone].cmd[comm].arg3);
  672.                 break;                    
  673.                 case 'D':
  674.                     zone_table[zone].cmd[comm].arg1 =
  675.                         real_room(zone_table[zone].cmd[comm].arg1);
  676.                 break;
  677.             }
  678. }
  679.  
  680.  
  681. #else
  682.  
  683.  
  684. void renum_zone_table(void)
  685. {
  686.     int zone, comm;
  687.  
  688.     for (zone = 0; zone <= top_of_zone_table; zone++)
  689.         for (comm = 0; zone_table[zone].cmd[comm].command != 'S'; comm++)
  690.             switch(zone_table[zone].cmd[comm].command)
  691.             {
  692.                 case 'M':
  693.                     zone_table[zone].cmd[comm].arg1 =
  694.                         real_mobile(zone_table[zone].cmd[comm].arg1);
  695.                     zone_table[zone].cmd[comm].arg3 = 
  696.                         real_room(zone_table[zone].cmd[comm].arg3);
  697.                 break;
  698.                 case 'O':
  699.                     zone_table[zone].cmd[comm].arg1 = 
  700.                         real_object(zone_table[zone].cmd[comm].arg1);
  701.                     if (zone_table[zone].cmd[comm].arg3 != NOWHERE)
  702.                         zone_table[zone].cmd[comm].arg3 =
  703.                         real_room(zone_table[zone].cmd[comm].arg3);
  704.                 break;
  705.                 case 'G':
  706.                     zone_table[zone].cmd[comm].arg1 =
  707.                         real_object(zone_table[zone].cmd[comm].arg1);
  708.                     zone_table[zone].cmd[comm].arg2 =
  709.                         real_mobile(zone_table[zone].cmd[comm].arg2);
  710.                 break;
  711.                 case 'E':
  712.                     zone_table[zone].cmd[comm].arg1 =
  713.                         real_object(zone_table[zone].cmd[comm].arg1);
  714.                     zone_table[zone].cmd[comm].arg2 =
  715.                         real_mobile(zone_table[zone].cmd[comm].arg2);
  716.                 break;
  717.                 case 'P':
  718.                     zone_table[zone].cmd[comm].arg1 =
  719.                         real_object(zone_table[zone].cmd[comm].arg1);
  720.                     zone_table[zone].cmd[comm].arg2 =
  721.                         real_object(zone_table[zone].cmd[comm].arg2);
  722.                 break;                    
  723.                 case 'D':
  724.                     zone_table[zone].cmd[comm].arg1 =
  725.                         real_room(zone_table[zone].cmd[comm].arg1);
  726.                 break;
  727.             }
  728. }
  729.  
  730.  
  731. #endif
  732.  
  733.  
  734. #ifdef NEW_ZONE_SYSTEM
  735.  
  736. /* load the zone table and command tables */
  737. void boot_zones(void)
  738. {
  739.     FILE *fl;
  740.     int zon = 0, cmd_no = 0, ch, expand, tmp;
  741.     char *check, buf[81];
  742.  
  743.     if (!(fl = fopen(ZONE_FILE, "r")))
  744.     {
  745.         perror("boot_zones");
  746.         exit(0);
  747.     }
  748.  
  749.     for (;;)
  750.     {
  751.         fscanf(fl, " #%*d\n");
  752.         check = fread_string(fl);
  753.  
  754.         if (*check == '$')
  755.             break;        /* end of file */
  756.  
  757.         /* alloc a new zone */
  758.  
  759.         if (!zon)
  760.             CREATE(zone_table, struct zone_data, 1);
  761.         else
  762.             if (!(zone_table = (struct zone_data *) realloc(zone_table,
  763.                 (zon + 1) * sizeof(struct zone_data))))
  764.                 {
  765.                     perror("boot_zones realloc");
  766.                     exit(0);
  767.                 }
  768.  
  769.         zone_table[zon].name = check;
  770.         fscanf(fl, " %d ", &zone_table[zon].top);
  771.         fscanf(fl, " %d ", &zone_table[zon].lifespan);
  772.         fscanf(fl, " %d ", &zone_table[zon].reset_mode);
  773.  
  774.         /* read the command table */
  775.  
  776.         cmd_no = 0;
  777.  
  778.         for (expand = 1;;)
  779.         {
  780.             if (expand)
  781.                 if (!cmd_no)
  782.                     CREATE(zone_table[zon].cmd, struct reset_com, 1);
  783.                 else
  784.                     if (!(zone_table[zon].cmd =
  785.                       (struct reset_com *) realloc(zone_table[zon].cmd, 
  786.                       (cmd_no + 1) * sizeof(struct reset_com))))
  787.                     {
  788.                         perror("reset command load");
  789.                         exit(0);
  790.                     }
  791.  
  792.             expand = 1;
  793.  
  794.             fscanf(fl, " "); /* skip blanks */
  795.             fscanf(fl, "%c", 
  796.                 &zone_table[zon].cmd[cmd_no].command);
  797.             
  798.             if (zone_table[zon].cmd[cmd_no].command == 'S')
  799.                 break;
  800.  
  801.             if (zone_table[zon].cmd[cmd_no].command == '*')
  802.             {
  803.                 expand = 0;
  804.                 fgets(buf, 80, fl); /* skip command */
  805.                 continue;
  806.             }
  807.  
  808.             fscanf(fl, " %d %d %d", 
  809.                 &tmp,
  810.                 &zone_table[zon].cmd[cmd_no].arg1,
  811.                 &zone_table[zon].cmd[cmd_no].arg2);
  812.  
  813.             zone_table[zon].cmd[cmd_no].if_flag = tmp;
  814.  
  815.             if (zone_table[zon].cmd[cmd_no].command == 'M' ||
  816.                 zone_table[zon].cmd[cmd_no].command == 'O' ||
  817.                 zone_table[zon].cmd[cmd_no].command == 'E' ||
  818.                 zone_table[zon].cmd[cmd_no].command == 'P' ||
  819.                 zone_table[zon].cmd[cmd_no].command == 'D')
  820.                 fscanf(fl, " %d", &zone_table[zon].cmd[cmd_no].arg3);
  821.  
  822.             fgets(buf, 80, fl);    /* read comment */
  823.  
  824.             cmd_no++;
  825.         }
  826.         zon++;
  827.     }
  828.     top_of_zone_table = --zon;
  829.     free(check);
  830.     fclose(fl);
  831. }
  832.  
  833.  
  834. #else
  835.  
  836.  
  837. /* load the zone table and command tables */
  838. void boot_zones(void)
  839. {
  840.     FILE *fl;
  841.     int zon = 0, cmd_no = 0, ch, expand;
  842.     char *check, buf[81];
  843.  
  844.     if (!(fl = fopen(ZONE_FILE, "r")))
  845.     {
  846.         perror("boot_zones");
  847.         exit(0);
  848.     }
  849.  
  850.     for (;;)
  851.     {
  852.         fscanf(fl, " #%*d\n");
  853.         check = fread_string(fl);
  854.  
  855.         if (*check == '$')
  856.             break;        /* end of file */
  857.  
  858.         /* alloc a new zone */
  859.  
  860.         if (!zon)
  861.             CREATE(zone_table, struct zone_data, 1);
  862.         else
  863.             if (!(zone_table = (struct zone_data *) realloc(zone_table,
  864.                 (zon + 1) * sizeof(struct zone_data))))
  865.                 {
  866.                     perror("boot_zones realloc");
  867.                     exit(0);
  868.                 }
  869.  
  870.         zone_table[zon].name = check;
  871.         fscanf(fl, " %d ", &zone_table[zon].top);
  872.         fscanf(fl, " %d ", &zone_table[zon].lifespan);
  873.         fscanf(fl, " %d ", &zone_table[zon].reset_mode);
  874.  
  875.         /* read the command table */
  876.  
  877.         cmd_no = 0;
  878.  
  879.         for (expand = 1;;)
  880.         {
  881.             if (expand)
  882.                 if (!cmd_no)
  883.                     CREATE(zone_table[zon].cmd, struct reset_com, 1);
  884.                 else
  885.                     if (!(zone_table[zon].cmd =
  886.                       (struct reset_com *) realloc(zone_table[zon].cmd, 
  887.                       (cmd_no + 1) * sizeof(struct reset_com))))
  888.                     {
  889.                         perror("reset command load");
  890.                         exit(0);
  891.                     }
  892.  
  893.             expand = 1;
  894.  
  895.             fscanf(fl, " "); /* skip blanks */
  896.             fscanf(fl, "%c", 
  897.                 &zone_table[zon].cmd[cmd_no].command);
  898.             
  899.             if (zone_table[zon].cmd[cmd_no].command == 'S')
  900.                 break;
  901.  
  902.             if (zone_table[zon].cmd[cmd_no].command == '*')
  903.             {
  904.                 expand = 0;
  905.                 fgets(buf, 80, fl); /* skip command */
  906.                 continue;
  907.             }
  908.  
  909.             fscanf(fl, " %d %d %d", 
  910.                 &zone_table[zon].cmd[cmd_no].if_flag,
  911.                 &zone_table[zon].cmd[cmd_no].arg1,
  912.                 &zone_table[zon].cmd[cmd_no].arg2);
  913.  
  914.             if (zone_table[zon].cmd[cmd_no].command == 'M' ||
  915.                 zone_table[zon].cmd[cmd_no].command == 'O' ||
  916.                 zone_table[zon].cmd[cmd_no].command == 'E' ||
  917.                 zone_table[zon].cmd[cmd_no].command == 'D')
  918.                 fscanf(fl, " %d", &zone_table[zon].cmd[cmd_no].arg3);
  919.  
  920.             fgets(buf, 80, fl);    /* read comment */
  921.  
  922.             cmd_no++;
  923.         }
  924.         zon++;
  925.     }
  926.     top_of_zone_table = --zon;
  927.     free(check);
  928.     fclose(fl);
  929. }
  930.  
  931.  
  932. #endif
  933.  
  934. /*************************************************************************
  935. *  procedures for resetting, both play-time and boot-time          *
  936. *********************************************************************** */
  937.  
  938.  
  939. /* read a mobile from MOB_FILE */
  940. struct char_data *read_mobile(int nr, int type)
  941. {
  942.     int i, skill_nr;
  943.     long tmp, tmp2, tmp3;
  944.     struct char_data *mob;
  945.     char chk[10], buf[100];
  946.     char letter;
  947.  
  948.     i = nr;
  949.     if (type == VIRTUAL)
  950.         if ((nr = real_mobile(nr)) < 0)
  951.     {
  952.         sprintf(buf, "Mobile (V) %d does not exist in database.", i);
  953.         return(0);
  954.     }
  955.  
  956.     fseek(mob_f, mob_index[nr].pos, 0);
  957.  
  958.     CREATE(mob, struct char_data, 1);
  959.     clear_char(mob);
  960.  
  961.     /***** String data *** */
  962.         
  963.     mob->player.name = fread_string(mob_f);
  964.     mob->player.short_descr = fread_string(mob_f);
  965.     mob->player.long_descr = fread_string(mob_f);
  966.     mob->player.description = fread_string(mob_f);
  967.     mob->player.title = 0;
  968.  
  969.     /* *** Numeric data *** */
  970.  
  971.     fscanf(mob_f, "%d ", &tmp);
  972.     mob->specials.act = tmp;
  973.     SET_BIT(mob->specials.act, ACT_ISNPC);
  974.  
  975.     fscanf(mob_f, " %d ", &tmp);
  976.     mob->specials.affected_by = tmp;
  977.  
  978.     fscanf(mob_f, " %d ", &tmp);
  979.     mob->specials.alignment = tmp;
  980.  
  981.     fscanf(mob_f, " %c \n", &letter);
  982.  
  983.     if (letter == 'S') {
  984.         /* The new easy monsters */
  985.         mob->abilities.str   = 11;
  986.         mob->abilities.intel = 11; 
  987.         mob->abilities.wis   = 11;
  988.         mob->abilities.dex   = 11;
  989.         mob->abilities.con   = 11;
  990.  
  991.         fscanf(mob_f, " %D ", &tmp);
  992.         GET_LEVEL(mob) = tmp;
  993.         
  994.         fscanf(mob_f, " %D ", &tmp);
  995.         mob->points.hitroll = 20-tmp;
  996.         
  997.         fscanf(mob_f, " %D ", &tmp);
  998.         mob->points.armor = 10*tmp;
  999.  
  1000.         fscanf(mob_f, " %Dd%D+%D ", &tmp, &tmp2, &tmp3);
  1001.         mob->points.max_hit = dice(tmp, tmp2)+tmp3;
  1002.         mob->points.hit = mob->points.max_hit;
  1003.  
  1004.         fscanf(mob_f, " %Dd%D+%D \n", &tmp, &tmp2, &tmp3);
  1005.         mob->points.damroll = tmp3;
  1006.         mob->specials.damnodice = tmp;
  1007.         mob->specials.damsizedice = tmp2;
  1008.  
  1009.         mob->points.mana = 10;
  1010.         mob->points.max_mana = 10;
  1011.  
  1012.         mob->points.move = 50;
  1013.         mob->points.max_move = 50;
  1014.  
  1015.         fscanf(mob_f, " %D ", &tmp);
  1016.         mob->points.gold = tmp;
  1017.  
  1018.         fscanf(mob_f, " %D \n", &tmp);
  1019.         GET_EXP(mob) = tmp;
  1020.  
  1021.         fscanf(mob_f, " %D ", &tmp);
  1022.         mob->specials.position = tmp;
  1023.  
  1024.         fscanf(mob_f, " %D ", &tmp);
  1025.         mob->specials.default_pos = tmp;
  1026.  
  1027.         fscanf(mob_f, " %D \n", &tmp);
  1028.         mob->player.sex = tmp;
  1029.  
  1030.         mob->player.class = 0;
  1031.  
  1032.         mob->player.time.birth = time(0);
  1033.         mob->player.time.played    = 0;
  1034.         mob->player.time.logon  = time(0);
  1035.         mob->player.weight = 200;
  1036.         mob->player.height = 198;
  1037.  
  1038.         for (i = 0; i < 3; i++)
  1039.             GET_COND(mob, i) = -1;
  1040.  
  1041.         for (i = 0; i < 5; i++)
  1042.             mob->specials.apply_saving_throw[i] = MAX(20-GET_LEVEL(mob), 2);
  1043.  
  1044.     } else {  /* The old monsters are down below here */
  1045.  
  1046.         fscanf(mob_f, " %D ", &tmp);
  1047.         mob->abilities.str = tmp;
  1048.  
  1049.         fscanf(mob_f, " %D ", &tmp);
  1050.         mob->abilities.intel = tmp; 
  1051.  
  1052.         fscanf(mob_f, " %D ", &tmp);
  1053.         mob->abilities.wis = tmp;
  1054.  
  1055.         fscanf(mob_f, " %D ", &tmp);
  1056.         mob->abilities.dex = tmp;
  1057.  
  1058.         fscanf(mob_f, " %D \n", &tmp);
  1059.         mob->abilities.con = tmp;
  1060.  
  1061.         fscanf(mob_f, " %D ", &tmp);
  1062.         fscanf(mob_f, " %D ", &tmp2);
  1063.  
  1064.         mob->points.max_hit = number(tmp, tmp2);
  1065.         mob->points.hit = mob->points.max_hit;
  1066.  
  1067.         fscanf(mob_f, " %D ", &tmp);
  1068.         mob->points.armor = 10*tmp;
  1069.  
  1070.         fscanf(mob_f, " %D ", &tmp);
  1071.         mob->points.mana = tmp;
  1072.         mob->points.max_mana = tmp;
  1073.  
  1074.         fscanf(mob_f, " %D ", &tmp);
  1075.         mob->points.move = tmp;        
  1076.         mob->points.max_move = tmp;
  1077.  
  1078.         fscanf(mob_f, " %D ", &tmp);
  1079.         mob->points.gold = tmp;
  1080.  
  1081.         fscanf(mob_f, " %D \n", &tmp);
  1082.         GET_EXP(mob) = tmp;
  1083.  
  1084.         fscanf(mob_f, " %D ", &tmp);
  1085.         mob->specials.position = tmp;
  1086.  
  1087.         fscanf(mob_f, " %D ", &tmp);
  1088.         mob->specials.default_pos = tmp;
  1089.  
  1090.         fscanf(mob_f, " %D ", &tmp);
  1091.         mob->player.sex = tmp;
  1092.  
  1093.         fscanf(mob_f, " %D ", &tmp);
  1094.         mob->player.class = tmp;
  1095.  
  1096.         fscanf(mob_f, " %D ", &tmp);
  1097.         GET_LEVEL(mob) = tmp;
  1098.  
  1099.         fscanf(mob_f, " %D ", &tmp);
  1100.         mob->player.time.birth = time(0);
  1101.         mob->player.time.played    = 0;
  1102.         mob->player.time.logon  = time(0);
  1103.  
  1104.         fscanf(mob_f, " %D ", &tmp);
  1105.         mob->player.weight = tmp;
  1106.  
  1107.         fscanf(mob_f, " %D \n", &tmp);
  1108.         mob->player.height = tmp;
  1109.  
  1110.         for (i = 0; i < 3; i++)
  1111.         {
  1112.             fscanf(mob_f, " %D ", &tmp);
  1113.             GET_COND(mob, i) = tmp;
  1114.         }
  1115.         fscanf(mob_f, " \n ");
  1116.  
  1117.         for (i = 0; i < 5; i++)
  1118.         {
  1119.             fscanf(mob_f, " %D ", &tmp);
  1120.             mob->specials.apply_saving_throw[i] = tmp;
  1121.         }
  1122.  
  1123.         fscanf(mob_f, " \n ");
  1124.  
  1125.         /* Set the damage as some standard 1d4 */
  1126.         mob->points.damroll = 0;
  1127.         mob->specials.damnodice = 1;
  1128.         mob->specials.damsizedice = 6;
  1129.  
  1130.         /* Calculate THAC0 as a formular of Level */
  1131.         mob->points.hitroll = MAX(1, GET_LEVEL(mob)-3);
  1132.     }
  1133.  
  1134.     mob->tmpabilities = mob->abilities;
  1135.  
  1136.     for (i = 0; i < MAX_WEAR; i++) /* Initialisering Ok */
  1137.         mob->equipment[i] = 0;
  1138.  
  1139.     mob->nr = nr;
  1140.  
  1141.     mob->desc = 0;
  1142.  
  1143.  
  1144.     /* insert in list */
  1145.  
  1146.     mob->next = character_list;
  1147.     character_list = mob;
  1148.  
  1149.     mob_index[nr].number++;
  1150.  
  1151.     return(mob);
  1152. }
  1153.  
  1154.  
  1155. /* read an object from OBJ_FILE */
  1156. struct obj_data *read_object(int nr, int type)
  1157. {
  1158.     struct obj_data *obj;
  1159.     int tmp, i;
  1160.     char chk[50], buf[100];
  1161.     struct extra_descr_data *new_descr;
  1162.  
  1163.     i = nr;
  1164.     if (type == VIRTUAL)
  1165.         if ((nr = real_object(nr)) < 0)
  1166.     {
  1167.         sprintf(buf, "Object (V) %d does not exist in database.", i);
  1168.         return(0);
  1169.     }
  1170.  
  1171.     fseek(obj_f, obj_index[nr].pos, 0);
  1172.  
  1173.     CREATE(obj, struct obj_data, 1);
  1174.  
  1175.     clear_object(obj);
  1176.  
  1177.     /* *** string data *** */
  1178.  
  1179.     obj->name = fread_string(obj_f);
  1180.     obj->short_description = fread_string(obj_f);
  1181.     obj->description = fread_string(obj_f);
  1182.     obj->action_description = fread_string(obj_f);
  1183.  
  1184.     /* *** numeric data *** */
  1185.  
  1186.     fscanf(obj_f, " %d ", &tmp);
  1187.     obj->obj_flags.type_flag = tmp;
  1188.     fscanf(obj_f, " %d ", &tmp);
  1189.     obj->obj_flags.extra_flags = tmp;
  1190.     fscanf(obj_f, " %d ", &tmp);
  1191.     obj->obj_flags.wear_flags = tmp;
  1192.     fscanf(obj_f, " %d ", &tmp);
  1193.     obj->obj_flags.value[0] = tmp;
  1194.     fscanf(obj_f, " %d ", &tmp);
  1195.     obj->obj_flags.value[1] = tmp;
  1196.     fscanf(obj_f, " %d ", &tmp);
  1197.     obj->obj_flags.value[2] = tmp;
  1198.     fscanf(obj_f, " %d ", &tmp);
  1199.     obj->obj_flags.value[3] = tmp;
  1200.     fscanf(obj_f, " %d ", &tmp);
  1201.     obj->obj_flags.weight = tmp;
  1202.     fscanf(obj_f, " %d \n", &tmp);
  1203.     obj->obj_flags.cost = tmp;
  1204.     fscanf(obj_f, " %d \n", &tmp);
  1205.     obj->obj_flags.cost_per_day = tmp;
  1206.  
  1207.     /* *** extra descriptions *** */
  1208.  
  1209.     obj->ex_description = 0;
  1210.  
  1211.     while (fscanf(obj_f, " %s \n", chk), *chk == 'E')
  1212.     {
  1213.         CREATE(new_descr, struct extra_descr_data, 1);
  1214.  
  1215.         new_descr->keyword = fread_string(obj_f);
  1216.         new_descr->description = fread_string(obj_f);
  1217.  
  1218.         new_descr->next = obj->ex_description;
  1219.         obj->ex_description = new_descr;
  1220.     }
  1221.  
  1222.     for( i = 0 ; (i < MAX_OBJ_AFFECT) && (*chk == 'A') ; i++)
  1223.     {
  1224.         fscanf(obj_f, " %d ", &tmp);
  1225.         obj->affected[i].location = tmp;
  1226.         fscanf(obj_f, " %d \n", &tmp);
  1227.         obj->affected[i].modifier = tmp;
  1228.         fscanf(obj_f, " %s \n", chk);
  1229.     }
  1230.  
  1231.     for (;(i < MAX_OBJ_AFFECT);i++)
  1232.     {
  1233.         obj->affected[i].location = APPLY_NONE;
  1234.         obj->affected[i].modifier = 0;
  1235.     }
  1236.  
  1237.     obj->in_room = NOWHERE;
  1238.     obj->next_content = 0;
  1239.     obj->carried_by = 0;
  1240.     obj->in_obj = 0;
  1241.     obj->contains = 0;
  1242.     obj->item_number = nr;    
  1243.  
  1244.     obj->next = object_list;
  1245.     object_list = obj;
  1246.  
  1247.     obj_index[nr].number++;
  1248.  
  1249.  
  1250.     return (obj);  
  1251. }
  1252.  
  1253.  
  1254.  
  1255.  
  1256. #define ZO_DEAD  999
  1257.  
  1258. /* update zone ages, queue for reset if necessary, and dequeue when possible */
  1259. void zone_update(void)
  1260. {
  1261.     int i;
  1262.     struct reset_q_element *update_u, *temp;
  1263.  
  1264.     /* enqueue zones */
  1265.  
  1266.     for (i = 0; i <= top_of_zone_table; i++)
  1267.     {
  1268.         if (zone_table[i].age < zone_table[i].lifespan &&
  1269.             zone_table[i].reset_mode)
  1270.             (zone_table[i].age)++;
  1271.         else
  1272.             if (zone_table[i].age < ZO_DEAD && zone_table[i].reset_mode)
  1273.             {
  1274.             /* enqueue zone */
  1275.  
  1276.             CREATE(update_u, struct reset_q_element, 1);
  1277.  
  1278.             update_u->zone_to_reset = i;
  1279.             update_u->next = 0;
  1280.  
  1281.             if (!reset_q.head)
  1282.                 reset_q.head = reset_q.tail = update_u;
  1283.             else
  1284.             {
  1285.                 reset_q.tail->next = update_u;
  1286.                 reset_q.tail = update_u;
  1287.             }
  1288.  
  1289.             zone_table[i].age = ZO_DEAD;
  1290.             }
  1291.     }
  1292.  
  1293.     /* dequeue zones (if possible) and reset */
  1294.  
  1295.     for (update_u = reset_q.head; update_u; update_u = update_u->next) 
  1296.         if (zone_table[update_u->zone_to_reset].reset_mode == 2 ||
  1297.             is_empty(update_u->zone_to_reset))
  1298.         {
  1299.         reset_zone(update_u->zone_to_reset);
  1300.  
  1301.         /* dequeue */
  1302.  
  1303.         if (update_u == reset_q.head)
  1304.             reset_q.head = reset_q.head->next;
  1305.         else
  1306.         {
  1307.             for (temp = reset_q.head; temp->next != update_u;
  1308.                 temp = temp->next);
  1309.  
  1310.             if (!update_u->next)
  1311.                 reset_q.tail = temp;
  1312.  
  1313.             temp->next = update_u->next;
  1314.  
  1315.  
  1316.         }
  1317.  
  1318.         free(update_u);
  1319.         break;
  1320.         } 
  1321. }
  1322.  
  1323.  
  1324.  
  1325.  
  1326. #ifdef NEW_ZONE_SYSTEM
  1327.  
  1328. #define ZCMD zone_table[zone].cmd[cmd_no]
  1329.  
  1330. /* execute the reset command table of a given zone */
  1331. void reset_zone(int zone)
  1332. {
  1333.     int cmd_no, last_cmd = 1;
  1334.     char buf[256];
  1335.     struct char_data *mob;
  1336.     struct obj_data *obj, *obj_to;
  1337.  
  1338.     for (cmd_no = 0;;cmd_no++)
  1339.     {
  1340.         if (ZCMD.command == 'S')
  1341.             break;
  1342.  
  1343.         if (last_cmd || !ZCMD.if_flag)
  1344.             switch(ZCMD.command)
  1345.         {
  1346.             case 'M': /* read a mobile */
  1347.                 if (mob_index[ZCMD.arg1].number < 
  1348.                     ZCMD.arg2)
  1349.                 {
  1350.                     mob = read_mobile(ZCMD.arg1, REAL);
  1351.                     char_to_room(mob, ZCMD.arg3);
  1352.                     last_cmd = 1;
  1353.                 }
  1354.                 else
  1355.                     last_cmd = 0;
  1356.             break;
  1357.  
  1358.             case 'O': /* read an object */
  1359.                 if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
  1360.                 if (ZCMD.arg3 >= 0)
  1361.                 {
  1362.                     if (!get_obj_in_list_num(ZCMD.arg1,world[ZCMD.arg3].contents))
  1363.                     {
  1364.                         obj = read_object(ZCMD.arg1, REAL);
  1365.                         obj_to_room(obj, ZCMD.arg3);
  1366.                         last_cmd = 1;
  1367.                     }
  1368.                     else
  1369.                         last_cmd = 0;
  1370.                 }
  1371.                 else
  1372.                 {
  1373.                     obj = read_object(ZCMD.arg1, REAL);
  1374.                     obj->in_room = NOWHERE;
  1375.                     last_cmd = 1;
  1376.                 }
  1377.                 else
  1378.                     last_cmd = 0;
  1379.             break;
  1380.  
  1381.             case 'P': /* object to object */
  1382.                 if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
  1383.                 {
  1384.                     obj = read_object(ZCMD.arg1, REAL);
  1385.                     obj_to = get_obj_num(ZCMD.arg3);
  1386.                     obj_to_obj(obj, obj_to);
  1387.                     last_cmd = 1;
  1388.                 }
  1389.                 else
  1390.                     last_cmd = 0;
  1391.             break;
  1392.  
  1393.             case 'G': /* obj_to_char */
  1394.                 if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
  1395.                 {        
  1396.                     obj = read_object(ZCMD.arg1, REAL);
  1397.                     obj_to_char(obj, mob);
  1398.                     last_cmd = 1;
  1399.                 }
  1400.                 else
  1401.                     last_cmd = 0;
  1402.             break;
  1403.  
  1404.             case 'E': /* object to equipment list */
  1405.                 if (obj_index[ZCMD.arg1].number < ZCMD.arg2)
  1406.                 {        
  1407.                     obj = read_object(ZCMD.arg1, REAL);
  1408.                     equip_char(mob, obj, ZCMD.arg3);
  1409.                     last_cmd = 1;
  1410.                 }
  1411.                 else
  1412.                     last_cmd = 0;
  1413.             break;
  1414.  
  1415.             case 'D': /* set state of door */
  1416.                 switch (ZCMD.arg3)
  1417.                 {
  1418.                     case 0:
  1419.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1420.                             EX_LOCKED);
  1421.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1422.                             EX_CLOSED);
  1423.                     break;
  1424.                     case 1:
  1425.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1426.                             EX_CLOSED);
  1427.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1428.                             EX_LOCKED);
  1429.                     break;
  1430.                     case 2:
  1431.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1432.                             EX_LOCKED);
  1433.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1434.                             EX_CLOSED);
  1435.                     break;
  1436.                 }
  1437.                 last_cmd = 1;
  1438.             break;
  1439.  
  1440.             default:
  1441.                 sprintf(buf, "Undefd cmd in reset table; zone %d cmd %d.\n\r",
  1442.                     zone, cmd_no);
  1443.                 log(buf);
  1444.                 exit(0);
  1445.             break;
  1446.         }
  1447.         else
  1448.             last_cmd = 0;
  1449.  
  1450.     }
  1451.  
  1452.     zone_table[zone].age = 0;
  1453. }
  1454.  
  1455. #undef ZCMD
  1456.  
  1457. #else
  1458.  
  1459.  
  1460. #define ZCMD zone_table[zone].cmd[cmd_no]
  1461.  
  1462. /* execute the reset command table of a given zone */
  1463. void reset_zone(int zone)
  1464. {
  1465.     int cmd_no, last_cmd = 1;
  1466.     char buf[256];
  1467.     struct char_data *mob;
  1468.     struct obj_data *obj, *obj_to;
  1469.  
  1470.     for (cmd_no = 0;;cmd_no++)
  1471.     {
  1472.         if (ZCMD.command == 'S')
  1473.             break;
  1474.  
  1475.         if (last_cmd || !ZCMD.if_flag)
  1476.             switch(ZCMD.command)
  1477.         {
  1478.             case 'M': /* read a mobile */
  1479.                 if (mob_index[ZCMD.arg1].number < 
  1480.                     ZCMD.arg2)
  1481.                 {
  1482.                     mob = read_mobile(ZCMD.arg1, REAL);
  1483.                     char_to_room(mob, ZCMD.arg3);
  1484.                     last_cmd = 1;
  1485.                 }
  1486.                 else
  1487.                     last_cmd = 0;
  1488.             break;
  1489.  
  1490.             case 'O': /* read an object */
  1491.                 if (obj_index[ZCMD.arg1].number <
  1492.                     ZCMD.arg2)
  1493.                 if (ZCMD.arg3 >= 0)
  1494.                 {
  1495.                     if (!get_obj_in_list_num(
  1496.                       ZCMD.arg1,world[ZCMD.arg3].contents))
  1497.                         {
  1498.                         obj = read_object(ZCMD.arg1, REAL);
  1499.                         obj_to_room(obj, ZCMD.arg3);
  1500.                         last_cmd = 1;
  1501.                         }
  1502.                     else
  1503.                         last_cmd = 0;
  1504.                 }
  1505.                 else
  1506.                 {
  1507.                     obj = read_object(ZCMD.arg1, REAL);
  1508.                     obj->in_room = NOWHERE;
  1509.                     last_cmd = 1;
  1510.                 }
  1511.                 else
  1512.                     last_cmd = 0;
  1513.             break;
  1514.  
  1515.             case 'P': /* object to object */
  1516.                 obj = get_obj_num(ZCMD.arg1);
  1517.                 obj_to = get_obj_num(ZCMD.arg2);
  1518.                 obj_to_obj(obj, obj_to);
  1519.                 last_cmd = 1;
  1520.             break;
  1521.  
  1522.             case 'G': /* obj_to_char */
  1523.                 obj = get_obj_num(ZCMD.arg1);
  1524.                 mob = get_char_num(ZCMD.arg2);
  1525.                 obj_to_char(obj, mob);
  1526.                 last_cmd = 1;
  1527.             break;
  1528.  
  1529.             case 'E': /* object to equipment list */
  1530.                 obj = get_obj_num(ZCMD.arg1);
  1531.                 mob = get_char_num(ZCMD.arg2);
  1532.                 equip_char(mob, obj, ZCMD.arg3);
  1533.                 last_cmd = 1;
  1534.             break;
  1535.  
  1536.             case 'D': /* set state of door */
  1537.                 switch (ZCMD.arg3)
  1538.                 {
  1539.                     case 0:
  1540.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1541.                             EX_LOCKED);
  1542.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1543.                             EX_CLOSED);
  1544.                     break;
  1545.                     case 1:
  1546.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1547.                             EX_CLOSED);
  1548.                         REMOVE_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1549.                             EX_LOCKED);
  1550.                     break;
  1551.                     case 2:
  1552.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1553.                             EX_LOCKED);
  1554.                         SET_BIT(world[ZCMD.arg1].dir_option[ZCMD.arg2]->exit_info,
  1555.                             EX_CLOSED);
  1556.                     break;
  1557.                 }
  1558.             break;
  1559.  
  1560.             default:
  1561.                 sprintf(buf, "Undefd cmd in reset table; zone %d cmd %d.\n\r",
  1562.                     zone, cmd_no);
  1563.                 log(buf);
  1564.                 exit(0);
  1565.             break;
  1566.         }
  1567.         else
  1568.             last_cmd = 0;
  1569.  
  1570.     }
  1571.  
  1572.     zone_table[zone].age = 0;
  1573. }
  1574.  
  1575. #undef ZCMD
  1576.  
  1577. #endif
  1578.  
  1579. /* for use in reset_zone; return TRUE if zone 'nr' is free of PC's  */
  1580. int is_empty(int zone_nr)
  1581. {
  1582.     struct descriptor_data *i;
  1583.  
  1584.     for (i = descriptor_list; i; i = i->next)
  1585.         if (!i->connected)
  1586.             if (world[i->character->in_room].zone == zone_nr)
  1587.                 return(0);
  1588.  
  1589.     return(1);
  1590. }
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596. /*************************************************************************
  1597. *  stuff related to the save/load player system                                  *
  1598. *********************************************************************** */
  1599.  
  1600. /* Load a char, TRUE if loaded, FALSE if not */
  1601. int load_char(char *name, struct char_file_u *char_element)
  1602. {
  1603.     FILE *fl;
  1604.     int player_i;
  1605.  
  1606.     int find_name(char *name);
  1607.  
  1608.     if ((player_i = find_name(name)) >= 0) {
  1609.  
  1610.         if (!(fl = fopen(PLAYER_FILE, "r"))) {
  1611.             perror("Opening player file for reading. (db.c, load_char)");
  1612.             exit(0);
  1613.         }
  1614.  
  1615.         fseek(fl, (long) (player_table[player_i].nr *
  1616.         sizeof(struct char_file_u)), 0);
  1617.  
  1618.         fread(char_element, sizeof(struct char_file_u), 1, fl);
  1619.         fclose(fl);
  1620.         return(player_i);
  1621.     } else
  1622.  
  1623.         return(-1);
  1624. }
  1625.  
  1626.  
  1627.  
  1628.  
  1629. /* copy data from the file structure to a char struct */    
  1630. void store_to_char(struct char_file_u *st, struct char_data *ch)
  1631. {
  1632.     int i;
  1633.  
  1634.     GET_SEX(ch) = st->sex;
  1635.     GET_CLASS(ch) = st->class;
  1636.     GET_LEVEL(ch) = st->level;
  1637.  
  1638.     ch->player.short_descr = 0;
  1639.     ch->player.long_descr = 0;
  1640.  
  1641.     if (*st->title)
  1642.     {
  1643.         CREATE(ch->player.title, char, strlen(st->title) + 1);
  1644.         strcpy(ch->player.title, st->title);
  1645.     }
  1646.     else
  1647.         GET_TITLE(ch) = 0;
  1648.  
  1649.     if (*st->description)
  1650.     {
  1651.         CREATE(ch->player.description, char, 
  1652.             strlen(st->description) + 1);
  1653.         strcpy(ch->player.description, st->description);
  1654.     }
  1655.     else
  1656.         ch->player.description = 0;
  1657.  
  1658.     ch->player.hometown = st->hometown;
  1659.  
  1660.     ch->player.time.birth = st->birth;
  1661.     ch->player.time.played = st->played;
  1662.     ch->player.time.logon  = time(0);
  1663.  
  1664.     for (i = 0; i <= MAX_TOUNGE - 1; i++)
  1665.         ch->player.talks[i] = st->talks[i];
  1666.  
  1667.     ch->player.weight = st->weight;
  1668.     ch->player.height = st->height;
  1669.  
  1670.     ch->abilities = st->abilities;
  1671.     ch->tmpabilities = st->abilities;
  1672.     ch->points = st->points;
  1673.  
  1674.     for (i = 0; i <= MAX_SKILLS - 1; i++)
  1675.         ch->skills[i] = st->skills[i];
  1676.  
  1677.     ch->specials.spells_to_learn = st->spells_to_learn;
  1678.     ch->specials.alignment    = st->alignment;
  1679.  
  1680.     ch->specials.act          = st->act;
  1681.     ch->specials.carry_weight = 0;
  1682.     ch->specials.carry_items  = 0;
  1683.     ch->points.armor          = 100;
  1684.     ch->points.hitroll        = 0;
  1685.     ch->points.damroll        = 0;
  1686.  
  1687.     CREATE(GET_NAME(ch), char, strlen(st->name) +1);
  1688.     strcpy(GET_NAME(ch), st->name);
  1689.  
  1690.     /* Not used as far as I can see (Michael) */
  1691.     for(i = 0; i <= 4; i++)
  1692.       ch->specials.apply_saving_throw[i] = st->apply_saving_throw[i];
  1693.  
  1694.     for(i = 0; i <= 2; i++)
  1695.       GET_COND(ch, i) = st->conditions[i];
  1696.  
  1697.     /* Add all spell effects */
  1698.     for(i=0; i < MAX_AFFECT; i++) {
  1699.         if (st->affected[i].type)
  1700.             affect_to_char(ch, &st->affected[i]);
  1701.     }
  1702.     ch->in_room = st->load_room;
  1703.     affect_total(ch);
  1704. } /* store_to_char */
  1705.  
  1706.     
  1707.  
  1708.     
  1709. /* copy vital data from a players char-structure to the file structure */
  1710. void char_to_store(struct char_data *ch, struct char_file_u *st)
  1711. {
  1712.     int i;
  1713.     struct affected_type *af;
  1714.     struct obj_data *char_eq[MAX_WEAR];
  1715.  
  1716.     /* Unaffect everything a character can be affected by */
  1717.  
  1718.     for(i=0; i<MAX_WEAR; i++) {
  1719.         if (ch->equipment[i])
  1720.             char_eq[i] = unequip_char(ch, i);
  1721.         else
  1722.             char_eq[i] = 0;
  1723.     }
  1724.  
  1725.     for(af = ch->affected, i = 0; i<MAX_AFFECT; i++) {
  1726.         if (af) {
  1727.             st->affected[i] = *af;
  1728.             st->affected[i].next = 0;
  1729.             /* subtract effect of the spell or the effect will be doubled */
  1730.             affect_modify( ch, st->affected[i].location,
  1731.                                st->affected[i].modifier,
  1732.                                st->affected[i].bitvector, FALSE);                         
  1733.             af = af->next;
  1734.         } else {
  1735.             st->affected[i].type = 0;  /* Zero signifies not used */
  1736.             st->affected[i].duration = 0;
  1737.             st->affected[i].modifier = 0;
  1738.             st->affected[i].location = 0;
  1739.             st->affected[i].bitvector = 0;
  1740.             st->affected[i].next = 0;
  1741.         }
  1742.     }
  1743.  
  1744.     if ((i >= MAX_AFFECT) && af && af->next)
  1745.         log("WARNING: OUT OF STORE ROOM FOR AFFECTED TYPES!!!");
  1746.  
  1747.  
  1748.  
  1749.     ch->tmpabilities = ch->abilities;
  1750.  
  1751.     st->birth      = ch->player.time.birth;
  1752.     st->played     = ch->player.time.played;
  1753.     st->played    += (long) (time(0) - ch->player.time.logon);
  1754.     st->last_logon = time(0);
  1755.  
  1756.     ch->player.time.played = st->played;
  1757.     ch->player.time.logon = time(0);
  1758.  
  1759.     st->hometown = ch->player.hometown;
  1760.     st->weight   = GET_WEIGHT(ch);
  1761.     st->height   = GET_HEIGHT(ch);
  1762.     st->sex      = GET_SEX(ch);
  1763.     st->class    = GET_CLASS(ch);
  1764.     st->level    = GET_LEVEL(ch);
  1765.     st->abilities = ch->abilities;
  1766.     st->points    = ch->points;
  1767.     st->alignment       = ch->specials.alignment;
  1768.     st->spells_to_learn = ch->specials.spells_to_learn;
  1769.     st->act             = ch->specials.act;
  1770.  
  1771.     st->points.armor   = 100;
  1772.     st->points.hitroll =  0;
  1773.     st->points.damroll =  0;
  1774.  
  1775.     if (GET_TITLE(ch))
  1776.         strcpy(st->title, GET_TITLE(ch));
  1777.     else
  1778.         *st->title = '\0';
  1779.  
  1780.     if (ch->player.description)
  1781.         strcpy(st->description, ch->player.description);
  1782.     else
  1783.         *st->description = '\0';
  1784.  
  1785.  
  1786.     for (i = 0; i <= MAX_TOUNGE - 1; i++)
  1787.         st->talks[i] = ch->player.talks[i];
  1788.  
  1789.     for (i = 0; i <= MAX_SKILLS - 1; i++)
  1790.         st->skills[i] = ch->skills[i];
  1791.  
  1792.     strcpy(st->name, GET_NAME(ch) );
  1793.  
  1794.     for(i = 0; i <= 4; i++)
  1795.       st->apply_saving_throw[i] = ch->specials.apply_saving_throw[i];
  1796.  
  1797.     for(i = 0; i <= 2; i++)
  1798.       st->conditions[i] = GET_COND(ch, i);
  1799.  
  1800.     for(af = ch->affected, i = 0; i<MAX_AFFECT; i++) {
  1801.         if (af) {
  1802.             /* Add effect of the spell or it will be lost */
  1803.             /* When saving without quitting               */
  1804.             affect_modify( ch, st->affected[i].location,
  1805.                                st->affected[i].modifier,
  1806.                                st->affected[i].bitvector, TRUE);
  1807.             af = af->next;
  1808.         }
  1809.     }
  1810.  
  1811.     for(i=0; i<MAX_WEAR; i++) {
  1812.         if (char_eq[i])
  1813.             equip_char(ch, char_eq[i], i);
  1814.     }
  1815.  
  1816.     affect_total(ch);
  1817. } /* Char to store */
  1818.  
  1819.  
  1820.  
  1821.  
  1822. /* create a new entry in the in-memory index table for the player file */
  1823. int create_entry(char *name)
  1824. {
  1825.     int i, pos;
  1826.     struct player_index_element tmp;
  1827.  
  1828.     if (top_of_p_table == -1)
  1829.     {
  1830.         CREATE(player_table, struct player_index_element, 1);
  1831.         top_of_p_table = 0;
  1832.     }
  1833.     else
  1834.         if (!(player_table = (struct player_index_element *) 
  1835.           realloc(player_table, sizeof(struct player_index_element) * 
  1836.           (++top_of_p_table + 1))))
  1837.         {
  1838.             perror("create entry");
  1839.             exit(1);
  1840.         }
  1841.  
  1842.     CREATE(player_table[top_of_p_table].name, char , strlen(name) + 1);
  1843.  
  1844.     /* copy lowercase equivalent of name to table field */
  1845.     for (i = 0; *(player_table[top_of_p_table].name + i) = 
  1846.             LOWER(*(name + i)); i++);
  1847.  
  1848.     player_table[top_of_p_table].nr = top_of_p_table;
  1849.  
  1850.     return (top_of_p_table);
  1851.  
  1852.     
  1853. }
  1854.         
  1855.  
  1856.  
  1857. /* write the vital data of a player to the player file */
  1858. void save_char(struct char_data *ch, sh_int load_room)
  1859. {
  1860.     struct char_file_u st;
  1861.     FILE *fl;
  1862.     char mode[4];
  1863.     int expand;
  1864.  
  1865.     if (IS_NPC(ch) || !ch->desc)
  1866.         return;
  1867.  
  1868.     if (expand = (ch->desc->pos > top_of_p_file))
  1869.     {
  1870.         strcpy(mode, "a");
  1871.         top_of_p_file++;
  1872.     }
  1873.     else
  1874.         strcpy(mode, "r+");
  1875.  
  1876.     char_to_store(ch, &st);
  1877.     st.load_room = load_room;
  1878.  
  1879.     strcpy(st.pwd, ch->desc->pwd);
  1880.  
  1881.     if (!(fl = fopen(PLAYER_FILE, mode)))
  1882.     {
  1883.         perror("save char");
  1884.         exit(1);
  1885.     }
  1886.  
  1887.     if (!expand)
  1888.         fseek(fl, ch->desc->pos * sizeof(struct char_file_u), 0);
  1889.  
  1890.     fwrite(&st, sizeof(struct char_file_u), 1, fl);
  1891.  
  1892.     fclose(fl);
  1893. }
  1894.  
  1895.  
  1896.  
  1897.  
  1898. /* for possible later use with qsort */
  1899. int compare(struct player_index_element *arg1, struct player_index_element 
  1900.     *arg2)
  1901. {
  1902.     return (str_cmp(arg1->name, arg2->name));
  1903. }
  1904.  
  1905.  
  1906.  
  1907.  
  1908. /************************************************************************
  1909. *  procs of a (more or less) general utility nature            *
  1910. ********************************************************************** */
  1911.  
  1912.  
  1913. /* read and allocate space for a '~'-terminated string from a given file */
  1914. char *fread_string(FILE *fl)
  1915. {
  1916.     char buf[MAX_STRING_LENGTH], tmp[500];
  1917.     char *rslt;
  1918.     register char *point;
  1919.     int flag;
  1920.  
  1921.     bzero(buf, MAX_STRING_LENGTH);
  1922.  
  1923.     do
  1924.     {
  1925.         if (!fgets(tmp, MAX_STRING_LENGTH, fl))
  1926.         {
  1927.             perror("fread_str");
  1928.             exit(0);
  1929.         }
  1930.  
  1931.         if (strlen(tmp) + strlen(buf) > MAX_STRING_LENGTH)
  1932.         {
  1933.             log("fread_string: string too large (db.c)");
  1934.             exit(0);
  1935.         }
  1936.         else
  1937.             strcat(buf, tmp);
  1938.  
  1939.         for (point = buf + strlen(buf) - 2; point >= buf && isspace(*point);
  1940.             point--);        
  1941.         if (flag = (*point == '~'))
  1942.             if (*(buf + strlen(buf) - 3) == '\n')
  1943.             {
  1944.                 *(buf + strlen(buf) - 2) = '\r';
  1945.                 *(buf + strlen(buf) - 1) = '\0';
  1946.             }
  1947.             else
  1948.                 *(buf + strlen(buf) -2) = '\0';
  1949.         else
  1950.         {
  1951.             *(buf + strlen(buf) + 1) = '\0';
  1952.             *(buf + strlen(buf)) = '\r';
  1953.         }
  1954.     }
  1955.     while (!flag);
  1956.  
  1957.     /* do the allocate boogie  */
  1958.  
  1959.     if (strlen(buf) > 0)
  1960.     {
  1961.         CREATE(rslt, char, strlen(buf) + 1);
  1962.         strcpy(rslt, buf);
  1963.     }
  1964.     else
  1965.         rslt = 0;
  1966.     return(rslt);
  1967. }
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973. /* release memory allocated for a char struct */
  1974. void free_char(struct char_data *ch)
  1975. {
  1976.     struct affected_type *af;
  1977.  
  1978.     free(GET_NAME(ch));
  1979.  
  1980.       if (ch->player.title)
  1981.         free(ch->player.title);
  1982.     if (ch->player.short_descr)
  1983.         free(ch->player.short_descr);
  1984.     if (ch->player.long_descr)
  1985.         free(ch->player.long_descr);
  1986.     if(ch->player.description)
  1987.         free(ch->player.description);
  1988.  
  1989.     for (af = ch->affected; af; af = af->next) 
  1990.         affect_remove(ch, af);
  1991.  
  1992.     free(ch);
  1993. }
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001. /* release memory allocated for an obj struct */
  2002. void free_obj(struct obj_data *obj)
  2003. {
  2004.     struct extra_descr_data *this, *next_one;
  2005.  
  2006.     free(obj->name);
  2007.     if(obj->description)
  2008.         free(obj->description);
  2009.     if(obj->short_description)
  2010.         free(obj->short_description);
  2011.     if(obj->action_description)
  2012.         free(obj->action_description);
  2013.  
  2014.     for( this = obj->ex_description ;
  2015.         (this != 0);this = next_one )
  2016.     {
  2017.         next_one = this->next;
  2018.         if(this->keyword)
  2019.             free(this->keyword);
  2020.         if(this->description)
  2021.             free(this->description);
  2022.         free(this);
  2023.     }
  2024.  
  2025.     free(obj);
  2026. }
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033. /* read contents of a text file, and place in buf */
  2034. int file_to_string(char *name, char *buf)
  2035. {
  2036.     FILE *fl;
  2037.     char tmp[100];
  2038.  
  2039.     *buf = '\0';
  2040.  
  2041.     if (!(fl = fopen(name, "r")))
  2042.     {
  2043.         perror("file-to-string");
  2044.         *buf = '\0';
  2045.         return(-1);
  2046.     }
  2047.  
  2048.     do
  2049.     {
  2050.         fgets(tmp, 99, fl);
  2051.  
  2052.         if (!feof(fl))
  2053.         {
  2054.             if (strlen(buf) + strlen(tmp) + 2 > MAX_STRING_LENGTH)
  2055.             {
  2056.                 log("fl->strng: string too big (db.c, file_to_string)");
  2057.                 *buf = '\0';
  2058.                 return(-1);
  2059.             }
  2060.  
  2061.             strcat(buf, tmp);
  2062.             *(buf + strlen(buf) + 1) = '\0';
  2063.             *(buf + strlen(buf)) = '\r';
  2064.         }
  2065.     }
  2066.     while (!feof(fl));
  2067.  
  2068.     fclose(fl);
  2069.  
  2070.     return(0);
  2071. }
  2072.  
  2073.  
  2074.  
  2075.  
  2076. /* clear some of the the working variables of a char */
  2077. void reset_char(struct char_data *ch)
  2078. {
  2079.     int i;
  2080.  
  2081.     for (i = 0; i < MAX_WEAR; i++) /* Initialisering */
  2082.         ch->equipment[i] = 0;
  2083.  
  2084.     ch->followers = 0;
  2085.     ch->master = 0;
  2086. /*    ch->in_room = NOWHERE; Used for start in room */
  2087.     ch->carrying = 0;
  2088.     ch->next = 0;
  2089.     ch->next_fighting = 0;
  2090.     ch->next_in_room = 0;
  2091.     ch->specials.fighting = 0;
  2092.     ch->specials.position = POSITION_STANDING;
  2093.     ch->specials.default_pos = POSITION_STANDING;
  2094.     ch->specials.carry_weight = 0;
  2095.     ch->specials.carry_items = 0;
  2096.  
  2097.     if (GET_HIT(ch) <= 0)
  2098.         GET_HIT(ch) = 1;
  2099.     if (GET_MOVE(ch) <= 0)
  2100.         GET_MOVE(ch) = 1;
  2101.     if (GET_MANA(ch) <= 0)
  2102.         GET_MANA(ch) = 1;
  2103. }
  2104.  
  2105.  
  2106.  
  2107. /* clear ALL the working variables of a char and do NOT free any space alloc'ed*/
  2108. void clear_char(struct char_data *ch)
  2109. {
  2110.     memset(ch, '\0', sizeof(struct char_data));
  2111.  
  2112.     ch->in_room = NOWHERE;
  2113.     ch->specials.was_in_room = NOWHERE;
  2114.     ch->specials.position = POSITION_STANDING;
  2115.     ch->specials.default_pos = POSITION_STANDING;
  2116.     GET_AC(ch) = 100; /* Basic Armor */
  2117. }
  2118.  
  2119.  
  2120. void clear_object(struct obj_data *obj)
  2121. {
  2122.     memset(obj, '\0', sizeof(struct obj_data));
  2123.  
  2124.     obj->item_number = -1;
  2125.     obj->in_room      = NOWHERE;
  2126. }
  2127.  
  2128.  
  2129.  
  2130.  
  2131. /* initialize a new character only if class is set */
  2132. void init_char(struct char_data *ch)
  2133. {
  2134.     int i;
  2135.  
  2136.     /* *** if this is our first player --- he be God *** */
  2137.  
  2138.     if (top_of_p_table < 0)
  2139.     {
  2140.         GET_EXP(ch) = 7000000;
  2141.         GET_LEVEL(ch) = 24;
  2142.     }
  2143.  
  2144.     set_title(ch);
  2145.  
  2146.     ch->player.short_descr = 0;
  2147.     ch->player.long_descr = 0;
  2148.     ch->player.description = 0;
  2149.  
  2150.     ch->player.hometown = number(1,4);
  2151.  
  2152.     ch->player.time.birth = time(0);
  2153.     ch->player.time.played = 0;
  2154.     ch->player.time.logon = time(0);
  2155.  
  2156.     for (i = 0; i < MAX_TOUNGE; i++)
  2157.      ch->player.talks[i] = 0;
  2158.  
  2159.     GET_STR(ch) = 9;
  2160.     GET_INT(ch) = 9;
  2161.     GET_WIS(ch) = 9;
  2162.     GET_DEX(ch) = 9;
  2163.     GET_CON(ch) = 9;
  2164.  
  2165.     /* make favors for sex */
  2166.     if (ch->player.sex == SEX_MALE) {
  2167.         ch->player.weight = number(120,180);
  2168.         ch->player.height = number(160,200);
  2169.     } else {
  2170.         ch->player.weight = number(100,160);
  2171.         ch->player.height = number(150,180);
  2172.     }
  2173.  
  2174.     ch->points.mana = GET_MAX_MANA(ch);
  2175.     ch->points.hit = GET_MAX_HIT(ch);
  2176.     ch->points.move = GET_MAX_MOVE(ch);
  2177.     ch->points.armor = 100;
  2178.  
  2179.     for (i = 0; i <= MAX_SKILLS - 1; i++)
  2180.     {
  2181.         if (GET_LEVEL(ch) <24) {
  2182.             ch->skills[i].learned = 0;
  2183.             ch->skills[i].recognise = FALSE;
  2184.         }    else {
  2185.             ch->skills[i].learned = 100;
  2186.             ch->skills[i].recognise = FALSE;
  2187.         }
  2188.     }
  2189.  
  2190.     ch->specials.affected_by = 0;
  2191.     ch->specials.spells_to_learn = 0;
  2192.  
  2193.     for (i = 0; i < 5; i++)
  2194.         ch->specials.apply_saving_throw[i] = 0;
  2195.  
  2196.     for (i = 0; i < 3; i++)
  2197.         GET_COND(ch, i) = (GET_LEVEL(ch) == 24 ? -1 : 24);
  2198. }
  2199.  
  2200.  
  2201.  
  2202. /* returns the real number of the room with given virtual number */
  2203. int real_room(int virtual)
  2204. {
  2205.     int bot, top, mid;
  2206.  
  2207.     bot = 0;
  2208.     top = top_of_world;
  2209.  
  2210.     /* perform binary search on world-table */
  2211.     for (;;)
  2212.     {
  2213.         mid = (bot + top) / 2;
  2214.  
  2215.         if ((world + mid)->number == virtual)
  2216.             return(mid);
  2217.         if (bot >= top)
  2218.         {
  2219.             fprintf(stderr, "Room %d does not exist in database\n", virtual);
  2220.             return(-1);
  2221.         }
  2222.         if ((world + mid)->number > virtual)
  2223.             top = mid - 1;
  2224.         else
  2225.             bot = mid + 1;
  2226.     }
  2227. }
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234. /* returns the real number of the monster with given virtual number */
  2235. int real_mobile(int virtual)
  2236. {
  2237.     int bot, top, mid;
  2238.  
  2239.     bot = 0;
  2240.     top = top_of_mobt;
  2241.  
  2242.     /* perform binary search on mob-table */
  2243.     for (;;)
  2244.     {
  2245.         mid = (bot + top) / 2;
  2246.  
  2247.         if ((mob_index + mid)->virtual == virtual)
  2248.             return(mid);
  2249.         if (bot >= top)
  2250.             return(-1);
  2251.         if ((mob_index + mid)->virtual > virtual)
  2252.             top = mid - 1;
  2253.         else
  2254.             bot = mid + 1;
  2255.     }
  2256. }
  2257.  
  2258.  
  2259.  
  2260.  
  2261.  
  2262.  
  2263. /* returns the real number of the object with given virtual number */
  2264. int real_object(int virtual)
  2265. {
  2266.     int bot, top, mid;
  2267.  
  2268.     bot = 0;
  2269.     top = top_of_objt;
  2270.  
  2271.     /* perform binary search on obj-table */
  2272.     for (;;)
  2273.     {
  2274.         mid = (bot + top) / 2;
  2275.  
  2276.         if ((obj_index + mid)->virtual == virtual)
  2277.             return(mid);
  2278.         if (bot >= top)
  2279.             return(-1);
  2280.         if ((obj_index + mid)->virtual > virtual)
  2281.             top = mid - 1;
  2282.         else
  2283.             bot = mid + 1;
  2284.     }
  2285. }
  2286.  
  2287.  
  2288.