/************************************************************************ * OasisOLC - Objects / oedit.c v2.0 * * Original author: Levork * * Copyright 1996 by Harvey Gilpin * * Copyright 1997-2001 by George Greer (greerga@circlemud.org) * ************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "comm.h" #include "interpreter.h" #include "spells.h" #include "utils.h" #include "db.h" #include "boards.h" #include "constants.h" #include "shop.h" #include "genolc.h" #include "genobj.h" #include "oasis.h" #include "improved-edit.h" /*------------------------------------------------------------------------*/ /* * External variable declarations. */ extern struct obj_data *obj_proto; extern struct index_data *obj_index; extern struct obj_data *object_list; extern obj_rnum top_of_objt; extern struct zone_data *zone_table; extern zone_rnum top_of_zone_table; extern struct shop_data *shop_index; extern struct attack_hit_type attack_hit_text[]; extern struct spell_info_type spell_info[]; extern struct board_info_type board_info[]; extern struct descriptor_data *descriptor_list; /*------------------------------------------------------------------------*/ /* * Handy macros. */ #define S_PRODUCT(s, i) ((s)->producing[(i)]) /*------------------------------------------------------------------------*\ Utility and exported functions \*------------------------------------------------------------------------*/ void oedit_setup_new(struct descriptor_data *d) { CREATE(OLC_OBJ(d), struct obj_data, 1); clear_object(OLC_OBJ(d)); OLC_OBJ(d)->name = str_dup("unfinished object"); OLC_OBJ(d)->description = str_dup("An unfinished object is lying here."); OLC_OBJ(d)->short_description = str_dup("an unfinished object"); GET_OBJ_WEAR(OLC_OBJ(d)) = ITEM_WEAR_TAKE; OLC_VAL(d) = 0; oedit_disp_menu(d); } /*------------------------------------------------------------------------*/ void oedit_setup_existing(struct descriptor_data *d, int real_num) { struct obj_data *obj; /* * Allocate object in memory. */ CREATE(obj, struct obj_data, 1); copy_object(obj, &obj_proto[real_num]); /* * Attach new object to player's descriptor. */ OLC_OBJ(d) = obj; OLC_VAL(d) = 0; oedit_disp_menu(d); } /*------------------------------------------------------------------------*/ void oedit_save_internally(struct descriptor_data *d) { int i; obj_rnum robj_num; struct descriptor_data *dsc; i = (real_object(OLC_NUM(d)) == NOTHING); if ((robj_num = add_object(OLC_OBJ(d), OLC_NUM(d))) < 0) { log("oedit_save_internally: add_object failed."); return; } if (!i) /* If it's not a new object, don't renumber. */ return; /* * Renumber produce in shops being edited. */ for (dsc = descriptor_list; dsc; dsc = dsc->next) if (STATE(dsc) == CON_SEDIT) for (i = 0; S_PRODUCT(OLC_SHOP(dsc), i) != -1; i++) if (S_PRODUCT(OLC_SHOP(dsc), i) >= robj_num) S_PRODUCT(OLC_SHOP(dsc), i)++; /* Update other people in zedit too. From: C.Raehl 4/27/99 */ for (dsc = descriptor_list; dsc; dsc = dsc->next) if (STATE(dsc) == CON_ZEDIT) for (i = 0; OLC_ZONE(dsc)->cmd[i].command != 'S'; i++) switch (OLC_ZONE(dsc)->cmd[i].command) { case 'P': OLC_ZONE(dsc)->cmd[i].arg3 += (OLC_ZONE(dsc)->cmd[i].arg3 >= robj_num); /* Fall through. */ case 'E': case 'G': case 'O': OLC_ZONE(dsc)->cmd[i].arg1 += (OLC_ZONE(dsc)->cmd[i].arg1 >= robj_num); break; case 'R': OLC_ZONE(dsc)->cmd[i].arg2 += (OLC_ZONE(dsc)->cmd[i].arg2 >= robj_num); break; default: break; } } /*------------------------------------------------------------------------*/ void oedit_save_to_disk(int zone_num) { save_objects(zone_table[zone_num].number); } /************************************************************************** Menu functions **************************************************************************/ /* * For container flags. */ void oedit_disp_container_flags_menu(struct descriptor_data *d) { get_char_colors(d->character); clear_screen(d); sprintbit(GET_OBJ_VAL(OLC_OBJ(d), 1), container_bits, buf1); sprintf(buf, "%s1%s) CLOSEABLE\r\n" "%s2%s) PICKPROOF\r\n" "%s3%s) CLOSED\r\n" "%s4%s) LOCKED\r\n" "Container flags: %s%s%s\r\n" "Enter flag, 0 to quit : ", grn, nrm, grn, nrm, grn, nrm, grn, nrm, cyn, buf1, nrm); SEND_TO_Q(buf, d); } /* * For extra descriptions. */ void oedit_disp_extradesc_menu(struct descriptor_data *d) { struct extra_descr_data *extra_desc = OLC_DESC(d); strcpy(buf1, !extra_desc->next ? "<Not set>\r\n" : "Set."); get_char_colors(d->character); clear_screen(d); sprintf(buf, "Extra desc menu\r\n" "%s1%s) Keyword: %s%s\r\n" "%s2%s) Description:\r\n%s%s\r\n" "%s3%s) Goto next description: %s\r\n" "%s0%s) Quit\r\n" "Enter choice : ", grn, nrm, yel, (extra_desc->keyword && *extra_desc->keyword) ? extra_desc->keyword : "<NONE>", grn, nrm, yel, (extra_desc->description && *extra_desc->description) ? extra_desc->description : "<NONE>", grn, nrm, buf1, grn, nrm); SEND_TO_Q(buf, d); OLC_MODE(d) = OEDIT_EXTRADESC_MENU; } /* * Ask for *which* apply to edit. */ void oedit_disp_prompt_apply_menu(struct descriptor_data *d) { int counter; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].modifier) { sprinttype(OLC_OBJ(d)->affected[counter].location, apply_types, buf2); sprintf(buf, " %s%d%s) %+d to %s\r\n", grn, counter + 1, nrm, OLC_OBJ(d)->affected[counter].modifier, buf2); SEND_TO_Q(buf, d); } else { sprintf(buf, " %s%d%s) None.\r\n", grn, counter + 1, nrm); SEND_TO_Q(buf, d); } } SEND_TO_Q("\r\nEnter affection to modify (0 to quit) : ", d); OLC_MODE(d) = OEDIT_PROMPT_APPLY; } /* * Ask for liquid type. */ void oedit_liquid_type(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_LIQ_TYPES; counter++) { sprintf(buf, " %s%2d%s) %s%-20.20s %s", grn, counter, nrm, yel, drinks[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } sprintf(buf, "\r\n%sEnter drink type : ", nrm); SEND_TO_Q(buf, d); OLC_MODE(d) = OEDIT_VALUE_3; } /* * The actual apply to set. */ void oedit_disp_apply_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_APPLIES; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter, nrm, apply_types[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } SEND_TO_Q("\r\nEnter apply type (0 is no apply) : ", d); OLC_MODE(d) = OEDIT_APPLY; } /* * Weapon type. */ void oedit_disp_weapon_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_ATTACK_TYPES; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter, nrm, attack_hit_text[counter].singular, !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } SEND_TO_Q("\r\nEnter weapon type : ", d); } /* * Spell type. */ void oedit_disp_spells_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_SPELLS; counter++) { sprintf(buf, "%s%2d%s) %s%-20.20s %s", grn, counter, nrm, yel, spell_info[counter].name, !(++columns % 3) ? "\r\n" : ""); SEND_TO_Q(buf, d); } sprintf(buf, "\r\n%sEnter spell choice (0 for none) : ", nrm); SEND_TO_Q(buf, d); } /* * Object value #1 */ void oedit_disp_val1_menu(struct descriptor_data *d) { OLC_MODE(d) = OEDIT_VALUE_1; switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_LIGHT: /* * values 0 and 1 are unused.. jump to 2 */ oedit_disp_val3_menu(d); break; case ITEM_SCROLL: case ITEM_WAND: case ITEM_STAFF: case ITEM_POTION: SEND_TO_Q("Spell level : ", d); break; case ITEM_WEAPON: /* * This doesn't seem to be used if I remembe right. */ SEND_TO_Q("Modifier to Hitroll : ", d); break; case ITEM_ARMOR: SEND_TO_Q("Apply to AC : ", d); break; case ITEM_CONTAINER: SEND_TO_Q("Max weight to contain : ", d); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: SEND_TO_Q("Max drink units : ", d); break; case ITEM_FOOD: SEND_TO_Q("Hours to fill stomach : ", d); break; case ITEM_MONEY: SEND_TO_Q("Number of gold coins : ", d); break; case ITEM_NOTE: /* * This is supposed to be language, but it's unused. */ break; default: oedit_disp_menu(d); } } /* * Object value #2 */ void oedit_disp_val2_menu(struct descriptor_data *d) { OLC_MODE(d) = OEDIT_VALUE_2; switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: oedit_disp_spells_menu(d); break; case ITEM_WAND: case ITEM_STAFF: SEND_TO_Q("Max number of charges : ", d); break; case ITEM_WEAPON: SEND_TO_Q("Number of damage dice : ", d); break; case ITEM_FOOD: /* * Values 2 and 3 are unused, jump to 4...Odd. */ oedit_disp_val4_menu(d); break; case ITEM_CONTAINER: /* * These are flags, needs a bit of special handling. */ oedit_disp_container_flags_menu(d); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: SEND_TO_Q("Initial drink units : ", d); break; default: oedit_disp_menu(d); } } /* * Object value #3 */ void oedit_disp_val3_menu(struct descriptor_data *d) { OLC_MODE(d) = OEDIT_VALUE_3; switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_LIGHT: SEND_TO_Q("Number of hours (0 = burnt, -1 is infinite) : ", d); break; case ITEM_SCROLL: case ITEM_POTION: oedit_disp_spells_menu(d); break; case ITEM_WAND: case ITEM_STAFF: SEND_TO_Q("Number of charges remaining : ", d); break; case ITEM_WEAPON: SEND_TO_Q("Size of damage dice : ", d); break; case ITEM_CONTAINER: SEND_TO_Q("Vnum of key to open container (-1 for no key) : ", d); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: oedit_liquid_type(d); break; default: oedit_disp_menu(d); } } /* * Object value #4 */ void oedit_disp_val4_menu(struct descriptor_data *d) { OLC_MODE(d) = OEDIT_VALUE_4; switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: case ITEM_WAND: case ITEM_STAFF: oedit_disp_spells_menu(d); break; case ITEM_WEAPON: oedit_disp_weapon_menu(d); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: case ITEM_FOOD: SEND_TO_Q("Poisoned (0 = not poison) : ", d); break; default: oedit_disp_menu(d); } } /* * Object type. */ void oedit_disp_type_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_ITEM_TYPES; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter, nrm, item_types[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } SEND_TO_Q("\r\nEnter object type : ", d); } /* * Object extra flags. */ void oedit_disp_extra_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_ITEM_FLAGS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter + 1, nrm, extra_bits[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } sprintbit(GET_OBJ_EXTRA(OLC_OBJ(d)), extra_bits, buf1); sprintf(buf, "\r\nObject flags: %s%s%s\r\n" "Enter object extra flag (0 to quit) : ", cyn, buf1, nrm); SEND_TO_Q(buf, d); } /* * Object perm flags. */ void oedit_disp_perm_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_AFF_FLAGS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter + 1, nrm, affected_bits[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } sprintbit(GET_OBJ_PERM(OLC_OBJ(d)), affected_bits, buf1); sprintf(buf, "\r\nObject permanent flags: %s%s%s\r\n" "Enter object perm flag (0 to quit) : ", cyn, buf1, nrm); SEND_TO_Q(buf, d); } /* * Object wear flags. */ void oedit_disp_wear_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_colors(d->character); clear_screen(d); for (counter = 0; counter < NUM_ITEM_WEARS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter + 1, nrm, wear_bits[counter], !(++columns % 2) ? "\r\n" : ""); SEND_TO_Q(buf, d); } sprintbit(GET_OBJ_WEAR(OLC_OBJ(d)), wear_bits, buf1); sprintf(buf, "\r\nWear flags: %s%s%s\r\n" "Enter wear flag, 0 to quit : ", cyn, buf1, nrm); SEND_TO_Q(buf, d); } /* * Display main menu. */ void oedit_disp_menu(struct descriptor_data *d) { struct obj_data *obj; obj = OLC_OBJ(d); get_char_colors(d->character); clear_screen(d); /* * Build buffers for first part of menu. */ sprinttype(GET_OBJ_TYPE(obj), item_types, buf1); sprintbit(GET_OBJ_EXTRA(obj), extra_bits, buf2); /* * Build first half of menu. */ sprintf(buf, "-- Item number : [%s%d%s]\r\n" "%s1%s) Namelist : %s%s\r\n" "%s2%s) S-Desc : %s%s\r\n" "%s3%s) L-Desc :-\r\n%s%s\r\n" "%s4%s) A-Desc :-\r\n%s%s" "%s5%s) Type : %s%s\r\n" "%s6%s) Extra flags : %s%s\r\n", cyn, OLC_NUM(d), nrm, grn, nrm, yel, (obj->name && *obj->name) ? obj->name : "undefined", grn, nrm, yel, (obj->short_description && *obj->short_description) ? obj->short_description : "undefined", grn, nrm, yel, (obj->description && *obj->description) ? obj->description : "undefined", grn, nrm, yel, (obj->action_description && *obj->action_description) ? obj->action_description : "<not set>\r\n", grn, nrm, cyn, buf1, grn, nrm, cyn, buf2 ); /* * Send first half. */ SEND_TO_Q(buf, d); /* * Build second half of menu. */ sprintbit(GET_OBJ_WEAR(obj), wear_bits, buf1); sprintbit(GET_OBJ_PERM(obj), affected_bits, buf2); sprintf(buf, "%s7%s) Wear flags : %s%s\r\n" "%s8%s) Weight : %s%d\r\n" "%s9%s) Cost : %s%d\r\n" "%sA%s) Cost/Day : %s%d\r\n" "%sB%s) Timer : %s%d\r\n" "%sC%s) Values : %s%d %d %d %d\r\n" "%sD%s) Applies menu\r\n" "%sE%s) Extra descriptions menu\r\n" "%sM%s) Min Level : %s%d\r\n" "%sP%s) Perm Affects: %s%s\r\n" "%sQ%s) Quit\r\n" "Enter choice : ", grn, nrm, cyn, buf1, grn, nrm, cyn, GET_OBJ_WEIGHT(obj), grn, nrm, cyn, GET_OBJ_COST(obj), grn, nrm, cyn, GET_OBJ_RENT(obj), grn, nrm, cyn, GET_OBJ_TIMER(obj), grn, nrm, cyn, GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), grn, nrm, grn, nrm, grn, nrm, cyn, GET_OBJ_LEVEL(obj), grn, nrm, cyn, buf2, grn, nrm ); SEND_TO_Q(buf, d); OLC_MODE(d) = OEDIT_MAIN_MENU; } /*************************************************************************** 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': SEND_TO_Q("Saving object to memory.\r\n", d); oedit_save_internally(d); sprintf(buf, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); mudlog(buf, CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE); /* Fall through. */ case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); return; default: SEND_TO_Q("Invalid choice!\r\n", d); SEND_TO_Q("Do you wish to save this object internally?\r\n", d); 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. */ SEND_TO_Q("Do you wish to save this object internally? : ", d); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': SEND_TO_Q("Enter namelist : ", d); OLC_MODE(d) = OEDIT_EDIT_NAMELIST; break; case '2': SEND_TO_Q("Enter short desc : ", d); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': SEND_TO_Q("Enter long desc :-\r\n| ", d); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); SEND_TO_Q("Enter action description:\r\n\r\n", d); if (OLC_OBJ(d)->action_description) { SEND_TO_Q(OLC_OBJ(d)->action_description, d); oldtext = str_dup(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': SEND_TO_Q("Enter weight : ", d); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': SEND_TO_Q("Enter cost : ", d); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': SEND_TO_Q("Enter cost per day : ", d); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': SEND_TO_Q("Enter timer : ", d); 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; 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': SEND_TO_Q("Enter new minimum level: ", d); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; default: oedit_disp_menu(d); break; } return; /* * end of OEDIT_MAIN_MENU */ 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)) { SEND_TO_Q("Invalid choice, try again : ", d); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; 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(GET_OBJ_EXTRA(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { SEND_TO_Q("That's not a valid choice!\r\n", d); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT(GET_OBJ_WEAR(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_TIMER: GET_OBJ_TIMER(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) TOGGLE_BIT(GET_OBJ_PERM(OLC_OBJ(d)), 1 << (number - 1)); 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 */ 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 >= NUM_SPELLS) oedit_disp_val2_menu(d); else { GET_OBJ_VAL(OLC_OBJ(d), 1) = number; 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; 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: min_val = -1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 1; max_val = 50; 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: 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) { SEND_TO_Q("Object already has that apply.", d); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number; SEND_TO_Q("Modifier : ", d); 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 **tmp_desc; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* * Clean up pointers */ for (tmp_desc = &(OLC_OBJ(d)->ex_description); *tmp_desc; tmp_desc = &((*tmp_desc)->next)) { if (*tmp_desc == OLC_DESC(d)) { *tmp_desc = NULL; break; } } free(OLC_DESC(d)); } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; SEND_TO_Q("Enter keywords, separated by spaces :-\r\n| ", d); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); SEND_TO_Q("Enter the extra description:\r\n\r\n", d); if (OLC_DESC(d)->description) { SEND_TO_Q(OLC_DESC(d)->description, d); oldtext = str_dup(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("SYSERR: OLC: Reached default case in oedit_parse()!", BRF, LVL_BUILDER, TRUE); SEND_TO_Q("Oops...\r\n", d); break; } /* * If we get here, we have changed something. */ OLC_VAL(d) = 1; oedit_disp_menu(d); } void oedit_string_cleanup(struct descriptor_data *d, int terminator) { switch (OLC_MODE(d)) { case OEDIT_ACTDESC: oedit_disp_menu(d); break; case OEDIT_EXTRADESC_DESCRIPTION: oedit_disp_extradesc_menu(d); break; } }