#include <stdio.h> #include <stdlib.h> #include "structs.h" #include "interpreter.h" #include "comm.h" #include "spells.h" #include "utils.h" #include "db.h" #include "boards.h" /* external variables */ extern struct obj_data *obj_proto; extern int top_of_objt; extern struct index_data *obj_index; extern struct zone_data *zone_table; /* for objects */ extern char *item_types[]; extern char *wear_bits[]; extern char *extra_bits[]; extern char *extra_bits2[]; extern char *affected_bits[]; extern char *affected_bits2[]; extern char *affected_bits3[]; extern char *drinks[]; extern char *apply_types[]; extern char *container_bits[]; /* for spell list */ extern char *spells[]; #define NUM_ITEM_TYPES 25 #define NUM_WEAR_FLAGS 17 #define NUM_EXTRA_FLAGS 31 #define NUM_EXTRA_FLAGS2 5 #define NUM_APPLY_FLAGS 25 #define NUM_AFFECTED1_FLAGS 31 #define NUM_AFFECTED2_FLAGS 11 #define NUM_AFFECTED3_FLAGS 1 #define NUM_SPELLS 91 void iedit_disp_container_flags_menu(struct descriptor_data * d); void iedit_disp_extradesc_menu(struct descriptor_data * d); void iedit_disp_weapon_menu(struct descriptor_data * d); void iedit_disp_val1_menu(struct descriptor_data * d); void iedit_disp_val2_menu(struct descriptor_data * d); void iedit_disp_val3_menu(struct descriptor_data * d); void iedit_disp_val4_menu(struct descriptor_data * d); void iedit_disp_type_menu(struct descriptor_data * d); void iedit_disp_extra_menu(struct descriptor_data * d); void iedit_disp_wear_menu(struct descriptor_data * d); void iedit_disp_menu(struct descriptor_data * d); void iedit_disp_affected1_menu(struct descriptor_data * d); void iedit_disp_affected2_menu(struct descriptor_data * d); void iedit_disp_affected3_menu(struct descriptor_data * d); void iedit_parse(struct descriptor_data * d, char *arg); void iedit_disp_spells_menu(struct descriptor_data * d); /************************************************************************** Menu functions **************************************************************************/ /* For container flags */ void iedit_disp_container_flags_menu(struct descriptor_data * d) { send_to_char("1) CLOSEABLE\r\n", d->character); send_to_char("2) PICKPROOF\r\n", d->character); send_to_char("3) CLOSED\r\n", d->character); send_to_char("4) LOCKED\r\n", d->character); sprintbit(GET_OBJ_VAL(d->edit_obj, 1), container_bits, buf1); sprintf(buf, "Container flags: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter flag, 0 to quit:", d->character); } /* For extra descriptions */ void iedit_disp_extradesc_menu(struct descriptor_data * d) { struct extra_descr_data *extra_desc = (struct extra_descr_data *) * d->misc_data; send_to_char("Extra desc menu\r\n", d->character); send_to_char("0) Quit\r\n", d->character); sprintf(buf, "1) Keyword: %s\r\n", extra_desc->keyword ? extra_desc->keyword : "<NONE>"); send_to_char(buf, d->character); sprintf(buf, "2) Description:\r\n%s\r\n", extra_desc->description ? extra_desc->description : "<NONE>"); send_to_char(buf, d->character); if (!extra_desc->next) send_to_char("3) <NOT SET>\r\n", d->character); else send_to_char("3) Set. <NOT VIEWED>\r\n", d->character); d->edit_mode = IEDIT_EXTRADESC_MENU; } /* Ask for *which* apply to edit */ void iedit_disp_prompt_apply_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (d->edit_obj->affected[counter].modifier) { sprinttype(d->edit_obj->affected[counter].location, apply_types, buf2); sprintf(buf, " %d) %+d to %s\r\n", counter + 1, d->edit_obj->affected[counter].modifier, buf2); send_to_char(buf, d->character); } else { sprintf(buf, " %d) None.\r\n", counter + 1); send_to_char(buf, d->character); } } send_to_char("Enter affection to modify (0 to quit):", d->character); d->edit_mode = IEDIT_PROMPT_APPLY; } /* The actual apply to set */ void iedit_disp_apply_menu(struct descriptor_data * d) { int counter; for (counter = 0; counter < NUM_APPLY_FLAGS; counter += 2) { sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter, apply_types[counter], counter + 1, counter + 1 < NUM_APPLY_FLAGS ? apply_types[counter + 1] : ""); send_to_char(buf, d->character); } send_to_char("Enter apply type (0 is no apply):", d->character); d->edit_mode = IEDIT_APPLY; } /* weapon type */ void iedit_disp_weapon_menu(struct descriptor_data * d) { send_to_char("1) sting\r\n", d->character); send_to_char("2) whip\r\n", d->character); send_to_char("3) slash\r\n", d->character); send_to_char("4) bite\r\n", d->character); send_to_char("5) bludgeon\r\n", d->character); send_to_char("6) crush\r\n", d->character); send_to_char("7) pound\r\n", d->character); send_to_char("8) claw\r\n", d->character); send_to_char("9) maul\r\n", d->character); send_to_char("10) thrash\r\n", d->character); send_to_char("11) pierce\r\n", d->character); send_to_char("12) blast\r\n", d->character); send_to_char("13) punch\r\n", d->character); send_to_char("14) stab\r\n", d->character); send_to_char("Enter weapon type:\r\n", d->character); } /* spell type */ void iedit_disp_spells_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 1; counter < NUM_SPELLS; counter += 3) { sprintf(buf, "%2d) %20.20s %2d) %20.20s %2d) %20.20s\r\n", counter, spells[counter], counter + 1, counter + 1 < NUM_SPELLS ? spells[counter + 1] : "", counter + 2, counter + 2 < NUM_SPELLS ? spells[counter + 2] : ""); send_to_char(buf, d->character); } send_to_char("Enter spell choice (0 for none):\r\n", d->character); } /* object value 1 */ void iedit_disp_val1_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_1; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_LIGHT: /* values 0 and 1 are unused.. jump to 2 */ iedit_disp_val3_menu(d); break; case ITEM_SCROLL: case ITEM_WAND: case ITEM_STAFF: case ITEM_POTION: send_to_char("Spell level:", d->character); break; case ITEM_WEAPON: case ITEM_FIREWEAPON: /* this seems to be a circleism.. not part of normal diku? */ send_to_char("+Dam:", d->character); break; case ITEM_MISSILE: send_to_char("Range:", d->character); break; case ITEM_ARMOR: send_to_char("Apply to AC:", d->character); break; case ITEM_CONTAINER: send_to_char("Max weight to contain:", d->character); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: send_to_char("Max drink units:", d->character); break; case ITEM_FOOD: send_to_char("Hours to fill stomach:", d->character); break; case ITEM_MONEY: send_to_char("Number of gold coins:", d->character); break; case ITEM_NOTE: /* this is supposed to be language, but it's unused */ break; default: iedit_disp_menu(d); } } /* object value 2 */ void iedit_disp_val2_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_2; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SCROLL: case ITEM_POTION: iedit_disp_spells_menu(d); break; case ITEM_WAND: case ITEM_STAFF: send_to_char("Max number of charges:", d->character); break; case ITEM_FIREWEAPON: case ITEM_WEAPON: case ITEM_MISSILE: send_to_char("Number of damage dice:", d->character); break; case ITEM_FOOD: /* values 2 and 3 are unused, jump to 4. how odd */ iedit_disp_val4_menu(d); break; case ITEM_CONTAINER: /* these are flags, needs a bit of special handling */ iedit_disp_container_flags_menu(d); break; default: iedit_disp_menu(d); } } /* object value 3 */ void iedit_disp_val3_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_3; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_LIGHT: send_to_char("Number of hours (0 = burnt, -1 is infinite):", d->character); break; case ITEM_SCROLL: case ITEM_POTION: iedit_disp_spells_menu(d); break; case ITEM_WAND: case ITEM_STAFF: send_to_char("Number of charges remaining:", d->character); break; case ITEM_WEAPON: case ITEM_FIREWEAPON: case ITEM_MISSILE: send_to_char("Size of damage dice:", d->character); break; case ITEM_CONTAINER: send_to_char("Vnum of key to open container (-1 for no key):", d->character); break; default: iedit_disp_menu(d); } } /* object value 4 */ void iedit_disp_val4_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_4; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SCROLL: case ITEM_POTION: case ITEM_WAND: case ITEM_STAFF: iedit_disp_spells_menu(d); break; case ITEM_WEAPON: iedit_disp_weapon_menu(d); break; case ITEM_FIREWEAPON: case ITEM_MISSILE: send_to_char("MissileID: ", d->character); break; case ITEM_FOOD: send_to_char("Poisoned (0 = not poison)", d->character); break; default: iedit_disp_menu(d); } } /* object type */ void iedit_disp_type_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_ITEM_TYPES; counter += 2) { sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter, item_types[counter], counter + 1, counter + 1 < NUM_ITEM_TYPES ? item_types[counter + 1] : ""); send_to_char(buf, d->character); } send_to_char("Enter object type:", d->character); } /* object extra flags */ void iedit_disp_extra_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter <= NUM_EXTRA_FLAGS + NUM_EXTRA_FLAGS2; counter += 2) { if (counter <= NUM_EXTRA_FLAGS) sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter + 1, extra_bits[counter], counter + 2, counter + 1 < NUM_EXTRA_FLAGS ? extra_bits[counter + 1] : ""); else sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter + 1, extra_bits2[counter - 32], counter + 2, counter + 1 < NUM_EXTRA_FLAGS + NUM_EXTRA_FLAGS2 ? extra_bits2[counter - 31] : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_EXTRA(d->edit_obj), extra_bits, buf1); sprintf(buf, "Object flags: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_EXTRA2(d->edit_obj), extra_bits2, buf1); sprintf(buf, "Object flags2: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter object extra flag, 0 to quit:", d->character); } /* object wear flags */ void iedit_disp_wear_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_WEAR_FLAGS; counter += 2) { sprintf(buf, "%2d) %20.20s %2d %20.20s\r\n", counter + 1, wear_bits[counter], counter + 2, counter + 1 < NUM_WEAR_FLAGS ? wear_bits[counter + 1] : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_WEAR(d->edit_obj), wear_bits, buf1); sprintf(buf, "Wear flags: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter wear flag, 0 to quit:", d->character); } /* object affected flags */ void iedit_disp_affected1_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_AFFECTED1_FLAGS; counter += 2) { sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter + 1, affected_bits[counter], counter + 2, counter + 1 < NUM_AFFECTED1_FLAGS ? affected_bits[counter + 1] : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_BIT(d->edit_obj), affected_bits, buf1); sprintf(buf, "Object affected 1 flags: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter object affect flag, 0 to quit:", d->character); } /* object affected flags */ void iedit_disp_affected2_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_AFFECTED2_FLAGS; counter += 2) { sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter + 1, affected_bits2[counter], counter + 2, counter + 1 < NUM_AFFECTED2_FLAGS ? affected_bits2[counter + 1] : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_BIT2(d->edit_obj), affected_bits2, buf1); sprintf(buf, "Object affected 2 flags: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter object affect flag, 0 to quit:", d->character); } /* object affected flags */ void iedit_disp_affected3_menu(struct descriptor_data * d) { int counter; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_AFFECTED3_FLAGS; counter += 2) { sprintf(buf, "%2d) %20.20s %2d) %20.20s\r\n", counter + 1, affected_bits3[counter], counter + 2, counter + 1 < NUM_AFFECTED3_FLAGS ? affected_bits3[counter + 1] : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_BIT3(d->edit_obj), affected_bits3, buf1); sprintf(buf, "Object affected 3 flags: %s\r\n", buf1); send_to_char(buf, d->character); send_to_char("Enter object affect flag, 0 to quit:", d->character); } /* display main menu */ void iedit_disp_menu(struct descriptor_data * d) { send_to_char("[H[J", d->character); sprintf(buf, "Item number: %d\r\n", d->edit_number); send_to_char(buf, d->character); sprintf(buf, "1) Item namelist: %s\r\n", d->edit_obj->name); send_to_char(buf, d->character); sprintf(buf, "2) Item shortdesc: %s\r\n", d->edit_obj->short_description); send_to_char(buf, d->character); sprintf(buf, "3) Item longdesc: %s\r\n", d->edit_obj->description); send_to_char(buf, d->character); sprintf(buf, "4) Item actdesc: %s\r\n", d->edit_obj->action_description ? d->edit_obj->action_description : "NOT SET"); send_to_char(buf, d->character); sprinttype(GET_OBJ_TYPE(d->edit_obj), item_types, buf1); sprintf(buf, "5) Item type: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_EXTRA(d->edit_obj), extra_bits, buf1); sprintf(buf, "6) Item extra flags: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_EXTRA2(d->edit_obj), extra_bits2, buf1); sprintf(buf, " Item extra2 flags: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_WEAR(d->edit_obj), wear_bits, buf1); sprintf(buf, "7) Item wear flags: %s\r\n", buf1); send_to_char(buf, d->character); sprintf(buf, "8) Item weight: %d\r\n", GET_OBJ_WEIGHT(d->edit_obj)); send_to_char(buf, d->character); sprintf(buf, "9) Item cost: %d\r\n", GET_OBJ_COST(d->edit_obj)); send_to_char(buf, d->character); sprintf(buf, "a) Item cost per day: %d\r\n", GET_OBJ_RENT(d->edit_obj)); send_to_char(buf, d->character); sprintf(buf, "b) Item timer: %d\r\n", GET_OBJ_TIMER(d->edit_obj)); send_to_char(buf, d->character); sprintf(buf, "c) Item values: %d %d %d %d\r\n", GET_OBJ_VAL(d->edit_obj, 0), GET_OBJ_VAL(d->edit_obj, 1), GET_OBJ_VAL(d->edit_obj, 2), GET_OBJ_VAL(d->edit_obj, 3)); send_to_char(buf, d->character); send_to_char("d) Item applies:\r\n", d->character); send_to_char("e) Item extra descriptions:\r\n", d->character); sprintbit(GET_OBJ_BIT(d->edit_obj), affected_bits, buf1); sprintf(buf, "f) Item affect flags: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_BIT2(d->edit_obj), affected_bits2, buf1); sprintf(buf, "g) Item affect flags2: %s\r\n", buf1); send_to_char(buf, d->character); sprintbit(GET_OBJ_BIT3(d->edit_obj), affected_bits3, buf1); sprintf(buf, "h) Item affect flags3: %s\r\n", buf1); send_to_char("q) Quit\r\n", d->character); send_to_char("Enter your choice:\r\n", d->character); d->edit_mode = IEDIT_MAIN_MENU; } /*************************************************************************** main loop (of sorts).. basically interpreter throws all input to here ***************************************************************************/ void iedit_parse(struct descriptor_data * d, char *arg) { int number; int obj_number; /* the RNUM */ switch (d->edit_mode) { case IEDIT_CONFIRM_EDIT: /* if player hits 'Y' then edit obj */ switch (*arg) { case 'y': case 'Y': SET_BIT(PLR_FLAGS(d->character), PLR_EDITING); iedit_disp_menu(d); break; case 'n': case 'N': STATE(d) = CON_PLAYING; /* free up the editing object */ if (d->edit_obj) free_obj(d->edit_obj); d->edit_obj = NULL; d->edit_number = 0; REMOVE_BIT(PLR_FLAGS(d->character), PLR_EDITING); break; default: send_to_char("That's not a valid choice!\r\n", d->character); send_to_char("Do you wish to edit it?\r\n", d->character); break; } break; /* end of IEDIT_CONFIRM_EDIT */ case IEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': { /* write to internal tables */ obj_number = real_object(d->edit_number); if (obj_number > 0) { /* we need to run through each and every object currently in the * game to see which ones are pointing to this prototype */ struct obj_data *i; struct extra_descr_data *this, *next_one; extern struct obj_data *object_list; struct obj_data *temp; /* if object is pointing to this prototype, then we need to replace * with the new one */ for (i = object_list; i; i = i->next) { if (i->item_number == obj_number) { /* alloc temp object */ CREATE(temp, struct obj_data, 1); *temp = *i; *i = *d->edit_obj; /* copy game-time dependent vars over */ i->in_room = temp->in_room; i->item_number = obj_number; i->carried_by = temp->carried_by; i->worn_by = temp->worn_by; i->worn_on = temp->worn_on; i->in_obj = temp->in_obj; i->contains = temp->contains; i->next_content = temp->next_content; i->next = temp->next; free_obj(temp); } } /* now safe to free old proto and write over */ if (obj_proto[obj_number].name) free(obj_proto[obj_number].name); if (obj_proto[obj_number].description) free(obj_proto[obj_number].description); if (obj_proto[obj_number].short_description) free(obj_proto[obj_number].short_description); if (obj_proto[obj_number].action_description) free(obj_proto[obj_number].action_description); if (obj_proto[obj_number].ex_description) for (this = obj_proto[obj_number].ex_description; this; this = next_one) { next_one = this->next; if (this->keyword) free(this->keyword); if (this->description) free(this->description); free(this); } obj_proto[obj_number] = *d->edit_obj; obj_proto[obj_number].item_number = obj_number; } else { /* uhoh.. need to make a new place in the object prototype table */ int counter; int found = FALSE; struct obj_data *new_obj_proto; struct index_data *new_obj_index; /* + 2.. strange but true */ CREATE(new_obj_index, struct index_data, top_of_objt + 2); CREATE(new_obj_proto, struct obj_data, top_of_objt + 2); /* start counting through both tables */ for (counter = 0; counter < top_of_objt + 1; counter++) { /* if we haven't found it */ if (!found) { /* check if current virtual is bigger than our virtual */ if (obj_index[counter].virtual > d->edit_number) { /* eureka. insert now */ /*---------*/ new_obj_index[counter].virtual = d->edit_number; new_obj_index[counter].number = 0; new_obj_index[counter].func = NULL; /*---------*/ new_obj_proto[counter] = *(d->edit_obj); new_obj_proto[counter].in_room = NOWHERE; /* it is now safe (and necessary!) to assign real number to * the edit_obj, which has been -1 all this time */ d->edit_obj->item_number = counter; /* and assign to prototype as well */ new_obj_proto[counter].item_number = counter; found = TRUE; /* insert the other proto at this point */ new_obj_index[counter + 1] = obj_index[counter]; new_obj_proto[counter + 1] = obj_proto[counter]; new_obj_proto[counter + 1].item_number = counter + 1; } else { /* just copy from old to new, no num change */ new_obj_proto[counter] = obj_proto[counter]; new_obj_index[counter] = obj_index[counter]; } } else { /* we HAVE already found it.. therefore copy to object + 1 */ new_obj_index[counter + 1] = obj_index[counter]; new_obj_proto[counter + 1] = obj_proto[counter]; new_obj_proto[counter + 1].item_number = counter + 1; } } /* if we STILL haven't found it, means the object was > than all * the other objects.. so insert at end */ if (!found) { new_obj_index[top_of_objt + 1].virtual = d->edit_number; new_obj_index[top_of_objt + 1].number = 0; new_obj_index[top_of_objt + 1].func = NULL; clear_object(new_obj_proto + top_of_objt + 1); new_obj_proto[top_of_objt + 1] = *(d->edit_obj); new_obj_proto[top_of_objt + 1].in_room = NOWHERE; new_obj_proto[top_of_objt + 1].item_number = top_of_objt + 1; } top_of_objt++; /* free and replace old tables */ free(obj_proto); free(obj_index); obj_proto = new_obj_proto; obj_index = new_obj_index; } send_to_char("Do you wish to write this object to disk?\r\n", d->character); d->edit_mode = IEDIT_CONFIRM_SAVEDB; } break; case 'n': case 'N': send_to_char("Object not saved, aborting.\r\n", d->character); STATE(d) = CON_PLAYING; /* free up the editing object. free_obj *is* safe since it checks against prototype table */ if (d->edit_obj) free_obj(d->edit_obj); d->edit_obj = NULL; d->edit_number = 0; REMOVE_BIT(PLR_FLAGS(d->character), PLR_EDITING); break; default: send_to_char("Invalid choice!\r\n", d->character); send_to_char("Do you wish to save this object internally?\r\n", d->character); break; } break; /* end of IEDIT_CONFIRM_SAVESTRING */ case IEDIT_CONFIRM_SAVEDB: switch (*arg) { case 'y': case 'Y': send_to_char("Writing object to disk..", d->character); { int counter, counter2, realcounter; FILE *fp; struct obj_data *obj; struct extra_descr_data *ex_desc; /* i want to use "obj" instead of just obj_proto[] because some of * the macros assume it's a pointer instead of just a struct as * obj_proto is, plus it's short to type in :P */ CREATE(obj, struct obj_data, 1); sprintf(buf, "%s/%d.obj", OBJ_PREFIX, zone_table[d->edit_zone].number); fp = fopen(buf, "w+"); /* start running through all objects in this zone */ for (counter = zone_table[d->edit_zone].number * 100; counter <= zone_table[d->edit_zone].top; counter++) { /* write object to disk */ realcounter = real_object(counter); if (realcounter >= 0) { *obj = obj_proto[realcounter]; fprintf(fp, "#%d\n", GET_OBJ_VNUM(obj)); fprintf(fp, "%s~\n", obj->name); fprintf(fp, "%s~\n", obj->short_description); fprintf(fp, "%s~\n", obj->description); if (obj->action_description) fprintf(fp, "%s~\n", obj->action_description); else fprintf(fp, "~\n"); fprintf(fp, "%d %ld %ld %ld\n", GET_OBJ_TYPE(obj), GET_OBJ_EXTRA(obj), GET_OBJ_EXTRA2(obj), GET_OBJ_WEAR(obj)); fprintf(fp, "%d %d %d %d\n", GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3)); fprintf(fp, "%d %d %d\n", GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj), GET_OBJ_RENT(obj)); /* do we have extra descriptions? */ if (obj->ex_description) { for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { fprintf(fp, "E\n"); fprintf(fp, "%s~\n", ex_desc->keyword); fprintf(fp, "%s~\n", ex_desc->description); } } if (obj->obj_flags.bitvector || obj->obj_flags.bitvector2 || obj->obj_flags.bitvector3) { fprintf(fp, "F\n"); fprintf(fp, "%ld %ld %ld\n", obj->obj_flags.bitvector, obj->obj_flags.bitvector2, obj->obj_flags.bitvector3); } /* do we have affects? */ for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++) { if (obj->affected[counter2].modifier) { fprintf(fp, "A\n"); fprintf(fp, "%d %d\n", obj->affected[counter2].location, obj->affected[counter2].modifier); } } } } /* write final line, close */ fprintf(fp, "$~\n"); fclose(fp); /* nuke temp object */ free_obj(obj); } if (d->edit_obj) free_obj(d->edit_obj); d->edit_obj = NULL; STATE(d) = CON_PLAYING; REMOVE_BIT(PLR_FLAGS(d->character), PLR_EDITING); send_to_char("Done.\r\n", d->character); break; case 'n': case 'N': send_to_char("Not saved to DB.\r\n", d->character); send_to_char("This object is available until the next reboot.\r\n", d->character); if (d->edit_obj) free_obj(d->edit_obj); d->edit_obj = NULL; STATE(d) = CON_PLAYING; REMOVE_BIT(PLR_FLAGS(d->character), PLR_EDITING); send_to_char("Done.\r\n", d->character); break; default: send_to_char("Invalid choice!\r\n", d->character); send_to_char("Do you wish to write this object to disk?\r\n", d->character); break; } break; /* end of IEDIT_CONFIRM_SAVEDB */ case IEDIT_MAIN_MENU: /* throw us out to whichever edit mode based on user input */ switch (*arg) { case 'q': case 'Q': send_to_char("Do you wish to save this object internally?\r\n", d->character); d->edit_mode = IEDIT_CONFIRM_SAVESTRING; break; case '1': send_to_char("Enter namelist:", d->character); d->edit_mode = IEDIT_EDIT_NAMELIST; break; case '2': send_to_char("Enter short desc:", d->character); d->edit_mode = IEDIT_SHORTDESC; break; case '3': send_to_char("Enter long desc:\r\n", d->character); d->edit_mode = IEDIT_LONGDESC; break; case '4': /* let's go out to modify.c */ send_to_char("Enter action desc:\r\n", d->character); d->edit_mode = IEDIT_ACTDESC; d->str = (char **) malloc(sizeof(char *)); *(d->str) = NULL; d->max_str = MAX_MESSAGE_LENGTH; d->mail_to = 0; break; case '5': iedit_disp_type_menu(d); d->edit_mode = IEDIT_TYPE; break; case '6': iedit_disp_extra_menu(d); d->edit_mode = IEDIT_EXTRAS; break; case '7': iedit_disp_wear_menu(d); d->edit_mode = IEDIT_WEAR; break; case '8': send_to_char("Enter weight:", d->character); d->edit_mode = IEDIT_WEIGHT; break; case '9': send_to_char("Enter cost:", d->character); d->edit_mode = IEDIT_COST; break; case 'a': case 'A': send_to_char("Enter cost per day:", d->character); d->edit_mode = IEDIT_COSTPERDAY; break; case 'b': case 'B': send_to_char("Enter timer:", d->character); d->edit_mode = IEDIT_TIMER; break; case 'c': case 'C': iedit_disp_val1_menu(d); break; case 'd': case 'D': iedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* if extra desc doesn't exist . */ if (!d->edit_obj->ex_description) { CREATE(d->edit_obj->ex_description, struct extra_descr_data, 1); d->edit_obj->ex_description->next = NULL; } /* There is a reason I need the double pointer. If at the extra desc * menu user presses '0' then I need to free the extra description. * Since it's at the end of list it's pointer must be pointing to * NULL.. thus the double pointer */ d->misc_data = (void **) &(d->edit_obj->ex_description); iedit_disp_extradesc_menu(d); break; case 'f': case 'F': iedit_disp_affected1_menu(d); d->edit_mode = IEDIT_AFFECTED1; break; case 'g': case 'G': iedit_disp_affected2_menu(d); d->edit_mode = IEDIT_AFFECTED2; break; case 'h': case 'H': iedit_disp_affected3_menu(d); d->edit_mode = IEDIT_AFFECTED3; break; default: /* hm, i just realized you probably can't see this.. maybe prompt for * an extra RETURN. well, maybe later */ send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_menu(d); break; } break; /* end of IEDIT_MAIN_MENU */ case IEDIT_EDIT_NAMELIST: if (d->edit_obj->name) free(d->edit_obj->name); d->edit_obj->name = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_SHORTDESC: if (d->edit_obj->short_description) free(d->edit_obj->short_description); d->edit_obj->short_description = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_LONGDESC: if (d->edit_obj->description) free(d->edit_obj->description); d->edit_obj->description = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_ACTDESC: /* WE SHOULD NEVER GET HERE!! */ break; case IEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number >= NUM_ITEM_TYPES)) send_to_char("That's not a valid choice!\r\n", d->character); else { GET_OBJ_TYPE(d->edit_obj) = number; iedit_disp_menu(d); } break; case IEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_EXTRA_FLAGS + NUM_EXTRA_FLAGS2 + 1)) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_extra_menu(d); } else { /* if 0, quit */ if (number == 0) iedit_disp_menu(d); /* if already set.. remove */ else if (number > NUM_EXTRA_FLAGS) { number -= (NUM_EXTRA_FLAGS + 1); if (IS_SET(GET_OBJ_EXTRA2(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_EXTRA2(d->edit_obj), 1 << (number - 1)); else /* set */ SET_BIT(GET_OBJ_EXTRA2(d->edit_obj), 1 << (number - 1)); iedit_disp_extra_menu(d); } else { if (IS_SET(GET_OBJ_EXTRA(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_EXTRA(d->edit_obj), 1 << (number - 1)); else /* set */ SET_BIT(GET_OBJ_EXTRA(d->edit_obj), 1 << (number - 1)); iedit_disp_extra_menu(d); } } break; case IEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_WEAR_FLAGS)) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_wear_menu(d); } else { /* if 0, quit */ if (number == 0) iedit_disp_menu(d); /* if already set.. remove */ else { if (IS_SET(GET_OBJ_WEAR(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_WEAR(d->edit_obj), 1 << (number - 1)); else SET_BIT(GET_OBJ_WEAR(d->edit_obj), 1 << (number - 1)); iedit_disp_wear_menu(d); } } break; case IEDIT_WEIGHT: number = atoi(arg); GET_OBJ_WEIGHT(d->edit_obj) = number; iedit_disp_menu(d); break; case IEDIT_COST: number = atoi(arg); GET_OBJ_COST(d->edit_obj) = number; iedit_disp_menu(d); break; case IEDIT_COSTPERDAY: number = atoi(arg); GET_OBJ_RENT(d->edit_obj) = number; iedit_disp_menu(d); break; case IEDIT_TIMER: number = atoi(arg); GET_OBJ_TIMER(d->edit_obj) = number; iedit_disp_menu(d); break; case IEDIT_VALUE_1: /* lucky, I don't need to check any of these for outofrange values */ number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: case ITEM_FIREWEAPON: GET_OBJ_VAL(d->edit_obj, 0) = number; iedit_disp_val2_menu(d); break; case ITEM_MISSILE: if (number < 0 || number > 10) { send_to_char("Invalid choice! Range is from 1 to 10", d->character); iedit_disp_val1_menu(d); } else { GET_OBJ_VAL(d->edit_obj, 0) = number; iedit_disp_val2_menu(d); } break; default: GET_OBJ_VAL(d->edit_obj, 0) = number; iedit_disp_val2_menu(d); /* proceed to menu 2 */ } break; case IEDIT_VALUE_2: /* here, I do need to check for outofrange values */ number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SCROLL: case ITEM_POTION: if (number < 1 || number >= NUM_SPELLS) { send_to_char("Invalid choice!", d->character); iedit_disp_val2_menu(d); } else { GET_OBJ_VAL(d->edit_obj, 1) = number; iedit_disp_val3_menu(d); } break; case ITEM_CONTAINER: /* needs some special handling since we are dealing with flag values * here */ /* if 0, quit */ number = atoi(arg); if (number < 0 || number > 4) { send_to_char("Invalid choice!\r\n", d->character); iedit_disp_container_flags_menu(d); } else { /* if 0, quit */ if (number != 0) { if (IS_SET(GET_OBJ_VAL(d->edit_obj, 1), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_VAL(d->edit_obj, 1), 1 << (number - 1)); else SET_BIT(GET_OBJ_VAL(d->edit_obj, 1), 1 << (number - 1)); iedit_disp_val2_menu(d); } else iedit_disp_val3_menu(d); } break; default: GET_OBJ_VAL(d->edit_obj, 1) = number; iedit_disp_val3_menu(d); } /* i think that's all that needs checking */ break; case IEDIT_VALUE_3: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SCROLL: case ITEM_POTION: if (number < 1 || number >= NUM_SPELLS) { send_to_char("Invalid choice!", d->character); iedit_disp_val3_menu(d); } break; } GET_OBJ_VAL(d->edit_obj, 2) = number; iedit_disp_val4_menu(d); break; case IEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SCROLL: case ITEM_POTION: case ITEM_WAND: case ITEM_STAFF: if (number < 1 || number >= NUM_SPELLS) { send_to_char("Invalid choice!", d->character); iedit_disp_val4_menu(d); } break; case ITEM_WEAPON: if (number < 1 || number > 11) { send_to_char("Invalid choice!", d->character); iedit_disp_weapon_menu(d); } break; default: break; } GET_OBJ_VAL(d->edit_obj, 3) = number; iedit_disp_menu(d); break; case IEDIT_AFFECTED1: number = atoi(arg); if ((number < 0) || (number > NUM_AFFECTED1_FLAGS)) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_affected1_menu(d); } else { /* if 0, quit */ if (number == 0) iedit_disp_menu(d); /* if already set.. remove */ else { if (IS_SET(GET_OBJ_BIT(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_BIT(d->edit_obj), 1 << (number - 1)); else /* set */ SET_BIT(GET_OBJ_BIT(d->edit_obj), 1 << (number - 1)); iedit_disp_affected1_menu(d); } } break; case IEDIT_AFFECTED2: number = atoi(arg); if ((number < 0) || (number > NUM_AFFECTED2_FLAGS)) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_affected2_menu(d); } else { /* if 0, quit */ if (number == 0) iedit_disp_menu(d); /* if already set.. remove */ else { if (IS_SET(GET_OBJ_BIT2(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_BIT2(d->edit_obj), 1 << (number - 1)); else /* set */ SET_BIT(GET_OBJ_BIT2(d->edit_obj), 1 << (number - 1)); iedit_disp_affected2_menu(d); } } break; case IEDIT_AFFECTED3: number = atoi(arg); if ((number < 0) || (number > NUM_AFFECTED3_FLAGS)) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_affected3_menu(d); } else { /* if 0, quit */ if (number == 0) iedit_disp_menu(d); /* if already set.. remove */ else { if (IS_SET(GET_OBJ_BIT3(d->edit_obj), 1 << (number - 1))) REMOVE_BIT(GET_OBJ_BIT3(d->edit_obj), 1 << (number - 1)); else /* set */ SET_BIT(GET_OBJ_BIT3(d->edit_obj), 1 << (number - 1)); iedit_disp_affected3_menu(d); } } break; case IEDIT_PROMPT_APPLY: number = atoi(arg); if (number == 0) { iedit_disp_menu(d); return; } else if (number < 0 || number > MAX_OBJ_AFFECT) { send_to_char("Invalid choice!\r\n", d->character); iedit_disp_prompt_apply_menu(d); } d->edit_number2 = number - 1; d->edit_mode = IEDIT_APPLY; iedit_disp_apply_menu(d); break; case IEDIT_APPLY: number = atoi(arg); if (number == 0) { d->edit_obj->affected[d->edit_number2].location = 0; d->edit_obj->affected[d->edit_number2].modifier = 0; iedit_disp_prompt_apply_menu(d); } else if (number < 0 || number >= NUM_APPLY_FLAGS) { send_to_char("Invalid choice!\r\n", d->character); iedit_disp_apply_menu(d); } else { d->edit_obj->affected[d->edit_number2].location = number; send_to_char("Modifier:", d->character); d->edit_mode = IEDIT_APPLYMOD; } break; case IEDIT_APPLYMOD: number = atoi(arg); d->edit_obj->affected[d->edit_number2].modifier = number; iedit_disp_prompt_apply_menu(d); break; case IEDIT_EXTRADESC_KEY: if (((struct extra_descr_data *) *d->misc_data)->keyword) free(((struct extra_descr_data *) *d->misc_data)->keyword); ((struct extra_descr_data *) * d->misc_data)->keyword = str_dup(arg); iedit_disp_extradesc_menu(d); break; case IEDIT_EXTRADESC_MENU: number = atoi(arg); switch (number) { case 0: { /* if something got left out */ if (!((struct extra_descr_data *) * d->misc_data)->keyword || !((struct extra_descr_data *) * d->misc_data)->description) { if (((struct extra_descr_data *) * d->misc_data)->keyword) free(((struct extra_descr_data *) * d->misc_data)->keyword); if (((struct extra_descr_data *) * d->misc_data)->description) free(((struct extra_descr_data *) * d->misc_data)->description); free(*d->misc_data); *d->misc_data = NULL; } /* else, we don't need to do anything.. jump to menu */ iedit_disp_menu(d); } break; case 1: d->edit_mode = IEDIT_EXTRADESC_KEY; send_to_char("Enter keywords, separated by spaces:", d->character); break; case 2: d->edit_mode = IEDIT_EXTRADESC_DESCRIPTION; send_to_char("Enter description:\r\n", d->character); /* send out to modify.c */ d->str = (char **) malloc(sizeof(char *)); *(d->str) = NULL; d->max_str = MAX_MESSAGE_LENGTH; d->mail_to = 0; break; case 3: /* if keyword or description has not been changed don't allow person to * edit next */ if (!((struct extra_descr_data *) d->misc_data)->keyword || !((struct extra_descr_data *) d->misc_data)->description) { send_to_char("You can't edit the next extra desc without completing this one.\r\n", d->character); iedit_disp_extradesc_menu(d); } else { struct extra_descr_data *new_extra; if (((struct extra_descr_data *) * d->misc_data)->next) d->misc_data = (void **) &((struct extra_descr_data *) * d->misc_data)->next; else { /* make new extra, attach at end */ CREATE(new_extra, struct extra_descr_data, 1); ((struct extra_descr_data *) * d->misc_data)->next = new_extra; /* edit new extra, we NEED double pointer because i will set * *d->misc_data to NULL later */ d->misc_data = (void **) &((struct extra_descr_data *) * d->misc_data)->next; } iedit_disp_extradesc_menu(d); } break; default: send_to_char("Invalid choice!\r\n", d->character); iedit_disp_extradesc_menu(d); break; } break; default: break; } }