/* * Idea by: Cris Jacobin <*****@*****.**> */ room_rnum duplicate_room(room_vnum dest_vnum, room_rnum orig) { int new_rnum, znum; struct room_data nroom; if (orig == NOWHERE || orig > top_of_world) { log("SYSERR: GenOLC: copy_room: Given bad original real room."); return -1; } else if ((znum = real_zone_by_thing(dest_vnum)) == NOWHERE) { log("SYSERR: GenOLC: copy_room: No such destination zone."); return -1; } /* * add_room will make its own copies of strings. */ if ((new_rnum = add_room(&nroom)) == NOWHERE) { log("SYSERR: GenOLC: copy_room: Problem adding room."); return -1; } nroom = world[new_rnum]; nroom.number = dest_vnum; nroom.zone = znum; /* So the people and objects aren't in two places at once... */ nroom.contents = NULL; nroom.people = NULL; return new_rnum; }
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; }
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; }
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); }
void medit_parse(struct descriptor_data *d, char *arg) { int i = -1, j; char *oldtext = NULL; if (OLC_MODE(d) > MEDIT_NUMERICAL_RESPONSE) { i = atoi(arg); if (!*arg || (!isdigit(arg[0]) && ((*arg == '-') && !isdigit(arg[1])))) { write_to_output(d, "Try again : "); return; } } else { /* String response. */ if (!genolc_checkstring(d, arg)) return; } switch (OLC_MODE(d)) { case MEDIT_CONFIRM_SAVESTRING: /* Ensure mob has MOB_ISNPC set. */ SET_BIT_AR(MOB_FLAGS(OLC_MOB(d)), MOB_ISNPC); switch (*arg) { case 'y': case 'Y': /* Save the mob in memory and to disk. */ medit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits mob %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { medit_save_to_disk(zone_table[real_zone_by_thing(OLC_NUM(d))].number); write_to_output(d, "Mobile saved to disk.\r\n"); } else write_to_output(d, "Mobile saved to memory.\r\n"); cleanup_olc(d, CLEANUP_ALL); return; case 'n': case 'N': /* If not saving, we must free the script_proto list. We do so by * assigning it to the edited mob and letting free_mobile in * cleanup_olc handle it. */ OLC_MOB(d)->proto_script = OLC_SCRIPT(d); cleanup_olc(d, CLEANUP_ALL); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save your changes? : "); return; } break; case MEDIT_MAIN_MENU: i = 0; switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /* Anything been changed? */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': OLC_MODE(d) = MEDIT_SEX; medit_disp_sex(d); return; case '2': OLC_MODE(d) = MEDIT_KEYWORD; i--; break; case '3': OLC_MODE(d) = MEDIT_S_DESC; i--; break; case '4': OLC_MODE(d) = MEDIT_L_DESC; i--; break; case '5': OLC_MODE(d) = MEDIT_D_DESC; send_editor_help(d); write_to_output(d, "Enter mob description:\r\n\r\n"); if (OLC_MOB(d)->player.description) { write_to_output(d, "%s", OLC_MOB(d)->player.description); oldtext = strdup(OLC_MOB(d)->player.description); } string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext); OLC_VAL(d) = 1; return; case '6': OLC_MODE(d) = MEDIT_POS; medit_disp_positions(d); return; case '7': OLC_MODE(d) = MEDIT_DEFAULT_POS; medit_disp_positions(d); return; case '8': OLC_MODE(d) = MEDIT_ATTACK; medit_disp_attack_types(d); return; case '9': OLC_MODE(d) = MEDIT_STATS_MENU; medit_disp_stats_menu(d); return; case 'a': case 'A': OLC_MODE(d) = MEDIT_NPC_FLAGS; medit_disp_mob_flags(d); return; case 'b': case 'B': OLC_MODE(d) = MEDIT_AFF_FLAGS; medit_disp_aff_flags(d); return; case 'w': case 'W': write_to_output(d, "Copy what mob? "); OLC_MODE(d) = MEDIT_COPY; return; case 'x': case 'X': write_to_output(d, "Are you sure you want to delete this mobile? "); OLC_MODE(d) = MEDIT_DELETE; return; case 's': case 'S': OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); return; default: medit_disp_menu(d); return; } if (i == 0) break; else if (i == 1) write_to_output(d, "\r\nEnter new value : "); else if (i == -1) write_to_output(d, "\r\nEnter new text :\r\n] "); else write_to_output(d, "Oops...\r\n"); return; case MEDIT_STATS_MENU: i=0; switch(*arg) { case 'q': case 'Q': medit_disp_menu(d); return; case '1': /* Edit level */ OLC_MODE(d) = MEDIT_LEVEL; i++; break; case '2': /* Autoroll stats */ medit_autoroll_stats(d); medit_disp_stats_menu(d); OLC_VAL(d) = TRUE; return; case '3': OLC_MODE(d) = MEDIT_NUM_HP_DICE; i++; break; case '4': OLC_MODE(d) = MEDIT_SIZE_HP_DICE; i++; break; case '5': OLC_MODE(d) = MEDIT_ADD_HP; i++; break; case '6': OLC_MODE(d) = MEDIT_NDD; i++; break; case '7': OLC_MODE(d) = MEDIT_SDD; i++; break; case '8': OLC_MODE(d) = MEDIT_DAMROLL; i++; break; case 'a': case 'A': OLC_MODE(d) = MEDIT_AC; i++; break; case 'b': case 'B': OLC_MODE(d) = MEDIT_EXP; i++; break; case 'c': case 'C': OLC_MODE(d) = MEDIT_GOLD; i++; break; case 'd': case 'D': OLC_MODE(d) = MEDIT_HITROLL; i++; break; case 'e': case 'E': OLC_MODE(d) = MEDIT_ALIGNMENT; i++; break; case 'f': case 'F': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_STR; i++; break; case 'g': case 'G': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_INT; i++; break; case 'h': case 'H': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_WIS; i++; break; case 'i': case 'I': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_DEX; i++; break; case 'j': case 'J': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_CON; i++; break; case 'k': case 'K': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_CHA; i++; break; case 'l': case 'L': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_PARA; i++; break; case 'm': case 'M': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_ROD; i++; break; case 'n': case 'N': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_PETRI; i++; break; case 'o': case 'O': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_BREATH; i++; break; case 'p': case 'P': if (!CONFIG_MEDIT_ADVANCED) { write_to_output(d, "Invalid Choice!\r\nEnter Choice : "); return; } OLC_MODE(d) = MEDIT_SPELL; i++; break; default: medit_disp_stats_menu(d); return; } if (i == 0) break; else if (i == 1) write_to_output(d, "\r\nEnter new value : "); else if (i == -1) write_to_output(d, "\r\nEnter new text :\r\n] "); else write_to_output(d, "Oops...\r\n"); return; case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case MEDIT_KEYWORD: smash_tilde(arg); if (GET_ALIAS(OLC_MOB(d))) free(GET_ALIAS(OLC_MOB(d))); GET_ALIAS(OLC_MOB(d)) = str_udup(arg); break; case MEDIT_S_DESC: smash_tilde(arg); if (GET_SDESC(OLC_MOB(d))) free(GET_SDESC(OLC_MOB(d))); GET_SDESC(OLC_MOB(d)) = str_udup(arg); break; case MEDIT_L_DESC: smash_tilde(arg); if (GET_LDESC(OLC_MOB(d))) free(GET_LDESC(OLC_MOB(d))); if (arg && *arg) { char buf[MAX_INPUT_LENGTH]; snprintf(buf, sizeof(buf), "%s\r\n", arg); GET_LDESC(OLC_MOB(d)) = strdup(buf); } else GET_LDESC(OLC_MOB(d)) = strdup("undefined"); break; case MEDIT_D_DESC: /* * We should never get here. */ cleanup_olc(d, CLEANUP_ALL); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached D_DESC case!"); write_to_output(d, "Oops...\r\n"); break; case MEDIT_NPC_FLAGS: if ((i = atoi(arg)) <= 0) break; else if ( (j = medit_get_mob_flag_by_number(i)) == -1) { write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Enter mob flags (0 to quit) :"); return; } else if (j <= NUM_MOB_FLAGS) { TOGGLE_BIT_AR(MOB_FLAGS(OLC_MOB(d)), (j)); } medit_disp_mob_flags(d); return; case MEDIT_AFF_FLAGS: if ((i = atoi(arg)) <= 0) break; else if (i <= NUM_AFF_FLAGS) TOGGLE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), i); /* Remove unwanted bits right away. */ REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_CHARM); REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_POISON); REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_GROUP); REMOVE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), AFF_SLEEP); medit_disp_aff_flags(d); return; /* Numerical responses. */ case MEDIT_SEX: GET_SEX(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_GENDERS - 1); break; case MEDIT_HITROLL: GET_HITROLL(OLC_MOB(d)) = LIMIT(i, 0, 50); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_DAMROLL: GET_DAMROLL(OLC_MOB(d)) = LIMIT(i, 0, 50); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_NDD: GET_NDD(OLC_MOB(d)) = LIMIT(i, 0, 30); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_SDD: GET_SDD(OLC_MOB(d)) = LIMIT(i, 0, 127); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_NUM_HP_DICE: GET_HIT(OLC_MOB(d)) = LIMIT(i, 0, 30); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_SIZE_HP_DICE: GET_MANA(OLC_MOB(d)) = LIMIT(i, 0, 1000); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_ADD_HP: GET_MOVE(OLC_MOB(d)) = LIMIT(i, 0, 30000); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_AC: GET_AC(OLC_MOB(d)) = LIMIT(i, -200, 200); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_EXP: GET_EXP(OLC_MOB(d)) = LIMIT(i, 0, MAX_MOB_EXP); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_GOLD: GET_GOLD(OLC_MOB(d)) = LIMIT(i, 0, MAX_MOB_GOLD); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_STR: GET_STR(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_INT: GET_INT(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_WIS: GET_WIS(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_DEX: GET_DEX(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_CON: GET_CON(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_CHA: GET_CHA(OLC_MOB(d)) = LIMIT(i, 11, 25); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_PARA: GET_SAVE(OLC_MOB(d), SAVING_PARA) = LIMIT(i, 0, 100); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_ROD: GET_SAVE(OLC_MOB(d), SAVING_ROD) = LIMIT(i, 0, 100); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_PETRI: GET_SAVE(OLC_MOB(d), SAVING_PETRI) = LIMIT(i, 0, 100); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_BREATH: GET_SAVE(OLC_MOB(d), SAVING_BREATH) = LIMIT(i, 0, 100); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_SPELL: GET_SAVE(OLC_MOB(d), SAVING_SPELL) = LIMIT(i, 0, 100); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_POS: GET_POS(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_POSITIONS - 1); break; case MEDIT_DEFAULT_POS: GET_DEFAULT_POS(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_POSITIONS - 1); break; case MEDIT_ATTACK: GET_ATTACK(OLC_MOB(d)) = LIMIT(i, 0, NUM_ATTACK_TYPES - 1); break; case MEDIT_LEVEL: GET_LEVEL(OLC_MOB(d)) = LIMIT(i, 1, LVL_IMPL); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_ALIGNMENT: GET_ALIGNMENT(OLC_MOB(d)) = LIMIT(i, -1000, 1000); OLC_VAL(d) = TRUE; medit_disp_stats_menu(d); return; case MEDIT_COPY: if ((i = real_mobile(atoi(arg))) != NOWHERE) { medit_setup_existing(d, i); } else write_to_output(d, "That mob does not exist.\r\n"); break; case MEDIT_DELETE: if (*arg == 'y' || *arg == 'Y') { if (delete_mobile(GET_MOB_RNUM(OLC_MOB(d))) != NOBODY) write_to_output(d, "Mobile deleted.\r\n"); else write_to_output(d, "Couldn't delete the mobile!\r\n"); cleanup_olc(d, CLEANUP_ALL); return; } else if (*arg == 'n' || *arg == 'N') { medit_disp_menu(d); OLC_MODE(d) = MEDIT_MAIN_MENU; return; } else write_to_output(d, "Please answer 'Y' or 'N': "); break; default: /* We should never get here. */ cleanup_olc(d, CLEANUP_ALL); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached default case!"); write_to_output(d, "Oops...\r\n"); break; } /* END OF CASE If we get here, we have probably changed something, and now want to return to main menu. Use OLC_VAL as a 'has changed' flag */ OLC_VAL(d) = TRUE; medit_disp_menu(d); }
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; }
void sedit_parse(struct descriptor_data *d, char *arg) { int i; if (OLC_MODE(d) > SEDIT_NUMERICAL_RESPONSE) { if (!isdigit(arg[0]) && ((*arg == '-') && (!isdigit(arg[1])))) { write_to_output(d, "Field must be numerical, try again : "); return; } } switch (OLC_MODE(d)) { /*-------------------------------------------------------------------*/ case SEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': sedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits shop %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { sedit_save_to_disk(real_zone_by_thing(OLC_NUM(d))); write_to_output(d, "Shop saved to disk.\r\n"); } else write_to_output(d, "Shop saved to memory.\r\n"); cleanup_olc(d, CLEANUP_STRUCTS); return; case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); return; default: write_to_output(d, "Invalid choice!\r\nDo you wish to save your changes? : "); return; } break; /*-------------------------------------------------------------------*/ case SEDIT_MAIN_MENU: i = 0; switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /* Anything been changed? */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = SEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '0': OLC_MODE(d) = SEDIT_KEEPER; write_to_output(d, "Enter vnum number of shop keeper : "); return; case '1': OLC_MODE(d) = SEDIT_OPEN1; i++; break; case '2': OLC_MODE(d) = SEDIT_CLOSE1; i++; break; case '3': OLC_MODE(d) = SEDIT_OPEN2; i++; break; case '4': OLC_MODE(d) = SEDIT_CLOSE2; i++; break; case '5': OLC_MODE(d) = SEDIT_BUY_PROFIT; i++; break; case '6': OLC_MODE(d) = SEDIT_SELL_PROFIT; i++; break; case '7': OLC_MODE(d) = SEDIT_NOITEM1; i--; break; case '8': OLC_MODE(d) = SEDIT_NOITEM2; i--; break; case '9': OLC_MODE(d) = SEDIT_NOCASH1; i--; break; case 'a': case 'A': OLC_MODE(d) = SEDIT_NOCASH2; i--; break; case 'b': case 'B': OLC_MODE(d) = SEDIT_NOBUY; i--; break; case 'c': case 'C': OLC_MODE(d) = SEDIT_BUY; i--; break; case 'd': case 'D': OLC_MODE(d) = SEDIT_SELL; i--; break; case 'e': case 'E': sedit_no_trade_menu(d); return; case 'f': case 'F': sedit_shop_flags_menu(d); return; case 'r': case 'R': sedit_rooms_menu(d); return; case 'p': case 'P': sedit_products_menu(d); return; case 't': case 'T': sedit_namelist_menu(d); return; default: sedit_disp_menu(d); return; } if (i == 0) break; else if (i == 1) write_to_output(d, "\r\nEnter new value : "); else if (i == -1) write_to_output(d, "\r\nEnter new text :\r\n] "); else write_to_output(d, "Oops...\r\n"); return; /*-------------------------------------------------------------------*/ case SEDIT_NAMELIST_MENU: switch (*arg) { case 'a': case 'A': sedit_types_menu(d); return; case 'd': case 'D': write_to_output(d, "\r\nDelete which entry? : "); OLC_MODE(d) = SEDIT_DELETE_TYPE; return; case 'q': case 'Q': break; } break; /*-------------------------------------------------------------------*/ case SEDIT_PRODUCTS_MENU: switch (*arg) { case 'a': case 'A': write_to_output(d, "\r\nEnter new product vnum number : "); OLC_MODE(d) = SEDIT_NEW_PRODUCT; return; case 'd': case 'D': write_to_output(d, "\r\nDelete which product? : "); OLC_MODE(d) = SEDIT_DELETE_PRODUCT; return; case 'q': case 'Q': break; } break; /*-------------------------------------------------------------------*/ case SEDIT_ROOMS_MENU: switch (*arg) { case 'a': case 'A': write_to_output(d, "\r\nEnter new room vnum number : "); OLC_MODE(d) = SEDIT_NEW_ROOM; return; case 'c': case 'C': sedit_compact_rooms_menu(d); return; case 'l': case 'L': sedit_rooms_menu(d); return; case 'd': case 'D': write_to_output(d, "\r\nDelete which room? : "); OLC_MODE(d) = SEDIT_DELETE_ROOM; return; case 'q': case 'Q': break; } break; /*-------------------------------------------------------------------*/ /* * String edits. */ case SEDIT_NOITEM1: if (genolc_checkstring(d, arg)) modify_string(&S_NOITEM1(OLC_SHOP(d)), arg); break; case SEDIT_NOITEM2: if (genolc_checkstring(d, arg)) modify_string(&S_NOITEM2(OLC_SHOP(d)), arg); break; case SEDIT_NOCASH1: if (genolc_checkstring(d, arg)) modify_string(&S_NOCASH1(OLC_SHOP(d)), arg); break; case SEDIT_NOCASH2: if (genolc_checkstring(d, arg)) modify_string(&S_NOCASH2(OLC_SHOP(d)), arg); break; case SEDIT_NOBUY: if (genolc_checkstring(d, arg)) modify_string(&S_NOBUY(OLC_SHOP(d)), arg); break; case SEDIT_BUY: if (genolc_checkstring(d, arg)) modify_string(&S_BUY(OLC_SHOP(d)), arg); break; case SEDIT_SELL: if (genolc_checkstring(d, arg)) modify_string(&S_SELL(OLC_SHOP(d)), arg); break; case SEDIT_NAMELIST: if (genolc_checkstring(d, arg)) { struct shop_buy_data new_entry; BUY_TYPE(new_entry) = OLC_VAL(d); BUY_WORD(new_entry) = strdup(arg); add_to_type_list(&(S_NAMELISTS(OLC_SHOP(d))), &new_entry); } sedit_namelist_menu(d); return; /*-------------------------------------------------------------------*/ /* * Numerical responses. */ case SEDIT_KEEPER: i = atoi(arg); if ((i = atoi(arg)) != -1) if ((i = real_mobile(i)) == NOBODY) { write_to_output(d, "That mobile does not exist, try again : "); return; } S_KEEPER(OLC_SHOP(d)) = i; if (i == -1) break; /* * Fiddle with special procs. */ S_FUNC(OLC_SHOP(d)) = mob_index[i].func != shop_keeper ? mob_index[i].func : NULL; mob_index[i].func = shop_keeper; break; case SEDIT_OPEN1: S_OPEN1(OLC_SHOP(d)) = LIMIT(atoi(arg), 0, 28); break; case SEDIT_OPEN2: S_OPEN2(OLC_SHOP(d)) = LIMIT(atoi(arg), 0, 28); break; case SEDIT_CLOSE1: S_CLOSE1(OLC_SHOP(d)) = LIMIT(atoi(arg), 0, 28); break; case SEDIT_CLOSE2: S_CLOSE2(OLC_SHOP(d)) = LIMIT(atoi(arg), 0, 28); break; case SEDIT_BUY_PROFIT: sscanf(arg, "%f", &S_BUYPROFIT(OLC_SHOP(d))); break; case SEDIT_SELL_PROFIT: sscanf(arg, "%f", &S_SELLPROFIT(OLC_SHOP(d))); break; case SEDIT_TYPE_MENU: OLC_VAL(d) = LIMIT(atoi(arg), 0, NUM_ITEM_TYPES - 1); write_to_output(d, "Enter namelist (return for none) :-\r\n] "); OLC_MODE(d) = SEDIT_NAMELIST; return; case SEDIT_DELETE_TYPE: remove_from_type_list(&(S_NAMELISTS(OLC_SHOP(d))), atoi(arg)); sedit_namelist_menu(d); return; case SEDIT_NEW_PRODUCT: if ((i = atoi(arg)) != -1) if ((i = real_object(i)) == NOTHING) { write_to_output(d, "That object does not exist, try again : "); return; } if (i > 0) add_to_int_list(&(S_PRODUCTS(OLC_SHOP(d))), i); sedit_products_menu(d); return; case SEDIT_DELETE_PRODUCT: remove_from_int_list(&(S_PRODUCTS(OLC_SHOP(d))), atoi(arg)); sedit_products_menu(d); return; case SEDIT_NEW_ROOM: if ((i = atoi(arg)) != -1) if ((i = real_room(i)) == NOWHERE) { write_to_output(d, "That room does not exist, try again : "); return; } if (i >= 0) add_to_int_list(&(S_ROOMS(OLC_SHOP(d))), atoi(arg)); sedit_rooms_menu(d); return; case SEDIT_DELETE_ROOM: remove_from_int_list(&(S_ROOMS(OLC_SHOP(d))), atoi(arg)); sedit_rooms_menu(d); return; case SEDIT_SHOP_FLAGS: if ((i = LIMIT(atoi(arg), 0, NUM_SHOP_FLAGS)) > 0) { TOGGLE_BIT(S_BITVECTOR(OLC_SHOP(d)), 1 << (i - 1)); sedit_shop_flags_menu(d); return; } break; case SEDIT_NOTRADE: if ((i = LIMIT(atoi(arg), 0, NUM_TRADERS)) > 0) { TOGGLE_BIT(S_NOTRADE(OLC_SHOP(d)), 1 << (i - 1)); sedit_no_trade_menu(d); return; } break; /*-------------------------------------------------------------------*/ default: /* * We should never get here. */ cleanup_olc(d, CLEANUP_ALL); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: sedit_parse(): Reached default case!"); write_to_output(d, "Oops...\r\n"); break; } /*-------------------------------------------------------------------*/ /* * END OF CASE * If we get here, we have probably changed something, and now want to * return to main menu. Use OLC_VAL as a 'has changed' flag. */ OLC_VAL(d) = 1; sedit_disp_menu(d); }
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); }
void oedit_parse(struct descriptor_data *d, char *arg) { int number, max_val, min_val; char *oldtext = NULL; struct board_info *tmp; struct obj_data *obj; obj_rnum robj; switch (OLC_MODE(d)) { case OEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': oedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { oedit_save_to_disk(real_zone_by_thing(OLC_NUM(d))); write_to_output(d, "Object saved to disk.\r\n"); } else write_to_output(d, "Object saved to memory.\r\n"); if (GET_OBJ_TYPE(OLC_OBJ(d)) == ITEM_BOARD) { if ((tmp=locate_board(GET_OBJ_VNUM(OLC_OBJ(d)))) != NULL) { save_board(tmp); } else { tmp = create_new_board(GET_OBJ_VNUM(OLC_OBJ(d))); BOARD_NEXT(tmp) = bboards; bboards = tmp; } } /* Fall through. */ case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); return; case 'a': /* abort quit */ case 'A': oedit_disp_menu(d); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save your changes? : \r\n"); return; } case OEDIT_MAIN_MENU: /* * Throw us out to whichever edit mode based on user input. */ switch (*arg) { case 'q': case 'Q': if (STATE(d) != CON_IEDIT) { if (OLC_VAL(d)) { /* Something has been modified. */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); } else { send_to_char(d->character, "\r\nCommitting iedit changes.\r\n"); obj = OLC_IOBJ(d); *obj = *(OLC_OBJ(d)); GET_ID(obj) = max_obj_id++; /* find_obj helper */ add_to_lookup_table(GET_ID(obj), (void *)obj); if (GET_OBJ_VNUM(obj) != NOTHING) { /* remove any old scripts */ if (SCRIPT(obj)) { extract_script(obj, OBJ_TRIGGER); SCRIPT(obj) = NULL; } free_proto_script(obj, OBJ_TRIGGER); robj = real_object(GET_OBJ_VNUM(obj)); copy_proto_script(&obj_proto[robj], obj, OBJ_TRIGGER); assign_triggers(obj, OBJ_TRIGGER); } SET_BIT_AR(GET_OBJ_EXTRA(obj), ITEM_UNIQUE_SAVE); /* Xap - ought to save the old pointer, free after assignment I suppose */ mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s iedit a unique #%d", GET_NAME(d->character), GET_OBJ_VNUM(obj)); if (d->character) { REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING); STATE(d) = CON_PLAYING; act("$n stops using OLC.", TRUE, d->character, 0, 0, TO_ROOM); } free(d->olc); d->olc = NULL; } return; case '1': write_to_output(d, "Enter namelist : "); OLC_MODE(d) = OEDIT_EDIT_NAMELIST; break; case '2': write_to_output(d, "Enter short desc : "); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': write_to_output(d, "Enter long desc :-\r\n| "); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); write_to_output(d, "Enter action description:\r\n\r\n"); if (OLC_OBJ(d)->action_description) { write_to_output(d, "%s", OLC_OBJ(d)->action_description); oldtext = strdup(OLC_OBJ(d)->action_description); } string_write(d, &OLC_OBJ(d)->action_description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; break; case '5': oedit_disp_type_menu(d); OLC_MODE(d) = OEDIT_TYPE; break; case '6': oedit_disp_extra_menu(d); OLC_MODE(d) = OEDIT_EXTRAS; break; case '7': oedit_disp_wear_menu(d); OLC_MODE(d) = OEDIT_WEAR; break; case '8': write_to_output(d, "Enter weight : "); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': write_to_output(d, "Enter cost : "); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': write_to_output(d, "Enter cost per day : "); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': write_to_output(d, "Enter timer : "); OLC_MODE(d) = OEDIT_TIMER; break; case 'c': case 'C': /* * Clear any old values */ GET_OBJ_VAL(OLC_OBJ(d), 0) = 0; GET_OBJ_VAL(OLC_OBJ(d), 1) = 0; GET_OBJ_VAL(OLC_OBJ(d), 2) = 0; GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; OLC_VAL(d) = 1; oedit_disp_val1_menu(d); break; case 'd': case 'D': oedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* * If extra descriptions don't exist. */ if (OLC_OBJ(d)->ex_description == NULL) { CREATE(OLC_OBJ(d)->ex_description, struct extra_descr_data, 1); OLC_OBJ(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_OBJ(d)->ex_description; oedit_disp_extradesc_menu(d); break; case 'm': case 'M': write_to_output(d, "Enter new minimum level: "); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; case 's': case 'S': if (STATE(d) != CON_IEDIT) { OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); } else { write_to_output(d, "\r\nScripts cannot be modified on individual objects.\r\nEnter choice : "); } return; default: oedit_disp_menu(d); break; } return; /* * end of OEDIT_MAIN_MENU */ case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case OEDIT_EDIT_NAMELIST: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->name) free(OLC_OBJ(d)->name); OLC_OBJ(d)->name = str_udup(arg); break; case OEDIT_SHORTDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->short_description) free(OLC_OBJ(d)->short_description); OLC_OBJ(d)->short_description = str_udup(arg); break; case OEDIT_LONGDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->description) free(OLC_OBJ(d)->description); OLC_OBJ(d)->description = str_udup(arg); break; case OEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number >= NUM_ITEM_TYPES)) { write_to_output(d, "Invalid choice, try again : "); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; /* what's the boundschecking worth if we don't do this ? -- Welcor */ GET_OBJ_VAL(OLC_OBJ(d), 0) = GET_OBJ_VAL(OLC_OBJ(d), 1) = GET_OBJ_VAL(OLC_OBJ(d), 2) = GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; break; case OEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_FLAGS)) { oedit_disp_extra_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT_AR(GET_OBJ_EXTRA(OLC_OBJ(d)), number - 1); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { write_to_output(d, "That's not a valid choice!\r\n"); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT_AR(GET_OBJ_WEAR(OLC_OBJ(d)), (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_WEIGHT); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_COST); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_RENT); break; case OEDIT_TIMER: switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_PORTAL: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), -1, MAX_OBJ_TIMER); break; default: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_TIMER); break; } break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, LVL_IMPL); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) { /* Setting AFF_CHARM on objects like this is dangerous. */ if (number != AFF_CHARM) { TOGGLE_BIT_AR(GET_OBJ_PERM(OLC_OBJ(d)), number); } } oedit_disp_perm_menu(d); return; case OEDIT_VALUE_1: /* * Lucky, I don't need to check any of these for out of range values. * Hmm, I'm not so sure - Rv */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 0) = MIN(MAX(atoi(arg), -50), 50); break; case ITEM_CONTAINER: GET_OBJ_VAL(OLC_OBJ(d), 0) = LIMIT(atoi(arg), -1, MAX_CONTAINER_SIZE); break; default: GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg); } /* * proceed to menu 2 */ oedit_disp_val2_menu(d); return; case OEDIT_VALUE_2: /* * Here, I do need to check for out of range values. */ number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) GET_OBJ_VAL(OLC_OBJ(d), 1) = -1; else GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, NUM_SPELLS-1); oedit_disp_val3_menu(d); break; case ITEM_CONTAINER: case ITEM_VEHICLE: case ITEM_HATCH: case ITEM_WINDOW: case ITEM_PORTAL: /* * Needs some special handling since we are dealing with flag values * here. */ if (number < 0 || number > 4) oedit_disp_container_flags_menu(d); else if (number != 0) { TOGGLE_BIT(GET_OBJ_VAL(OLC_OBJ(d), 1), 1 << (number - 1)); OLC_VAL(d) = 1; oedit_disp_val2_menu(d); } else oedit_disp_val3_menu(d); break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, MAX_WEAPON_NDICE); oedit_disp_val3_menu(d); break; default: GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } return; case OEDIT_VALUE_3: number = atoi(arg); /* * Quick'n'easy error checking. */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 2) = -1; oedit_disp_val4_menu(d); return; } min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 1; max_val = MAX_WEAPON_SDICE; break; case ITEM_WAND: case ITEM_STAFF: min_val = 0; max_val = 20; break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: min_val = 0; max_val = NUM_LIQ_TYPES - 1; break; case ITEM_KEY: min_val = 0; max_val = 32099; break; default: min_val = -32000; max_val = 32000; } GET_OBJ_VAL(OLC_OBJ(d), 2) = LIMIT(number, min_val, max_val); oedit_disp_val4_menu(d); return; case OEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 3) = -1; oedit_disp_menu(d); return; } min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WAND: case ITEM_STAFF: min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 0; max_val = NUM_ATTACK_TYPES - 1; break; default: min_val = -32000; max_val = 32000; break; } GET_OBJ_VAL(OLC_OBJ(d), 3) = LIMIT(number, min_val, max_val); break; case OEDIT_PROMPT_APPLY: if ((number = atoi(arg)) == 0) break; else if (number < 0 || number > MAX_OBJ_AFFECT) { oedit_disp_prompt_apply_menu(d); return; } OLC_VAL(d) = number - 1; OLC_MODE(d) = OEDIT_APPLY; oedit_disp_apply_menu(d); return; case OEDIT_APPLY: if ((number = atoi(arg)) == 0) { OLC_OBJ(d)->affected[OLC_VAL(d)].location = 0; OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = 0; oedit_disp_prompt_apply_menu(d); } else if (number < 0 || number >= NUM_APPLIES) oedit_disp_apply_menu(d); else { int counter; /* add in check here if already applied.. deny builders another */ if (GET_LEVEL(d->character) < LVL_IMPL) { for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].location == number) { write_to_output(d, "Object already has that apply."); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number; write_to_output(d, "Modifier : "); OLC_MODE(d) = OEDIT_APPLYMOD; } return; case OEDIT_APPLYMOD: OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = atoi(arg); oedit_disp_prompt_apply_menu(d); return; case OEDIT_EXTRADESC_KEY: if (genolc_checkstring(d, arg)) { if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); OLC_DESC(d)->keyword = str_udup(arg); } oedit_disp_extradesc_menu(d); return; case OEDIT_EXTRADESC_MENU: switch ((number = atoi(arg))) { case 0: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data *temp; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* * Clean up pointers */ REMOVE_FROM_LIST(OLC_DESC(d), OLC_OBJ(d)->ex_description, next); free(OLC_DESC(d)); OLC_DESC(d) = NULL; } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; write_to_output(d, "Enter keywords, separated by spaces :-\r\n| "); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); write_to_output(d, "Enter the extra description:\r\n\r\n"); if (OLC_DESC(d)->description) { write_to_output(d, "%s", OLC_DESC(d)->description); oldtext = strdup(OLC_DESC(d)->description); } string_write(d, &OLC_DESC(d)->description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; return; case 3: /* * Only go to the next description if this one is finished. */ if (OLC_DESC(d)->keyword && OLC_DESC(d)->description) { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* Make new extra description and attach at end. */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = OLC_DESC(d)->next; } } /* * No break - drop into default case. */ default: oedit_disp_extradesc_menu(d); return; } break; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: Reached default case in oedit_parse()!"); write_to_output(d, "Oops...\r\n"); break; }
int delete_object(obj_rnum rnum) { obj_rnum i; zone_rnum zrnum; struct obj_data *obj, *tmp, *next_tmp; int shop, j, zone, cmd_no; if (rnum == NOTHING || rnum > top_of_objt) return NOTHING; obj = &obj_proto[rnum]; zrnum = real_zone_by_thing(GET_OBJ_VNUM(obj)); /* This is something you might want to read about in the logs. */ log("GenOLC: delete_object: Deleting object #%d (%s).", GET_OBJ_VNUM(obj), obj->short_description); for (tmp = object_list; tmp; tmp = next_tmp) { next_tmp = tmp->next; if (tmp->item_number != obj->item_number) continue; /* extract_obj() will just axe contents. */ if (tmp->contains) { struct obj_data *this_content, *next_content; for (this_content = tmp->contains; this_content; this_content = next_content) { next_content = this_content->next_content; if (IN_ROOM(tmp)) { /* Transfer stuff from object to room. */ obj_from_obj(this_content); obj_to_room(this_content, IN_ROOM(tmp)); } else if (tmp->worn_by || tmp->carried_by) { /* Transfer stuff from object to person inventory. */ obj_from_char(this_content); obj_to_char(this_content, tmp->carried_by); } else if (tmp->in_obj) { /* Transfer stuff from object to containing object. */ obj_from_obj(this_content); obj_to_obj(this_content, tmp->in_obj); } } } /* Remove from object_list, etc. - handles weightchanges, and similar. */ extract_obj(tmp); } /* Make sure all are removed. */ assert(obj_index[rnum].number == 0); /* Adjust rnums of all other objects. */ for (tmp = object_list; tmp; tmp = tmp->next) { GET_OBJ_RNUM(tmp) -= (GET_OBJ_RNUM(tmp) > rnum); } for (i = rnum; i < top_of_objt; i++) { obj_index[i] = obj_index[i + 1]; obj_proto[i] = obj_proto[i + 1]; obj_proto[i].item_number = i; } top_of_objt--; RECREATE(obj_index, struct index_data, top_of_objt + 1); RECREATE(obj_proto, struct obj_data, top_of_objt + 1); /* Renumber notice boards. */ for (j = 0; j < NUM_OF_BOARDS; j++) BOARD_RNUM(j) -= (BOARD_RNUM(j) > rnum); /* Renumber shop produce. */ for (shop = 0; shop <= top_shop; shop++) for (j = 0; SHOP_PRODUCT(shop, j) != NOTHING; j++) SHOP_PRODUCT(shop, j) -= (SHOP_PRODUCT(shop, j) > rnum); /* Renumber zone table. */ for (zone = 0; zone <= top_of_zone_table; zone++) { for (cmd_no = 0; ZCMD(zone, cmd_no).command != 'S'; cmd_no++) { switch (ZCMD(zone, cmd_no).command) { case 'P': if (ZCMD(zone, cmd_no).arg3 == rnum) { delete_command(&zone_table[zone], cmd_no); } else ZCMD(zone, cmd_no).arg3 -= (ZCMD(zone, cmd_no).arg3 > rnum); break; case 'O': case 'G': case 'E': if (ZCMD(zone, cmd_no).arg1 == rnum) { delete_command(&zone_table[zone], cmd_no); } else ZCMD(zone, cmd_no).arg1 -= (ZCMD(zone, cmd_no).arg1 > rnum); break; case 'R': if (ZCMD(zone, cmd_no).arg2 == rnum) { delete_command(&zone_table[zone], cmd_no); } else ZCMD(zone, cmd_no).arg2 -= (ZCMD(zone, cmd_no).arg2 > rnum); break; } } } save_objects(zrnum); return rnum; }
int delete_mobile(mob_rnum refpt) { struct char_data *live_mob; struct char_data *proto; int counter, cmd_no; mob_vnum vnum; zone_rnum zone; #if CIRCLE_UNSIGNED_INDEX if (refpt == NOBODY || refpt > top_of_mobt) { #else if (refpt < 0 || refpt > top_of_mobt) { #endif log("SYSERR: GenOLC: delete_mobile: Invalid rnum %d.", refpt); return NOBODY; } vnum = mob_index[refpt].vnum; proto = &mob_proto[refpt]; extract_mobile_all(vnum); extract_char(proto); 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'){ if (ZCMD(zone, cmd_no).arg1 == refpt) { delete_zone_command(&zone_table[zone], cmd_no); } else ZCMD(zone, cmd_no).arg1 -= (ZCMD(zone, cmd_no).arg1 > refpt); } /* Update shop keepers. */ if (shop_index) for (counter = 0; counter <= top_shop; counter++) SHOP_KEEPER(counter) -= (SHOP_KEEPER(counter) >= refpt); save_mobiles(real_zone_by_thing(vnum)); return refpt; } int copy_mobile_strings(struct char_data *t, struct char_data *f) { if (f->player.name) t->player.name = strdup(f->player.name); if (f->player.title) t->player.title = strdup(f->player.title); if (f->player.short_descr) t->player.short_descr = strdup(f->player.short_descr); if (f->player.long_descr) t->player.long_descr = strdup(f->player.long_descr); if (f->player.description) t->player.description = strdup(f->player.description); return TRUE; } int update_mobile_strings(struct char_data *t, struct char_data *f) { if (f->player.name) t->player.name = f->player.name; if (f->player.title) t->player.title = f->player.title; if (f->player.short_descr) t->player.short_descr = f->player.short_descr; if (f->player.long_descr) t->player.long_descr = f->player.long_descr; if (f->player.description) t->player.description = f->player.description; return TRUE; } int free_mobile_strings(struct char_data *mob) { if (mob->player.name) free(mob->player.name); if (mob->player.title) free(mob->player.title); if (mob->player.short_descr) free(mob->player.short_descr); if (mob->player.long_descr) free(mob->player.long_descr); if (mob->player.description) free(mob->player.description); return TRUE; } /* Free a mobile structure that has been edited. Take care of existing mobiles * and their mob_proto! */ int free_mobile(struct char_data *mob) { mob_rnum i; if (mob == NULL) return FALSE; /* Non-prototyped mobile. Also known as new mobiles. */ if ((i = GET_MOB_RNUM(mob)) == NOBODY) { free_mobile_strings(mob); /* free script proto list */ free_proto_script(mob, MOB_TRIGGER); } else { /* Prototyped mobile. */ if (mob->player.name && mob->player.name != mob_proto[i].player.name) free(mob->player.name); if (mob->player.title && mob->player.title != mob_proto[i].player.title) free(mob->player.title); if (mob->player.short_descr && mob->player.short_descr != mob_proto[i].player.short_descr) free(mob->player.short_descr); if (mob->player.long_descr && mob->player.long_descr != mob_proto[i].player.long_descr) free(mob->player.long_descr); if (mob->player.description && mob->player.description != mob_proto[i].player.description) free(mob->player.description); /* free script proto list if it's not the prototype */ if (mob->proto_script && mob->proto_script != mob_proto[i].proto_script) free_proto_script(mob, MOB_TRIGGER); } while (mob->affected) affect_remove(mob, mob->affected); /* free any assigned scripts */ if (SCRIPT(mob)) extract_script(mob, MOB_TRIGGER); free(mob); return TRUE; }
/* * Idea by: Cris Jacobin <*****@*****.**> */ room_rnum duplicate_room(room_vnum dest_vnum, room_rnum orig) { int new_rnum, znum; struct room_data nroom; #if CIRCLE_UNSIGNED_INDEX if (orig == NOWHERE || orig > top_of_world) { #else if (orig < 0 || orig > top_of_world) { #endif log("SYSERR: GenOLC: copy_room: Given bad original real room."); return NOWHERE; } else if ((znum = real_zone_by_thing(dest_vnum)) == NOWHERE) { log("SYSERR: GenOLC: copy_room: No such destination zone."); return NOWHERE; } /* * add_room will make its own copies of strings. */ if ((new_rnum = add_room(&nroom)) == NOWHERE) { log("SYSERR: GenOLC: copy_room: Problem adding room."); return NOWHERE; } nroom = world[new_rnum]; nroom.number = dest_vnum; nroom.zone = znum; /* So the people and objects aren't in two places at once... */ nroom.contents = NULL; nroom.people = NULL; return new_rnum; } /* -------------------------------------------------------------------------- */ /* * Copy strings over so bad things don't happen. We do not free the * existing strings here because copy_room() did a shallow copy previously * and we'd be freeing the very strings we're copying. If this function * is used elsewhere, be sure to free_room_strings() the 'dest' room first. */ int copy_room_strings(struct room_data *dest, struct room_data *source) { int i; if (dest == NULL || source == NULL) { log("SYSERR: GenOLC: copy_room_strings: NULL values passed."); return FALSE; } dest->description = str_udup(source->description); dest->name = str_udup(source->name); for (i = 0; i < NUM_OF_DIRS; i++) { if (!R_EXIT(source, i)) continue; CREATE(R_EXIT(dest, i), struct room_direction_data, 1); *R_EXIT(dest, i) = *R_EXIT(source, i); if (R_EXIT(source, i)->general_description) R_EXIT(dest, i)->general_description = strdup(R_EXIT(source, i)->general_description); if (R_EXIT(source, i)->keyword) R_EXIT(dest, i)->keyword = strdup(R_EXIT(source, i)->keyword); } if (source->ex_description) copy_ex_descriptions(&dest->ex_description, source->ex_description); return TRUE; }
/* main loop (of sorts).. basically interpreter throws all input to here. */ void oedit_parse(struct descriptor_data *d, char *arg) { int number, max_val, min_val; char *oldtext = NULL; switch (OLC_MODE(d)) { case OEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': oedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { oedit_save_to_disk(real_zone_by_thing(OLC_NUM(d))); write_to_output(d, "Object saved to disk.\r\n"); } else write_to_output(d, "Object saved to memory.\r\n"); cleanup_olc(d, CLEANUP_ALL); return; case 'n': case 'N': /* If not saving, we must free the script_proto list. */ OLC_OBJ(d)->proto_script = OLC_SCRIPT(d); free_proto_script(OLC_OBJ(d), OBJ_TRIGGER); cleanup_olc(d, CLEANUP_ALL); return; case 'a': /* abort quit */ case 'A': oedit_disp_menu(d); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save your changes? : \r\n"); return; } case OEDIT_MAIN_MENU: /* Throw us out to whichever edit mode based on user input. */ switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /* Something has been modified. */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': write_to_output(d, "Enter keywords : "); OLC_MODE(d) = OEDIT_KEYWORD; break; case '2': write_to_output(d, "Enter short desc : "); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': write_to_output(d, "Enter long desc :-\r\n| "); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); write_to_output(d, "Enter action description:\r\n\r\n"); if (OLC_OBJ(d)->action_description) { write_to_output(d, "%s", OLC_OBJ(d)->action_description); oldtext = strdup(OLC_OBJ(d)->action_description); } string_write(d, &OLC_OBJ(d)->action_description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; break; case '5': oedit_disp_type_menu(d); OLC_MODE(d) = OEDIT_TYPE; break; case '6': oedit_disp_extra_menu(d); OLC_MODE(d) = OEDIT_EXTRAS; break; case '7': oedit_disp_wear_menu(d); OLC_MODE(d) = OEDIT_WEAR; break; case '8': write_to_output(d, "Enter weight : "); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': write_to_output(d, "Enter cost : "); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': write_to_output(d, "Enter cost per day : "); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': write_to_output(d, "Enter timer : "); OLC_MODE(d) = OEDIT_TIMER; break; case 'c': case 'C': /* Clear any old values */ GET_OBJ_VAL(OLC_OBJ(d), 0) = 0; GET_OBJ_VAL(OLC_OBJ(d), 1) = 0; GET_OBJ_VAL(OLC_OBJ(d), 2) = 0; GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; OLC_VAL(d) = 1; oedit_disp_val1_menu(d); break; case 'd': case 'D': oedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* If extra descriptions don't exist. */ if (OLC_OBJ(d)->ex_description == NULL) { CREATE(OLC_OBJ(d)->ex_description, struct extra_descr_data, 1); OLC_OBJ(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_OBJ(d)->ex_description; oedit_disp_extradesc_menu(d); break; case 'm': case 'M': write_to_output(d, "Enter new minimum level: "); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; case 's': case 'S': OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); return; case 'w': case 'W': write_to_output(d, "Copy what object? "); OLC_MODE(d) = OEDIT_COPY; break; case 'x': case 'X': write_to_output(d, "Are you sure you want to delete this object? "); OLC_MODE(d) = OEDIT_DELETE; break; default: oedit_disp_menu(d); break; } return; /* end of OEDIT_MAIN_MENU */ case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case OEDIT_KEYWORD: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->name) free(OLC_OBJ(d)->name); OLC_OBJ(d)->name = str_udup(arg); break; case OEDIT_SHORTDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->short_description) free(OLC_OBJ(d)->short_description); OLC_OBJ(d)->short_description = str_udup(arg); break; case OEDIT_LONGDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->description) free(OLC_OBJ(d)->description); OLC_OBJ(d)->description = str_udup(arg); break; case OEDIT_TYPE: number = atoi(arg); if ((number < 0) || (number >= NUM_ITEM_TYPES)) { write_to_output(d, "Invalid choice, try again : "); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; /* what's the boundschecking worth if we don't do this ? -- Welcor */ GET_OBJ_VAL(OLC_OBJ(d), 0) = GET_OBJ_VAL(OLC_OBJ(d), 1) = GET_OBJ_VAL(OLC_OBJ(d), 2) = GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; break; case OEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_FLAGS)) { oedit_disp_extra_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT_AR(GET_OBJ_EXTRA(OLC_OBJ(d)), (number - 1)); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { write_to_output(d, "That's not a valid choice!\r\n"); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT_AR(GET_OBJ_WEAR(OLC_OBJ(d)), (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_WEIGHT); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_COST); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_RENT); break; case OEDIT_TIMER: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_TIMER); break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, LVL_IMPL); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) { /* Setting AFF_CHARM on objects like this is dangerous. */ if (number != AFF_CHARM) { TOGGLE_BIT_AR(GET_OBJ_AFFECT(OLC_OBJ(d)), number); } } oedit_disp_perm_menu(d); return; case OEDIT_VALUE_1: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_FURNITURE: if (number < 0 || number > MAX_PEOPLE) oedit_disp_val1_menu(d); else { GET_OBJ_VAL(OLC_OBJ(d), 0) = number; oedit_disp_val2_menu(d); } break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 0) = MIN(MAX(atoi(arg), -50), 50); break; case ITEM_CONTAINER: GET_OBJ_VAL(OLC_OBJ(d), 0) = LIMIT(atoi(arg), -1, MAX_CONTAINER_SIZE); break; default: GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg); } /* proceed to menu 2 */ oedit_disp_val2_menu(d); return; case OEDIT_VALUE_2: /* Here, I do need to check for out of range values. */ number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) GET_OBJ_VAL(OLC_OBJ(d), 1) = -1; else GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, NUM_SPELLS); oedit_disp_val3_menu(d); break; case ITEM_CONTAINER: /* Needs some special handling since we are dealing with flag values here. */ if (number < 0 || number > 4) oedit_disp_container_flags_menu(d); else if (number != 0) { TOGGLE_BIT(GET_OBJ_VAL(OLC_OBJ(d), 1), 1 << (number - 1)); OLC_VAL(d) = 1; oedit_disp_val2_menu(d); } else oedit_disp_val3_menu(d); break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, MAX_WEAPON_NDICE); oedit_disp_val3_menu(d); break; default: GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } return; case OEDIT_VALUE_3: number = atoi(arg); /* Quick'n'easy error checking. */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 2) = -1; oedit_disp_val4_menu(d); return; } min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WEAPON: min_val = 1; max_val = MAX_WEAPON_SDICE; break; case ITEM_WAND: case ITEM_STAFF: min_val = 0; max_val = 20; break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: min_val = 0; max_val = NUM_LIQ_TYPES - 1; number--; break; case ITEM_KEY: min_val = 0; max_val = 65099; break; default: min_val = -65000; max_val = 65000; } GET_OBJ_VAL(OLC_OBJ(d), 2) = LIMIT(number, min_val, max_val); oedit_disp_val4_menu(d); return; case OEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 3) = -1; oedit_disp_menu(d); return; } min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WAND: case ITEM_STAFF: min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WEAPON: min_val = 0; max_val = NUM_ATTACK_TYPES - 1; break; default: min_val = -65000; max_val = 65000; break; } GET_OBJ_VAL(OLC_OBJ(d), 3) = LIMIT(number, min_val, max_val); break; case OEDIT_PROMPT_APPLY: if ((number = atoi(arg)) == 0) break; else if (number < 0 || number > MAX_OBJ_AFFECT) { oedit_disp_prompt_apply_menu(d); return; } OLC_VAL(d) = number - 1; OLC_MODE(d) = OEDIT_APPLY; oedit_disp_apply_menu(d); return; case OEDIT_APPLY: if (((number = atoi(arg)) == 0) || ((number = atoi(arg)) == 1)) { OLC_OBJ(d)->affected[OLC_VAL(d)].location = 0; OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = 0; oedit_disp_prompt_apply_menu(d); } else if (number < 0 || number > NUM_APPLIES) oedit_disp_apply_menu(d); else { int counter; /* add in check here if already applied.. deny builders another */ if (GET_LEVEL(d->character) < LVL_IMPL) { for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].location == number) { write_to_output(d, "Object already has that apply."); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number - 1; write_to_output(d, "Modifier : "); OLC_MODE(d) = OEDIT_APPLYMOD; } return; case OEDIT_APPLYMOD: OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = atoi(arg); oedit_disp_prompt_apply_menu(d); return; case OEDIT_EXTRADESC_KEY: if (genolc_checkstring(d, arg)) { if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); OLC_DESC(d)->keyword = str_udup(arg); } oedit_disp_extradesc_menu(d); return; case OEDIT_EXTRADESC_MENU: switch ((number = atoi(arg))) { case 0: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data *temp; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* Clean up pointers */ REMOVE_FROM_LIST(OLC_DESC(d), OLC_OBJ(d)->ex_description, next); free(OLC_DESC(d)); OLC_DESC(d) = NULL; } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; write_to_output(d, "Enter keywords, separated by spaces :-\r\n| "); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); write_to_output(d, "Enter the extra description:\r\n\r\n"); if (OLC_DESC(d)->description) { write_to_output(d, "%s", OLC_DESC(d)->description); oldtext = strdup(OLC_DESC(d)->description); } string_write(d, &OLC_DESC(d)->description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; return; case 3: /* Only go to the next description if this one is finished. */ if (OLC_DESC(d)->keyword && OLC_DESC(d)->description) { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* Make new extra description and attach at end. */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = OLC_DESC(d)->next; } } /* No break - drop into default case. */ default: oedit_disp_extradesc_menu(d); return; } break; case OEDIT_COPY: if ((number = real_object(atoi(arg))) != NOTHING) { oedit_setup_existing(d, number); } else write_to_output(d, "That object does not exist.\r\n"); break; case OEDIT_DELETE: if (*arg == 'y' || *arg == 'Y') { if (delete_object(GET_OBJ_RNUM(OLC_OBJ(d))) != NOTHING) write_to_output(d, "Object deleted.\r\n"); else write_to_output(d, "Couldn't delete the object!\r\n"); cleanup_olc(d, CLEANUP_ALL); } else if (*arg == 'n' || *arg == 'N') { oedit_disp_menu(d); OLC_MODE(d) = OEDIT_MAIN_MENU; } else write_to_output(d, "Please answer 'Y' or 'N': "); return; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: Reached default case in oedit_parse()!"); write_to_output(d, "Oops...\r\n"); break; }