#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "olc.h" #include "tables.h" #include "clans/new_clans.h" #include "clans/new_clans_comm.h" #include "clans/new_clans_io.h" #include "clans/new_clans_util.h" extern AREA_DATA *area_first; extern ROOM_INDEX_DATA *room_index_hash[]; extern MOB_INDEX_DATA *mob_index_hash[]; extern char *dir_name[]; extern int enc_shift; extern bool is_encrypted; void otsave args((FILE *fp, AREA_DATA *pArea)); void do_echo (CHAR_DATA * ch, char *argument); inline void encrypt_write (char *encbuf, FILE * fp) { char *c, tcbuf[MAX_STRING_LENGTH]; int newc; strcpy (tcbuf, encbuf); c = tcbuf; while (*c != '\0') { if (is_encrypted) { if (*c > 8 && *c < 127) { newc = *c + enc_shift; if (newc > 126) newc = (newc - 126) + 8; } else newc = *c; } else newc = *c; /* fprintf(fp, "%c", newc); */ fputc (newc, fp); c++; } } char *fix_string (const char *str) { static char strfix[MAX_STRING_LENGTH]; int i; int o; if (str == NULL) return '\0'; for (o = i = 0; str[i + o] != '\0'; i++) { if (str[i + o] == '\r' || str[i + o] == '~') o++; strfix[i] = str[i + o]; } strfix[i] = '\0'; return strfix; } /***************************************************************************** Name: save_area_list Purpose: Saves the listing of files to be loaded at startup. Called by: do_asave(olc_save.c). ****************************************************************************/ void save_area_list () { FILE *fp; AREA_DATA *pArea; if ((fp = fopen ("area.lst", "w")) == NULL) { bug ("Save_area_list: fopen", 0); perror ("area.lst"); } else { /* * Add any help files that need to be loaded at * startup to this section. */ fprintf (fp, "help.are\n"); fprintf (fp, "social.are\n"); /* ROM OLC */ fprintf (fp, "rom.are\n"); /* ROM OLC */ fprintf (fp, "group.are\n"); /* ROM OLC */ fprintf (fp, "olc.hlp\n"); for (pArea = area_first; pArea; pArea = pArea->next) { fprintf (fp, "%s\n", pArea->filename); } // fprintf (fp, "obj_trig.are\n"); /* Object Triggers area */ fprintf (fp, "$\n"); fclose (fp); } return; } /* * ROM OLC * Used in save_mobile and save_object below. Writes * flags on the form fread_flag reads. * * buf[] must hold at least 32+1 characters. * */ char *fwrite_flag (long flags, char buf[]) { buf[0] = '\0'; if (flags == 0) { strcpy (buf, "0"); return buf; } if (flags < 0) { sprintf (buf, "%d", (int) flags); return buf; } if (flags & A) strcat (buf, "A"); if (flags & B) strcat (buf, "B"); if (flags & C) strcat (buf, "C"); if (flags & D) strcat (buf, "D"); if (flags & E) strcat (buf, "E"); if (flags & F) strcat (buf, "F"); if (flags & G) strcat (buf, "G"); if (flags & H) strcat (buf, "H"); if (flags & I) strcat (buf, "I"); if (flags & J) strcat (buf, "J"); if (flags & K) strcat (buf, "K"); if (flags & L) strcat (buf, "L"); if (flags & M) strcat (buf, "M"); if (flags & N) strcat (buf, "N"); if (flags & O) strcat (buf, "O"); if (flags & P) strcat (buf, "P"); if (flags & Q) strcat (buf, "Q"); if (flags & R) strcat (buf, "R"); if (flags & S) strcat (buf, "S"); if (flags & T) strcat (buf, "T"); if (flags & U) strcat (buf, "U"); if (flags & V) strcat (buf, "V"); if (flags & W) strcat (buf, "W"); if (flags & X) strcat (buf, "X"); if (flags & Y) strcat (buf, "Y"); if (flags & Z) strcat (buf, "Z"); if (flags & aa) strcat (buf, "a"); if (flags & bb) strcat (buf, "b"); if (flags & cc) strcat (buf, "c"); if (flags & dd) strcat (buf, "d"); if (flags & ee) strcat (buf, "e"); return buf; } /***************************************************************************** Name: save_mobile Purpose: Save one mobile to file, new format -- Hugin Called by: save_mobiles (below). ****************************************************************************/ void save_mobile (FILE * fp, MOB_INDEX_DATA * pMobIndex) { char letter[16]; char tcbuf[MAX_STRING_LENGTH]; sh_int race = pMobIndex->race; char buf[MAX_STRING_LENGTH]; int i=0; #ifdef VERBOSE_SAVE sprintf (buf, "save_mobile: saving %s", pMobIndex->player_name); log_string (buf); #endif /* */ sprintf (tcbuf, "#%d\n", pMobIndex->vnum); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pMobIndex->player_name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pMobIndex->short_descr); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", fix_string (pMobIndex->long_descr)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", fix_string (pMobIndex->description)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", race_table[race].name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s %d %d %d\n", fwrite_flag (pMobIndex->recruit_flags, buf), pMobIndex->recruit_value[0], pMobIndex->recruit_value[1], pMobIndex->recruit_value[2]); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->act, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->affected_by, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d %d\n", pMobIndex->alignment, pMobIndex->group); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d ", pMobIndex->level); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d ", pMobIndex->hitroll); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%dd%d+%d ", pMobIndex->hit[DICE_NUMBER], pMobIndex->hit[DICE_TYPE], pMobIndex->hit[DICE_BONUS]); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER], pMobIndex->mana[DICE_TYPE], pMobIndex->mana[DICE_BONUS]); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%dd%d+%d ", pMobIndex->damage[DICE_NUMBER], pMobIndex->damage[DICE_TYPE], pMobIndex->damage[DICE_BONUS]); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", attack_table[pMobIndex->dam_type].name); encrypt_write (tcbuf, fp); /* if (pMobIndex->act2 == 0) { sprintf (tcbuf, "%d %d %d %d\n", pMobIndex->ac[AC_PIERCE] / 10, pMobIndex->ac[AC_BASH] / 10, pMobIndex->ac[AC_SLASH] / 10, pMobIndex->ac[AC_EXOTIC] / 10); encrypt_write (tcbuf, fp); } else {*/ sprintf (tcbuf, "%d %d %d %d %d\n", pMobIndex->ac[AC_PIERCE] / 10, pMobIndex->ac[AC_BASH] / 10, pMobIndex->ac[AC_SLASH] / 10, 999, pMobIndex->ac[AC_EXOTIC] / 10); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->act2, buf)); encrypt_write (tcbuf, fp); if (pMobIndex->number_of_attacks != -1) { sprintf (tcbuf, "%d ", pMobIndex->blocks_exit+60); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d ", pMobIndex->number_of_attacks); encrypt_write (tcbuf, fp); } else { sprintf (tcbuf, "%d ", pMobIndex->blocks_exit); encrypt_write (tcbuf, fp); } sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->off_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->imm_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->res_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pMobIndex->vuln_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s %s %s %ld\n", position_table[pMobIndex->start_pos].short_name, position_table[pMobIndex->default_pos].short_name, flag_string (sex_flags, pMobIndex->sex), pMobIndex->wealth); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->form, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pMobIndex->parts, buf)); encrypt_write (tcbuf, fp); //Iblis 8/29/04 - Added setable stats (con/str/etc) + a slot for a rune card vnum for (i=0;i<MAX_STATS;i++) { sprintf (tcbuf, "%d ", pMobIndex->perm_stat[i]); encrypt_write(tcbuf, fp); } sprintf (tcbuf, "%d\n",pMobIndex->card_vnum); encrypt_write(tcbuf, fp); //Iblis end 8/29/04 additions switch (pMobIndex->size) { default: strcpy (letter, "medium"); break; case SIZE_TINY: strcpy (letter, "tiny"); break; case SIZE_SMALL: strcpy (letter, "small"); break; case SIZE_LARGE: strcpy (letter, "large"); break; case SIZE_HUGE: strcpy (letter, "huge"); break; case SIZE_GIANT: strcpy (letter, "giant"); break; } sprintf (tcbuf, "%s ", letter); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pMobIndex->material); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d %d %d %d\n", pMobIndex->defbonus, pMobIndex->attackbonus, pMobIndex->max_weight, pMobIndex->move); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d\n%s~\n", pMobIndex->default_mood, pMobIndex->vocfile); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pMobIndex->script_fn); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_mobiles Purpose: Save #MOBILES secion of an area file. Called by: save_area(olc_save.c). Notes: Changed for ROM OLC. ****************************************************************************/ void save_mobiles (FILE * fp, AREA_DATA * pArea) { int i; MOB_INDEX_DATA *pMob; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#MOBILES\n"); encrypt_write (tcbuf, fp); for (i = pArea->lvnum; i <= pArea->uvnum; i++) { if ((pMob = get_mob_index (i))) save_mobile (fp, pMob); } sprintf (tcbuf, "#0\n\n"); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_object Purpose: Save one object to file. new ROM format saving -- Hugin Called by: save_objects (below). ****************************************************************************/ void save_object (FILE * fp, OBJ_INDEX_DATA * pObjIndex) { char letter; AFFECT_DATA *pAf; EXTRA_DESCR_DATA *pEd; int i; #ifdef VERBOSE_SAVE char verb[MAX_STRING_LENGTH]; #endif /* */ char buf[MAX_STRING_LENGTH]; char tcbuf[MAX_STRING_LENGTH]; #ifdef VERBOSE_SAVE sprintf (verb, "save_object: vnum: %d %s", pObjIndex->vnum, pObjIndex->name); log_string (verb); #endif /* */ sprintf (tcbuf, "#%d\n", pObjIndex->vnum); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->short_descr); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", fix_string (pObjIndex->description)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->material); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d\n", pObjIndex->timer); encrypt_write (tcbuf, fp); // new_clans -- this is a fixup to handle new style donation boxes if (pObjIndex->item_type == ITEM_CLAN_DONATION) { pObjIndex->item_type = ITEM_NEWCLANS_DBOX; } sprintf (tcbuf, "%s ", item_name (pObjIndex->item_type)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d\n", MAX_EXTRA_FLAGS); encrypt_write (tcbuf, fp); for (i = 0; i < MAX_EXTRA_FLAGS;i++) { sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->extra_flags[i], buf)); encrypt_write (tcbuf, fp); } sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->wear_flags, buf)); encrypt_write (tcbuf, fp); // Akamai 4/30/99 - Support class/race specific equipment // Area files that are version AREA_VER_CLASSRACE and greater // will include both class_flags and race_flags in the objects sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->class_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->race_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->clan_flags, buf)); encrypt_write (tcbuf, fp); // Iblis 1/1/04 - Support 16 obj trigger vnum on equipment // Area files that are version AREA_VER_OBJTRIG2 and greater // will include this vnum slow in the objects for (i=0;i<MAX_OBJ_TRIGS;i++) { sprintf (tcbuf, "%d\n", pObjIndex->obj_trig_vnum[i]); encrypt_write (tcbuf, fp); } sprintf (tcbuf, "%d\n", pObjIndex->rarity); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->string1); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->string2); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->string3); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pObjIndex->string4); encrypt_write (tcbuf, fp); /* * Using fwrite_flag to write most values gives a strange * looking area file, consider making a case for each * item type later. */ sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[0], buf)); encrypt_write (tcbuf, fp); switch (pObjIndex->item_type) { default: #ifdef VERBOSE_SAVE sprintf (verb, "save_object: %s -> type: %d, a %s", pObjIndex->name, pObjIndex->item_type, item_name (pObjIndex->item_type)); log_string (verb); #endif /* */ sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[1], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[2], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[3], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[4], buf)); encrypt_write (tcbuf, fp); break; case ITEM_PILL: case ITEM_SCROLL: case ITEM_POTION: #ifdef VERBOSE_SAVE sprintf (verb, "save_object: %s -> type: %d, a %s", pObjIndex->name, pObjIndex->item_type, item_name (pObjIndex->item_type)); log_string (verb); #endif /* */ if (pObjIndex->value[1] < 0 || pObjIndex->value[1] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s' ", skill_table[pObjIndex->value[1]].name); } encrypt_write (tcbuf, fp); if (pObjIndex->value[2] < 0 || pObjIndex->value[2] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s' ", skill_table[pObjIndex->value[2]].name); } encrypt_write (tcbuf, fp); if (pObjIndex->value[3] < 0 || pObjIndex->value[3] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s' ", skill_table[pObjIndex->value[3]].name); } encrypt_write (tcbuf, fp); if (pObjIndex->value[4] < 0 || pObjIndex->value[4] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s'\n", skill_table[pObjIndex->value[4]].name); } encrypt_write (tcbuf, fp); break; case ITEM_WAND: case ITEM_STAFF: #ifdef VERBOSE_SAVE sprintf (verb, "save_object: %s -> type: %d, a %s", pObjIndex->name, pObjIndex->item_type, item_name (pObjIndex->item_type)); log_string (verb); #endif /* */ sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[1], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[2], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[3], buf)); encrypt_write (tcbuf, fp); if (pObjIndex->value[4] < 0 || pObjIndex->value[4] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s'\n", skill_table[pObjIndex->value[4]].name); } encrypt_write (tcbuf, fp); break; case ITEM_CLAN_DONATION: // new_clans // this is here in case this stuff gets through // the fixup above should do the job but I'm paranoid #ifdef VERBOSE_SAVE sprintf (verb, "save_object: %s -> type: %d, a %s", pObjIndex->name, pObjIndex->item_type, item_name (pObjIndex->item_type)); log_string (verb); #endif /* */ sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[1], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[2], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[3], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[4], buf)); encrypt_write (tcbuf, fp); break; case ITEM_NEWCLANS_DBOX: // new_clans #ifdef VERBOSE_SAVE sprintf (verb, "save_object: %s -> type: %d, a %s", pObjIndex->name, pObjIndex->item_type, item_name (pObjIndex->item_type)); log_string (verb); #endif /* */ // this is paired with the load_objects read in db2.c // got to write items value[1] .. value[4] sprintf (tcbuf, "%s~\n", get_clan_name (pObjIndex->value[1])); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[2], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[3], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[4], buf)); encrypt_write (tcbuf, fp); break; } sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[5], buf)); encrypt_write (tcbuf, fp); if (pObjIndex->item_type == ITEM_CARD) { if (pObjIndex->value[6] < 0 || pObjIndex->value[6] > MAX_SKILL) { sprintf (tcbuf, "-1 "); } else { sprintf (tcbuf, "'%s'\n", skill_table[pObjIndex->value[6]].name); } encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[7], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[8], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[9], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[10], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[11], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[12], buf)); encrypt_write (tcbuf, fp); } else if(pObjIndex->item_type == ITEM_OBJ_TRAP ||pObjIndex->item_type == ITEM_ROOM_TRAP ||pObjIndex->item_type == ITEM_PORTAL_TRAP ) { sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[6], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[7], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[8], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[9], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[10], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pObjIndex->value[11], buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s \n", fwrite_flag (pObjIndex->value[12], buf)); encrypt_write (tcbuf, fp); } else { sprintf (tcbuf, "%s\n", fwrite_flag (pObjIndex->value[6], buf)); encrypt_write (tcbuf, fp); } sprintf (tcbuf, "%d ", pObjIndex->level); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d ", pObjIndex->weight); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d ", pObjIndex->cost); encrypt_write (tcbuf, fp); if (pObjIndex->condition > 90) letter = 'P'; else if (pObjIndex->condition > 75) letter = 'G'; else if (pObjIndex->condition > 50) letter = 'A'; else if (pObjIndex->condition > 25) letter = 'W'; else if (pObjIndex->condition > 10) letter = 'D'; else if (pObjIndex->condition > 0) letter = 'B'; else letter = 'R'; sprintf (tcbuf, "%c\n", letter); encrypt_write (tcbuf, fp); for (pAf = pObjIndex->affected; pAf; pAf = pAf->next) { if (pAf->type == -1) { sprintf (tcbuf, "A\n%d %d\n", pAf->location, pAf->modifier); encrypt_write (tcbuf, fp); } else { if (pAf->where != TO_SKILL || pAf->location == 0) { sprintf (tcbuf, "S\n %d %d %d %d %d %d %d\n", pAf->where, pAf->type, pAf->level, pAf->duration, pAf->modifier, pAf->location, pAf->bitvector); encrypt_write (tcbuf, fp); } else { sprintf (tcbuf, "S\n %d %d %d %d %d '%s' %d\n", // sprintf (tcbuf, "S\n %d %d %d %d %d %d %d\n", pAf->where, pAf->type, pAf->level, pAf->duration, pAf->modifier, skill_table[pAf->location].name, pAf->bitvector); encrypt_write (tcbuf, fp); } } } for (pEd = pObjIndex->extra_descr; pEd; pEd = pEd->next) { sprintf (tcbuf, "E\n%s~\n%s~\n", pEd->keyword, fix_string (pEd->description)); encrypt_write (tcbuf, fp); if (pEd->next == pEd) break; } return; } /***************************************************************************** Name: save_objects Purpose: Save #OBJECTS section of an area file. Called by: save_area(olc_save.c). Notes: Changed for ROM OLC. ****************************************************************************/ void save_objects (FILE * fp, AREA_DATA * pArea) { int i; OBJ_INDEX_DATA *pObj; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#OBJECTS\n"); encrypt_write (tcbuf, fp); for (i = pArea->lvnum; i <= pArea->uvnum; i++) { if ((pObj = get_obj_index (i))) save_object (fp, pObj); } sprintf (tcbuf, "#0\n\n"); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_rooms Purpose: Save #ROOMS section of an area file. Called by: save_area(olc_save.c). ****************************************************************************/ void save_rooms (FILE * fp, AREA_DATA * pArea) { ROOM_INDEX_DATA *pRoomIndex; EXTRA_DESCR_DATA *pEd; EXIT_DATA *pExit; int iHash; int door; char buf[MAX_STRING_LENGTH]; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#ROOMS\n"); encrypt_write (tcbuf, fp); for (iHash = 0; iHash < MAX_KEY_HASH; iHash++) { for (pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next) { if (pRoomIndex->area == pArea) { #ifdef VERBOSE_SAVE sprintf (buf, "save_rooms: saving %s", pRoomIndex->name); log_string (buf); #endif /* */ sprintf (tcbuf, "#%d\n", pRoomIndex->vnum); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d %ld\n", pRoomIndex->tp_level, pRoomIndex->tp_exp); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pRoomIndex->tp_msg); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n%s~\n", pRoomIndex->enter_msg, pRoomIndex->exit_msg); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%ld %ld %d\n", pRoomIndex->class_flags, pRoomIndex->race_flags, pRoomIndex->max_level); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pRoomIndex->name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", fix_string (pRoomIndex->description)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "0 "); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s ", fwrite_flag (pRoomIndex->room_flags, buf)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d\n", pRoomIndex->sector_type); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d\n%s~\n", pRoomIndex->max_in_room, pRoomIndex->max_message); encrypt_write (tcbuf, fp); if (pRoomIndex->heal_rate != 100) { sprintf (tcbuf, "H%d\n", pRoomIndex->heal_rate); encrypt_write (tcbuf, fp); } // Adeon 6/30/03 -- support new room flags and sinking rooms sprintf (tcbuf, "I %s ", fwrite_flag (pRoomIndex->room_flags2, buf)); encrypt_write (tcbuf, fp); if (IS_SET (pRoomIndex->room_flags2, ROOM_SINKING)) { sprintf (tcbuf, "J %s~\n", pRoomIndex->sink_msg); encrypt_write (tcbuf, fp); sprintf (tcbuf, "K %s~\n", pRoomIndex->sink_warning); encrypt_write (tcbuf, fp); sprintf (tcbuf, "L%d\n", pRoomIndex->sink_timer); encrypt_write (tcbuf, fp); sprintf (tcbuf, "N%d\n", pRoomIndex->sink_dest); encrypt_write (tcbuf, fp); sprintf (tcbuf, "Q %s~\n", pRoomIndex->sink_msg_others); encrypt_write (tcbuf, fp); } // insert support for further room_flags2 flags here!!! if (pRoomIndex->mana_rate != 100) { sprintf (tcbuf, "M%d\n", pRoomIndex->mana_rate); encrypt_write (tcbuf, fp); } if (pRoomIndex->owner[0] != '\0') { sprintf (tcbuf, "O %s~\n", pRoomIndex->owner); encrypt_write (tcbuf, fp); } if (pRoomIndex->clan != CLAN_BOGUS) { sprintf (tcbuf, "C %s~\n", get_clan_name (pRoomIndex->clan)); encrypt_write (tcbuf, fp); } if (pRoomIndex->epl_filename != NULL) { sprintf (tcbuf, "P %s~\n", pRoomIndex->epl_filename); encrypt_write (tcbuf, fp); } for (pEd = pRoomIndex->extra_descr; pEd; pEd = pEd->next) { sprintf (tcbuf, "E\n%s~\n%s~\n", pEd->keyword, fix_string (pEd->description)); encrypt_write (tcbuf, fp); } for (door = 0; door < MAX_DIR; door++) { if ((pExit = pRoomIndex->exit[door]) && pExit->u1.to_room) { int locks = 0; // Iblis - 4/25/04 - A slightly better way to get save the flags we want. locks = EX_ISDOOR | EX_PICKPROOF | EX_NOBASH | EX_NOPASS | EX_HARD | EX_INFURIATING; locks &= pExit->rs_flags; /* switch (pExit->rs_flags) { case EX_ISDOOR: locks = 1; break; case EX_ISDOOR | EX_PICKPROOF: locks = 2; break; case EX_ISDOOR | EX_NOPASS: locks = 3; break; case EX_ISDOOR | EX_NOPASS | EX_PICKPROOF: locks = 4; break; case EX_ISDOOR | EX_NOBASH: locks = 5; break; case EX_ISDOOR | EX_NOBASH | EX_NOPASS: locks = 6; break; case EX_ISDOOR | EX_NOBASH | EX_PICKPROOF: locks = 7; break; case EX_ISDOOR | EX_NOPASS | EX_PICKPROOF | EX_NOBASH: locks = 8; break; }*/ sprintf (tcbuf, "D%d\n", pExit->orig_door); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", fix_string (pExit->description)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pExit->keyword); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d %d %d\n", locks, pExit->key, pExit->u1.to_room->vnum); encrypt_write (tcbuf, fp); } } sprintf (tcbuf, "S\n"); encrypt_write (tcbuf, fp); } } } sprintf (tcbuf, "#0\n\n"); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_specials Purpose: Save #SPECIALS section of area file. Called by: save_area(olc_save.c). ****************************************************************************/ void save_specials (FILE * fp, AREA_DATA * pArea) { int iHash; MOB_INDEX_DATA *pMobIndex; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#SPECIALS\n"); encrypt_write (tcbuf, fp); for (iHash = 0; iHash < MAX_KEY_HASH; iHash++) { for (pMobIndex = mob_index_hash[iHash]; pMobIndex; pMobIndex = pMobIndex->next) { if (pMobIndex && pMobIndex->area == pArea && pMobIndex->spec_fun) { sprintf (tcbuf, "M %d %s\t\t* %s\n", pMobIndex->vnum, spec_string (pMobIndex->spec_fun), pMobIndex->short_descr); encrypt_write (tcbuf, fp); } } } sprintf (tcbuf, "S\n\n"); encrypt_write (tcbuf, fp); return; } void save_resets (FILE * fp, AREA_DATA * pArea) { RESET_DATA *pReset; MOB_INDEX_DATA *pLastMob = NULL; OBJ_INDEX_DATA *pLastObj; ROOM_INDEX_DATA *pRoom; char buf[MAX_STRING_LENGTH]; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#RESETS\n"); encrypt_write (tcbuf, fp); for (pReset = pArea->reset_first; pReset; pReset = pReset->next) { #ifdef VERBOSE_SAVE sprintf (buf, "save_resets: reset command %c", pReset->command); log_string (buf); #endif /* */ switch (pReset->command) { default: bug ("Save_resets: bad command %c.", pReset->command); break; case 'D': pRoom = get_room_index (pReset->arg1); if (pRoom == NULL) continue; sprintf (tcbuf, "D 0 %4d %3d %4d\t* %s [%s]\n", pReset->arg1, pReset->arg2, pReset->arg3, pRoom->name, dir_name[pReset->arg2]); encrypt_write (tcbuf, fp); break; case 'M': pLastMob = get_mob_index (pReset->arg1); if (pLastMob == NULL) continue; sprintf (tcbuf, "M 0 %4d %3d %4d %2d\t* %s\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, capitalize (pLastMob->short_descr)); encrypt_write (tcbuf, fp); break; case 'O': pLastObj = get_obj_index (pReset->arg1); pRoom = get_room_index (pReset->arg3); if (pLastObj == NULL || pRoom == NULL) continue; sprintf (tcbuf, "O 0 %d 0 %d %d\t* %s at %s\n", pReset->arg1, pReset->arg3, pReset->arg4, capitalize (pLastObj->short_descr), pRoom->name); encrypt_write (tcbuf, fp); break; case 'P': pLastObj = get_obj_index (pReset->arg1); if (pLastObj == NULL) continue; sprintf (tcbuf, "P 0 %d %d %d %d\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4); encrypt_write (tcbuf, fp); break; case 'G': sprintf (tcbuf, "G 0 %4d -1\t\t* %s to %s\n", pReset->arg1, capitalize (get_obj_index (pReset->arg1)->short_descr), pLastMob ? pLastMob->short_descr : "!NO_MOB!"); encrypt_write (tcbuf, fp); if (!pLastMob) { sprintf (buf, "Save_resets: !NO_MOB! in [%s]", pArea->filename); bug (buf, 0); } break; case 'E': if (pLastMob == NULL) continue; sprintf (tcbuf, "E 0 %4d -1 %4d\t* item to %s\n", pReset->arg1, pReset->arg3, capitalize (pLastMob->short_descr)); encrypt_write (tcbuf, fp); break; case 'R': pRoom = get_room_index (pReset->arg1); if (pRoom == NULL) continue; sprintf (tcbuf, "R 0 %4d %3d\n", pReset->arg1, pReset->arg2); encrypt_write (tcbuf, fp); break; } /* if (pReset == pArea->reset_last) break; */ } sprintf (tcbuf, "S\n\n"); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_shops Purpose: Saves the #SHOPS section of an area file. Called by: save_area(olc_save.c) ****************************************************************************/ void save_shops (FILE * fp, AREA_DATA * pArea) { SHOP_DATA *pShopIndex; MOB_INDEX_DATA *pMobIndex; int iTrade; int iHash; char tcbuf[MAX_STRING_LENGTH]; sprintf (tcbuf, "#SHOPS\n"); encrypt_write (tcbuf, fp); for (iHash = 0; iHash < MAX_KEY_HASH; iHash++) { for (pMobIndex = mob_index_hash[iHash]; pMobIndex; pMobIndex = pMobIndex->next) { if (pMobIndex && pMobIndex->area == pArea && pMobIndex->pShop) { pShopIndex = pMobIndex->pShop; sprintf (tcbuf, "%d ", pShopIndex->keeper); encrypt_write (tcbuf, fp); for (iTrade = 0; iTrade < MAX_TRADE; iTrade++) { if (pShopIndex->buy_type[iTrade] != 0) { sprintf (tcbuf, "%2d ", pShopIndex->buy_type[iTrade]); encrypt_write (tcbuf, fp); } else { sprintf (tcbuf, " 0 "); encrypt_write (tcbuf, fp); } } sprintf (tcbuf, "\t%d %3d ", pShopIndex->profit_buy, pShopIndex->profit_sell); encrypt_write (tcbuf, fp); sprintf (tcbuf, "\t%d %2d\t* %s\n", pShopIndex->open_hour, pShopIndex->close_hour, pMobIndex->short_descr); encrypt_write (tcbuf, fp); } } } sprintf (tcbuf, "0\n\n"); encrypt_write (tcbuf, fp); return; } /***************************************************************************** Name: save_area Purpose: Save an area, note that this format is new. Called by: do_asave(olc_save.c). ****************************************************************************/ void save_area (AREA_DATA * pArea) { FILE *fp; #ifdef VERBOSE_SAVE char buf[MAX_STRING_LENGTH]; #endif /* */ char tcbuf[MAX_STRING_LENGTH]; int tpoints; fclose (fpReserve); if (strstr (pArea->filename, ".enc")) is_encrypted = TRUE; if (!(fp = fopen (pArea->filename, "w"))) { bug ("Open_area: fopen", 0); //perror (pArea->filename); do_echo (descriptor_list->character, "I don't THINK so! Everyone laugh at the stupid imm. HAha!\r\n"); return; } #ifdef VERBOSE_SAVE sprintf (buf, "save_area: saving %s -> file %s", pArea->name, pArea->filename); log_string (buf); #endif /* */ sprintf (tcbuf, "#AREA\n %d~\n", AREA_VER_CURRENT); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pArea->filename); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pArea->name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "{%2d %2d} %s %s~\n", pArea->llev, pArea->ulev, pArea->creator, pArea->name); encrypt_write (tcbuf, fp); sprintf (tcbuf, "{%2d %2d} %s\t%s", pArea->llev, pArea->ulev, pArea->creator, pArea->name); free_string (pArea->credits); pArea->credits = str_dup (tcbuf); sprintf (tcbuf, "%s~\n%d %d\n", pArea->help, pArea->lvnum, pArea->uvnum); encrypt_write (tcbuf, fp); /* tpoints = pArea->points; if (IS_SET (pArea->area_flags,AREA_IMP_ONLY)) tpoints += POINTS_IMP_ONLY; if (IS_SET (pArea->area_flags,AREA_NO_QUIT)) tpoints += POINTS_NO_QUIT; if (IS_SET (pArea->area_flags,AREA_NO_REPOP_WIA)) tpoints += POINTS_NO_REPOP_WIA; if (IS_SET (pArea->area_flags,AREA_NO_TREE)) tpoints += POINTS_NO_TREE;*/ // save and restore clan ownership as the clan name tpoints = pArea->area_flags; REMOVE_BIT(tpoints,AREA_CHANGED || AREA_ADDED || AREA_LOADING); sprintf (tcbuf, "%d %s %d\n", pArea->points, print_flags(tpoints),get_clan_ident (pArea->clan)); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%d %d\n", pArea->noclan, pArea->construct); encrypt_write (tcbuf, fp); sprintf (tcbuf, "%s~\n", pArea->helper); encrypt_write (tcbuf, fp); #ifdef VERBOSE_SAVE log_string ("save_area: save_mobiles"); #endif /* */ save_mobiles (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_objects"); #endif /* */ save_objects (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_rooms"); #endif /* */ save_rooms (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_resets"); #endif /* */ save_resets (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_shops"); #endif /* */ save_shops (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_specials"); #endif /* */ save_specials (fp, pArea); #ifdef VERBOSE_SAVE log_string ("save_area: save_object_triggers"); #endif /* */ otsave(fp,pArea); sprintf (tcbuf, "#$\n"); encrypt_write (tcbuf, fp); is_encrypted = FALSE; fclose (fp); #ifdef VERBOSE_SAVE sprintf (buf, "save_area: completed %s -> %s", pArea->name, pArea->filename); log_string (buf); #endif /* */ fpReserve = fopen (NULL_FILE, "r"); return; } /***************************************************************************** Name: do_asave Purpose: Entry point for saving area data. Called by: interpreter(interp.c) ****************************************************************************/ void do_asave (CHAR_DATA * ch, char *argument) { char arg1[MAX_INPUT_LENGTH]; AREA_DATA *pArea; FILE *fp; int value; if (!IS_BUILDER (ch)) { send_to_char ("You do not have authorization to do that.\n\r", ch); return; } fp = NULL; if (!ch) { /* Do an autosave */ save_area_list (); for (pArea = area_first; pArea; pArea = pArea->next) { save_area (pArea); REMOVE_BIT (pArea->area_flags, AREA_CHANGED); } return; } smash_tilde (argument); strcpy (arg1, argument); if (arg1[0] == '\0') { send_to_char ("Syntax:\n\r" " asave <vnum> - saves a particular area\n\r" " asave list - saves the area.lst file\n\r" " asave area - saves the area being edited\n\r" " asave changed - saves all changed zones\n\r" " asave world - saves the world! (db dump)\n\r", ch); return; } /* Snarf the value (which need not be numeric). */ value = atoi (arg1); if (!(pArea = get_area_data (value)) && is_number (arg1)) { send_to_char ("That area does not exist.\n\r", ch); return; } /* Save area of given vnum. */ /* ------------------------ */ if (is_number (arg1)) { if (!is_builder (ch, pArea)) { send_to_char ("You are not that area's creator.\n\r", ch); return; } save_area_list (); save_area (pArea); REMOVE_BIT (pArea->area_flags, AREA_CHANGED); send_to_char ("Area saved.\n\r", ch); return; } /* Save the world, only authorized areas. */ /* -------------------------------------- */ if (!str_cmp ("world", arg1)) { save_area_list (); for (pArea = area_first; pArea; pArea = pArea->next) { /* Builder must be assigned this area. */ if (!is_builder (ch, pArea)) continue; save_area (pArea); REMOVE_BIT (pArea->area_flags, AREA_CHANGED); } send_to_char ("You saved the world.\n\r", ch); return; } /* Save changed areas, only authorized areas. */ /* ------------------------------------------ */ if (!str_cmp ("changed", arg1)) { char buf[MAX_INPUT_LENGTH]; save_area_list (); send_to_char ("Saved zones:\n\r", ch); sprintf (buf, "None.\n\r"); for (pArea = area_first; pArea; pArea = pArea->next) { /* Builder must be assigned this area. */ if (!is_builder (ch, pArea)) continue; /* Save changed areas. */ if (IS_SET (pArea->area_flags, AREA_CHANGED)) { save_area (pArea); sprintf (buf, "%24s - '%s'\n\r", pArea->name, pArea->filename); send_to_char (buf, ch); REMOVE_BIT (pArea->area_flags, AREA_CHANGED); } } if (!str_cmp (buf, "None.\n\r")) send_to_char (buf, ch); return; } /* Save the area.lst file. */ /* ----------------------- */ if (!str_cmp (arg1, "list")) { save_area_list (); return; } /* Save area being edited, if authorized. */ /* -------------------------------------- */ if (!str_cmp (arg1, "area")) { /* Is character currently editing. */ if (ch->desc->editor == 0) { send_to_char ("You are not editing an area, " "therefore an area vnum is required.\n\r", ch); return; } /* Find the area to save. */ switch (ch->desc->editor) { case ED_AREA: pArea = (AREA_DATA *) ch->desc->pEdit; break; case ED_ROOM: pArea = ch->in_room->area; break; case ED_OBJECT: pArea = ((OBJ_INDEX_DATA *) ch->desc->pEdit)->area; break; case ED_MOBILE: pArea = ((MOB_INDEX_DATA *) ch->desc->pEdit)->area; break; default: pArea = ch->in_room->area; break; } if (!is_builder (ch, pArea)) { send_to_char ("You are not that area's creator.\n\r", ch); return; } save_area_list (); save_area (pArea); REMOVE_BIT (pArea->area_flags, AREA_CHANGED); send_to_char ("Area saved.\n\r", ch); return; } /* Show correct syntax. */ /* -------------------- */ do_asave (ch, ""); return; }