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

olc_save.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *  File: olc_save.c                                                       *
00003  *                                                                         *
00004  *  Much time and thought has gone into this software and you are          *
00005  *  benefitting.  We hope that you share your changes too.  What goes      *
00006  *  around, comes around.                                                  *
00007  *                                                                         *
00008  *  This code was freely distributed with the The Isles 1.1 source code,   *
00009  *  and has been used here for OLC - OLC would not be what it is without   *
00010  *  all the previous coders who released their source code.                *
00011  *                                                                         *
00012  ***************************************************************************/
00013 /* OLC_SAVE.C
00014  * This takes care of saving all the .are information.
00015  * Notes:
00016  * -If a good syntax checker is used for setting vnum ranges of areas
00017  *  then it would become possible to just cycle through vnums instead
00018  *  of using the iHash stuff and checking that the room or reset or
00019  *  mob etc is part of that area.
00020  */
00021 
00022 #if defined(macintosh)
00023 #include <types.h>
00024 #else
00025 #include <sys/types.h>
00026 #endif
00027 #include <ctype.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <time.h>
00032 #include "merc.h"
00033 #include "tables.h"
00034 #include "olc.h"
00035 
00036 #define DIF(a,b) (~((~a)|(b)))
00037 
00038 /*
00039  *  Verbose writes reset data in plain english into the comments
00040  *  section of the resets.  It makes areas considerably larger but
00041  *  may aid in debugging.
00042  */
00043 
00044 /* #define VERBOSE */
00045 
00046 /*****************************************************************************
00047  Name:        fix_string
00048  Purpose:    Returns a string without \r and ~.
00049  ****************************************************************************/
00050 char *fix_string (const char *str)
00051 {
00052     static char strfix[MAX_STRING_LENGTH * 2];
00053     int i;
00054     int o;
00055 
00056     if (str == NULL)
00057         return '\0';
00058 
00059     for (o = i = 0; str[i + o] != '\0'; i++)
00060     {
00061         if (str[i + o] == '\r' || str[i + o] == '~')
00062             o++;
00063         strfix[i] = str[i + o];
00064     }
00065     strfix[i] = '\0';
00066     return strfix;
00067 }
00068 
00069 
00070 
00071 /*****************************************************************************
00072  Name:        save_area_list
00073  Purpose:    Saves the listing of files to be loaded at startup.
00074  Called by:    do_asave(olc_save.c).
00075  ****************************************************************************/
00076 void save_area_list ()
00077 {
00078     FILE *fp;
00079     AREA_DATA *pArea;
00080     extern HELP_AREA *had_list;
00081     HELP_AREA *ha;
00082 
00083     if ((fp = fopen ("area.lst", "w")) == NULL)
00084     {
00085         bug ("Save_area_list: fopen", 0);
00086         perror ("area.lst");
00087     }
00088     else
00089     {
00090         /*
00091          * Add any help files that need to be loaded at
00092          * startup to this section.
00093          */
00094         fprintf (fp, "social.are\n");    /* ROM OLC */
00095 
00096         for (ha = had_list; ha; ha = ha->next)
00097             if (ha->area == NULL)
00098                 fprintf (fp, "%s\n", ha->filename);
00099 
00100         for (pArea = area_first; pArea; pArea = pArea->next)
00101         {
00102         if (pArea->adelete)
00103             
00104                 continue;
00105             
00106         fprintf (fp, "%s\n", pArea->file_name);
00107         }
00108 
00109         fprintf (fp, "$\n");
00110         fclose (fp);
00111     }
00112 
00113     return;
00114 }
00115 
00116 
00117 /*
00118  * ROM OLC
00119  * Used in save_mobile and save_object below.  Writes
00120  * flags on the form fread_flag reads.
00121  * 
00122  * buf[] must hold at least 32+1 characters.
00123  *
00124  * -- Hugin
00125  */
00126 char *fwrite_flag (long flags, char buf[])
00127 {
00128     char offset;
00129     char *cp;
00130 
00131     buf[0] = '\0';
00132 
00133     if (flags == 0)
00134     {
00135         strcpy (buf, "0");
00136         return buf;
00137     }
00138 
00139     /* 32 -- number of bits in a long */
00140 
00141     for (offset = 0, cp = buf; offset < 32; offset++)
00142         if (flags & ((long) 1 << offset))
00143         {
00144             if (offset <= 'Z' - 'A')
00145                 *(cp++) = 'A' + offset;
00146             else
00147                 *(cp++) = 'a' + offset - ('Z' - 'A' + 1);
00148         }
00149 
00150     *cp = '\0';
00151 
00152     return buf;
00153 }
00154 
00155 void save_mobprogs (FILE * fp, AREA_DATA * pArea)
00156 {
00157     MPROG_CODE *pMprog;
00158     int i;
00159     
00160 
00161     fprintf (fp, "#MOBPROGS\n");
00162 
00163     for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
00164     {
00165         if ((pMprog = get_mprog_index (i)) != NULL)
00166         {
00167             
00168         fprintf (fp, "#%d\n", i);
00169             fprintf (fp, "%s~\n", fix_string (pMprog->code));
00170         }
00171     }
00172 
00173     fprintf (fp, "#0\n\n");
00174     return;
00175 }
00176 
00177 /*****************************************************************************
00178  Name:        save_mobile
00179  Purpose:    Save one mobile to file, new format -- Hugin
00180  Called by:    save_mobiles (below).
00181  ****************************************************************************/
00182 void save_mobile (FILE * fp, MOB_INDEX_DATA * pMobIndex)
00183 {
00184     sh_int race = pMobIndex->race;
00185     MPROG_LIST *pMprog;
00186     char buf[MAX_STRING_LENGTH];
00187     long temp;
00188 
00189     if (pMobIndex->area->adelete)
00190         return;
00191 
00192     fprintf (fp, "#%d\n", pMobIndex->vnum);
00193     fprintf (fp, "%s~\n", pMobIndex->player_name);
00194     fprintf (fp, "%s~\n", pMobIndex->short_descr);
00195     fprintf (fp, "%s~\n", fix_string (pMobIndex->long_descr));
00196     fprintf (fp, "%s~\n", fix_string (pMobIndex->description));
00197     fprintf (fp, "%s~\n", race_table[race].name);
00198     fprintf (fp, "%s ", fwrite_flag (pMobIndex->act, buf));
00199     fprintf (fp, "%s ", fwrite_flag (pMobIndex->affected_by, buf));
00200     fprintf (fp, "%d %d\n", pMobIndex->alignment, pMobIndex->group);
00201     fprintf (fp, "%d ", pMobIndex->level);
00202     fprintf (fp, "%d ", pMobIndex->hitroll);
00203     fprintf (fp, "%dd%d+%d ", pMobIndex->hit[DICE_NUMBER],
00204              pMobIndex->hit[DICE_TYPE], pMobIndex->hit[DICE_BONUS]);
00205     fprintf (fp, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER],
00206              pMobIndex->mana[DICE_TYPE], pMobIndex->mana[DICE_BONUS]);
00207     fprintf (fp, "%dd%d+%d ", pMobIndex->damage[DICE_NUMBER],
00208              pMobIndex->damage[DICE_TYPE], pMobIndex->damage[DICE_BONUS]);
00209     fprintf (fp, "%s\n", attack_table[pMobIndex->dam_type].name);
00210     fprintf (fp, "%d %d %d %d\n",
00211              pMobIndex->ac[AC_PIERCE] / 10,
00212              pMobIndex->ac[AC_BASH] / 10,
00213              pMobIndex->ac[AC_SLASH] / 10, pMobIndex->ac[AC_EXOTIC] / 10);
00214     fprintf (fp, "%s ", fwrite_flag (pMobIndex->off_flags, buf));
00215     fprintf (fp, "%s ", fwrite_flag (pMobIndex->imm_flags, buf));
00216     fprintf (fp, "%s ", fwrite_flag (pMobIndex->res_flags, buf));
00217     fprintf (fp, "%s\n", fwrite_flag (pMobIndex->vuln_flags, buf));
00218     fprintf (fp, "%s %s %s %ld\n",
00219              position_table[pMobIndex->start_pos].short_name,
00220              position_table[pMobIndex->default_pos].short_name,
00221              sex_table[pMobIndex->sex].name, pMobIndex->wealth);
00222     fprintf (fp, "%s ", fwrite_flag (pMobIndex->form, buf));
00223     fprintf (fp, "%s ", fwrite_flag (pMobIndex->parts, buf));
00224 
00225     fprintf (fp, "%s ", size_table[pMobIndex->size].name);
00226     fprintf (fp, "%s\n",
00227              IS_NULLSTR (pMobIndex->
00228                          material) ? pMobIndex->material : "unknown");
00229 
00230     if ((temp = DIF (race_table[race].act, pMobIndex->act)))
00231         fprintf (fp, "F act %s\n", fwrite_flag (temp, buf));
00232 
00233     if ((temp = DIF (race_table[race].aff, pMobIndex->affected_by)))
00234         fprintf (fp, "F aff %s\n", fwrite_flag (temp, buf));
00235 
00236     if ((temp = DIF (race_table[race].off, pMobIndex->off_flags)))
00237         fprintf (fp, "F off %s\n", fwrite_flag (temp, buf));
00238 
00239     if ((temp = DIF (race_table[race].imm, pMobIndex->imm_flags)))
00240         fprintf (fp, "F imm %s\n", fwrite_flag (temp, buf));
00241 
00242     if ((temp = DIF (race_table[race].res, pMobIndex->res_flags)))
00243         fprintf (fp, "F res %s\n", fwrite_flag (temp, buf));
00244 
00245     if ((temp = DIF (race_table[race].vuln, pMobIndex->vuln_flags)))
00246         fprintf (fp, "F vul %s\n", fwrite_flag (temp, buf));
00247 
00248     if ((temp = DIF (race_table[race].form, pMobIndex->form)))
00249         fprintf (fp, "F for %s\n", fwrite_flag (temp, buf));
00250 
00251     if ((temp = DIF (race_table[race].parts, pMobIndex->parts)))
00252         fprintf (fp, "F par %s\n", fwrite_flag (temp, buf));
00253 
00254     for (pMprog = pMobIndex->mprogs; pMprog; pMprog = pMprog->next)
00255     {
00256         fprintf (fp, "M %s %d %s~\n",
00257                  mprog_type_to_name (pMprog->trig_type), pMprog->vnum,
00258                  pMprog->trig_phrase);
00259     }
00260 
00261     return;
00262 }
00263 
00264 
00265 /*****************************************************************************
00266  Name:        save_mobiles
00267  Purpose:    Save #MOBILES secion of an area file.
00268  Called by:    save_area(olc_save.c).
00269  Notes:         Changed for ROM OLC.
00270  ****************************************************************************/
00271 void save_mobiles (FILE * fp, AREA_DATA * pArea)
00272 {
00273     int i;
00274     MOB_INDEX_DATA *pMob;
00275     if (pArea->adelete)
00276         return;
00277 
00278     fprintf (fp, "#MOBILES\n");
00279 
00280     for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
00281     {
00282             //f (pMob->area->adelete)
00283     //      continue;
00284         if ((pMob = get_mob_index (i)))
00285             save_mobile (fp, pMob);
00286     }
00287 
00288     fprintf (fp, "#0\n\n\n\n");
00289     return;
00290 }
00291 
00292 
00293 
00294 
00295 
00296 /*****************************************************************************
00297  Name:        save_object
00298  Purpose:    Save one object to file.
00299                 new ROM format saving -- Hugin
00300  Called by:    save_objects (below).
00301  ****************************************************************************/
00302 void save_object (FILE * fp, OBJ_INDEX_DATA * pObjIndex)
00303 {
00304     char letter;
00305     AFFECT_DATA *pAf;
00306     EXTRA_DESCR_DATA *pEd;
00307     char buf[MAX_STRING_LENGTH];
00308 
00309     if (pObjIndex->area->adelete)
00310         return;
00311     fprintf (fp, "#%d\n", pObjIndex->vnum);
00312     fprintf (fp, "%s~\n", pObjIndex->name);
00313     fprintf (fp, "%s~\n", pObjIndex->short_descr);
00314     fprintf (fp, "%s~\n", fix_string (pObjIndex->description));
00315     fprintf (fp, "%s~\n", pObjIndex->material);
00316     fprintf (fp, "%s ", item_name (pObjIndex->item_type));
00317     fprintf (fp, "%s ", fwrite_flag (pObjIndex->extra_flags, buf));
00318     fprintf (fp, "%s\n", fwrite_flag (pObjIndex->wear_flags, buf));
00319 
00320 /*
00321  *  Using fwrite_flag to write most values gives a strange
00322  *  looking area file, consider making a case for each
00323  *  item type later.
00324  */
00325 
00326     switch (pObjIndex->item_type)
00327     {
00328         default:
00329             fprintf (fp, "%s ", fwrite_flag (pObjIndex->value[0], buf));
00330             fprintf (fp, "%s ", fwrite_flag (pObjIndex->value[1], buf));
00331             fprintf (fp, "%s ", fwrite_flag (pObjIndex->value[2], buf));
00332             fprintf (fp, "%s ", fwrite_flag (pObjIndex->value[3], buf));
00333             fprintf (fp, "%s\n", fwrite_flag (pObjIndex->value[4], buf));
00334             break;
00335 
00336         case ITEM_DRINK_CON:
00337         case ITEM_FOUNTAIN:
00338             fprintf (fp, "%d %d '%s' %d %d\n",
00339                      pObjIndex->value[0],
00340                      pObjIndex->value[1],
00341                      liq_table[pObjIndex->value[2]].liq_name,
00342                      pObjIndex->value[3], pObjIndex->value[4]);
00343             break;
00344 
00345         case ITEM_CONTAINER:
00346             fprintf (fp, "%d %s %d %d %d\n",
00347                      pObjIndex->value[0],
00348                      fwrite_flag (pObjIndex->value[1], buf),
00349                      pObjIndex->value[2],
00350                      pObjIndex->value[3], pObjIndex->value[4]);
00351             break;
00352 
00353         case ITEM_WEAPON:
00354             fprintf (fp, "%s %d %d %s %s\n",
00355                      weapon_name (pObjIndex->value[0]),
00356                      pObjIndex->value[1],
00357                      pObjIndex->value[2],
00358                      attack_table[pObjIndex->value[3]].name,
00359                      fwrite_flag (pObjIndex->value[4], buf));
00360             break;
00361 
00362         case ITEM_PILL:
00363         case ITEM_POTION:
00364         case ITEM_SCROLL:
00365             fprintf (fp, "%d '%s' '%s' '%s' '%s'\n", pObjIndex->value[0] > 0 ?    /* no negative numbers */
00366                      pObjIndex->value[0]
00367                      : 0,
00368                      pObjIndex->value[1] != -1 ?
00369                      skill_table[pObjIndex->value[1]].name
00370                      : "",
00371                      pObjIndex->value[2] != -1 ?
00372                      skill_table[pObjIndex->value[2]].name
00373                      : "",
00374                      pObjIndex->value[3] != -1 ?
00375                      skill_table[pObjIndex->value[3]].name
00376                      : "",
00377                      pObjIndex->value[4] != -1 ?
00378                      skill_table[pObjIndex->value[4]].name : "");
00379             break;
00380 
00381         case ITEM_STAFF:
00382         case ITEM_WAND:
00383             fprintf (fp, "%d %d %d '%s' %d\n",
00384                      pObjIndex->value[0],
00385                      pObjIndex->value[1],
00386                      pObjIndex->value[2],
00387                      pObjIndex->value[3] != -1 ?
00388                      skill_table[pObjIndex->value[3]].name :
00389                      "", pObjIndex->value[4]);
00390             break;
00391     }
00392 
00393     fprintf (fp, "%d ", pObjIndex->level);
00394     fprintf (fp, "%d ", pObjIndex->weight);
00395     fprintf (fp, "%d ", pObjIndex->cost);
00396 
00397     if (pObjIndex->condition > 90)
00398         letter = 'P';
00399     else if (pObjIndex->condition > 75)
00400         letter = 'G';
00401     else if (pObjIndex->condition > 50)
00402         letter = 'A';
00403     else if (pObjIndex->condition > 25)
00404         letter = 'W';
00405     else if (pObjIndex->condition > 10)
00406         letter = 'D';
00407     else if (pObjIndex->condition > 0)
00408         letter = 'B';
00409     else
00410         letter = 'R';
00411 
00412     fprintf (fp, "%c\n", letter);
00413 
00414     for (pAf = pObjIndex->affected; pAf; pAf = pAf->next)
00415     {
00416         if (pAf->where == TO_OBJECT || pAf->bitvector == 0)
00417             fprintf (fp, "A\n%d %d\n", pAf->location, pAf->modifier);
00418         else
00419         {
00420             fprintf (fp, "F\n");
00421 
00422             switch (pAf->where)
00423             {
00424                 case TO_AFFECTS:
00425                     fprintf (fp, "A ");
00426                     break;
00427                 case TO_IMMUNE:
00428                     fprintf (fp, "I ");
00429                     break;
00430                 case TO_RESIST:
00431                     fprintf (fp, "R ");
00432                     break;
00433                 case TO_VULN:
00434                     fprintf (fp, "V ");
00435                     break;
00436                 default:
00437                     bug ("olc_save: Invalid Affect->where", 0);
00438                     break;
00439             }
00440 
00441             fprintf (fp, "%d %d %s\n", pAf->location, pAf->modifier,
00442                      fwrite_flag (pAf->bitvector, buf));
00443         }
00444     }
00445 
00446     for (pEd = pObjIndex->extra_descr; pEd; pEd = pEd->next)
00447     {
00448         fprintf (fp, "E\n%s~\n%s~\n", pEd->keyword,
00449                  fix_string (pEd->description));
00450     }
00451 
00452     return;
00453 }
00454 
00455 
00456 
00457 
00458 /*****************************************************************************
00459  Name:        save_objects
00460  Purpose:    Save #OBJECTS section of an area file.
00461  Called by:    save_area(olc_save.c).
00462  Notes:         Changed for ROM OLC.
00463  ****************************************************************************/
00464 void save_objects (FILE * fp, AREA_DATA * pArea)
00465 {
00466     int i;
00467     OBJ_INDEX_DATA *pObj;
00468 
00469     if (pArea->adelete)
00470         return;
00471 
00472     fprintf (fp, "#OBJECTS\n");
00473 
00474     
00475     for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
00476     {
00477         if ((pObj = get_obj_index (i)))
00478             save_object (fp, pObj);
00479     }
00480 
00481     fprintf (fp, "#0\n\n\n\n");
00482     return;
00483 }
00484 
00485 
00486 
00487 
00488 
00489 /*****************************************************************************
00490  Name:        save_rooms
00491  Purpose:    Save #ROOMS section of an area file.
00492  Called by:    save_area(olc_save.c).
00493  ****************************************************************************/
00494     void save_rooms (FILE * fp, AREA_DATA * pArea)
00495     {
00496         ROOM_INDEX_DATA *pRoomIndex;
00497         EXTRA_DESCR_DATA *pEd;
00498         EXIT_DATA *pExit;
00499         int iHash;
00500         int door;
00501 
00502         fprintf (fp, "#ROOMS\n");
00503         for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
00504         {
00505         for (pRoomIndex = room_index_hash[iHash]; pRoomIndex;
00506              pRoomIndex = pRoomIndex->next)
00507         {
00508             if (pRoomIndex->area == pArea)
00509             {
00510             
00511             if (pRoomIndex->rdelete)
00512                 continue;
00513 
00514             fprintf (fp, "#%d\n", pRoomIndex->vnum);
00515             fprintf (fp, "%s~\n", pRoomIndex->name);
00516             fprintf (fp, "%d\n",  pRoomIndex->travel_route == FALSE ? 0 : 1);
00517             fprintf (fp, "%d\n",  pRoomIndex->travel_type);
00518             fprintf (fp, "%d\n",  pRoomIndex->travel_state);
00519             fprintf (fp, "%s~\n", fix_string (pRoomIndex->description));
00520             if (pRoomIndex->night_description == NULL)
00521                 pRoomIndex->night_description = pRoomIndex->description;
00522             fprintf (fp, "%s~\n", fix_string (pRoomIndex->night_description));
00523 
00524             
00525             
00526             fprintf (fp, "0 ");
00527             fprintf (fp, "%d ", pRoomIndex->room_flags);
00528             if (pRoomIndex->room_flags_extra <= 0)
00529             {
00530                 fprintf(fp, "0 ");
00531             }
00532             else {
00533                 
00534             fprintf (fp, "%d ", pRoomIndex->room_flags_extra);
00535             }
00536             fprintf (fp, "%d\n", pRoomIndex->sector_type);
00537             
00538 
00539             for (pEd = pRoomIndex->extra_descr; pEd; pEd = pEd->next)
00540             {
00541                 fprintf (fp, "E\n%s~\n%s~\n", pEd->keyword,
00542                      fix_string (pEd->description));
00543             }
00544             for (door = 0; door < MAX_DIR; door++)
00545             {                /* I hate this! */
00546                 if ((pExit = pRoomIndex->exit[door]) && pExit->u1.to_room)
00547                 {
00548                 
00549                 int locks = 0;
00550                 if (pExit->u1.to_room->rdelete)
00551                     continue;
00552                 if (pExit->u1.to_room->area->adelete)
00553                     continue;
00554 
00555                 /* HACK : TO PREVENT EX_LOCKED etc without EX_ISDOOR
00556                    to stop booting the mud */
00557                 if (IS_SET (pExit->rs_flags, EX_CLOSED)
00558                     || IS_SET (pExit->rs_flags, EX_LOCKED)
00559                     || IS_SET (pExit->rs_flags, EX_PICKPROOF)
00560                     || IS_SET (pExit->rs_flags, EX_NOPASS)
00561                     || IS_SET (pExit->rs_flags, EX_EASY)
00562                     || IS_SET (pExit->rs_flags, EX_HARD)
00563                     || IS_SET (pExit->rs_flags, EX_INFURIATING)
00564                     || IS_SET (pExit->rs_flags, EX_NOCLOSE)
00565                     || IS_SET (pExit->rs_flags, EX_NOLOCK))
00566                     SET_BIT (pExit->rs_flags, EX_ISDOOR);
00567                 else
00568                     REMOVE_BIT (pExit->rs_flags, EX_ISDOOR);
00569 
00570                 /* THIS SUCKS but it's backwards compatible */
00571                 /* NOTE THAT EX_NOCLOSE NOLOCK etc aren't being saved */
00572                 if (IS_SET (pExit->rs_flags, EX_ISDOOR)
00573                     && (!IS_SET (pExit->rs_flags, EX_PICKPROOF))
00574                     && (!IS_SET (pExit->rs_flags, EX_NOPASS)))
00575                     locks = 1;
00576                 if (IS_SET (pExit->rs_flags, EX_ISDOOR)
00577                     && (IS_SET (pExit->rs_flags, EX_PICKPROOF))
00578                     && (!IS_SET (pExit->rs_flags, EX_NOPASS)))
00579                     locks = 2;
00580                 if (IS_SET (pExit->rs_flags, EX_ISDOOR)
00581                     && (!IS_SET (pExit->rs_flags, EX_PICKPROOF))
00582                     && (IS_SET (pExit->rs_flags, EX_NOPASS)))
00583                     locks = 3;
00584                 if (IS_SET (pExit->rs_flags, EX_ISDOOR)
00585                     && (IS_SET (pExit->rs_flags, EX_PICKPROOF))
00586                     && (IS_SET (pExit->rs_flags, EX_NOPASS)))
00587                     locks = 4;
00588 
00589                 fprintf (fp, "D%d\n", pExit->orig_door);
00590                 fprintf (fp, "%s~\n", fix_string (pExit->description));
00591                 fprintf (fp, "%s~\n", pExit->keyword);
00592                 fprintf (fp, "%d %d %d\n", locks,
00593                      pExit->key, pExit->u1.to_room->vnum);
00594                 }
00595             }
00596             if (pRoomIndex->mana_rate != 100
00597                 || pRoomIndex->heal_rate != 100) fprintf (fp,
00598                                       "M %d H %d\n",
00599                                       pRoomIndex->mana_rate,
00600                                       pRoomIndex->heal_rate);
00601             if (pRoomIndex->clan > 0)
00602                 fprintf (fp, "C %s~\n",
00603                      clan_table[pRoomIndex->clan].name);
00604 
00605             if (!IS_NULLSTR (pRoomIndex->owner))
00606                 fprintf (fp, "O %s~\n", pRoomIndex->owner);
00607 
00608             fprintf (fp, "S\n");
00609             }
00610         }
00611         }
00612         fprintf (fp, "#0\n\n\n\n");
00613         return;
00614     }
00615 
00616 
00617 
00618     /*****************************************************************************
00619      Name:        save_specials
00620      Purpose:    Save #SPECIALS section of area file.
00621      Called by:    save_area(olc_save.c).
00622      ****************************************************************************/
00623     void save_specials (FILE * fp, AREA_DATA * pArea)
00624     {
00625         int iHash;
00626         MOB_INDEX_DATA *pMobIndex;
00627 
00628         fprintf (fp, "#SPECIALS\n");
00629 
00630         for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
00631         {
00632         for (pMobIndex = mob_index_hash[iHash]; pMobIndex;
00633              pMobIndex = pMobIndex->next)
00634         {
00635             
00636             if (pMobIndex->area->adelete)
00637                 continue;
00638             if (pMobIndex && pMobIndex->area == pArea && pMobIndex->spec_fun)
00639             {
00640 #if defined( VERBOSE )
00641             fprintf (fp, "M %d %s Load to: %s\n", pMobIndex->vnum,
00642                  spec_name (pMobIndex->spec_fun),
00643                  pMobIndex->short_descr);
00644 #else
00645             fprintf (fp, "M %d %s\n", pMobIndex->vnum,
00646                  spec_name (pMobIndex->spec_fun));
00647 #endif
00648             }
00649         }
00650         }
00651 
00652         fprintf (fp, "S\n\n\n\n");
00653         return;
00654     }
00655 
00656 
00657 
00658     /*
00659      * This function is obsolete.  It it not needed but has been left here
00660      * for historical reasons.  It is used currently for the same reason.
00661      *
00662      * I don't think it's obsolete in ROM -- Hugin.
00663      */
00664     void save_door_resets (FILE * fp, AREA_DATA * pArea)
00665     {
00666         int iHash;
00667         ROOM_INDEX_DATA *pRoomIndex;
00668         EXIT_DATA *pExit;
00669         int door;
00670 
00671         for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
00672         {
00673         for (pRoomIndex = room_index_hash[iHash]; pRoomIndex;
00674              pRoomIndex = pRoomIndex->next)
00675         {
00676             if (pRoomIndex->area == pArea)
00677             {
00678             for (door = 0; door < MAX_DIR; door++)
00679             {
00680                 if ((pExit = pRoomIndex->exit[door])
00681                 && pExit->u1.to_room
00682                 && (IS_SET (pExit->rs_flags, EX_CLOSED)
00683                     || IS_SET (pExit->rs_flags, EX_LOCKED)))
00684                 {
00685                     
00686                     if (pExit->u1.to_room->area->adelete)
00687                         continue;
00688 #if defined( VERBOSE )
00689                 fprintf (fp, "D 0 %d %d %d The %s door of %s is %s\n",
00690                      pRoomIndex->vnum,
00691                      pExit->orig_door,
00692                      IS_SET (pExit->rs_flags, EX_LOCKED) ? 2 : 1,
00693                      dir_name[pExit->orig_door],
00694                      pRoomIndex->name,
00695                      IS_SET (pExit->rs_flags,
00696                          EX_LOCKED) ? "closed and locked" :
00697                      "closed");
00698 #endif
00699 #if !defined( VERBOSE )
00700                 if (pExit->u1.to_room->area->adelete)
00701                     continue;
00702                 
00703                 fprintf (fp, "D 0 %d %d %d\n",
00704                      pRoomIndex->vnum,
00705                      pExit->orig_door,
00706                      IS_SET (pExit->rs_flags, EX_LOCKED) ? 2 : 1);
00707 #endif
00708                 }
00709             }
00710             }
00711         }
00712         }
00713         return;
00714     }
00715 
00716 
00717 
00718 
00719     /*****************************************************************************
00720      Name:        save_resets
00721      Purpose:    Saves the #RESETS section of an area file.
00722      Called by:    save_area(olc_save.c)
00723      ****************************************************************************/
00724     void save_resets (FILE * fp, AREA_DATA * pArea)
00725     {
00726         RESET_DATA *pReset;
00727         MOB_INDEX_DATA *pLastMob = NULL;
00728         OBJ_INDEX_DATA *pLastObj;
00729         ROOM_INDEX_DATA *pRoom;
00730         char buf[MAX_STRING_LENGTH];
00731         int iHash;
00732 
00733         fprintf (fp, "#RESETS\n");
00734 
00735         save_door_resets (fp, pArea);
00736 
00737         for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
00738         {
00739         for (pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next)
00740         {
00741             if (pRoom->area == pArea)
00742             {
00743             for (pReset = pRoom->reset_first; pReset;
00744                  pReset = pReset->next)
00745             {
00746                 switch (pReset->command)
00747                 {
00748                 default:
00749                     bug ("Save_resets: bad command %c.",
00750                      pReset->command);
00751                     break;
00752 
00753                 case 'M':
00754                     pLastMob = get_mob_index (pReset->arg1);
00755                     if (pLastMob->area->adelete)
00756                         break;
00757                     fprintf (fp, "M 0 %d %d %d %d Load %s\n",
00758                          pReset->arg1,
00759                          pReset->arg2,
00760                          pReset->arg3,
00761                          pReset->arg4, pLastMob->short_descr);
00762                     break;
00763 
00764                 case 'O':
00765                     pLastObj = get_obj_index (pReset->arg1);
00766                     if (pLastObj->area->adelete)
00767                         break;
00768                     pRoom = get_room_index (pReset->arg3);
00769                     fprintf (fp, "O 0 %d 0 %d %s loaded to %s\n",
00770                          pReset->arg1,
00771                          pReset->arg3,
00772                          capitalize (pLastObj->short_descr),
00773                          pRoom->name);
00774                     break;
00775 
00776                 case 'P':
00777                     pLastObj = get_obj_index (pReset->arg1);
00778                     if (pLastObj->area->adelete)
00779                         break;
00780                     fprintf (fp, "P 0 %d %d %d %d %s put inside %s\n",
00781                          pReset->arg1,
00782                          pReset->arg2,
00783                          pReset->arg3,
00784                          pReset->arg4,
00785                          capitalize (get_obj_index
00786                              (pReset->arg1)->short_descr),
00787                          pLastObj->short_descr);
00788                     break;
00789 
00790                 case 'G':
00791                     if ((get_obj_index(pReset->arg1))->area->adelete)
00792                             break;
00793                     fprintf (fp, "G 0 %d 0 %s is given to %s\n",
00794                          pReset->arg1,
00795                          capitalize (get_obj_index
00796                              (pReset->arg1)->short_descr),
00797                          pLastMob ? pLastMob->short_descr :
00798                          "!NO_MOB!");
00799                     if (!pLastMob)
00800                     {
00801                     sprintf (buf, "Save_resets: !NO_MOB! in [%s]",
00802                          pArea->file_name);
00803                     bug (buf, 0);
00804                     }
00805                     break;
00806 
00807                 case 'E':
00808                     if (get_obj_index(pReset->arg1)->area->adelete)
00809                         break;
00810                     fprintf (fp,
00811                          "E 0 %d 0 %d %s is loaded %s of %s\n",
00812                          pReset->arg1, pReset->arg3,
00813                          capitalize (get_obj_index
00814                              (pReset->arg1)->short_descr),
00815                          flag_string (wear_loc_strings,
00816                               pReset->arg3),
00817                          pLastMob ? pLastMob->short_descr :
00818                          "!NO_MOB!");
00819                     if (!pLastMob)
00820                     {
00821                     sprintf (buf, "Save_resets: !NO_MOB! in [%s]",
00822                          pArea->file_name);
00823                     bug (buf, 0);
00824                     }
00825                     break;
00826 
00827                 case 'D':
00828                     break;
00829 
00830                 case 'R':
00831                     pRoom = get_room_index (pReset->arg1);
00832                     if (pRoom->area->adelete)
00833                         break;
00834                     fprintf (fp, "R 0 %d %d Randomize %s\n",
00835                          pReset->arg1, pReset->arg2, pRoom->name);
00836                     break;
00837                 }
00838             }
00839             }                    /* End if correct area */
00840         }                        /* End for pRoom */
00841         }                            /* End for iHash */
00842 
00843         fprintf (fp, "S\n\n\n\n");
00844         return;
00845     }
00846 
00847 
00848 
00849     /*****************************************************************************
00850      Name:        save_shops
00851      Purpose:    Saves the #SHOPS section of an area file.
00852      Called by:    save_area(olc_save.c)
00853      ****************************************************************************/
00854     void save_shops (FILE * fp, AREA_DATA * pArea)
00855     {
00856         SHOP_DATA *pShopIndex;
00857         MOB_INDEX_DATA *pMobIndex;
00858         int iTrade;
00859         int iHash;
00860 
00861         fprintf (fp, "#SHOPS\n");
00862 
00863         for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
00864         {
00865         for (pMobIndex = mob_index_hash[iHash]; pMobIndex;
00866              pMobIndex = pMobIndex->next)
00867         {
00868             if (pMobIndex && pMobIndex->area == pArea && pMobIndex->pShop)
00869             {
00870             pShopIndex = pMobIndex->pShop;
00871 
00872             fprintf (fp, "%d ", pShopIndex->keeper);
00873             for (iTrade = 0; iTrade < MAX_TRADE; iTrade++)
00874             {
00875                 if (pShopIndex->buy_type[iTrade] != 0)
00876                 {
00877                 fprintf (fp, "%d ", pShopIndex->buy_type[iTrade]);
00878                 }
00879                 else
00880                 fprintf (fp, "0 ");
00881             }
00882             fprintf (fp, "%d %d ", pShopIndex->profit_buy,
00883                  pShopIndex->profit_sell);
00884             fprintf (fp, "%d %d\n", pShopIndex->open_hour,
00885                  pShopIndex->close_hour);
00886             }
00887         }
00888         }
00889 
00890         fprintf (fp, "0\n\n\n\n");
00891         return;
00892     }
00893 
00894     /*void save_helps (FILE * fp, HELP_AREA * ha)
00895     {
00896         HELP_DATA *help = ha->first;
00897 
00898         fprintf (fp, "#HELPS\n");
00899 
00900         for (; help; help = help->next_area)
00901         {
00902         fprintf (fp, "%d %s~\n", help->level, help->keyword);
00903         fprintf (fp, "%s~\n\n", fix_string (help->text));
00904         }
00905 
00906         fprintf (fp, "-1 $~\n\n");
00907 
00908         ha->changed = FALSE;
00909 
00910         return;
00911     }
00912     */
00913     /*void save_other_helps (CHAR_DATA * ch)
00914     {
00915         extern HELP_AREA *had_list;
00916         HELP_AREA *ha;
00917         FILE *fp;
00918 
00919         for (ha = had_list; ha; ha = ha->next)
00920         if (ha->changed == TRUE)
00921         {
00922             fp = fopen (ha->filename, "w");
00923 
00924             if (!fp)
00925             {
00926             perror (ha->filename);
00927             return;
00928             }
00929 
00930             save_helps (fp, ha);
00931 
00932             if (ch)
00933             printf_to_char (ch, "%s\n\r", ha->filename);
00934 
00935             fprintf (fp, "#$\n");
00936             fclose (fp);
00937         }
00938 
00939         return;
00940     }
00941     */
00942     /*****************************************************************************
00943      Name:        save_area
00944      Purpose:    Save an area, note that this format is new.
00945      Called by:    do_asave(olc_save.c).
00946      ****************************************************************************/
00947     void save_area (AREA_DATA * pArea)
00948     {
00949         FILE *fp;
00950         if (pArea->adelete)
00951             return;
00952 
00953         fclose (fpReserve);
00954         if (!(fp = fopen (pArea->file_name, "w")))
00955         {
00956         bug ("Open_area: fopen", 0);
00957         perror (pArea->file_name);
00958         }
00959 
00960         fprintf (fp, "#AREADATA\n");
00961         fprintf (fp, "Name %s~\n", pArea->name);
00962         fprintf (fp, "Builders %s~\n", fix_string (pArea->builders));
00963         fprintf (fp, "VNUMs %d %d\n", pArea->min_vnum, pArea->max_vnum);
00964         fprintf (fp, "Credits %s~\n", pArea->credits);
00965         fprintf (fp, "Security %d\n", pArea->security);
00966         if (pArea->cont == NULL || (cont_lookup(pArea->cont) == 0))
00967             fprintf(fp,"Cont None~\n");
00968         else
00969             fprintf (fp, "Cont %s~\n", pArea->cont);
00970         fprintf (fp, "End\n\n\n\n");
00971 
00972         save_mobiles (fp, pArea);
00973         save_objects (fp, pArea);
00974         save_rooms (fp, pArea);
00975     save_specials (fp, pArea);
00976     save_resets (fp, pArea);
00977     save_shops (fp, pArea);
00978     save_mobprogs (fp, pArea);
00979 
00980     //if (pArea->helps && pArea->helps->first)
00981        // save_helps (fp, pArea->helps);
00982 
00983     fprintf (fp, "#$\n");
00984 
00985     fclose (fp);
00986     fpReserve = fopen (NULL_FILE, "r");
00987     return;
00988 }
00989 
00990 
00991 /*****************************************************************************
00992  Name:        do_asave
00993  Purpose:    Entry point for saving area data.
00994  Called by:    interpreter(interp.c)
00995  ****************************************************************************/
00996 void do_asave (CHAR_DATA * ch, char *argument)
00997 {
00998     char arg1[MAX_INPUT_LENGTH];
00999     AREA_DATA *pArea;
01000     FILE *fp;
01001     int value, sec;
01002 
01003     fp = NULL;
01004 
01005     if (!ch)                    /* Do an autosave */
01006         sec = 9;
01007     else if (!IS_NPC (ch))
01008         sec = ch->pcdata->security;
01009     else
01010         sec = 0;
01011 
01012 /*    {
01013     save_area_list();
01014     for( pArea = area_first; pArea; pArea = pArea->next )
01015     {
01016         save_area( pArea );
01017         REMOVE_BIT( pArea->area_flags, AREA_CHANGED );
01018     }
01019     return;
01020     } */
01021 
01022     smash_tilde (argument);
01023     strcpy (arg1, argument);
01024 
01025     if (arg1[0] == '\0')
01026     {
01027         if (ch)
01028         {
01029             send_to_char ("Syntax:\n\r", ch);
01030             send_to_char ("  asave <vnum>   - saves a particular area\n\r",
01031                           ch);
01032             send_to_char ("  asave list     - saves the area.lst file\n\r",
01033                           ch);
01034             send_to_char
01035                 ("  asave area     - saves the area being edited\n\r", ch);
01036             send_to_char ("  asave changed  - saves all changed zones\n\r",
01037                           ch);
01038             send_to_char ("  asave world    - saves the world! (db dump)\n\r",
01039                           ch);
01040         send_to_char( "  asave helps    - saves the help files\n\r",    ch );
01041             send_to_char ("\n\r", ch);
01042         }
01043 
01044         return;
01045     }
01046 
01047     /* Snarf the value (which need not be numeric). */
01048     value = atoi (arg1);
01049     if (!(pArea = get_area_data (value)) && is_number (arg1))
01050     {
01051         if (ch)
01052             send_to_char ("That area does not exist.\n\r", ch);
01053         return;
01054     }
01055 
01056     /* Save area of given vnum. */
01057     /* ------------------------ */
01058     if (is_number (arg1))
01059     {
01060         if (ch && !IS_BUILDER (ch, pArea))
01061         {
01062             send_to_char ("You are not a builder for this area.\n\r", ch);
01063             return;
01064         }
01065 
01066         save_area_list ();
01067         save_area (pArea);
01068 
01069         return;
01070     }
01071 
01072     /* Save the world, only authorized areas. */
01073     /* -------------------------------------- */
01074     if (!str_cmp ("world", arg1))
01075     {
01076         save_area_list ();
01077         for (pArea = area_first; pArea; pArea = pArea->next)
01078         {
01079             /* Builder must be assigned this area. */
01080             if (ch && !IS_BUILDER (ch, pArea))
01081                 continue;
01082 
01083             save_area (pArea);
01084             REMOVE_BIT (pArea->area_flags, AREA_CHANGED);
01085         }
01086 
01087         if (ch)
01088             send_to_char ("You saved the world.\n\r", ch);
01089 
01090         //save_other_helps (NULL);
01091 
01092         return;
01093     }
01094 
01095     /* Save changed areas, only authorized areas. */
01096     /* ------------------------------------------ */
01097     if (!str_cmp ("changed", arg1))
01098     {
01099         char buf[MAX_INPUT_LENGTH];
01100 
01101         save_area_list ();
01102 
01103         if (ch)
01104             send_to_char ("Saved zones:\n\r", ch);
01105         else
01106             log_string ("Saved zones:");
01107 
01108         sprintf (buf, "None.\n\r");
01109 
01110         for (pArea = area_first; pArea; pArea = pArea->next)
01111         {
01112             /* Builder must be assigned this area. */
01113             if (ch && !IS_BUILDER (ch, pArea))
01114                 continue;
01115 
01116             /* Save changed areas. */
01117             if (IS_SET (pArea->area_flags, AREA_CHANGED))
01118             {
01119                 save_area (pArea);
01120                 sprintf (buf, "%24s - '%s'", pArea->name, pArea->file_name);
01121                 if (ch)
01122                 {
01123                     send_to_char (buf, ch);
01124                     send_to_char ("\n\r", ch);
01125                 }
01126                 else
01127                     log_string (buf);
01128                 REMOVE_BIT (pArea->area_flags, AREA_CHANGED);
01129             }
01130         }
01131 
01132         //save_other_helps (ch);
01133 
01134         if (!str_cmp (buf, "None.\n\r"))
01135         {
01136             if (ch)
01137                 send_to_char (buf, ch);
01138             else
01139                 log_string ("None.");
01140         }
01141 
01142         return;
01143     }
01144 
01145     /* Save the area.lst file. */
01146     /* ----------------------- */
01147     if (!str_cmp (arg1, "list"))
01148     {
01149         save_area_list ();
01150         return;
01151     }
01152 
01153     /* Save area being edited, if authorized. */
01154     /* -------------------------------------- */
01155     if (!str_cmp (arg1, "area"))
01156     {
01157         if (!ch || !ch->desc)
01158             return;
01159 
01160         /* Is character currently editing. */
01161         if (ch->desc->editor == ED_NONE)
01162         {
01163             send_to_char ("You are not editing an area, "
01164                           "therefore an area vnum is required.\n\r", ch);
01165             return;
01166         }
01167 
01168         /* Find the area to save. */
01169         switch (ch->desc->editor)
01170         {
01171             case ED_AREA:
01172                 pArea = (AREA_DATA *) ch->desc->pEdit;
01173                 break;
01174             case ED_ROOM:
01175                 pArea = ch->in_room->area;
01176                 break;
01177             case ED_OBJECT:
01178                 pArea = ((OBJ_INDEX_DATA *) ch->desc->pEdit)->area;
01179                 break;
01180             case ED_MOBILE:
01181                 pArea = ((MOB_INDEX_DATA *) ch->desc->pEdit)->area;
01182                 break;
01183             case ED_HELP:
01184                 send_to_char ("Grabando area : ", ch);
01185                 //save_other_helps (ch);
01186                 return;
01187             default:
01188                 pArea = ch->in_room->area;
01189                 break;
01190         }
01191 
01192         if (!IS_BUILDER (ch, pArea))
01193         {
01194             send_to_char ("You are not a builder for this area.\n\r", ch);
01195             return;
01196         }
01197 
01198         save_area_list ();
01199         save_area (pArea);
01200         REMOVE_BIT (pArea->area_flags, AREA_CHANGED);
01201         send_to_char ("Area saved.\n\r", ch);
01202         return;
01203     }
01204      /* Save Help File */
01205     if(!str_cmp(arg1, "helps"))
01206     {
01207         save_helps();
01208         send_to_char( "Helps Saved.\n\r", ch);
01209         return;
01210     }
01211 
01212     /* Show correct syntax. */
01213     /* -------------------- */
01214     if (ch)
01215         do_asave (ch, "");
01216 
01217     return;
01218 }
01219 
01220 void save_helps()
01221 {
01222     HELP_DATA * pHelp;
01223     FILE * fp;
01224 
01225     if (! (fp = fopen( "help.are", "w") ) )
01226     {
01227         bug( "Open_help: fopen", 0);
01228         perror( "help.are");
01229      }
01230 
01231         fprintf(fp, "#HELPS\n");
01232 
01233         for ( pHelp = help_first; pHelp != NULL; pHelp = pHelp->next )
01234         {
01235             if(pHelp->delete)
01236                 continue;
01237             
01238             fprintf(fp, "%d %s~\n\n%s~\n",
01239                     pHelp->level, pHelp->keyword, fix_string(pHelp->text));
01240         }
01241 
01242         fprintf(fp,"0 $~\n\n#$\n");
01243         fclose(fp);
01244         return;
01245 }

Generated on Thu Jan 13 21:48:13 2005 for Beyond the Shadows by  doxygen 1.4.0