/* real zone of room/mobile/object/shop given */ zone_rnum real_zone_by_thing(room_vnum vznum) { zone_rnum bot, top, mid; int low, high; bot = 0; top = top_of_zone_table; if (genolc_zone_bottom(bot) > vznum || zone_table[top].top < vznum) return (NOWHERE); /* perform binary search on zone-table */ while (bot <= top) { mid = (bot + top) / 2; /* Upper/lower bounds of the zone. */ low = genolc_zone_bottom(mid); high = zone_table[mid].top; if (low <= vznum && vznum <= high) return mid; if (low > vznum) top = mid - 1; else bot = mid + 1; } return (NOWHERE); }
/* real zone of room/mobile/object/shop given */ zone_rnum real_zone_by_thing(room_vnum vznum) { zone_rnum bot, top, mid, last_top; int low, high; bot = 0; top = top_of_zone_table; /* perform binary search on zone-table */ for (;;) { last_top = top; mid = (bot + top) / 2; /* Upper/lower bounds of the zone. */ low = genolc_zone_bottom(mid); high = zone_table[mid].top; if (low <= vznum && vznum <= high) return mid; if (bot >= top) return NOWHERE; if (low > vznum) top = mid - 1; else bot = mid + 1; if (top > last_top) return NOWHERE; } }
zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top, const char **error) { FILE *fp; struct zone_data *zone; int i; zone_rnum rznum; char buf[MAX_STRING_LENGTH]; if (vzone_num < 0) { *error = "You can't make negative zones.\r\n"; return NOWHERE; } else if (bottom > top) { *error = "Bottom room cannot be greater than top room.\r\n"; return NOWHERE; } #if _CIRCLEMUD < CIRCLEMUD_VERSION(3,0,21) /* * New with bpl19, the OLC interface should decide whether * to allow overlap before calling this function. There * are more complicated rules for that but it's not covered * here. */ if (vzone_num > 326) { *error = "326 is the highest zone allowed.\r\n"; return NOWHERE; } /* * Make sure the zone does not exist. */ room = vzone_num * 100; /* Old CircleMUD 100-zones. */ for (i = 0; i <= top_of_zone_table; i++) if (genolc_zone_bottom(i) <= room && zone_table[i].top >= room) { *error = "A zone already covers that area.\r\n"; return NOWHERE; } #else for (i = 0; i < top_of_zone_table; i++) if (zone_table[i].number == vzone_num) { *error = "That virtual zone already exists.\r\n"; return NOWHERE; } #endif /* * Create the zone file. */ snprintf(buf, sizeof(buf), "%s/%d.zon", ZON_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new zone file."); *error = "Could not write zone file.\r\n"; return NOWHERE; } #if _CIRCLEMUD >= CIRCLEMUD_VERSION(3,0,21) /* File format changed. */ fprintf(fp, "#%d\nNone~\nNew Zone~\n%d %d 30 2\nS\n$\n", vzone_num, bottom, top); #else fprintf(fp, "#%d\nNew Zone~\n%d 30 2\nS\n$\n", vzone_num, (vzone_num * 100) + 99); #endif fclose(fp); /* * Create the room file. */ snprintf(buf, sizeof(buf), "%s/%d.wld", WLD_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new world file."); *error = "Could not write world file.\r\n"; return NOWHERE; } fprintf(fp, "#%d\nThe Beginning~\nNot much here.\n~\n%d 0 0\nS\n$\n", bottom, vzone_num); fclose(fp); /* * Create the mobile file. */ snprintf(buf, sizeof(buf), "%s/%d.mob", MOB_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new mob file."); *error = "Could not write mobile file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the object file. */ snprintf(buf, sizeof(buf), "%s/%d.obj", OBJ_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new obj file."); *error = "Could not write object file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the shop file. */ snprintf(buf, sizeof(buf), "%s/%d.shp", SHP_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new shop file."); *error = "Could not write shop file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Create the trigger file. */ snprintf(buf, sizeof(buf), "%s/%d.trg", TRG_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new trigger file"); *error = "Could not write trigger file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Update index files. */ create_world_index(vzone_num, "zon"); create_world_index(vzone_num, "wld"); create_world_index(vzone_num, "mob"); create_world_index(vzone_num, "obj"); create_world_index(vzone_num, "shp"); create_world_index(vzone_num, "trg"); /* * Make a new zone in memory. This was the source of all the zedit new * crashes reported to the CircleMUD list. It was happily overwriting * the stack. This new loop by Andrew Helm fixes that problem and is * more understandable at the same time. * * The variable is 'top_of_zone_table_table + 2' because we need record 0 * through top_of_zone (top_of_zone_table + 1 items) and a new one which * makes it top_of_zone_table + 2 elements large. */ RECREATE(zone_table, struct zone_data, top_of_zone_table + 2); zone_table[top_of_zone_table + 1].number = 32000; if (vzone_num > zone_table[top_of_zone_table].number) rznum = top_of_zone_table + 1; else { for (i = top_of_zone_table + 1; i > 0 && vzone_num < zone_table[i - 1].number; i--) zone_table[i] = zone_table[i - 1]; rznum = i; } zone = &zone_table[rznum]; /* * Ok, insert the new zone here. */ zone->name = strdup("New Zone"); zone->number = vzone_num; zone->builders = strdup("None"); #if _CIRCLEMUD >= CIRCLEMUD_VERSION(3,0,21) zone->bot = bottom; zone->top = top; #else zone->top = (vzone_num * 100) + 99; #endif zone->lifespan = 30; zone->age = 0; zone->reset_mode = 2; /* * No zone commands, just terminate it with an 'S' */ CREATE(zone->cmd, struct reset_com, 1); zone->cmd[0].command = 'S'; top_of_zone_table++; add_to_save_list(zone->number, SL_ZON); return rznum; }
/* * Save all the zone_table for this zone to disk. This function now * writes simple comments in the form of (<name>) to each record. A * header for each field is also there. */ int save_zone(zone_rnum zone_num) { int subcmd, arg1 = -1, arg2 = -1, arg3 = -1; char fname[128], oldname[128]; const char *comment = NULL; FILE *zfile; #if CIRCLE_UNSIGNED_INDEX if (zone_num == NOWHERE || zone_num > top_of_zone_table) { #else if (zone_num < 0 || zone_num > top_of_zone_table) { #endif log("SYSERR: GenOLC: save_zone: Invalid real zone number %d. (0-%d)", zone_num, top_of_zone_table); return FALSE; } snprintf(fname, sizeof(fname), "%s/%d.new", ZON_PREFIX, zone_table[zone_num].number); if (!(zfile = fopen(fname, "w"))) { mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: save_zones: Can't write zone %d.", zone_table[zone_num].number); return FALSE; } /* * Print zone header to file */ fprintf(zfile, "#%d\n" "%s~\n" "%s~\n" "%d %d %d %d\n", zone_table[zone_num].number, (zone_table[zone_num].builders && *zone_table[zone_num].builders) ? zone_table[zone_num].builders : "None.", (zone_table[zone_num].name && *zone_table[zone_num].name) ? zone_table[zone_num].name : "undefined", genolc_zone_bottom(zone_num), zone_table[zone_num].top, zone_table[zone_num].lifespan, zone_table[zone_num].reset_mode ); /* * Handy Quick Reference Chart for Zone Values. * * Field #1 Field #3 Field #4 Field #5 * ------------------------------------------------- * M (Mobile) Mob-Vnum Wld-Max Room-Vnum * O (Object) Obj-Vnum Wld-Max Room-Vnum * G (Give) Obj-Vnum Wld-Max Unused * E (Equip) Obj-Vnum Wld-Max EQ-Position * P (Put) Obj-Vnum Wld-Max Target-Obj-Vnum * D (Door) Room-Vnum Door-Dir Door-State * R (Remove) Room-Vnum Obj-Vnum Unused * T (Trigger) Trig-type Trig-Vnum Room-Vnum * V (var) Trig-type Context Room-Vnum Varname Value * ------------------------------------------------- */ for (subcmd = 0; ZCMD(zone_num, subcmd).command != 'S'; subcmd++) { switch (ZCMD(zone_num, subcmd).command) { case 'M': arg1 = mob_index[ZCMD(zone_num, subcmd).arg1].vnum; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = world[ZCMD(zone_num, subcmd).arg3].number; comment = mob_proto[ZCMD(zone_num, subcmd).arg1].player.short_descr; break; case 'O': arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = world[ZCMD(zone_num, subcmd).arg3].number; comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description; break; case 'G': arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = -1; comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description; break; case 'E': arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = ZCMD(zone_num, subcmd).arg3; comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description; break; case 'P': arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = obj_index[ZCMD(zone_num, subcmd).arg3].vnum; comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description; break; case 'D': arg1 = world[ZCMD(zone_num, subcmd).arg1].number; arg2 = ZCMD(zone_num, subcmd).arg2; arg3 = ZCMD(zone_num, subcmd).arg3; comment = world[ZCMD(zone_num, subcmd).arg1].name; break; case 'R': arg1 = world[ZCMD(zone_num, subcmd).arg1].number; arg2 = obj_index[ZCMD(zone_num, subcmd).arg2].vnum; comment = obj_proto[ZCMD(zone_num, subcmd).arg2].short_description; arg3 = -1; break; case 'T': arg1 = ZCMD(zone_num, subcmd).arg1; /* trigger type */ arg2 = trig_index[ZCMD(zone_num, subcmd).arg2]->vnum; /* trigger vnum */ arg3 = world[ZCMD(zone_num, subcmd).arg3].number; /* room num */ comment = GET_TRIG_NAME(trig_index[real_trigger(arg2)]->proto); break; case 'V': arg1 = ZCMD(zone_num, subcmd).arg1; /* trigger type */ arg2 = ZCMD(zone_num, subcmd).arg2; /* context */ arg3 = world[ZCMD(zone_num, subcmd).arg3].number; break; case '*': /* * Invalid commands are replaced with '*' - Ignore them. */ continue; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: z_save_to_disk(): Unknown cmd '%c' - NOT saving", ZCMD(zone_num, subcmd).command); continue; } if (ZCMD(zone_num, subcmd).command != 'V') fprintf(zfile, "%c %d %d %d %d \t(%s)\n", ZCMD(zone_num, subcmd).command, ZCMD(zone_num, subcmd).if_flag, arg1, arg2, arg3, comment); else fprintf(zfile, "%c %d %d %d %d %s %s\n", ZCMD(zone_num, subcmd).command, ZCMD(zone_num, subcmd).if_flag, arg1, arg2, arg3, ZCMD(zone_num, subcmd).sarg1, ZCMD(zone_num, subcmd).sarg2); } fputs("S\n$\n", zfile); fclose(zfile); snprintf(oldname, sizeof(oldname), "%s/%d.zon", ZON_PREFIX, zone_table[zone_num].number); remove(oldname); rename(fname, oldname); if (in_save_list(zone_table[zone_num].number, SL_ZON)) remove_from_save_list(zone_table[zone_num].number, SL_ZON); return TRUE; } /*-------------------------------------------------------------------*/ /* * Some common code to count the number of comands in the list. */ int count_commands(struct reset_com *list) { int count = 0; while (list[count].command != 'S') count++; return count; }
zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top, const char **error) { FILE *fp; struct zone_data *zone; int i; zone_rnum rznum; char buf[MAX_STRING_LENGTH]; #if CIRCLE_UNSIGNED_INDEX if (vzone_num == NOWHERE) { #else if (vzone_num < 0) { #endif *error = "You can't make negative zones.\r\n"; return NOWHERE; } else if (bottom > top) { *error = "Bottom room cannot be greater than top room.\r\n"; return NOWHERE; } #if _CIRCLEMUD < CIRCLEMUD_VERSION(3,0,21) /* * New with bpl19, the OLC interface should decide whether * to allow overlap before calling this function. There * are more complicated rules for that but it's not covered * here. */ if (vzone_num > 326) { *error = "326 is the highest zone allowed.\r\n"; return NOWHERE; } /* * Make sure the zone does not exist. */ room = vzone_num * 100; /* Old CircleMUD 100-zones. */ for (i = 0; i <= top_of_zone_table; i++) if (genolc_zone_bottom(i) <= room && zone_table[i].top >= room) { *error = "A zone already covers that area.\r\n"; return NOWHERE; } #else for (i = 0; i < top_of_zone_table; i++) if (zone_table[i].number == vzone_num) { *error = "That virtual zone already exists.\r\n"; return NOWHERE; } #endif /* * Create the zone file. */ snprintf(buf, sizeof(buf), "%s%d.zon", ZON_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new zone file."); *error = "Could not write zone file.\r\n"; return NOWHERE; } #if _CIRCLEMUD >= CIRCLEMUD_VERSION(3,0,21) /* File format changed. */ fprintf(fp, "#%d\nNone~\nNew Zone~\n%d %d 30 2\nS\n$\n", vzone_num, bottom, top); #else fprintf(fp, "#%d\nNew Zone~\n%d 30 2\nS\n$\n", vzone_num, (vzone_num * 100) + 99); #endif fclose(fp); /* * Create the room file. */ snprintf(buf, sizeof(buf), "%s%d.wld", WLD_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new world file."); *error = "Could not write world file.\r\n"; return NOWHERE; } fprintf(fp, "#%d\nThe Beginning~\nNot much here.\n~\n%d 0 0\nS\n$\n", bottom, vzone_num); fclose(fp); /* * Create the mobile file. */ snprintf(buf, sizeof(buf), "%s%d.mob", MOB_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new mob file."); *error = "Could not write mobile file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the object file. */ snprintf(buf, sizeof(buf), "%s%d.obj", OBJ_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new obj file."); *error = "Could not write object file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the shop file. */ snprintf(buf, sizeof(buf), "%s%d.shp", SHP_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new shop file."); *error = "Could not write shop file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Create the trigger file. */ snprintf(buf, sizeof(buf), "%s%d.trg", TRG_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new trigger file"); *error = "Could not write trigger file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Create Gld file . */ snprintf(buf, sizeof(buf), "%s/%i.gld", GLD_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new guild file"); *error = "Could not write guild file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Update index files. */ create_world_index(vzone_num, "zon"); create_world_index(vzone_num, "wld"); create_world_index(vzone_num, "mob"); create_world_index(vzone_num, "obj"); create_world_index(vzone_num, "shp"); create_world_index(vzone_num, "trg"); create_world_index(vzone_num, "gld"); /* * Make a new zone in memory. This was the source of all the zedit new * crashes reported to the CircleMUD list. It was happily overwriting * the stack. This new loop by Andrew Helm fixes that problem and is * more understandable at the same time. * * The variable is 'top_of_zone_table_table + 2' because we need record 0 * through top_of_zone (top_of_zone_table + 1 items) and a new one which * makes it top_of_zone_table + 2 elements large. */ RECREATE(zone_table, struct zone_data, top_of_zone_table + 2); zone_table[top_of_zone_table + 1].number = 32000; if (vzone_num > zone_table[top_of_zone_table].number) rznum = top_of_zone_table + 1; else { int j, room; for (i = top_of_zone_table + 1; i > 0 && vzone_num < zone_table[i - 1].number; i--) { zone_table[i] = zone_table[i - 1]; for (j = zone_table[i].bot; j <= zone_table[i].top; j++) if ((room = real_room(j)) != NOWHERE) world[room].zone++; } rznum = i; } zone = &zone_table[rznum]; /* * Ok, insert the new zone here. */ zone->name = strdup("New Zone"); zone->number = vzone_num; zone->builders = strdup("None"); #if _CIRCLEMUD >= CIRCLEMUD_VERSION(3,0,21) zone->bot = bottom; zone->top = top; #else zone->top = (vzone_num * 100) + 99; #endif zone->lifespan = 30; zone->age = 0; zone->reset_mode = 2; zone->zone_flags[0] = 0; zone->zone_flags[1] = 0; zone->zone_flags[2] = 0; zone->zone_flags[3] = 0; zone->min_level = 0; zone->max_level = LVL_IMPL; /* * No zone commands, just terminate it with an 'S' */ CREATE(zone->cmd, struct reset_com, 1); zone->cmd[0].command = 'S'; top_of_zone_table++; for (i = top_of_world; i > 0; i--) if (world[i].zone < real_zone(rznum)) break; else world[i].zone = real_zone_by_thing(GET_ROOM_VNUM(i)); add_to_save_list(zone->number, SL_ZON); return rznum; } /*-------------------------------------------------------------------*/ void create_world_index(int znum, const char *type) { FILE *newfile, *oldfile; char new_name[32], old_name[32], *prefix; int num, found = FALSE; char buf[MAX_STRING_LENGTH]; char buf1[MAX_STRING_LENGTH]; switch (*type) { case 'z': prefix = ZON_PREFIX; break; case 'w': prefix = WLD_PREFIX; break; case 'o': prefix = OBJ_PREFIX; break; case 'm': prefix = MOB_PREFIX; break; case 's': prefix = SHP_PREFIX; break; case 't': prefix = TRG_PREFIX; break; case 'g': prefix = GLD_PREFIX; break; default: /* * Caller messed up */ return; } snprintf(old_name, sizeof(old_name), "%s/index", prefix); snprintf(new_name, sizeof(new_name), "%s/newindex", prefix); if (!(oldfile = fopen(old_name, "r"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to open %s.", old_name); return; } else if (!(newfile = fopen(new_name, "w"))) { mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to open %s.", new_name); fclose(oldfile); return; } /* * Index contents must be in order: search through the old file for the * right place, insert the new file, then copy the rest over. */ snprintf(buf1, sizeof(buf1), "%d.%s", znum, type); while (get_line(oldfile, buf)) { if (*buf == '$') { /* * The following used to add a blank line, thanks to Brian Taylor for the fix... (Mythran) */ fprintf(newfile, "%s", (!found ? strncat(buf1, "\n$\n", sizeof(buf1)-1) : "$\n")); break; } else if (!found) { sscanf(buf, "%d", &num); if (num == znum) { found = TRUE; } else if (num > znum) { found = TRUE; fprintf(newfile, "%s\n", buf1); } } fprintf(newfile, "%s\n", buf); } fclose(newfile); fclose(oldfile); /* * Out with the old, in with the new. */ remove(old_name); rename(new_name, old_name); }
int save_quests(zone_rnum zone_num) { FILE *sf; char filename[128], oldname[128], quest_flags[MAX_STRING_LENGTH]; char quest_desc[MAX_STRING_LENGTH], quest_info[MAX_STRING_LENGTH]; char quest_done[MAX_STRING_LENGTH], quest_quit[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; int i, num_quests = 0; #if CIRCLE_UNSIGNED_INDEX if (zone_num == NOWHERE || zone_num > top_of_zone_table) { #else if (zone_num < 0 || zone_num > top_of_zone_table) { #endif log("SYSERR: GenOLC: save_quests: Invalid zone number %d passed! (0-%d)", zone_num, top_of_zone_table); return FALSE; } log("GenOLC: save_quests: Saving quests in zone #%d (%d-%d).", zone_table[zone_num].number, genolc_zone_bottom(zone_num), zone_table[zone_num].top); snprintf(filename, sizeof(filename), "%s/%d.new", QST_PREFIX, zone_table[zone_num].number); if (!(sf = fopen(filename, "w"))) { perror("SYSERR: save_quests"); return FALSE; } for (i = genolc_zone_bottom(zone_num); i <= zone_table[zone_num].top; i++) { qst_rnum rnum; if ((rnum = real_quest(i)) != NOTHING) { /* Copy the text strings and strip off trailing newlines. */ strncpy(quest_desc, QST_DESC(rnum) ? QST_DESC(rnum) : "undefined", sizeof(quest_desc)-1 ); strncpy(quest_info, QST_INFO(rnum) ? QST_INFO(rnum) : "undefined", sizeof(quest_info)-1 ); strncpy(quest_done, QST_DONE(rnum) ? QST_DONE(rnum) : "undefined", sizeof(quest_done)-1 ); strncpy(quest_quit, QST_QUIT(rnum) ? QST_QUIT(rnum) : "undefined", sizeof(quest_quit)-1 ); strip_cr(quest_desc); strip_cr(quest_info); strip_cr(quest_done); strip_cr(quest_quit); /* Save the quest details to the file. */ sprintascii(quest_flags, QST_FLAGS(rnum)); sprintf(buf, "#%d\n" "%s%c\n" "%s%c\n" "%s%c\n" "%s%c\n" "%s%c\n" "%d %d %s %d %d %d %d\n" "%d %d %d %d %d %d %d\n" "%d %d %d\n" "S\n", QST_NUM(rnum), QST_NAME(rnum) ? QST_NAME(rnum) : "Untitled", STRING_TERMINATOR, quest_desc, STRING_TERMINATOR, quest_info, STRING_TERMINATOR, quest_done, STRING_TERMINATOR, quest_quit, STRING_TERMINATOR, QST_TYPE(rnum), QST_MASTER(rnum) == NOBODY ? -1 : QST_MASTER(rnum), quest_flags, QST_TARGET(rnum) == NOTHING ? -1 : QST_TARGET(rnum), QST_PREV(rnum) == NOTHING ? -1 : QST_PREV(rnum), QST_NEXT(rnum) == NOTHING ? -1 : QST_NEXT(rnum), QST_PREREQ(rnum) == NOTHING ? -1 : QST_PREREQ(rnum), QST_POINTS(rnum), QST_PENALTY(rnum), QST_MINLEVEL(rnum), QST_MAXLEVEL(rnum), QST_TIME(rnum), QST_RETURNMOB(rnum) == NOBODY ? -1 : QST_RETURNMOB(rnum), QST_QUANTITY(rnum), QST_GOLD(rnum), QST_EXP(rnum), QST_OBJ(rnum) ); fprintf(sf, convert_from_tabs(buf), 0); num_quests++; } } /* Write the final line and close it. */ fprintf(sf, "$~\n"); fclose(sf); /* Old file we're replacing. */ snprintf(oldname, sizeof(oldname), "%s/%d.qst", QST_PREFIX, zone_table[zone_num].number); remove(oldname); rename(filename, oldname); /* Do we need to update the index file? */ if (num_quests > 0) create_world_index(zone_table[zone_num].number, "qst"); if (in_save_list(zone_table[zone_num].number, SL_QST)) remove_from_save_list(zone_table[zone_num].number, SL_QST); return TRUE; }
int save_rooms(zone_rnum rzone) { int i; int dflag = 0; struct room_data *room; FILE *sf; char buf[MAX_STRING_LENGTH]; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; if (rzone == NOWHERE || rzone > top_of_zone_table) { log("SYSERR: GenOLC: save_rooms: Invalid zone number %d passed! (0-%d)", rzone, top_of_zone_table); return FALSE; } log("GenOLC: save_rooms: Saving rooms in zone #%d (%d-%d).", zone_table[rzone].number, genolc_zone_bottom(rzone), zone_table[rzone].top); sprintf(buf, "%s/%d.new", WLD_PREFIX, zone_table[rzone].number); if (!(sf = fopen(buf, "w"))) { perror("SYSERR: save_rooms"); return FALSE; } for (i = genolc_zone_bottom(rzone); i <= zone_table[rzone].top; i++) { int rnum; if ((rnum = real_room(i)) != NOWHERE) { int j; room = (world + rnum); /* * Copy the description and strip off trailing newlines. */ strcpy(buf, room->description ? room->description : "Empty room."); strip_cr(buf); /* * Save the numeric and string section of the file. */ sprintasciilong(buf2, room->room_flags); fprintf(sf, "#%d\n" "%s%c\n" "%s%c\n" "%d %s %d %d %d %d %d\n", room->number, room->name ? room->name : "Untitled", STRING_TERMINATOR, buf, STRING_TERMINATOR, zone_table[room->zone].number, buf2, room->sector_type, room->size, room->nat_light, room->min_level, room->max_level ); /* * Now you write out the exits for the room. */ for (j = 0; j < NUM_OF_DIRS; j++) { if (R_EXIT(room, j)) { if (R_EXIT(room, j)->general_description) { strcpy(buf, R_EXIT(room, j)->general_description); strip_cr(buf); } else *buf = '\0'; /* * Figure out door flag. */ if (IS_SET(R_EXIT(room, j)->exit_info, EX_ISDOOR)) { dflag = 1; if (IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF) && !IS_SET(R_EXIT(room, j)->exit_info, EX_HIDDEN)) dflag = 2; if (IS_SET(R_EXIT(room, j)->exit_info, EX_HIDDEN) && !IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF)) dflag = 3; if (IS_SET(R_EXIT(room, j)->exit_info, EX_HIDDEN) && IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF)) dflag = 4; } else if (!IS_SET(R_EXIT(room, j)->exit_info, EX_HIDDEN)) dflag = 0; if (R_EXIT(room, j)->keyword) strcpy(buf1, R_EXIT(room, j)->keyword); else *buf1 = '\0'; /* * Now write the exit to the file. */ fprintf(sf, "D%d\n" "%s~\n" "%s~\n" "%d %d %d\n", j, buf, buf1, dflag, R_EXIT(room, j)->key, R_EXIT(room, j)->to_room != -1 ? world[R_EXIT(room, j)->to_room].number : -1); } } if (room->ex_description) { struct extra_descr_data *xdesc; for (xdesc = room->ex_description; xdesc; xdesc = xdesc->next) { strcpy(buf, xdesc->description); strip_cr(buf); fprintf(sf, "E\n" "%s~\n" "%s~\n", xdesc->keyword, buf); } } if (room->pain_message) { fprintf(sf, "P\n" "%s~\n" "%d~\n" "%d~\n", room->pain_message, room->pain_damage, room->pain_rate ); } if (room->nomagic_message_room && room->nomagic_message_caster ) { fprintf(sf, "N\n" "%s~\n" "%s~\n", room->nomagic_message_caster, room->nomagic_message_room ); } if (room->min_level_message || room->max_level_message ) { fprintf(sf, "F\n" "%s~\n" "%s~\n", room->min_level_message, room->max_level_message ); } fprintf(sf, "S\n"); script_save_to_disk(sf, room, WLD_TRIGGER); } } /* * Write the final line and close it. */ fprintf(sf, "$~\n"); fclose(sf); /* New file we just made. */ sprintf(buf, "%s/%d.new", WLD_PREFIX, zone_table[rzone].number); /* Old file we're replacing. */ sprintf(buf2, "%s/%d.wld", WLD_PREFIX, zone_table[rzone].number); remove(buf2); rename(buf, buf2); remove_from_save_list(zone_table[rzone].number, SL_WLD); return TRUE; }
int save_objects(zone_rnum zone_num) { char fname[128], buf[MAX_STRING_LENGTH]; char ebuf1[MAX_STRING_LENGTH], ebuf2[MAX_STRING_LENGTH]; char ebuf3[MAX_STRING_LENGTH], ebuf4[MAX_STRING_LENGTH]; char wbuf1[MAX_STRING_LENGTH], wbuf2[MAX_STRING_LENGTH]; char wbuf3[MAX_STRING_LENGTH], wbuf4[MAX_STRING_LENGTH]; char pbuf1[MAX_STRING_LENGTH], pbuf2[MAX_STRING_LENGTH]; char pbuf3[MAX_STRING_LENGTH], pbuf4[MAX_STRING_LENGTH]; int counter, counter2, realcounter; FILE *fp; struct obj_data *obj; struct extra_descr_data *ex_desc; #if CIRCLE_UNSIGNED_INDEX if (zone_num == NOWHERE || zone_num > top_of_zone_table) { #else if (zone_num < 0 || zone_num > top_of_zone_table) { #endif log("SYSERR: GenOLC: save_objects: Invalid real zone number %d. (0-%d)", zone_num, top_of_zone_table); return FALSE; } snprintf(fname, sizeof(fname), "%s%d.new", OBJ_PREFIX, zone_table[zone_num].number); if (!(fp = fopen(fname, "w+"))) { mudlog(BRF, LVL_IMMORT, TRUE, "SYSERR: OLC: Cannot open objects file %s!", fname); return FALSE; } /* * Start running through all objects in this zone. */ for (counter = genolc_zone_bottom(zone_num); counter <= zone_table[zone_num].top; counter++) { if ((realcounter = real_object(counter)) != NOTHING) { if ((obj = &obj_proto[realcounter])->action_description) { strncpy(buf, obj->action_description, sizeof(buf) - 1); strip_cr(buf); } else *buf = '\0'; fprintf(fp, "#%d\n" "%s~\n" "%s~\n" "%s~\n" "%s~\n", GET_OBJ_VNUM(obj), (obj->name && *obj->name) ? obj->name : "undefined", (obj->short_description && *obj->short_description) ? obj->short_description : "undefined", (obj->description && *obj->description) ? obj->description : "undefined", buf); sprintascii(ebuf1, GET_OBJ_EXTRA(obj)[0]); sprintascii(ebuf2, GET_OBJ_EXTRA(obj)[1]); sprintascii(ebuf3, GET_OBJ_EXTRA(obj)[2]); sprintascii(ebuf4, GET_OBJ_EXTRA(obj)[3]); sprintascii(wbuf1, GET_OBJ_WEAR(obj)[0]); sprintascii(wbuf2, GET_OBJ_WEAR(obj)[1]); sprintascii(wbuf3, GET_OBJ_WEAR(obj)[2]); sprintascii(wbuf4, GET_OBJ_WEAR(obj)[3]); sprintascii(pbuf1, GET_OBJ_PERM(obj)[0]); sprintascii(pbuf2, GET_OBJ_PERM(obj)[1]); sprintascii(pbuf3, GET_OBJ_PERM(obj)[2]); sprintascii(pbuf4, GET_OBJ_PERM(obj)[3]); fprintf(fp, "%d %s %s %s %s %s %s %s %s %s %s %s %s\n" "%d %d %d %d\n" "%d %d %d %d\n", GET_OBJ_TYPE(obj), ebuf1, ebuf2, ebuf3, ebuf4, wbuf1, wbuf2, wbuf3, wbuf4, pbuf1, pbuf2, pbuf3, pbuf4, GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj), GET_OBJ_RENT(obj), GET_OBJ_LEVEL(obj) ); /* * Do we have script(s) attached ? */ script_save_to_disk(fp, obj, OBJ_TRIGGER); /* * Do we have extra descriptions? */ if (obj->ex_description) { /* Yes, save them too. */ for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { /* * Sanity check to prevent nasty protection faults. */ if (!ex_desc->keyword || !ex_desc->description || !*ex_desc->keyword || !*ex_desc->description) { mudlog(BRF, LVL_IMMORT, TRUE, "SYSERR: OLC: oedit_save_to_disk: Corrupt ex_desc!"); continue; } strncpy(buf, ex_desc->description, sizeof(buf) - 1); strip_cr(buf); fprintf(fp, "E\n" "%s~\n" "%s~\n", ex_desc->keyword, buf); } } /* * Do we have affects? */ for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++) if (obj->affected[counter2].modifier) fprintf(fp, "A\n" "%d %d\n", obj->affected[counter2].location, obj->affected[counter2].modifier); } } /* * Write the final line, close the file. */ fprintf(fp, "$~\n"); fclose(fp); snprintf(buf, sizeof(buf), "%s%d.obj", OBJ_PREFIX, zone_table[zone_num].number); remove(buf); rename(fname, buf); if (in_save_list(zone_table[zone_num].number, SL_OBJ)) { remove_from_save_list(zone_table[zone_num].number, SL_OBJ); create_world_index(zone_table[zone_num].number, "obj"); log("GenOLC: save_objects: Saving objects '%s'", buf); } return TRUE; } /* * Free all, unconditionally. */ void free_object_strings(struct obj_data *obj) { #if 0 /* Debugging, do not enable. */ extern struct obj_data *object_list; struct obj_data *t; int i = 0; for (t = object_list; t; t = t->next) { if (t == obj) { i++; continue; } assert(obj->name != t->name); assert(obj->description != t->description); assert(obj->short_description != t->short_description); assert(obj->action_description != t->action_description); assert(obj->ex_description != t->ex_description); } assert(i <= 1); #endif if (obj->name) free(obj->name); if (obj->description) free(obj->description); if (obj->short_description) free(obj->short_description); if (obj->action_description) free(obj->action_description); if (obj->ex_description) free_ex_descriptions(obj->ex_description); } /* * For object instances that are not the prototype. */ void free_object_strings_proto(struct obj_data *obj) { int robj_num = GET_OBJ_RNUM(obj); if (obj->name && obj->name != obj_proto[robj_num].name) free(obj->name); if (obj->description && obj->description != obj_proto[robj_num].description) free(obj->description); if (obj->short_description && obj->short_description != obj_proto[robj_num].short_description) free(obj->short_description); if (obj->action_description && obj->action_description != obj_proto[robj_num].action_description) free(obj->action_description); if (obj->ex_description) { struct extra_descr_data *thised, *plist, *next_one; /* O(horrible) */ int ok_key, ok_desc, ok_item; for (thised = obj->ex_description; thised; thised = next_one) { next_one = thised->next; for (ok_item = ok_key = ok_desc = 1, plist = obj_proto[robj_num].ex_description; plist; plist = plist->next) { if (plist->keyword == thised->keyword) ok_key = 0; if (plist->description == thised->description) ok_desc = 0; if (plist == thised) ok_item = 0; } if (thised->keyword && ok_key) free(thised->keyword); if (thised->description && ok_desc) free(thised->description); if (ok_item) free(thised); } } }
int save_mobiles(zone_rnum rznum) { zone_vnum vznum; FILE *mobfd; room_vnum i; mob_rnum rmob; int written; char mobfname[64], usedfname[64]; #if CIRCLE_UNSIGNED_INDEX if (rznum == NOWHERE || rznum > top_of_zone_table) { #else if (rznum < 0 || rznum > top_of_zone_table) { #endif log("SYSERR: GenOLC: save_mobiles: Invalid real zone number %d. (0-%d)", rznum, top_of_zone_table); return FALSE; } vznum = zone_table[rznum].number; snprintf(mobfname, sizeof(mobfname), "%s%d.new", MOB_PREFIX, vznum); if ((mobfd = fopen(mobfname, "w")) == NULL) { mudlog(BRF, LVL_GOD, TRUE, "SYSERR: GenOLC: Cannot open mob file for writing."); return FALSE; } for (i = genolc_zone_bottom(rznum); i <= zone_table[rznum].top; i++) { if ((rmob = real_mobile(i)) == NOBODY) continue; check_mobile_strings(&mob_proto[rmob]); if (write_mobile_record(i, &mob_proto[rmob], mobfd) < 0) log("SYSERR: GenOLC: Error writing mobile #%d.", i); } fputs("$\n", mobfd); written = ftell(mobfd); fclose(mobfd); snprintf(usedfname, sizeof(usedfname), "%s%d.mob", MOB_PREFIX, vznum); remove(usedfname); rename(mobfname, usedfname); if (in_save_list(vznum, SL_MOB)) remove_from_save_list(vznum, SL_MOB); log("GenOLC: '%s' saved, %d bytes written.", usedfname, written); return written; } int write_mobile_espec(mob_vnum mvnum, struct char_data *mob, FILE *fd) { if (GET_ATTACK(mob) != 0) fprintf(fd, "BareHandAttack: %d\n", GET_ATTACK(mob)); if (GET_STR(mob) != 11) fprintf(fd, "Str: %d\n", GET_STR(mob)); if (GET_ADD(mob) != 0) fprintf(fd, "StrAdd: %d\n", GET_ADD(mob)); if (GET_DEX(mob) != 11) fprintf(fd, "Dex: %d\n", GET_DEX(mob)); if (GET_INT(mob) != 11) fprintf(fd, "Int: %d\n", GET_INT(mob)); if (GET_WIS(mob) != 11) fprintf(fd, "Wis: %d\n", GET_WIS(mob)); if (GET_CON(mob) != 11) fprintf(fd, "Con: %d\n", GET_CON(mob)); if (GET_CHA(mob) != 11) fprintf(fd, "Cha: %d\n", GET_CHA(mob)); if (GET_SAVE(mob, SAVING_PARA) != 0) fprintf(fd, "SavingPara: %d\n", GET_SAVE(mob, SAVING_PARA)); if (GET_SAVE(mob, SAVING_ROD) != 0) fprintf(fd, "SavingRod: %d\n", GET_SAVE(mob, SAVING_ROD)); if (GET_SAVE(mob, SAVING_PETRI) != 0) fprintf(fd, "SavingPetri: %d\n", GET_SAVE(mob, SAVING_PETRI)); if (GET_SAVE(mob, SAVING_BREATH) != 0) fprintf(fd, "SavingBreath: %d\n", GET_SAVE(mob, SAVING_BREATH)); if (GET_SAVE(mob, SAVING_SPELL) != 0) fprintf(fd, "SavingSpell: %d\n", GET_SAVE(mob, SAVING_SPELL)); fputs("E\n", fd); return TRUE; } int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) { char ldesc[MAX_STRING_LENGTH]; char ddesc[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; ldesc[MAX_STRING_LENGTH - 1] = '\0'; ddesc[MAX_STRING_LENGTH - 1] = '\0'; strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1)); strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1)); int n = snprintf(buf, MAX_STRING_LENGTH, "#%d\n" "%s%c\n" "%s%c\n" "%s%c\n" "%s%c\n", mvnum, GET_ALIAS(mob), STRING_TERMINATOR, GET_SDESC(mob), STRING_TERMINATOR, ldesc, STRING_TERMINATOR, ddesc, STRING_TERMINATOR ); if(n < MAX_STRING_LENGTH) { fprintf(fd, "%s", convert_from_tabs(buf)); fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n" "%d %d %d %dd%d+%d %dd%d+%d\n", MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1], MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3], AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1], AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3], GET_ALIGNMENT(mob), GET_LEVEL(mob), 20 - GET_HITROLL(mob), GET_AC(mob) / 10, GET_HIT(mob), GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob), GET_DAMROLL(mob)); fprintf(fd, "%d %d\n" "%d %d %d\n", GET_GOLD(mob), GET_EXP(mob), GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob) ); if (write_mobile_espec(mvnum, mob, fd) < 0) log("SYSERR: GenOLC: Error writing E-specs for mobile #%d.", mvnum); script_save_to_disk(fd, mob, MOB_TRIGGER); #if CONFIG_GENOLC_MOBPROG if (write_mobile_mobprog(mvnum, mob, fd) < 0) log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum); #endif } else { mudlog(BRF,LVL_BUILDER,TRUE, "SYSERR: Could not save mobile #%d due to size (%d > maximum of %d)", mvnum, n, MAX_STRING_LENGTH); } return TRUE; }
int save_rooms(zone_rnum zone_num) { int i; struct room_data *room; FILE *sf; char filename[128]; char buf[MAX_STRING_LENGTH], buf1[MAX_STRING_LENGTH]; char rbuf1[MAX_STRING_LENGTH], rbuf2[MAX_STRING_LENGTH]; char rbuf3[MAX_STRING_LENGTH], rbuf4[MAX_STRING_LENGTH]; #if CIRCLE_UNSIGNED_INDEX if (zone_num == NOWHERE || zone_num > top_of_zone_table) { #else if (zone_num < 0 || zone_num > top_of_zone_table) { #endif log("SYSERR: GenOLC: save_rooms: Invalid zone number %d passed! (0-%d)", zone_num, top_of_zone_table); return FALSE; } log("GenOLC: save_rooms: Saving rooms in zone #%d (%d-%d).", zone_table[zone_num].number, genolc_zone_bottom(zone_num), zone_table[zone_num].top); snprintf(filename, sizeof(filename), "%s%d.new", WLD_PREFIX, zone_table[zone_num].number); if (!(sf = fopen(filename, "w"))) { perror("SYSERR: save_rooms"); return FALSE; } for (i = genolc_zone_bottom(zone_num); i <= zone_table[zone_num].top; i++) { room_rnum rnum; if ((rnum = real_room(i)) != NOWHERE) { int j; room = (world + rnum); /* * Copy the description and strip off trailing newlines. */ strncpy(buf, room->description ? room->description : "Empty room.", sizeof(buf)-1 ); strip_cr(buf); /* * Save the numeric and string section of the file. */ sprintascii(rbuf1, room->room_flags[0]); sprintascii(rbuf2, room->room_flags[1]); sprintascii(rbuf3, room->room_flags[2]); sprintascii(rbuf4, room->room_flags[3]); fprintf(sf, "#%d\n" "%s%c\n" "%s%c\n" "%d %s %s %s %s %d\n", room->number, room->name ? room->name : "Untitled", STRING_TERMINATOR, buf, STRING_TERMINATOR, zone_table[room->zone].number, rbuf1, rbuf2, rbuf3, rbuf4, room->sector_type ); /* * Now you write out the exits for the room. */ for (j = 0; j < NUM_OF_DIRS; j++) { if (R_EXIT(room, j)) { int dflag; if (R_EXIT(room, j)->general_description) { strncpy(buf, R_EXIT(room, j)->general_description, sizeof(buf)-1); strip_cr(buf); } else *buf = '\0'; /* * Figure out door flag. */ if (IS_SET(R_EXIT(room, j)->exit_info, EX_ISDOOR)) { if (IS_SET(R_EXIT(room, j)->exit_info, EX_SECRET) && IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF)) dflag = 4; else if (IS_SET(R_EXIT(room, j)->exit_info, EX_SECRET)) dflag = 3; else if (IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF)) dflag = 2; else dflag = 1; } else dflag = 0; if (R_EXIT(room, j)->keyword) strncpy(buf1, R_EXIT(room, j)->keyword, sizeof(buf1)-1 ); else *buf1 = '\0'; /* * Now write the exit to the file. */ fprintf(sf, "D%d\n" "%s~\n" "%s~\n" "%d %d %d\n", j, buf, buf1, dflag, R_EXIT(room, j)->key != NOTHING ? R_EXIT(room, j)->key : -1, R_EXIT(room, j)->to_room != NOWHERE ? world[R_EXIT(room, j)->to_room].number : -1); } } if (room->ex_description) { struct extra_descr_data *xdesc; for (xdesc = room->ex_description; xdesc; xdesc = xdesc->next) { strncpy(buf, xdesc->description, sizeof(buf)); strip_cr(buf); fprintf(sf, "E\n" "%s~\n" "%s~\n", xdesc->keyword, buf); } } fprintf(sf, "S\n"); script_save_to_disk(sf, room, WLD_TRIGGER); } } /* * Write the final line and close it. */ fprintf(sf, "$~\n"); fclose(sf); /* Old file we're replacing. */ snprintf(buf, sizeof(buf), "%s%d.wld", WLD_PREFIX, zone_table[zone_num].number); remove(buf); rename(filename, buf); if (in_save_list(zone_table[zone_num].number, SL_WLD)) { remove_from_save_list(zone_table[zone_num].number, SL_WLD); create_world_index(zone_table[zone_num].number, "wld"); log("GenOLC: save_rooms: Saving rooms '%s'", buf); } return TRUE; } int copy_room(struct room_data *to, struct room_data *from) { free_room_strings(to); *to = *from; copy_room_strings(to, from); /* Don't put people and objects in two locations. Am thinking this shouldn't be done here... */ from->people = NULL; from->contents = NULL; return TRUE; }
/* * NOTE: This clobbers all of the global variable strings. Do not * save anything in them around calls to this function. * * buf, buf1, buf2, arg */ int save_objects(zone_rnum zone_num) { char buf[MAX_STRING_LENGTH]; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; int counter, counter2, realcounter, i; FILE *fp; struct obj_data *obj; struct extra_descr_data *ex_desc; if (zone_num == NOTHING || zone_num > top_of_zone_table) { log("SYSERR: GenOLC: save_objects: Invalid real zone number %d. (0-%d)", zone_num, top_of_zone_table); return FALSE; } sprintf(buf, "%s/%d.new", OBJ_PREFIX, zone_table[zone_num].number); if (!(fp = fopen(buf, "w+"))) { mudlog(BRF, LVL_SAINT, TRUE, "SYSERR: OLC: Cannot open objects file!"); return FALSE; } /* * Start running through all objects in this zone. */ for (counter = genolc_zone_bottom(zone_num); counter <= zone_table[zone_num].top; counter++) { if ((realcounter = real_object(counter)) != NOTHING) { if ((obj = &obj_proto[realcounter])->action_description) { buf1[MAX_STRING_LENGTH - 1] = '\0'; strncpy(buf1, obj->action_description, MAX_STRING_LENGTH - 1); strip_cr(buf1); } else *buf1 = '\0'; fprintf(fp, "#%d\n" "%s~\n" "%s~\n" "%s~\n" "%s~\n", GET_OBJ_VNUM(obj), (obj->name && *obj->name) ? obj->name : STRING_UNDEFINED, (obj->short_description && *obj->short_description) ? obj->short_description : STRING_UNDEFINED, (obj->description && *obj->description) ? obj->description : STRING_UNDEFINED, buf1); sprintasciilong(buf1, GET_OBJ_EXTRA(obj)); sprintasciilong(buf3, GET_OBJ_CLASS(obj)); sprintascii(buf2, GET_OBJ_WEAR(obj)); sprintasciilong(arg, GET_OBJ_PERM(obj)); fprintf(fp, "%d %s %s %s %s\n" "%d %d %d %d %d\n" "%d %d %d %d %d\n", GET_OBJ_TYPE(obj), buf1, buf2, arg, buf3, GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), GET_OBJ_SIZE(obj), GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj), GET_OBJ_RENT(obj), GET_OBJ_LEVEL(obj), GET_OBJ_MAX_LEVEL(obj) ); /* * Do we have script(s) attached ? */ script_save_to_disk(fp, obj, OBJ_TRIGGER); /* save resists */ for (i = 0; i < MAX_ATTACK_TYPES; i++) { if(obj->resist[i] == 1) fprintf(fp, "R\n%d %d\n",i, obj->resist[i]); } for (i = 0; i < MAX_ATTACK_TYPES; i++) { if(obj->vulnerable[i] == 1) fprintf(fp, "V\n%d %d\n",i, obj->vulnerable[i]); } for (i = 0; i < MAX_ATTACK_TYPES; i++) { if(obj->immune[i] == 1) fprintf(fp, "I\n%d %d\n",i, obj->immune[i]); } /* * Do we have extra descriptions? */ if (obj->ex_description) { /* Yes, save them too. */ for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { /* * Sanity check to prevent nasty protection faults. */ if (!ex_desc->keyword || !ex_desc->description || !*ex_desc->keyword || !*ex_desc->description) { mudlog(BRF, LVL_SAINT, TRUE, "SYSERR: OLC: oedit_save_to_disk: Corrupt ex_desc!"); continue; } buf1[MAX_STRING_LENGTH - 1] = '\0'; strncpy(buf1, ex_desc->description, MAX_STRING_LENGTH - 1); strip_cr(buf1); fprintf(fp, "E\n" "%s~\n" "%s~\n", ex_desc->keyword, buf1); } } /* * Do we have affects? */ for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++) if (obj->affected[counter2].modifier) fprintf(fp, "A\n" "%d %d\n", obj->affected[counter2].location, obj->affected[counter2].modifier); } } /* * Write the final line, close the file. */ fprintf(fp, "$~\n"); fclose(fp); sprintf(buf2, "%s/%d.obj", OBJ_PREFIX, zone_table[zone_num].number); remove(buf2); rename(buf, buf2); remove_from_save_list(zone_table[zone_num].number, SL_OBJ); return TRUE; }