/* ******************************************* * * * iedit.cc * * Part of AwakeOLC, * * a component of AwakeMUD * * * * (c)2001 Andrew Hynek, and the * * AwakeMUD Consortium * * * ******************************************* */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "structs.h" #include "awake.h" #include "interpreter.h" #include "comm.h" #include "spells.h" #include "utils.h" #include "db.h" #include "dblist.h" #include "boards.h" #include "screen.h" #include "olc.h" #include "memory.h" #include "newmagic.h" #define OBJ d->edit_obj extern class memoryClass *Mem; extern class objList ObjList; void write_objs_to_disk(int zone); /* 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; // extern funcs extern char *cleanup(char *dest, const char *src); extern int real_zone(int vnum); /* for objects */ extern const char *item_types[]; extern const char *wear_bits[]; extern const char *extra_bits[]; extern const char *drinks[]; extern const char *apply_types[]; extern const char *container_bits[]; extern const char *material_names[]; extern const char *barrier_names[]; extern const char *affected_bits[]; extern const char *patch_names[]; extern const char *cyberware_names[]; extern const char *bioware_names[]; extern const char *program_types[]; extern const char *file_types[]; extern const char *file_ratings[]; extern const char *composition_names[]; extern const char *spirits[]; extern const char *spell_categories[]; extern int material_ratings[]; extern int barrier_ratings[]; extern struct board_info_type board_info[NUM_OF_BOARDS]; extern spell_a grimoire[]; /* for spell list */ extern const char *spells[]; #define NUM_WEAR_FLAGS 17 #define NUM_EXTRA_FLAGS 13 #define NUM_APPLY_FLAGS 25 #define NUM_SPELLS 49 #define NUM_WEAPON_TYPES 27 #define NUM_SKILL_TYPES 19 #define NUM_DRINK_TYPES 18 #define NUM_PATCHES 4 #define NUM_CYBERWARE_TYPES 32 #define NUM_BIOWARE_TYPES 11 #define NUM_PROGRAMS 15 #define NUM_FILES 7 #define NUM_FILE_RATINGS 8 #define NUM_SPIRITS 17 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_val5_menu(struct descriptor_data * d); void iedit_disp_val6_menu(struct descriptor_data * d); void iedit_disp_val7_menu(struct descriptor_data * d); void iedit_disp_val8_menu(struct descriptor_data * d); void iedit_disp_val9_menu(struct descriptor_data * d); void iedit_disp_val10_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_drinktype_menu(struct descriptor_data *d); void iedit_disp_patch_menu(struct descriptor_data *d); void iedit_parse(struct descriptor_data * d, char *arg); void iedit_disp_spells_menu(struct descriptor_data * d); void iedit_disp_cybertype_menu(struct descriptor_data * d); void iedit_program_types_menu(struct descriptor_data *d); void iedit_disp_biotype_menu(struct descriptor_data * d); /************************************************************************** Menu functions **************************************************************************/ /* For container flags */ void iedit_disp_container_flags_menu(struct descriptor_data * d) { sprintbit(GET_OBJ_VAL(d->edit_obj, 1), container_bits, buf1); send_to_char(CH, "1) Closeable\r\n" "2) Pickproof\r\n" "3) Closed\r\n" "4) Locked\r\n" "Container flags: %s%s%s\r\n" "Enter flag, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); } /* 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(CH, "Extra desc menu\r\n" "0) Quit\r\n" "1) Keyword: %s%s%s\r\n" "2) Description:\r\n%s\r\n" "3) %s%s%s\r\n", CCCYN(CH, C_CMP), (extra_desc->keyword ? extra_desc->keyword : "(none)"), CCNRM(CH, C_CMP), (extra_desc->description ? extra_desc->description : "(none)"), CCCYN(CH, C_CMP), (!extra_desc->next ? "(not set)" : "Set (not viewed)."), CCNRM(CH, C_CMP)); d->edit_mode = IEDIT_EXTRADESC_MENU; } /* Ask for *which* apply to edit */ void iedit_disp_prompt_apply_menu(struct descriptor_data * d) { int counter; CLS(CH); 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); send_to_char(CH, " %d) %+d to %s%s%s\r\n", counter + 1, d->edit_obj->affected[counter].modifier, CCCYN(CH, C_CMP), buf2, CCNRM(CH, C_CMP)); } else send_to_char(CH, " %d) None.\r\n", counter + 1); } 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) send_to_char(CH, "%2d) %-18s %2d) %-18s\r\n", counter, apply_types[counter], counter + 1, counter + 1 < NUM_APPLY_FLAGS ? apply_types[counter + 1] : ""); send_to_char("Enter apply type (0 is no apply):", d->character); d->edit_mode = IEDIT_APPLY; } /* skill needed in weapon */ void iedit_disp_skill_menu(struct descriptor_data *d) { CLS(CH); send_to_char( " 1) Edged Weapons\r\n" " 2) Pole Arms\r\n" " 3) Whips and flails\r\n" " 4) Clubs\r\n" " 5) Pistols\r\n" " 6) Rifles\r\n" " 7) Shotguns\r\n" " 8) Assault Rifles\r\n" " 9) Submachine Guns\r\n" "10) Grenade Launchers\r\n" "11) Tasers\r\n" "12) Machine Guns\r\n" "13) Missile Launchers\r\n" "14) Assault Cannons\r\n" "15) Artillery\r\n" "16) Bows\r\n" "17) Crossbows\r\n" "18) Non-aerodynamic throwing weapons\r\n" "19) Aerodynamic throwing weapons\r\n" "Enter skill needed for weapon:\r\n", CH); } /* weapon type */ void iedit_disp_weapon_menu(struct descriptor_data * d) { CLS(CH); send_to_char(" 1) sting 2) whip\r\n" " 3) slash 4) bite\r\n" " 5) bludgeon 6) crush\r\n" " 7) pound 8) claw\r\n" " 9) maul 10) thrash\r\n" "11) pierce 12) punch\r\n" "13) stab 14) taser\r\n" "15) shuriken 16) throwing knife\r\n" "17) arrow/bolt 18) hand grenade\r\n" "19) grenade launcher 20) rocket\r\n" "21) pistol 22) blast\r\n" "23) rifle 24) shotgun\r\n" "25) machine gun 26) cannon\r\n" "Enter weapon type:\r\n", CH); } /* spell type */ void iedit_disp_spells_menu(struct descriptor_data * d) { int counter; CLS(CH); for (counter = 1; counter <= NUM_SPELLS; counter += 3) send_to_char(CH, "%2d) %-18s %2d) %-18s %2d) %-18s\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("Enter spell:\r\n", CH); } /* 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 force:", d->character); break; case ITEM_WEAPON: case ITEM_FIREWEAPON: send_to_char("Power (0 for melee weapon or bow):", d->character); break; case ITEM_MISSILE: send_to_char("\r\n 0) Arrow 1) Bolt\r\nMissile type: ", CH); break; case ITEM_ARMOR: send_to_char("Ballistic:", d->character); break; case ITEM_QUIVER: send_to_char("Max projectiles to contain: ", CH); 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 nuyen: ", d->character); break; case ITEM_CYBERWARE: case ITEM_BIOWARE: send_to_char("Rating:", CH); break; case ITEM_CYBERDECK: send_to_char("MPCP Rating: ", CH); break; case ITEM_PROGRAM: iedit_program_types_menu(d); break; case ITEM_GUN_CLIP: send_to_char("Number of bullets clip contains (must match max load of weapon):", CH); break; case ITEM_DOCWAGON: send_to_char(" 1) Basic contract\r\n 2) Gold contract\r\n 3) Platinum contract\r\nDocWagon type: ", CH); break; case ITEM_WORKING_GEAR: CLS(CH); send_to_char(" 1) Medical\r\n" " 2) Electronic\r\n" " 3) Cyberdeck\r\n" "Enter type of kit: ", CH); break; case ITEM_PATCH: iedit_disp_patch_menu(d); break; case ITEM_SPELL_FORMULA: iedit_disp_val3_menu(d); break; case ITEM_DECK_ACCESSORY: send_to_char(" 0) Data file\r\n 1) Upgrade\r\n" "Accessory type: ", CH); break; case ITEM_GUN_ACCESSORY: send_to_char(" 0) Top\r\n 1) Barrel\r\n 2) Under\r\nLocation to mount accessory: ", CH); break; case ITEM_FOCUS: send_to_char(" 0) Specific spell\r\n 1) Spell category\r\n 2) Spirit\r\n 3) Power\r\n" " 4) Spell lock\r\n 5) Weapon\r\nFocus type: ", CH); break; case ITEM_CLIMBING: send_to_char("Enter rating (1-3): ", CH); break; case ITEM_RADIO: iedit_disp_val2_menu(d); 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_WAND: case ITEM_STAFF: send_to_char("Max number of charges:", d->character); break; case ITEM_WEAPON: case ITEM_FIREWEAPON: send_to_char("Base Damage (1 - Light, 2 - Moderate, 3 - Serious, 4 - Deadly):", d->character); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: send_to_char("Drink units left:", CH); break; case ITEM_ARMOR: send_to_char("Impact:", CH); 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; case ITEM_QUIVER: send_to_char(" 0) Arrows\r\n 1) Bolts\r\n 2) Shurikens\r\n 3) Throwing knives\r\n" "Quiver type: ", CH); break; case ITEM_CYBERWARE: send_to_char("Essence cost (x 100): ", CH); break; case ITEM_BIOWARE: send_to_char("Body index cost (x 100): ", CH); break; case ITEM_CYBERDECK: send_to_char("Hardening: ", CH); break; case ITEM_PROGRAM: send_to_char("Program Rating: ", CH); break; case ITEM_PATCH: send_to_char("Rating: ", CH); break; case ITEM_DECK_ACCESSORY: switch (GET_OBJ_VAL(OBJ, 0)) { case TYPE_FILE: send_to_char("File size: ", CH); break; case TYPE_UPGRADE: send_to_char(" 0) MPCP (replacement)\r\n 1) Active memory\r\n" " 2) Storage memory\r\n 3) Load speed\r\n 4) IO speed\r\n" " 5) Reaction increase\r\nUpgrade type: ", CH); break; } break; case ITEM_GUN_ACCESSORY: send_to_char(" 1) Smartlink\r\n 2) Scope\r\n 3) Gas vent\r\n 4) Shock pad\r\nAccessory type: ", CH); break; case ITEM_FOCUS: if (GET_OBJ_VAL(OBJ, 0) != FOCI_LOCK) send_to_char("Focus rating: ", CH); else iedit_disp_menu(d); break; case ITEM_GUN_CLIP: send_to_char(" 1) Pistol 2) Blast\r\n" " 3) Rifle 4) Shotgun\r\n" " 5) Machine gun 6) Cannon\r\n" " 7) Grenade launcher 8) Rocket\r\nClip type: ", CH); break; case ITEM_RADIO: send_to_char("Enter radio's range (0-5): ", CH); break; case ITEM_MONEY: send_to_char("Type (1 - cash, 2 - credstick): ", d->character); break; default: iedit_disp_menu(d); } } /* object value 3 */ void iedit_disp_val3_menu(struct descriptor_data * d) { int i; 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_WAND: case ITEM_STAFF: send_to_char("Number of charges remaining:", d->character); break; case ITEM_WEAPON: case ITEM_FIREWEAPON: send_to_char("Strength bonus for melee (0 for non-melee weapons):", CH); break; case ITEM_CONTAINER: send_to_char("Vnum of key to open container (-1 for no key):", d->character); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: iedit_disp_drinktype_menu(d); break; case ITEM_CYBERWARE: iedit_disp_cybertype_menu(d); break; case ITEM_BIOWARE: iedit_disp_biotype_menu(d); break; case ITEM_CYBERDECK: send_to_char("Active: ", CH); break; case ITEM_PROGRAM: send_to_char("Program size: ", CH); break; case ITEM_SPELL_FORMULA: send_to_char("Force: ", CH); break; case ITEM_DECK_ACCESSORY: switch (GET_OBJ_VAL(OBJ, 0)) { case TYPE_FILE: for (i = 1; i <= NUM_FILES; i++) { sprintf(buf, " %2d) %s\r\n", i, file_types[i]); send_to_char(buf, CH); } send_to_char("Enter file type: ", CH); break; case TYPE_UPGRADE: switch (GET_OBJ_VAL(OBJ, 1)) { case 0: send_to_char("MPCP Rating: ", CH); break; case 1: send_to_char("Active memory increase: ", CH); break; case 2: send_to_char("Storage memory increase: ", CH); break; case 3: send_to_char("Load speed increase: ", CH); break; case 4: send_to_char("I/O speed increase: ", CH); break; case 5: send_to_char("Reaction increase level: ", CH); break; } break; } break; case ITEM_GUN_ACCESSORY: if (GET_OBJ_VAL(OBJ, 1) == 3) send_to_char("Recoil modifier: ", CH); else iedit_disp_menu(d); break; case ITEM_FOCUS: if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPIRIT) { CLS(CH); for (i = 1; *spirits[i] != '\n'; i++) send_to_char(CH, "%2d) %20s", i, spirits[i]); send_to_char("Enter spirit type: ", CH); } else if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPELL) iedit_disp_spells_menu(d); else if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPELL_CAT) { CLS(CH); for (i = 0; *spell_categories[i] != '\n'; i++) send_to_char(CH, "%2d %s\r\n", i + 1, spell_categories[i]); send_to_char("Enter spell category: ", CH); } else iedit_disp_menu(d); break; case ITEM_RADIO: send_to_char("Enter encryption/decryption rating (1-6): ", CH); break; case ITEM_MONEY: if (GET_OBJ_VAL(OBJ, 1)) send_to_char(" 1) 6-digit code\r\n 2) thumbprint\r\n 3) retinal scan\r\n" "Enter credstick security: ", d->character); else iedit_disp_menu(d); break; default: iedit_disp_menu(d); } } /* object value 4 */ void iedit_disp_val4_menu(struct descriptor_data * d) { int i; 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: case ITEM_FIREWEAPON: iedit_disp_weapon_menu(d); break; case ITEM_CONTAINER: send_to_char("Lock level on container:", d->character); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: case ITEM_FOOD: send_to_char("Poison Rating (0 = not poison): ", d->character); break; case ITEM_CYBERWARE: iedit_disp_val5_menu(d); break; case ITEM_CYBERDECK: send_to_char("Storage: ", CH); break; case ITEM_PROGRAM: if (GET_OBJ_VAL(OBJ, 2) != PROG_ATTACK) { GET_OBJ_VAL(OBJ, 3) = 300; iedit_disp_menu(d); return; } send_to_char("Program attack type:\r\n\r\n" " 1) Hit 2) Sting\r\n" " 3) Whip 4) Slash\r\n" " 5) Bite 6) Bludgeon\r\n" " 7) Crush 8) Pound\r\n" " 9) Claw 10) Maul\r\n" " 11) Thrash 12) Pierce\r\n" " 13) Punch 14) Stab\r\n" " 15) Taser 16) Shuriken\r\n" " 17) Throwing knife 18) Arrow/bolt\r\n" " 19) Hand grenade 20) Grenade launcher\r\n" " 21) Rocket 22) Pistol\r\n" " 23) Blast 24) Rifle\r\n" " 25) Shotgun 26) Machine gun\r\n" " 27) Cannon\r\n" "Program attack type: ", CH); break; case ITEM_SPELL_FORMULA: iedit_disp_spells_menu(d); d->edit_mode = IEDIT_VALUE_7; break; case ITEM_DECK_ACCESSORY: switch (GET_OBJ_VAL(OBJ, 0)) { case TYPE_FILE: for (i = 0; i < NUM_FILE_RATINGS; i++) { sprintf(buf, " %2d) %s\r\n", i + 1, file_ratings[i]); send_to_char(buf, CH); } send_to_char("Enter file rating: ", CH); break; case TYPE_UPGRADE: if (GET_OBJ_VAL(OBJ, 1) == 5) send_to_char("MPCP to enhance: ", CH); else iedit_disp_menu(d); break; } break; default: iedit_disp_menu(d); } } /* object value 5 */ void iedit_disp_val5_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_5; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: case ITEM_FIREWEAPON: iedit_disp_skill_menu(d); break; case ITEM_CYBERDECK: send_to_char("Load: ", CH); break; case ITEM_CYBERWARE: if (GET_OBJ_VAL(OBJ, 2) == 2 || GET_OBJ_VAL(OBJ, 2) == 3) send_to_char("Enter radio's range (0-5): ", CH); else iedit_disp_menu(d); break; default: iedit_disp_menu(d); } } /* object value 6 */ void iedit_disp_val6_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_6; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: send_to_char("Max Ammo (-1 if doesn't use ammo): ", CH); break; case ITEM_FIREWEAPON: send_to_char(" 0) Bow\r\n 1) Crossbow\r\nType: ", CH); break; case ITEM_CYBERWARE: send_to_char("Enter encryption/decryption rating (1-6): ", CH); break; default: iedit_disp_menu(d); } } /* object value 7 */ void iedit_disp_val7_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_7; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: send_to_char("Current Ammo: ", CH); break; case ITEM_FIREWEAPON: send_to_char("Enter strength minimum: ", CH); break; case ITEM_SPELL_FORMULA: iedit_disp_spells_menu(d); break; default: iedit_disp_menu(d); } } /* object value 8 */ void iedit_disp_val8_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_8; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SPELL_FORMULA: send_to_char("0 for mage spell, 1 for shaman spell: ", CH); break; case ITEM_WEAPON: if (access_level(CH, LVL_PRESIDENT)) { if (GET_OBJ_VAL(OBJ, 7) > -1) send_to_char("Enter vnum of object to attach on top: ", CH); else iedit_disp_val9_menu(d); } else iedit_disp_menu(d); break; default: iedit_disp_menu(d); } } /* object value 9 */ void iedit_disp_val9_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_9; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: if (access_level(CH, LVL_PRESIDENT)) { if (GET_OBJ_VAL(OBJ, 8) > -1) send_to_char("Enter vnum of object to attach on barrel: ", CH); else iedit_disp_val10_menu(d); } else iedit_disp_menu(d); break; default: iedit_disp_menu(d); } } /* object value 10 */ void iedit_disp_val10_menu(struct descriptor_data * d) { d->edit_mode = IEDIT_VALUE_10; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: if (access_level(CH, LVL_PRESIDENT) && GET_OBJ_VAL(OBJ, 9) > -1) send_to_char("Enter vnum of object to attach under: ", CH); else iedit_disp_menu(d); break; default: iedit_disp_menu(d); } } /* object type */ void iedit_disp_type_menu(struct descriptor_data * d) { int counter; CLS(CH); for (counter = 1; counter <= NUM_ITEM_TYPES; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter, item_types[counter], counter + 1, counter + 1 <= NUM_ITEM_TYPES ? item_types[counter + 1] : ""); } send_to_char("Enter object type (0 to quit):", d->character); } void iedit_disp_drinktype_menu(struct descriptor_data *d) { int counter; CLS(CH); for (counter = 0; counter < NUM_DRINK_TYPES; ++counter) send_to_char(CH, "%2d) %s\r\n", counter + 1, drinks[counter]); send_to_char("Enter drink type: ", CH); } void iedit_disp_material_menu(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter < NUM_MATERIALS; ++counter) send_to_char(CH, "%2d) %s\r\n", counter + 1, material_names[counter]); send_to_char("Enter material type, 0 to return: ", CH); } void iedit_disp_patch_menu(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter < NUM_PATCHES; ++counter) send_to_char(CH, "%2d) %s\r\n", counter + 1, patch_names[counter]); send_to_char("Enter patch type, 0 to return: ", CH); } void iedit_disp_spell_type(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter <= NUM_SPELLS; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, spells[counter], counter + 2, counter + 1 <= NUM_SPELLS ? spells[counter + 1] : ""); } send_to_char("Enter spell, 0 to return: ", CH); } void iedit_disp_cybertype_menu(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter <= NUM_CYBERWARE_TYPES; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, cyberware_names[counter], counter + 2, counter + 1 < NUM_CYBERWARE_TYPES ? cyberware_names[counter + 1] : ""); } send_to_char("Enter cyberware type, 0 to return: ", CH); } void iedit_disp_biotype_menu(struct descriptor_data *d) { CLS(CH); for (int counter = 0; counter <= NUM_BIOWARE_TYPES; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, bioware_names[counter], counter + 2, counter + 1 < NUM_BIOWARE_TYPES ? bioware_names[counter + 1] : ""); } send_to_char("Enter bioware type, 0 to return: ", CH); } void iedit_program_types_menu(struct descriptor_data *d) { int counter; CLS(CH); for (counter = 1; counter < NUM_PROGRAMS; counter += 3) { send_to_char(CH, " %2d) %-15s %2d) %-15s %2d) %-15s\r\n", counter, program_types[counter], counter + 1, counter + 1 < NUM_PROGRAMS ? program_types[counter + 1] : "", counter + 2, counter + 2 < NUM_PROGRAMS ? program_types[counter + 2] : ""); } send_to_char("Program type: ", d->character); } void iedit_disp_rating_menu(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter < NUM_BARRIERS; ++counter) send_to_char(CH, "%2d) %s\r\n", counter + 1, barrier_names[counter]); send_to_char("Enter construction category, 0 to return: ", CH); } /* object extra flags */ void iedit_disp_extra_menu(struct descriptor_data * d) { int counter; CLS(CH); for (counter = 0; counter < NUM_EXTRA_FLAGS; counter += 2) send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, extra_bits[counter], counter + 2, counter + 1 < NUM_EXTRA_FLAGS ? extra_bits[counter + 1] : ""); sprintbit(GET_OBJ_EXTRA(d->edit_obj), extra_bits, buf1); send_to_char(CH, "Object flags: %s%s%s\r\n" "Enter object extra flag, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); } void iedit_disp_aff_menu(struct descriptor_data *d) { CLS(CH); for (register int counter = 0; counter < NUM_AFF_FLAGS; counter += 2) send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, affected_bits[counter], counter + 2, counter + 1 < NUM_AFF_FLAGS ? affected_bits[counter + 1] : ""); sprintbit(OBJ->obj_flags.bitvector, affected_bits, buf1); send_to_char(CH, "Object flags: %s%s%s\r\n" "Enter affected flags, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); } /* object wear flags */ void iedit_disp_wear_menu(struct descriptor_data * d) { int counter; CLS(CH); for (counter = 0; counter < NUM_WEAR_FLAGS; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, wear_bits[counter], counter + 2, counter + 1 < NUM_WEAR_FLAGS ? wear_bits[counter + 1] : ""); } sprintbit(GET_OBJ_WEAR(d->edit_obj), wear_bits, buf1); send_to_char(CH, "Wear flags: %s%s%s\r\n" "Enter wear flag, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); } /* display main menu */ void iedit_disp_menu(struct descriptor_data * d) { CLS(CH); send_to_char(CH, "Item number: %s%d%s\r\n", CCCYN(CH, C_CMP), d->edit_number, CCNRM(CH, C_CMP)); send_to_char(CH, "1) Item namelist: %s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->name, CCNRM(CH, C_CMP)); send_to_char(CH, "2) Item shortdesc: %s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->short_description, CCNRM(CH, C_CMP)); send_to_char(CH, "3) Item descript: %s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->description, CCNRM(CH, C_CMP)); send_to_char(CH, "4) Item longdesc: \r\n%s\r\n", d->edit_obj->long_description ? d->edit_obj->long_description : "(not set)"); sprinttype(GET_OBJ_TYPE(d->edit_obj), item_types, buf1); send_to_char(CH, "5) Item type: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); sprintbit(GET_OBJ_EXTRA(d->edit_obj), extra_bits, buf1); send_to_char(CH, "6) Item extra flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); sprintbit(OBJ->obj_flags.bitvector, affected_bits, buf1); send_to_char(CH, "7) Item affected bits: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); sprintbit(GET_OBJ_WEAR(d->edit_obj), wear_bits, buf1); send_to_char(CH, "8) Item wear flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); send_to_char(CH, "9) Item weight: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_OBJ_WEIGHT(d->edit_obj), CCNRM(CH, C_CMP)); send_to_char(CH, "a) Item cost: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_OBJ_COST(d->edit_obj), CCNRM(CH, C_CMP)); if (GET_OBJ_TYPE(OBJ) == ITEM_CYBERDECK) send_to_char(CH, "b) I/O Speed: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_OBJ_RENT(d->edit_obj), CCNRM(CH, C_CMP)); else send_to_char(CH, "b) Item composition: %s%s%s\r\n", CCCYN(CH, C_CMP), (GET_OBJ_RENT(OBJ) >= 0 && GET_OBJ_RENT(OBJ) <= ITEM_SILVER ? composition_names[GET_OBJ_RENT(OBJ)] : "UNDEFINED"), CCNRM(CH, C_CMP)); send_to_char(CH, "c) Item timer: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_OBJ_TIMER(d->edit_obj), CCNRM(CH, C_CMP)); send_to_char(CH, "d) Item Material: %s%s%s\r\n", CCCYN(CH, C_CMP), material_names[GET_OBJ_MATERIAL(d->edit_obj)], CCNRM(CH, C_CMP)); send_to_char(CH, "e) Item Barrier Rating: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_OBJ_BARRIER(d->edit_obj), CCNRM(CH, C_CMP)); send_to_char(CH, "f) Item values: ^c%d %d %d %d %d %d %d %d %d %d^n\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), GET_OBJ_VAL(d->edit_obj, 4), GET_OBJ_VAL(d->edit_obj, 5), GET_OBJ_VAL(d->edit_obj, 6), GET_OBJ_VAL(d->edit_obj, 7), GET_OBJ_VAL(d->edit_obj, 8), GET_OBJ_VAL(d->edit_obj, 9)); send_to_char("g) Item applies:\r\n" "h) Item extra descriptions:\r\n" "q) Quit and save\r\n" "x) Exit and abort\r\n" "Enter your choice:\r\n", CH); 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, j; int obj_number; /* the RNUM */ bool modified = FALSE; switch (d->edit_mode) { case IEDIT_CONFIRM_EDIT: /* if player hits 'Y' then edit obj */ switch (*arg) { case 'y': case 'Y': iedit_disp_menu(d); break; case 'n': case 'N': STATE(d) = CON_PLAYING; /* free up the editing object */ if (d->edit_obj) Mem->DeleteObject(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; struct use_descr_data *This2, *next_one2; struct obj_data *temp; /* if object is pointing to this prototype, then we need to replace * with the new one */ // this function updates pointers to the active list of objects // in the mud ObjList.UpdateObjs(d->edit_obj, obj_number); /* now safe to free old proto and write over */ if (obj_proto[obj_number].name) delete [] obj_proto[obj_number].name; if (obj_proto[obj_number].description) delete [] obj_proto[obj_number].description; if (obj_proto[obj_number].short_description) delete [] obj_proto[obj_number].short_description; if (obj_proto[obj_number].long_description) delete [] obj_proto[obj_number].long_description; if (obj_proto[obj_number].use_description) for (This2 = obj_proto[obj_number].use_description; This2; This2 = next_one2) { next_one2 = This2->next; if (This2->keyword) delete [] This2->keyword; if (This2->description1) delete [] This2->description1; if (This2->description2) delete [] This2->description2; delete This2; } 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) delete [] This->keyword; if (This->description) delete [] This->description; delete 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 realcounter; int counter; int found = FALSE; struct obj_data *new_obj_proto; struct index_data *new_obj_index; struct obj_data *temp_obj; /* + 2.. strange but true */ new_obj_index = new struct index_data[top_of_objt + 2]; new_obj_proto = new 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].virt > d->edit_number) { /* eureka. insert now */ /*---------*/ new_obj_index[counter].virt = 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].virt = 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; /* 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 = top_of_objt + 1; } top_of_objt++; /* we also have to renumber all the objects currently existing in the world. This is because when I start extracting objects, bad things will happen! */ ObjList.UpdateNums(d->edit_obj->item_number); //for (temp_obj = object_list; temp_obj; temp_obj = temp_obj->next) // if (GET_OBJ_RNUM (temp_obj) >= d->edit_obj->item_number) // GET_OBJ_RNUM (temp_obj)++; /* free and replace old tables */ delete [] obj_proto; delete [] obj_index; obj_proto = new_obj_proto; obj_index = new_obj_index; /* RENUMBER ZONE TABLES HERE, only because I ADDED an object! This code shamelessly ripped off from db.c */ { extern int top_of_zone_table; int zone, cmd_no; for (zone = 0; zone <= top_of_zone_table; zone++) for (cmd_no = 0; cmd_no < zone_table[zone].num_cmds; cmd_no++) { switch (ZCMD.command) { case 'O': ZCMD.arg1 = (ZCMD.arg1 >= d->edit_obj->item_number ? ZCMD.arg1 + 1 : ZCMD.arg1); break; case 'G': ZCMD.arg1 = (ZCMD.arg1 >= d->edit_obj->item_number ? ZCMD.arg1 + 1 : ZCMD.arg1); break; case 'E': ZCMD.arg1 = (ZCMD.arg1 >= d->edit_obj->item_number ? ZCMD.arg1 + 1 : ZCMD.arg1); break; case 'P': ZCMD.arg1 = (ZCMD.arg1 >= d->edit_obj->item_number ? ZCMD.arg1 + 1 : ZCMD.arg1); ZCMD.arg3 = (ZCMD.arg3 >= d->edit_obj->item_number ? ZCMD.arg3 + 1 : ZCMD.arg3); break; case 'R': /* rem obj from room */ ZCMD.arg2 = (ZCMD.arg2 >= d->edit_obj->item_number ? ZCMD.arg2 + 1 : ZCMD.arg2); break; } } } /* this fixes the creeping board problems */ // not needed since real nums aren't used with boards anymore /* realcounter = real_object (d->edit_number); for (counter = 0; counter < NUM_OF_BOARDS; counter++) { if (BOARD_RNUM (counter) >= realcounter) BOARD_RNUM (counter) = BOARD_RNUM (counter) + 1; } */ } /* end of obj insertion */ send_to_char("Writing object to disk..", d->character); write_objs_to_disk(d->character->player_specials->saved.zonenum); // don't wanna nuke the strings, so we use ClearObject if (d->edit_obj) Mem->ClearObject(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("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) Mem->DeleteObject(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_MAIN_MENU: /* throw us out to whichever edit mode based on user input */ switch (*arg) { case 'q': case 'Q': d->edit_mode = IEDIT_CONFIRM_SAVESTRING; #if CONFIRM_SAVE send_to_char("Do you wish to save this object internally?\r\n", d->character); #else iedit_parse(d, "y"); #endif break; case 'x': case 'X': d->edit_mode = IEDIT_CONFIRM_SAVESTRING; #if CONFIRM_SAVE send_to_char("Do you wish to save this object internally?\r\n", d->character); #else iedit_parse(d, "y"); #endif 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 normal desc:\r\n", d->character); d->edit_mode = IEDIT_DESC; break; case '4': /* let's go out to modify.c */ send_to_char("Enter long desc:\r\n", d->character); d->edit_mode = IEDIT_LONGDESC; //d->str = (char **) xmalloc(sizeof(char *)); d->str = new (char *); if (!d->str) { mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE); exit(1); } *(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_aff_menu(d); d->edit_mode = IEDIT_AFF_BITS; break; case '8': iedit_disp_wear_menu(d); d->edit_mode = IEDIT_WEAR; break; case '9': send_to_char("Enter weight:", d->character); d->edit_mode = IEDIT_WEIGHT; break; case 'a': case 'A': send_to_char("Enter cost:", d->character); d->edit_mode = IEDIT_COST; break; case 'b': case 'B': if (GET_OBJ_TYPE(OBJ) == ITEM_CYBERDECK) send_to_char("Enter I/O Speed: ", CH); else send_to_char(" 0) Other\r\n 1) Plastic\r\n 2) Iron\r\n 3) Silver\r\n" "Item compisition (affects only allergies): ", CH); d->edit_mode = IEDIT_COSTPERDAY; break; case 'c': case 'C': send_to_char("Enter timer:", d->character); d->edit_mode = IEDIT_TIMER; break; case 'd': case 'D': iedit_disp_material_menu(d); d->edit_mode = IEDIT_MATERIAL; break; case 'e': case 'E': iedit_disp_rating_menu(d); d->edit_mode = IEDIT_RATING; break; case 'f': case 'F': iedit_disp_val1_menu(d); break; case 'g': case 'G': iedit_disp_prompt_apply_menu(d); break; case 'h': case 'H': /* if extra desc doesn't exist . */ if (!d->edit_obj->ex_description) { d->edit_obj->ex_description = new extra_descr_data; memset((char *) d->edit_obj->ex_description, 0, sizeof(extra_descr_data)); } /* 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; 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) delete [] 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) delete [] d->edit_obj->short_description; d->edit_obj->short_description = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_DESC: if (d->edit_obj->description) delete [] d->edit_obj->description; d->edit_obj->description = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_LONGDESC: // we shouldn't get here break; case IEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number > NUM_ITEM_TYPES) || (number == ITEM_CYBERWARE && !access_level(CH, LVL_PRESIDENT)) || (number == ITEM_BIOWARE && !access_level(CH, LVL_PRESIDENT))) { send_to_char("That's not a valid choice!\r\n", d->character); iedit_disp_type_menu(d); } else if (number != 0) { GET_OBJ_TYPE(d->edit_obj) = number; GET_OBJ_VAL(d->edit_obj, 0) = 0; GET_OBJ_VAL(d->edit_obj, 1) = 0; GET_OBJ_VAL(d->edit_obj, 2) = 0; GET_OBJ_VAL(d->edit_obj, 3) = 0; GET_OBJ_VAL(d->edit_obj, 4) = 0; GET_OBJ_VAL(d->edit_obj, 5) = 0; GET_OBJ_VAL(d->edit_obj, 6) = 0; GET_OBJ_VAL(d->edit_obj, 7) = 0; GET_OBJ_VAL(d->edit_obj, 8) = 0; GET_OBJ_VAL(d->edit_obj, 9) = 0; } iedit_disp_menu(d); break; case IEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_EXTRA_FLAGS)) { 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 (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_AFF_BITS: number = atoi(arg); if ((number > 0) && (number <= NUM_AFF_FLAGS)) { if (IS_SET(OBJ->obj_flags.bitvector, 1 << (number - 1))) REMOVE_BIT(OBJ->obj_flags.bitvector, 1 << (number - 1)); else SET_BIT(OBJ->obj_flags.bitvector, 1 << (number - 1)); } else if (number == 0) { iedit_disp_menu(d); return; } iedit_disp_aff_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); if (number < 0 || number > ITEM_SILVER && GET_OBJ_TYPE(OBJ) != ITEM_CYBERDECK) { send_to_char("Invalid choice!\r\nItem composition: ", CH); return; } 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_SCROLL: case ITEM_WAND: case ITEM_POTION: case ITEM_STAFF: if (number < 0 || number > 10) { send_to_char("Force must be between 1 and 10.\r\nSpell force: ", d->character); return; } if (GET_OBJ_TYPE(d->edit_obj) == ITEM_SCROLL || GET_OBJ_TYPE(d->edit_obj) == ITEM_POTION) { GET_OBJ_VAL(d->edit_obj, 0) = number; iedit_disp_val4_menu(d); return; } break; case ITEM_WEAPON: if (number < 0 || number > 50) { send_to_char("Value must be between 0 and 50:\r\n" "Power (0 for melee weapon): ", d->character); return; } break; case ITEM_FIREWEAPON: if (number < 0 || number > 50) { send_to_char("Value must be between 0 and 50:\r\n" "Power (0 for melee weapon): ", d->character); return; } number = 0; break; case ITEM_MISSILE: if (number < 0 || number > 1) { send_to_char("Value must be 0 or 1!\r\nMissile type: ", CH); return; } break; case ITEM_BIOWARE: if (number < 1 || number > 5) { send_to_char("Value must be between 1 and 5.\r\nRating of bioware: ", CH); return; } break; case ITEM_CYBERWARE: if (number < 1 || number > 5) { send_to_char("Value must be between 1 and 5.\r\nRating of cyberware: ", CH); return; } break; case ITEM_CYBERDECK: if (number < 1 || number > 15) { send_to_char("Value must be between 1 and 15.\r\nMPCP Rating: ", CH); return; } break; case ITEM_PROGRAM: if (number < 1 || number > 30) { iedit_program_types_menu(d); return; } break; case ITEM_WORKING_GEAR: if (number < 1 || number > 3) { CLS(CH); send_to_char("1) Medical\r\n" "2) Electronic\r\n" "3) Cyberdeck\r\n" "Enter type of kit: ", CH); return; } else number--; break; case ITEM_DECK_ACCESSORY: if (number < 0 || number > 1) { send_to_char("Invalid option! Accessory type: ", CH); return; } break; case ITEM_GUN_ACCESSORY: if (number < 0 || number > 2) { send_to_char("Invalid option! Accessory location: ", CH); return; } break; case ITEM_DOCWAGON: if (number < 1 || number > 3) { send_to_char("Value must be between 1 and 3. DocWagon type: ", CH); return; } break; case ITEM_PATCH: if (number < 1 || number > NUM_PATCHES) { iedit_disp_patch_menu(d); return; } else number--; break; case ITEM_FOCUS: if (number < FOCI_SPELL || number > FOCI_WEAPON) { send_to_char("Invalid option.\r\nFocus type: ", CH); return; } break; case ITEM_CLIMBING: if (number < 1 || number > 3) { send_to_char("Rating must range from 1 to 3. Rating: ", CH); return; } break; case ITEM_MONEY: if (number < 0 || number > 25000) { send_to_char("Value must range between 0 and 25000 nuyen.\r\nValue: ", CH); return; } break; } GET_OBJ_VAL(d->edit_obj, 0) = number; /* proceed to menu 2 */ iedit_disp_val2_menu(d); 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_POTION: if (number < 1 || number > NUM_SPELLS) { send_to_char("Invalid choice!", d->character); iedit_disp_val2_menu(d); return; } else { GET_OBJ_VAL(d->edit_obj, 1) = number; iedit_disp_val3_menu(d); return; } break; case ITEM_CONTAINER: 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); return; } else { iedit_disp_val3_menu(d); return; } } break; case ITEM_QUIVER: if (number < 0 || number > 3) { send_to_char("Invalid input!\r\nQuiver type: ", CH); return; } break; case ITEM_WEAPON: case ITEM_FIREWEAPON: if ((number < 1) || (number > 4)) { send_to_char("Value must be between 1 and 4.\r\n" "Base damage (1 - Light, 2 - Moderate, 3 - Serious, 4 - Deadly): ", d->character); return; } break; case ITEM_PROGRAM: if (number < 1 || number > 20) { send_to_char("Rating must be between 1 and 20.\r\nProgram Rating: ", CH); return; } break; case ITEM_BIOWARE: if (number < 10 || number > 600) { send_to_char("Body index cost must be between 10 and 600.\r\nBody index cost (x 100): ", CH); return; } break; case ITEM_CYBERWARE: if (number < 10 || number > 600) { send_to_char("Essence cost must be between 10 and 600.\r\nEssence cost (x 100): ", CH); return; } break; case ITEM_DECK_ACCESSORY: switch (GET_OBJ_VAL(OBJ, 0)) { case TYPE_FILE: if (number < 0) { send_to_char("Size must be greater than 0. File size: ", CH); return; } break; case TYPE_UPGRADE: if (number < 0 || number > 5) { send_to_char("Invalid choice! Upgrade type: ", CH); return; } break; } break; case ITEM_PATCH: if ((number < 1) || (number > 10)) { send_to_char("Rating must be between 1 and 10.\r\n", CH); return; } break; case ITEM_GUN_ACCESSORY: if (number < 1 || number > 4) { send_to_char("Invalid option! Accessory type: ", CH); return; } break; case ITEM_FOCUS: if (number < 1 || number > 10) { send_to_char("Rating must be between 1 and 10.\r\n", CH); return; } break; case ITEM_GUN_CLIP: if (number < 1 || number > 8) { send_to_char("Invalid option!\r\nClip type: ", CH); return; } number += 20; if (number == 27) number = 19; if (number == 28) number = 20; break; case ITEM_RADIO: if (number < 0 || number > 5) { send_to_char("Enter radio's range (0-5): ", CH); return; } break; case ITEM_MONEY: if (number < 1 || number > 2) { iedit_disp_val2_menu(d); return; } number--; break; default: break; } GET_OBJ_VAL(d->edit_obj, 1) = number; iedit_disp_val3_menu(d); break; case IEDIT_VALUE_3: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_POTION: if (number < 1 || number > NUM_SPELLS) { send_to_char("Invalid choice!", d->character); iedit_disp_val3_menu(d); return; } break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: if (number < 1 || number > NUM_DRINK_TYPES) { send_to_char("Invalid choice.", CH); iedit_disp_val4_menu(d); return; } number--; // to give the correct value to the object break; case ITEM_WEAPON: case ITEM_FIREWEAPON: if (number < 0 || number > 4) { send_to_char("Value must be between 0 and 4.\r\n", CH); iedit_disp_val3_menu(d); return; } break; case ITEM_BIOWARE: if (number < 0 || number > NUM_BIOWARE_TYPES) { iedit_disp_biotype_menu(d); return; } number--; break; case ITEM_CYBERWARE: if (number < 0 || number > NUM_CYBERWARE_TYPES) { iedit_disp_cybertype_menu(d); return; } number--; break; case ITEM_PROGRAM: if (number < 0) { send_to_char("Invalid input.\r\nProgram Size: ", CH); return; } break; case ITEM_DECK_ACCESSORY: if (GET_OBJ_VAL(OBJ, 0) == TYPE_FILE) { if (number < 1 || number > NUM_FILES) { iedit_disp_val3_menu(d); return; } } else switch (GET_OBJ_VAL(OBJ, 1)) { case 0: if (number < 1 || number > 15) { send_to_char("MPCP must be between 1 and 15. MPCP Rating: ", CH); return; } break; case 1: if (number < 1 || number > 1000) { send_to_char("Invalid value! Active memory increase: ", CH); return; } break; case 2: if (number < 1 || number > 20000) { send_to_char("Invalid value! Storage memory increase: ", CH); return; } break; case 3: if (number < 1 || number > 100) { send_to_char("Invalid value! Load speed increase: ", CH); return; } break; case 4: if (number < 1 || number > 50) { send_to_char("Invalid value! I/O speed increase: ", CH); return; } break; case 5: if (number < 1 || number > 3) { send_to_char("Values must range from 1 to 3. Reaction increase level: ", CH); return; } break; } break; case ITEM_GUN_ACCESSORY: if (number < -3 || number > -1) { send_to_char("Modifier must be between -3 and -1. Recoil modifier: ", CH); return; } break; case ITEM_FOCUS: if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPIRIT && (number < 1 || number > NUM_SPIRITS)) { send_to_char("Invalid response. Focus spirit type: ", CH); return; } else if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPELL && (number < 1 || number > NUM_SPELLS)) { send_to_char("Invalid choice!\r\n", CH); iedit_disp_val3_menu(d); return; } else if (GET_OBJ_VAL(OBJ, 0) == FOCI_SPELL_CAT) { if (number < 1 || number > 5) { send_to_char("Invalid choice! Focus spell category: ", CH); return; } else number--; } break; case ITEM_SPELL_FORMULA: if ((number < 1) || (number > 50)) { send_to_char("Force must be between 1 and 50.\r\n", CH); return; } break; case ITEM_RADIO: if (number < 1 || number > 6) { send_to_char("Enter encryption/decryption rating (1-6): ", CH); return; } break; case ITEM_MONEY: if (number < 1 || number > 3) { iedit_disp_val3_menu(d); return; } break; default: 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); return; } break; case ITEM_WEAPON: if (number < 1 || (!access_level(CH, LVL_PRESIDENT) && number == TYPE_BIFURCATE) || number > NUM_WEAPON_TYPES) { send_to_char("Invalid choice!", d->character); iedit_disp_weapon_menu(d); return; } switch (number + TYPE_HIT) { case TYPE_PISTOL: case TYPE_BLAST: GET_OBJ_VAL(OBJ, 7) = 0; GET_OBJ_VAL(OBJ, 8) = -1; GET_OBJ_VAL(OBJ, 9) = 0; break; case TYPE_SHOTGUN: GET_OBJ_VAL(OBJ, 7) = 0; GET_OBJ_VAL(OBJ, 8) = 0; GET_OBJ_VAL(OBJ, 9) = -1; break; case TYPE_GRENADE_LAUNCHER: case TYPE_ROCKET: case TYPE_RIFLE: case TYPE_MACHINE_GUN: case TYPE_CANNON: case TYPE_BIFURCATE: GET_OBJ_VAL(OBJ, 7) = 0; GET_OBJ_VAL(OBJ, 8) = 0; GET_OBJ_VAL(OBJ, 9) = 0; break; default: GET_OBJ_VAL(OBJ, 7) = -1; GET_OBJ_VAL(OBJ, 8) = -1; GET_OBJ_VAL(OBJ, 9) = -1; } break; case ITEM_FIREWEAPON: if (number < 1 || (!access_level(CH, LVL_PRESIDENT) && number == TYPE_BIFURCATE) || number > NUM_WEAPON_TYPES) { send_to_char("Invalid choice!", d->character); iedit_disp_weapon_menu(d); return; } number = TYPE_ARROW; break; case ITEM_PROGRAM: if (number < 1 || (!access_level(CH, LVL_PRESIDENT) && number == TYPE_BIFURCATE) || number > NUM_WEAPON_TYPES) { iedit_disp_val6_menu(d); return; } number = number + TYPE_HIT - 1; break; case ITEM_SPELL_FORMULA: return; case ITEM_DECK_ACCESSORY: if (GET_OBJ_VAL(OBJ, 0) == TYPE_FILE) { number -= 1; if (number < 0 || number > (NUM_FILE_RATINGS - 1)) { iedit_disp_val4_menu(d); return; } } else if (number < 1 || number > 15) { send_to_char("MPCP value must be between 1 and 15!\r\nMPCP to enhance: ", CH); return; } break; default: break; } GET_OBJ_VAL(d->edit_obj, 3) = number; if (GET_OBJ_TYPE(OBJ) == ITEM_WEAPON) GET_OBJ_VAL(OBJ, 3) += TYPE_HIT; iedit_disp_val5_menu(d); break; case IEDIT_VALUE_5: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: case ITEM_FIREWEAPON: if (number < 1 || number > NUM_SKILL_TYPES) { send_to_char("Invalid choice!", d->character); iedit_disp_skill_menu(d); } else { // this is to skip these general skills which aren't in the list number += 102; if (number >= SKILL_UNARMED_COMBAT) number += 3; if (number >= SKILL_FIREARMS) number++; if (number >= SKILL_GUNNERY) number++; if (number >= SKILL_PROJECTILES) number++; if (number >= SKILL_THROWING_WEAPONS) number++; } break; case ITEM_CYBERWARE: if (number < 0 || number > 5) { send_to_char("Enter radio's range (0-5): ", CH); return; } break; default: break; } GET_OBJ_VAL(d->edit_obj, 4) = number; iedit_disp_val6_menu(d); break; case IEDIT_VALUE_6: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: break; case ITEM_FIREWEAPON: if (number < 0 || number > 1) { send_to_char("Value must be 0 or 1!\r\nType: ", CH); return; } break; case ITEM_CYBERWARE: if (number < 1 || number > 6) { send_to_char("Enter encryption/decryption rating (1-6): ", CH); return; } break; default: break; } GET_OBJ_VAL(d->edit_obj, 5) = number; iedit_disp_val7_menu(d); break; case IEDIT_VALUE_7: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: break; case ITEM_FIREWEAPON: if (number < 1 || number > 10) { send_to_char("Strength min. must be between 1 and 10. Enter strength minimum: ", CH); return; } break; case ITEM_SPELL_FORMULA: // adjust the values from the type of spell if (number <= 0 || number > NUM_SPELLS) { iedit_disp_spells_menu(d); return; } GET_OBJ_VAL(OBJ, 0) = grimoire[number].physical; GET_OBJ_VAL(OBJ, 1) = grimoire[number].category; GET_OBJ_VAL(OBJ, 3) = grimoire[number].target; GET_OBJ_VAL(OBJ, 4) = grimoire[number].drain; GET_OBJ_VAL(OBJ, 5) = grimoire[number].damage; GET_OBJ_VAL(OBJ, 8) = SPELL_ELEMENT_NONE; break; default: break; } GET_OBJ_VAL(d->edit_obj, 6) = number; iedit_disp_val8_menu(d); break; case IEDIT_VALUE_8: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_SPELL_FORMULA: if (number < 0 || number > 1) { send_to_char("0 for mage, 1 for shaman: ", CH); return; } break; case ITEM_WEAPON: if (!access_level(CH, LVL_PRESIDENT)) if (!read_object(number, VIRTUAL)) { send_to_char("Invalid vnum.\r\n", CH); iedit_disp_val8_menu(d); } if (number > 0) { modified = FALSE; for (j = 0; (j < MAX_OBJ_AFFECT && !modified); j++) if (!(OBJ->affected[j].modifier)) { OBJ->affected[j].location = read_object(number, VIRTUAL)->affected[0].location; OBJ->affected[j].modifier = read_object(number, VIRTUAL)->affected[0].modifier; modified = TRUE; } GET_OBJ_WEIGHT(OBJ) += GET_OBJ_WEIGHT(read_object(number, VIRTUAL)); GET_OBJ_COST(OBJ) += GET_OBJ_COST(read_object(number, VIRTUAL)); } break; default: break; } GET_OBJ_VAL(d->edit_obj, 7) = number; iedit_disp_val9_menu(d); break; case IEDIT_VALUE_9: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: if (!access_level(CH, LVL_PRESIDENT)) if (!read_object(number, VIRTUAL)) { send_to_char("Invalid vnum.\r\n", CH); iedit_disp_val9_menu(d); return; } if (number > 0) { modified = FALSE; for (j = 0; (j < MAX_OBJ_AFFECT && !modified); j++) if (!(OBJ->affected[j].modifier)) { OBJ->affected[j].location = read_object(number, VIRTUAL)->affected[0].location; OBJ->affected[j].modifier = read_object(number, VIRTUAL)->affected[0].modifier; modified = TRUE; } GET_OBJ_WEIGHT(OBJ) += GET_OBJ_WEIGHT(read_object(number, VIRTUAL)); GET_OBJ_COST(OBJ) += GET_OBJ_COST(read_object(number, VIRTUAL)); } break; default: break; } GET_OBJ_VAL(d->edit_obj, 8) = number; iedit_disp_val10_menu(d); break; case IEDIT_VALUE_10: number = atoi(arg); switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WEAPON: if (!access_level(CH, LVL_PRESIDENT)) if (!read_object(number, VIRTUAL)) { send_to_char("Invalid vnum.\r\n", CH); iedit_disp_val10_menu(d); return; } if (number > 0) { modified = FALSE; for (j = 0; (j < MAX_OBJ_AFFECT && !modified); j++) if (!(OBJ->affected[j].modifier)) { OBJ->affected[j].location = read_object(number, VIRTUAL)->affected[0].location; OBJ->affected[j].modifier = read_object(number, VIRTUAL)->affected[0].modifier; modified = TRUE; } GET_OBJ_WEIGHT(OBJ) += GET_OBJ_WEIGHT(read_object(number, VIRTUAL)); GET_OBJ_COST(OBJ) += GET_OBJ_COST(read_object(number, VIRTUAL)); } break; default: break; } GET_OBJ_VAL(d->edit_obj, 9) = number; iedit_disp_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); } else { 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) delete [] ((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_MATERIAL: number = atoi(arg); if (number == 0) iedit_disp_menu(d); else if (number > 0 && number < NUM_MATERIALS + 1) { GET_OBJ_MATERIAL(OBJ) = number - 1; iedit_disp_menu(d); } else iedit_disp_material_menu(d); break; case IEDIT_RATING: number = atoi(arg); if (number == 0) iedit_disp_menu(d); else if (number > 0 && number < NUM_BARRIERS + 1) { GET_OBJ_CONDITION(OBJ) = GET_OBJ_BARRIER(OBJ) = barrier_ratings[number - 1]; iedit_disp_menu(d); } else iedit_disp_rating_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) delete [] ((struct extra_descr_data *) * d->misc_data)->keyword; if (((struct extra_descr_data *) * d->misc_data)->description) delete [] ((struct extra_descr_data *) * d->misc_data)->description; delete *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 **) xmalloc(sizeof(char *)); d->str = new (char *); if (!d->str) { mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE); exit(1); } *(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 */ new_extra = new extra_descr_data; memset((char *) new_extra, 0, sizeof(extra_descr_data)); ((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; } } #undef OBJ void write_objs_to_disk(int zone) { int counter, counter2, realcounter; FILE *fp; struct obj_data *obj; struct extra_descr_data *ex_desc; zone = real_zone(zone); obj = Mem->GetObject(); sprintf(buf, "%s/%d.obj", OBJ_PREFIX, zone_table[zone].number); fp = fopen(buf, "w+"); /* start running through all objects in this zone */ for (counter = zone_table[zone].number * 100; counter <= zone_table[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 ? obj->name : "unnamed"); fprintf(fp, "%s~\n", obj->short_description ? obj->short_description : "an unnamed object"); fprintf(fp, "%s~\n", obj->description ? obj->description : "An unnamed object sits here"); if (obj->long_description) fprintf(fp, "%s~\n", cleanup(buf2, obj->long_description)); else fprintf(fp, "You see an uncreative object.~\n"); fprintf(fp, "%d %d %d %d %d %ld\n", GET_OBJ_TYPE(obj), GET_OBJ_EXTRA(obj), GET_OBJ_WEAR(obj), GET_OBJ_MATERIAL(obj), GET_OBJ_BARRIER(obj), obj->obj_flags.bitvector); fprintf(fp, "%d %d %d %d %d %d %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), GET_OBJ_VAL(obj, 4), GET_OBJ_VAL(obj, 5), GET_OBJ_VAL(obj, 6), GET_OBJ_VAL(obj, 7), GET_OBJ_VAL(obj, 8), GET_OBJ_VAL(obj, 9)); 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", cleanup(buf2, ex_desc->description)); } /* 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, but not the strings */ Mem->ClearObject(obj); write_index_file("obj"); }