int add_shop(struct shop_data *nshp) { shop_rnum rshop; int found = 0; zone_rnum rznum = real_zone_by_thing(S_NUM(nshp)); /* * The shop already exists, just update it. */ if ((rshop = real_shop(S_NUM(nshp))) != NOWHERE) { free_shop_strings(&shop_index[rshop]); copy_shop(&shop_index[rshop], nshp); if (rznum != NOWHERE) add_to_save_list(zone_table[rznum].number, SL_SHP); else mudlog("SYSERR: GenOLC: Cannot determine shop zone.", BRF, LVL_BUILDER, TRUE); return rshop; } top_shop++; RECREATE(shop_index, struct shop_data, top_shop + 1); for (rshop = top_shop; rshop > 0; rshop--) { if (nshp->vnum > SHOP_NUM(rshop - 1)) { found = rshop; /* Make a "nofree" variant and remove these later. */ shop_index[rshop].in_room = NULL; shop_index[rshop].producing = NULL; shop_index[rshop].type = NULL; copy_shop(&shop_index[rshop], nshp); break; } shop_index[rshop] = shop_index[rshop - 1]; } if (!found) { /* Make a "nofree" variant and remove these later. */ shop_index[rshop].in_room = NULL; shop_index[rshop].producing = NULL; shop_index[rshop].type = NULL; copy_shop(&shop_index[0], nshp); } if (rznum != NOWHERE) add_to_save_list(zone_table[rznum].number, SL_SHP); else mudlog("SYSERR: GenOLC: Cannot determine shop zone.", BRF, LVL_BUILDER, TRUE); return rshop; }
obj_rnum add_object(struct obj_data *newobj, obj_vnum ovnum) { int found = NOTHING; zone_rnum rznum = real_zone_by_thing(ovnum); /* * Write object to internal tables. */ if ((newobj->item_number = real_object(ovnum)) != NOTHING) { copy_object(&obj_proto[newobj->item_number], newobj); update_objects(&obj_proto[newobj->item_number]); add_to_save_list(zone_table[rznum].number, SL_OBJ); return newobj->item_number; } found = insert_object(newobj, ovnum); adjust_objects(found); add_to_save_list(zone_table[rznum].number, SL_OBJ); return (found); }
int delete_mobile(mob_rnum refpt) { struct char_data *live_mob; int vnum, counter, zone, cmd_no; if (refpt < 0 || refpt > top_of_mobt) { log("SYSERR: GenOLC: delete_mobile: Invalid rnum %d.", refpt); return FALSE; } vnum = mob_index[refpt].vnum; add_to_save_list(zone_table[real_zone_by_thing(vnum)].number, SL_MOB); extract_mobile_all(vnum); free_mobile_strings(&mob_proto[refpt]); for (counter = refpt; counter < top_of_mobt; counter++) { mob_index[counter] = mob_index[counter + 1]; mob_proto[counter] = mob_proto[counter + 1]; mob_proto[counter].nr--; } top_of_mobt--; RECREATE(mob_index, struct index_data, top_of_mobt + 1); RECREATE(mob_proto, struct char_data, top_of_mobt + 1); /* * Update live mobile rnums. */ for (live_mob = character_list; live_mob; live_mob = live_mob->next) GET_MOB_RNUM(live_mob) -= (GET_MOB_RNUM(live_mob) >= refpt); /* * Update zone table. */ for (zone = 0; zone <= top_of_zone_table; zone++) for (cmd_no = 0; ZCMD(zone, cmd_no).command != 'S'; cmd_no++) if (ZCMD(zone, cmd_no).command == 'M') ZCMD(zone, cmd_no).arg1 -= (ZCMD(zone, cmd_no).arg1 >= refpt); /* * Update shop keepers. */ if (shop_index) for (counter = 0; counter <= top_shop - top_shop_offset; counter++) SHOP_KEEPER(counter) -= (SHOP_KEEPER(counter) >= refpt); return TRUE; }
int add_quest(struct aq_data *nqst) { qst_rnum rnum; mob_rnum qmrnum; zone_rnum rznum = real_zone_by_thing(nqst->vnum); /* The quest already exists, just update it. */ if ((rnum = real_quest(nqst->vnum)) != NOWHERE) { copy_quest(&aquest_table[rnum], nqst, TRUE); } else { /* increase the number of quest table entries */ total_quests++; RECREATE(aquest_table, struct aq_data, total_quests ); /* Initialise top quest strings to null */ QST_NAME(total_quests - 1) = NULL; QST_DESC(total_quests - 1) = NULL; QST_INFO(total_quests - 1) = NULL; QST_DONE(total_quests - 1) = NULL; QST_QUIT(total_quests - 1) = NULL; /* Now process enties from the top down to see where the new one goes */ for (rnum = total_quests - 1; rnum > 0; rnum--) { if (nqst->vnum > QST_NUM(rnum - 1)) break; //found the place aquest_table[rnum] = aquest_table[rnum - 1]; //shift quest up one } copy_quest(&aquest_table[rnum], nqst, FALSE); } qmrnum = real_mobile(QST_MASTER(rnum)); /* Make sure we assign spec procs to the questmaster */ if (qmrnum != NOBODY && mob_index[qmrnum].func && mob_index[qmrnum].func != questmaster) QST_FUNC(rnum) = mob_index[qmrnum].func; if(qmrnum != NOBODY) mob_index[qmrnum].func = questmaster; /* And make sure we save the updated quest information to disk */ if (rznum != NOWHERE) add_to_save_list(zone_table[rznum].number, SL_QST); else mudlog(BRF, ADMLVL_BUILDER, TRUE, "SYSERR: GenOLC: Cannot determine quest zone."); return rnum; }
int delete_quest(qst_rnum rnum) { qst_rnum i; zone_rnum rznum; mob_vnum qm = QST_MASTER(rnum); SPECIAL (*tempfunc); int quests_remaining = 0; if (rnum >= total_quests) return FALSE; rznum = real_zone_by_thing(QST_NUM(rnum)); log("GenOLC: delete_quest: Deleting quest #%d (%s).", QST_NUM(rnum), QST_NAME(rnum)); /* make a note of the quest master's secondary spec proc */ tempfunc = QST_FUNC(rnum); free_quest_strings(&aquest_table[rnum]); for (i = rnum; i < total_quests - 1; i++) { aquest_table[i] = aquest_table[i + 1]; } total_quests--; if (total_quests > 0) RECREATE(aquest_table, struct aq_data, total_quests); else { free(aquest_table); aquest_table = NULL; } if (rznum != NOWHERE) add_to_save_list(zone_table[rznum].number, SL_QST); else mudlog(BRF, ADMLVL_BUILDER, TRUE, "SYSERR: GenOLC: Cannot determine quest zone."); /* does the questmaster mob have any quests left? */ if (qm != NOBODY) { for (i = 0; i < total_quests; i++) { if (QST_MASTER(i) == qm) quests_remaining++; } if (quests_remaining == 0) mob_index[qm].func = tempfunc; // point back to original spec proc } return TRUE; }
/* * Save all the information in the player's temporary buffer back into * the current zone table. */ void zedit_save_internally(struct descriptor_data *d) { int mobloaded = FALSE, objloaded = FALSE, subcmd = 0, room_num = real_room(OLC_NUM(d)); remove_room_zone_commands(OLC_ZNUM(d), room_num); /* * Now add all the entries in the players descriptor list */ for (subcmd = 0; MYCMD.command != 'S'; subcmd++) { add_cmd_to_list(&(zone_table[OLC_ZNUM(d)].cmd), &MYCMD, subcmd); /* * Since Circle does not keep track of what rooms the 'G', 'E', and * 'P' commands are exitted in, but OasisOLC groups zone commands * by rooms, this creates interesting problems when builders use these * commands without loading a mob or object first. This fix prevents such * commands from being saved and 'wandering' through the zone command * list looking for mobs/objects to latch onto. * C.Raehl 4/27/99 */ switch (MYCMD.command) { case 'M': mobloaded = TRUE; break; case 'G': case 'E': if (mobloaded) break; SEND_TO_Q("Equip/Give command not saved since no mob was loaded first.\r\n", d); remove_cmd_from_list(&(OLC_ZONE(d)->cmd), subcmd); break; case 'O': objloaded = TRUE; break; case 'P': if (objloaded) break; SEND_TO_Q("Put command not saved since another object was not loaded first.\r\n", d); remove_cmd_from_list(&(OLC_ZONE(d)->cmd), subcmd); break; default: mobloaded = objloaded = FALSE; break; } } /* * Finally, if zone headers have been changed, copy over */ if (OLC_ZONE(d)->number) { free(zone_table[OLC_ZNUM(d)].name); zone_table[OLC_ZNUM(d)].name = str_dup(OLC_ZONE(d)->name); zone_table[OLC_ZNUM(d)].top = OLC_ZONE(d)->top; zone_table[OLC_ZNUM(d)].reset_mode = OLC_ZONE(d)->reset_mode; zone_table[OLC_ZNUM(d)].lifespan = OLC_ZONE(d)->lifespan; } add_to_save_list(zone_table[OLC_ZNUM(d)].number, SL_ZON); }
int add_mobile(struct char_data *mob, mob_vnum vnum) { int rnum, i, found = FALSE, shop, cmd_no; zone_rnum zone; struct char_data *live_mob; if ((rnum = real_mobile(vnum)) != NOBODY) { /* Copy over the mobile and free() the old strings. */ copy_mobile(&mob_proto[rnum], mob); /* Now re-point all existing mobile strings to here. */ for (live_mob = character_list; live_mob; live_mob = live_mob->next) if (rnum == live_mob->nr) update_mobile_strings(live_mob, &mob_proto[rnum]); add_to_save_list(zone_table[real_zone_by_thing(vnum)].number, SL_MOB); log("GenOLC: add_mobile: Updated existing mobile #%d.", vnum); return TRUE; } RECREATE(mob_proto, struct char_data, top_of_mobt + 2); RECREATE(mob_index, struct index_data, top_of_mobt + 2); top_of_mobt++; for (i = top_of_mobt; i > 0; i--) { if (vnum > mob_index[i - 1].vnum) { mob_proto[i] = *mob; mob_proto[i].nr = i; copy_mobile_strings(mob_proto + i, mob); mob_index[i].vnum = vnum; mob_index[i].number = 0; mob_index[i].func = 0; found = i; break; } mob_index[i] = mob_index[i - 1]; mob_proto[i] = mob_proto[i - 1]; mob_proto[i].nr++; } if (!found) { mob_proto[0] = *mob; mob_proto[0].nr = 0; copy_mobile_strings(&mob_proto[0], mob); mob_index[0].vnum = vnum; mob_index[0].number = 0; mob_index[0].func = 0; } log("GenOLC: add_mobile: Added mobile %d at index #%d.", vnum, found); #if CONFIG_GENOLC_MOBPROG GET_MPROG(OLC_MOB(d)) = OLC_MPROGL(d); GET_MPROG_TYPE(OLC_MOB(d)) = (OLC_MPROGL(d) ? OLC_MPROGL(d)->type : 0); while (OLC_MPROGL(d)) { GET_MPROG_TYPE(OLC_MOB(d)) |= OLC_MPROGL(d)->type; OLC_MPROGL(d) = OLC_MPROGL(d)->next; } #endif /* * Update live mobile rnums. */ for (live_mob = character_list; live_mob; live_mob = live_mob->next) GET_MOB_RNUM(live_mob) += (GET_MOB_RNUM(live_mob) >= found); /* * Update zone table. */ for (zone = 0; zone <= top_of_zone_table; zone++) for (cmd_no = 0; ZCMD(zone, cmd_no).command != 'S'; cmd_no++) if (ZCMD(zone, cmd_no).command == 'M') ZCMD(zone, cmd_no).arg1 += (ZCMD(zone, cmd_no).arg1 >= found); /* * Update shop keepers. */ if (shop_index) for (shop = 0; shop <= top_shop - top_shop_offset; shop++) SHOP_KEEPER(shop) += (SHOP_KEEPER(shop) >= found); add_to_save_list(zone_table[real_zone_by_thing(vnum)].number, SL_MOB); return found; }
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; }
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); }
/************************************************************************\ ** Description : ** ** Removes a room from memory, updates the world list, and moves ** ** all of the objects, mobiles, and players to the void. ** ** ** ** Return Value: ** ** TRUE if successful...otherwise, FALSE. ** ** ** ** Parameters : ** ** rnum : The real number of the room requested to delete. ** \************************************************************************/ int remove_room_from_memory(room_rnum rnum) { struct char_data *tch; struct obj_data *obj; struct room_data *room; int i, j; if (rnum <= 0 || rnum > top_of_world) return FALSE; room = &world[rnum]; add_to_save_list(zone_table[room->zone].number, SL_WLD); log("GenOLC: delete_room: Deleting room #%d (%s).", room->number, room->name); /* * Dump the contents of this room into the void. We could also just * exract the people, mobs, and objects here. */ for (obj = world[rnum].contents; obj; obj = obj->next_content) { obj_from_room(obj); obj_to_room(obj, 0); } for (tch = world[rnum].people; tch; tch = tch->next_in_room) { char_from_room(tch); char_to_room(tch, 0); } free_room(room); /* * Change any exit going to this room to go to the void. This way, * the builders know when they type show errors. */ for (i = top_of_world; i >= 0; i--) for (j = 0; j < NUM_OF_DIRS; j++) if (W_EXIT(i, j) == NULL) continue; else if (W_EXIT(i, j)->to_room > rnum) W_EXIT(i, j)->to_room--; else if (W_EXIT(i, j)->to_room == rnum) W_EXIT(i, j)->to_room = 0; /* * Find what zone the room was in so we can update the loading table. */ for (i = 0; i <= top_of_zone_table; i++) for (j = 0; ZCMD(i, j).command != 'S'; j++) switch (ZCMD(i, j).command) { case 'M': case 'O': if (ZCMD(i, j).arg3 == rnum) ZCMD(i, j).command = '*'; /* Cancel Command */ else if (ZCMD(i, j).arg3 > rnum) ZCMD(i, j).arg3--; break; case 'D': case 'R': if (ZCMD(i, j).arg1 == rnum) ZCMD(i, j).command = '*'; /* Cancel Command */ else if (ZCMD(i, j).arg1 > rnum) ZCMD(i, j).arg1--; break; case 'G': case 'P': case 'E': case '*': /* Known zone entries we don't use here. */ break; default: mudlog(BRF, LVL_GOD, TRUE, "SYSERR: GenOLC: delete_room: Unknown zone entry found!"); } /* * Now we actually move the rooms down. */ for (i = rnum; i < top_of_world; i++) { world[i] = world[i + 1]; for (tch = world[i].people; tch; tch = tch->next_in_room) IN_ROOM(tch) -= (IN_ROOM(tch) != NOWHERE); /* Redundant Check? */ for (obj = world[i].contents; obj; obj = obj->next_content) IN_ROOM(obj) -= (IN_ROOM(obj) != NOWHERE); } top_of_world--; RECREATE(world, struct room_data, top_of_world + 1); return (TRUE); }
zone_rnum create_new_zone(zone_vnum vzone_num, const char **error) { FILE *fp; struct zone_data *zone; int i, room; zone_rnum rznum; if (vzone_num < 0) { *error = "You can't make negative zones.\r\n"; return NOWHERE; } 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; for (i = 0; i <= top_of_zone_table; i++) if (zone_table[i].number * 100 <= room && zone_table[i].top >= room) { *error = "A zone already covers that area.\r\n"; return NOWHERE; } /* * Create the zone file. */ sprintf(buf, "%s/%d.zon", ZON_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new zone file.", BRF, LVL_IMPL, TRUE); *error = "Could not write zone file.\r\n"; return NOWHERE; } fprintf(fp, "#%d\nNew Zone~\n%d 30 2\nS\n$\n", vzone_num, (vzone_num * 100) + 99); fclose(fp); /* * Create the room file. */ sprintf(buf, "%s/%d.wld", WLD_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new world file.", BRF, LVL_IMPL, TRUE); *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", vzone_num * 100, vzone_num); fclose(fp); /* * Create the mobile file. */ sprintf(buf, "%s/%d.mob", MOB_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new mob file.", BRF, LVL_IMPL, TRUE); *error = "Could not write mobile file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the object file. */ sprintf(buf, "%s/%d.obj", OBJ_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new obj file.", BRF, LVL_IMPL, TRUE); *error = "Could not write object file.\r\n"; return NOWHERE; } fprintf(fp, "$\n"); fclose(fp); /* * Create the shop file. */ sprintf(buf, "%s/%d.shp", SHP_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new shop file.", BRF, LVL_IMPL, TRUE); *error = "Could not write shop file.\r\n"; return NOWHERE; } fprintf(fp, "$~\n"); fclose(fp); /* * Create the quest file. */ sprintf(buf, "%s/%d.qst", QST_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new trigger file", BRF, LVL_IMPL, TRUE); 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, "qst"); /* * 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 = str_dup("New Zone"); zone->number = vzone_num; zone->top = (vzone_num * 100) + 99; 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; }
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; } 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; } /* 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; } fprintf(fp, "#%d\nNone~\nNew Zone~\n%d %d 30 2\nS\n$\n", vzone_num, bottom, top); 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. 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"); zone->bot = bottom; zone->top = top; 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; } 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; 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. */ 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; 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); }
/* * This function will copy the strings so be sure you free your own * copies of the description, title, and such. */ room_rnum add_room(struct room_data *room) { struct char_data *tch; struct obj_data *tobj; int i, j, found = FALSE; if (room == NULL) return NOWHERE; if ((i = real_room(room->number)) != NOWHERE) { tch = world[i].people; tobj = world[i].contents; copy_room(&world[i], room); world[i].people = tch; world[i].contents = tobj; add_to_save_list(zone_table[room->zone].number, SL_WLD); log("GenOLC: add_room: Updated existing room #%d.", room->number); return i; } RECREATE(world, struct room_data, top_of_world + 2); top_of_world++; for (i = top_of_world; i > 0; i--) { if (room->number > world[i - 1].number) { world[i] = *room; copy_room_strings(&world[i], room); found = i; break; } else { /* Copy the room over now. */ world[i] = world[i - 1]; /* People in this room must have their in_rooms moved up one. */ for (tch = world[i].people; tch; tch = tch->next_in_room) IN_ROOM(tch) += (IN_ROOM(tch) != NOWHERE); /* Move objects too. */ for (tobj = world[i].contents; tobj; tobj = tobj->next_content) IN_ROOM(tobj) += (IN_ROOM(tobj) != NOWHERE); } } if (!found) { world[0] = *room; /* Last place, in front. */ copy_room_strings(&world[0], room); } log("GenOLC: add_room: Added room %d at index #%d.", room->number, found); /* found is equal to the array index where we added the room. */ /* * Find what zone that room was in so we can update the loading table. */ for (i = room->zone; i <= top_of_zone_table; i++) for (j = 0; ZCMD(i, j).command != 'S'; j++) switch (ZCMD(i, j).command) { case 'M': case 'O': case 'T': case 'V': ZCMD(i, j).arg3 += (ZCMD(i, j).arg3 >= found); break; case 'D': case 'R': ZCMD(i, j).arg1 += (ZCMD(i, j).arg1 >= found); case 'G': case 'P': case 'E': case '*': /* Known zone entries we don't care about. */ break; default: mudlog(BRF, LVL_DEITY, TRUE, "SYSERR: GenOLC: add_room: Unknown zone entry found!"); } /* * Update the loadroom table. Adds 1 or 0. */ r_mortal_start_room += (r_mortal_start_room >= found); r_immort_start_room += (r_immort_start_room >= found); r_frozen_start_room += (r_frozen_start_room >= found); r_newbie_start_room += (r_newbie_start_room >= found); r_sorin_start_room += (r_sorin_start_room >= found); /* * Update world exits & triggers. */ for (i = top_of_world; i >= 0; i--) { /* exits */ for (j = 0; j < NUM_OF_DIRS; j++) if (W_EXIT(i, j)) W_EXIT(i, j)->to_room += (W_EXIT(i, j)->to_room >= found); /* TRIGGERS */ if(SCRIPT(&world[i])) { extract_script(SCRIPT(&world[i])); SCRIPT(&world[i]) = NULL; } assign_triggers(&world[i], WLD_TRIGGER); } add_to_save_list(zone_table[room->zone].number, SL_WLD); /* * Return what array entry we placed the new room in. */ return found; }
int delete_room(room_rnum rnum) { int i, j; struct char_data *ppl, *next_ppl; struct obj_data *obj, *next_obj; struct room_data *room; if (rnum <= 0 || rnum > top_of_world) /* Can't delete void yet. */ return FALSE; room = &world[rnum]; add_to_save_list(zone_table[room->zone].number, SL_WLD); /* This is something you might want to read about in the logs. */ log("GenOLC: delete_room: Deleting room #%d (%s).", room->number, room->name); if (r_mortal_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting mortal start room!"); r_mortal_start_room = 0; /* The Void */ } if (r_immort_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting immortal start room!"); r_immort_start_room = 0; /* The Void */ } if (r_newbie_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting newbie start room!"); r_newbie_start_room = 0; /* The Void */ } if (r_sorin_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting sorin start room!"); r_sorin_start_room = 0; /* The Void */ } if (r_frozen_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting frozen start room!"); r_frozen_start_room = 0; /* The Void */ } /* * Dump the contents of this room into the Void. We could also just * extract the people, mobs, and objects here. */ for (obj = world[rnum].contents; obj; obj = next_obj) { next_obj = obj->next_content; obj_from_room(obj); obj_to_room(obj, 0); } for (ppl = world[rnum].people; ppl; ppl = next_ppl) { next_ppl = ppl->next_in_room; char_from_room(ppl); char_to_room(ppl, 0); } free_room_strings(room); /* * Change any exit going to this room to go the void. * Also fix all the exits pointing to rooms above this. */ for (i = top_of_world; i >= 0; i--) for (j = 0; j < NUM_OF_DIRS; j++) if (W_EXIT(i, j) == NULL) continue; else if (W_EXIT(i, j)->to_room > rnum) W_EXIT(i, j)->to_room--; else if (W_EXIT(i, j)->to_room == rnum) W_EXIT(i, j)->to_room = 0; /* Some may argue -1. */ /* * Find what zone that room was in so we can update the loading table. */ for (i = 0; i <= top_of_zone_table; i++) for (j = 0; ZCMD(i , j).command != 'S'; j++) switch (ZCMD(i, j).command) { case 'M': case 'O': case 'T': case 'V': if (ZCMD(i, j).arg3 == rnum) ZCMD(i, j).command = '*'; /* Cancel command. */ else if (ZCMD(i, j).arg3 > rnum) ZCMD(i, j).arg3--; break; case 'D': case 'R': if (ZCMD(i, j).arg1 == rnum) ZCMD(i, j).command = '*'; /* Cancel command. */ else if (ZCMD(i, j).arg1 > rnum) ZCMD(i, j).arg1--; case 'G': case 'P': case 'E': case '*': /* Known zone entries we don't care about. */ break; default: mudlog(BRF, LVL_DEITY, TRUE, "SYSERR: GenOLC: delete_room: Unknown zone entry found!"); } /* * Now we actually move the rooms down. */ for (i = rnum; i < top_of_world; i++) { world[i] = world[i + 1]; for (ppl = world[i].people; ppl; ppl = ppl->next_in_room) IN_ROOM(ppl) -= (IN_ROOM(ppl) != NOWHERE); /* Redundant check? */ for (obj = world[i].contents; obj; obj = obj->next_content) IN_ROOM(obj) -= (IN_ROOM(obj) != NOWHERE); /* Redundant check? */ } top_of_world--; RECREATE(world, struct room_data, top_of_world + 1); return TRUE; }
int delete_room(room_rnum rnum) { room_rnum i; int j; struct char_data *ppl, *next_ppl; struct obj_data *obj, *next_obj; struct room_data *room; if (rnum <= 0 || rnum > top_of_world) /* Can't delete void yet. */ return FALSE; room = &world[rnum]; add_to_save_list(zone_table[room->zone].number, SL_WLD); /* remove from realnum lookup tree */ htree_del(room_htree, room->number); /* This is something you might want to read about in the logs. */ log("GenOLC: delete_room: Deleting room #%d (%s).", room->number, room->name); if (r_mortal_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting mortal start room!"); r_mortal_start_room = 0; /* The Void */ } if (r_immort_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting immortal start room!"); r_immort_start_room = 0; /* The Void */ } if (r_frozen_start_room == rnum) { log("WARNING: GenOLC: delete_room: Deleting frozen start room!"); r_frozen_start_room = 0; /* The Void */ } /* * Dump the contents of this room into the Void. We could also just * extract the people, mobs, and objects here. */ for (obj = world[rnum].contents; obj; obj = next_obj) { next_obj = obj->next_content; obj_from_room(obj); obj_to_room(obj, 0); } for (ppl = world[rnum].people; ppl; ppl = next_ppl) { next_ppl = ppl->next_in_room; char_from_room(ppl); char_to_room(ppl, 0); } free_room_strings(room); if (SCRIPT(room)) extract_script(room, WLD_TRIGGER); free_proto_script(room, WLD_TRIGGER); /* * Change any exit going to this room to go the void. * Also fix all the exits pointing to rooms above this. */ i = top_of_world + 1; do { i--; for (j = 0; j < NUM_OF_DIRS; j++) if (W_EXIT(i, j) == NULL) continue; else if (W_EXIT(i, j)->to_room > rnum) W_EXIT(i, j)->to_room -= (W_EXIT(i, j)->to_room != NOWHERE); /* with unsigned NOWHERE > any rnum */ else if (W_EXIT(i, j)->to_room == rnum) { if ((!W_EXIT(i, j)->keyword || !*W_EXIT(i, j)->keyword) && (!W_EXIT(i, j)->general_description || !*W_EXIT(i, j)->general_description)) { /* no description, remove exit completely */ if (W_EXIT(i, j)->keyword) free(W_EXIT(i, j)->keyword); if (W_EXIT(i, j)->general_description) free(W_EXIT(i, j)->general_description); free(W_EXIT(i, j)); W_EXIT(i, j) = NULL; } else { /* description is set, just point to nowhere */ W_EXIT(i, j)->to_room = NOWHERE; } } } while (i > 0); /* * Find what zone that room was in so we can update the loading table. */ for (i = 0; i <= top_of_zone_table; i++) for (j = 0; ZCMD(i , j).command != 'S'; j++) switch (ZCMD(i, j).command) { case 'M': case 'O': case 'T': case 'V': if (ZCMD(i, j).arg3 == rnum) ZCMD(i, j).command = '*'; /* Cancel command. */ else if (ZCMD(i, j).arg3 > rnum) ZCMD(i, j).arg3 -= (ZCMD(i, j).arg3 != NOWHERE); /* with unsigned NOWHERE > any rnum */ break; case 'D': case 'R': if (ZCMD(i, j).arg1 == rnum) ZCMD(i, j).command = '*'; /* Cancel command. */ else if (ZCMD(i, j).arg1 > rnum) ZCMD(i, j).arg1 -= (ZCMD(i, j).arg1 != NOWHERE); /* with unsigned NOWHERE > any rnum */ case 'G': case 'P': case 'E': case '*': /* Known zone entries we don't care about. */ break; default: mudlog(BRF, LVL_GOD, TRUE, "SYSERR: GenOLC: delete_room: Unknown zone entry found!"); } /* * Remove this room from all shop lists. */ { extern int top_shop; for (i = 0;i < top_shop;i++) { for (j = 0;SHOP_ROOM(i, j) != NOWHERE;j++) { if (SHOP_ROOM(i, j) == world[rnum].number) SHOP_ROOM(i, j) = 0; /* set to the void */ } } } /* * Now we actually move the rooms down. */ for (i = rnum; i < top_of_world; i++) { world[i] = world[i + 1]; update_wait_events(&world[i], &world[i+1]); for (ppl = world[i].people; ppl; ppl = ppl->next_in_room) IN_ROOM(ppl) -= (IN_ROOM(ppl) != NOWHERE); /* Redundant check? */ for (obj = world[i].contents; obj; obj = obj->next_content) IN_ROOM(obj) -= (IN_ROOM(obj) != NOWHERE); /* Redundant check? */ } top_of_world--; RECREATE(world, struct room_data, top_of_world + 1); return TRUE; }