/* ******************************************* * * * 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" #include "constants.h" #include "handler.h" extern spell_a grimoire[]; #define OBJ d->edit_obj void write_objs_to_disk(int zone); // extern funcs extern char *cleanup(char *dest, const char *src); #define NUM_SPELLS 49 #define NUM_WEAPON_TYPES 27 #define NUM_SKILL_TYPES 20 #define NUM_DRINK_TYPES 33 #define NUM_PATCHES 4 #define NUM_CYBERWARE_TYPES 35 #define NUM_BIOWARE_TYPES 11 #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) { if (GET_OBJ_TYPE(d->edit_obj) == ITEM_MOD) sprinttype(d->edit_obj->affected[counter].location, veh_aff, buf2); else 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; if (GET_OBJ_TYPE(d->edit_obj) == ITEM_MOD) { for (counter = 0; counter < VAFF_MAX; counter += 2) send_to_char(CH, "%2d) %-18s %2d) %-18s\r\n", counter, veh_aff[counter], counter + 1, counter + 1 < VAFF_MAX ? veh_aff[counter + 1] : ""); } else { for (counter = 0; counter < AFF_MAX; counter += 2) send_to_char(CH, "%2d) %-18s %2d) %-18s\r\n", counter, apply_types[counter], counter + 1, counter + 1 < APPLY_MAX ? 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" "20) Unarmed Combat\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; int c, line = 0; switch (GET_OBJ_TYPE(d->edit_obj)) { case ITEM_WORKSHOP: send_to_char(CH, "0) General\r\n1) Electronic\r\n2) Microtronic\r\n3) Cyberware\r\n4) Vehicle\r\n5) Weaponry\r\n6) Medical\r\nWorkshop Type: "); break; case ITEM_CAMERA: send_to_char("0) Camera\r\n1) Photo\r\nObject Type: ", CH); break; case ITEM_LIGHT: /* values 0 and 1 are unused.. jump to 2 */ iedit_disp_val3_menu(d); 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_GYRO: send_to_char("RATING: ", 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" " 4) Mechanical\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 2) Computer\r\n 3) Parts\r\n 4) Chip Cooker\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; case ITEM_MOD: send_to_char(" 0) Suspension\r\n" " 1) Engine\r\n" " 2) Steering\r\n" " 3) Tires\r\n" " 4) Brakes\r\n" " 5) Armor Plating\r\n" " 6) Computer\r\n" " 7) Phones\r\n" " 8) Sensors\r\n" " 9) ECM\r\n" " 10) Ignition\r\n" " 11) Alarm\r\n" " 12) Seats\r\n" " 13) Body Style\r\n" " 14) Radio\r\n" " 15) Mount\r\n" "Enter type of Mod: ", CH); break; case ITEM_HOLSTER: send_to_char("Type (0 - Pistol/SMG, 1 - Sword, 2 - Rifle (or larger)): ", d->character); break; case ITEM_WORN: send_to_char("Holster/Sheath/Quiver Space: ", d->character); break; case ITEM_RCDECK: send_to_char("Rating: ", d->character); break; case ITEM_PHONE: send_to_char("Area Code (0 - Seattle, 1 - Tacoma, 2 - Portland)): ", d->character); break; case ITEM_CHIP: CLS(CH); for (c = 0; c < MAX_SKILLS; c++) { line++; if ((line % 3) == 1) sprintf(buf, "%2d) %-20s ", c, skills[c].name); else sprintf(buf, "%s%2d) %-20s ", buf, c, skills[c].name); if (!(line % 3)) { sprintf(buf, "%s\r\n", buf); send_to_char(buf, CH); } } if ((line % 3) != 0) { sprintf(buf, "%s\r\nEnter a skill (0 to quit): ", buf); send_to_char(buf, CH); } 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_CHIP: send_to_char(CH, "Enter skillsoft rating: "); 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_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) Hitcher Jack\r\n 4) IO speed\r\n" " 5) Reaction increase\r\nUpgrade type: ", CH); break; case TYPE_COMPUTER: send_to_char("Active Memory: ", CH); break; case TYPE_PARTS: send_to_char(" 0) General Parts\r\n 1) Memory Chips\r\n", CH); break; case TYPE_COOKER: send_to_char("Enter rating: ", 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\n" " 5) Silencer\r\n 6) Sound Suppressor\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; case ITEM_MOD: if (GET_OBJ_VAL(d->edit_obj, 0) == MOD_MOUNT) send_to_char(" 0) Firmpoint Internal Fixed Mount\r\n" " 1) Firmpoint External Fixed Mount\r\n" " 2) Hardpoint Internal Fixed Mount\r\n" " 3) Hardpoint External Fixed Mount\r\n" " 4) Turret\r\n" " 5) Mini-Turret\r\n" "Type of Mount: ", CH); else send_to_char("Load space taken up: ", d->character); break; case ITEM_WORN: send_to_char("Space for clips: ", CH); 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_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_GUN_CLIP: send_to_char(" 0) Normal 1) APDS\r\n" " 2) Explosive 3) EX\r\n" " 4) Flechette 5) Gel\r\n" "Select Type: ", CH); 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_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: iedit_disp_menu(d); break; case 4: send_to_char("I/O speed increase: ", CH); break; case 5: send_to_char("Reaction increase level: ", CH); break; } break; case TYPE_COMPUTER: send_to_char("Storage Memory: ", CH); break; default: iedit_disp_menu(d); break; } break; case ITEM_GUN_ACCESSORY: if (GET_OBJ_VAL(OBJ, 1) == 1) send_to_char("Smartlink Rating: ", CH); else 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; case ITEM_MOD: if (GET_OBJ_VAL(d->edit_obj, 0) == MOD_RADIO) send_to_char("Radio Range (0-5): ", CH); else iedit_disp_val5_menu(d); break; case ITEM_WORN: send_to_char("Space for grenades: ", CH); 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_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_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: iedit_disp_menu(d); break; case TYPE_UPGRADE: if (GET_OBJ_VAL(OBJ, 1) == 5) send_to_char("MPCP to enhance: ", CH); else iedit_disp_menu(d); break; case TYPE_COMPUTER: iedit_disp_menu(d); break; } break; case ITEM_PROGRAM: if (GET_OBJ_VAL(d->edit_obj, 0) == SOFT_ATTACK) send_to_char("Damage Rating (1-Light 2-Moderate 3-Serious 4-Deadly): ", CH); else iedit_disp_menu(d); break; case ITEM_WORN: send_to_char("Space for shuriken: ", CH); break; case ITEM_MOD: if (GET_OBJ_VAL(d->edit_obj, 0) == MOD_RADIO) send_to_char("Crypt Level (0-6): ", CH); 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; case ITEM_WORN: send_to_char("Space for Misc small items: ", CH); break; case ITEM_MOD: send_to_char("Designed For (0 - Vehicle, 1 - Drone, 2 - Both): ", CH); 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; case ITEM_WORN: send_to_char("Ballistic Rating: ", CH); break; case ITEM_CYBERDECK: iedit_disp_val7_menu(d); 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; case ITEM_WORN: send_to_char("Impact Rating: ", CH); break; case ITEM_CYBERDECK: send_to_char("Response Increase: ", CH); 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_ADMIN)) { 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; case ITEM_WORN: send_to_char("Concealibility rating (+harder -easier): ", CH); 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_ADMIN)) { 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_ADMIN) && 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 < ITEM_EXTRA_MAX; counter += 2) send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, extra_bits[counter], counter + 2, counter + 1 < ITEM_EXTRA_MAX ? extra_bits[counter + 1] : ""); GET_OBJ_EXTRA(d->edit_obj).PrintBits(buf1, MAX_STRING_LENGTH, extra_bits, ITEM_EXTRA_MAX); 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 < AFF_MAX; counter += 2) send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, affected_bits[counter], counter + 2, counter + 1 < AFF_MAX ? affected_bits[counter + 1] : ""); OBJ->obj_flags.bitvector.PrintBits(buf1, MAX_STRING_LENGTH, affected_bits, AFF_MAX); 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 < ITEM_WEAR_MAX; counter += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", counter + 1, wear_bits[counter], counter + 2, counter + 1 < ITEM_WEAR_MAX ? wear_bits[counter + 1] : ""); } GET_OBJ_WEAR(d->edit_obj).PrintBits(buf1, MAX_STRING_LENGTH, wear_bits, ITEM_WEAR_MAX); 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 keywords: %s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->text.keywords, CCNRM(CH, C_CMP)); send_to_char(CH, "2) Item name: %s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->text.name, CCNRM(CH, C_CMP)); send_to_char(CH, "3) Room description:\r\n%s%s%s\r\n", CCCYN(CH, C_CMP), d->edit_obj->text.room_desc, CCNRM(CH, C_CMP)); send_to_char(CH, "4) Look description: \r\n%s\r\n", d->edit_obj->text.look_desc ? d->edit_obj->text.look_desc : "(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)); GET_OBJ_EXTRA(d->edit_obj).PrintBits(buf1, MAX_STRING_LENGTH, extra_bits, ITEM_EXTRA_MAX); send_to_char(CH, "6) Item extra flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); OBJ->obj_flags.bitvector.PrintBits(buf1, MAX_STRING_LENGTH, affected_bits, AFF_MAX); send_to_char(CH, "7) Item affection flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); OBJ->obj_flags.wear_flags.PrintBits(buf1, MAX_STRING_LENGTH, wear_bits, NUM_WEARS); 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%.2f%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)); send_to_char(CH, "b) Item availability: ^c%d^n/^c%.2f^n days\r\n", GET_OBJ_AVAILTN(d->edit_obj), GET_OBJ_AVAILDAY(d->edit_obj)); 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[(int)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) { long number, j; long 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; PLR_FLAGS(d->character).RemoveBit(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 */ if (!from_ip_zone(d->edit_number)) { sprintf(buf,"%s wrote new obj #%ld", GET_CHAR_NAME(d->character), d->edit_number); mudlog(buf, d->character, LOG_WIZLOG, TRUE); } 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 extra_descr_data *This, *next_one; /* 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].text.keywords) delete [] obj_proto[obj_number].text.keywords; if (obj_proto[obj_number].text.name) delete [] obj_proto[obj_number].text.name; if (obj_proto[obj_number].text.room_desc) delete [] obj_proto[obj_number].text.room_desc; if (obj_proto[obj_number].text.look_desc) delete [] obj_proto[obj_number].text.look_desc; 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 */ long counter; int found = FALSE; struct obj_data *new_obj_proto; struct index_data *new_obj_index; /* + 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_VNUM_RNUM(counter) > d->edit_number) { /* eureka. insert now */ /*---------*/ new_obj_index[counter].vnum = 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].vnum = 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 */ { 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 are not 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); // do not 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; PLR_FLAGS(d->character).RemoveBit(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; PLR_FLAGS(d->character).RemoveBit(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; iedit_parse(d, "y"); break; case 'x': case 'X': d->edit_mode = IEDIT_CONFIRM_SAVESTRING; iedit_parse(d, "n"); 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); shutdown(); } *(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': send_to_char(CH, "Enter Availibilty TN: "); d->edit_mode = IEDIT_AVAILTN; 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->text.keywords) delete [] d->edit_obj->text.keywords; d->edit_obj->text.keywords = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_SHORTDESC: if (d->edit_obj->text.name) delete [] d->edit_obj->text.name; d->edit_obj->text.name = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_DESC: if (d->edit_obj->text.room_desc) delete [] d->edit_obj->text.room_desc; d->edit_obj->text.room_desc = str_dup(arg); iedit_disp_menu(d); break; case IEDIT_LONGDESC: // we should not get here break; case IEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number > NUM_ITEM_TYPES) || (number == ITEM_CYBERWARE && !access_level(CH, LVL_ADMIN)) || (number == ITEM_BIOWARE && !access_level(CH, LVL_ADMIN))) { 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 > ITEM_EXTRA_MAX)) { 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 { GET_OBJ_EXTRA(d->edit_obj).ToggleBit(number-1); iedit_disp_extra_menu(d); } } break; case IEDIT_AFF_BITS: number = atoi(arg); if ((number > 0) && (number <= AFF_MAX)) { OBJ->obj_flags.bitvector.ToggleBit(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 > ITEM_WEAR_MAX)) { 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 { GET_OBJ_WEAR(d->edit_obj).ToggleBit(number-1); iedit_disp_wear_menu(d); } } break; case IEDIT_WEIGHT: GET_OBJ_WEIGHT(d->edit_obj) = atof(arg); iedit_disp_menu(d); break; case IEDIT_AVAILTN: GET_OBJ_AVAILTN(d->edit_obj) = atoi(arg); send_to_char(CH, "Enter Availabilty Time in Days: "); d->edit_mode = IEDIT_AVAILDAY; break; case IEDIT_AVAILDAY: GET_OBJ_AVAILDAY(d->edit_obj) = atof(arg); iedit_disp_menu(d); break; case IEDIT_COST: GET_OBJ_COST(d->edit_obj) = atoi(arg); iedit_disp_menu(d); break; case IEDIT_TIMER: GET_OBJ_TIMER(d->edit_obj) = atoi(arg); 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_WORKSHOP: if (number < 0 || number > 6) { send_to_char(CH, "Invalid value. Enter Workshop Type: "); return; } break; case ITEM_CAMERA: if (number < 0 || number > 1) { send_to_char(CH,"Value must be 0 or 1: \r\n"); 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 > 10) { send_to_char("Value must be between 1 and 10.\r\nRating of cyberware: ", CH); return; } break; case ITEM_CYBERDECK: if (number < 1 || number > 30) { send_to_char("Value must be between 1 and 30.\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 > 4) { CLS(CH); send_to_char("1) Medical\r\n" "2) Electronic\r\n" "3) Cyberdeck\r\n" "4) Mechanical\r\n" "Enter type of kit: ", CH); return; } else number--; break; case ITEM_DECK_ACCESSORY: if (number < 0 || number > 4) { 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; case ITEM_CHIP: if ((number < 0) || (number > MAX_SKILLS)) { send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS); send_to_char("Enter a skill (0 to quit): ", 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_CHIP: if (number < 0 || number > 15) { send_to_char(CH, "Rating must be between 0 and 15. Enter skillsoft rating: "); return; } break; 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; } case TYPE_PARTS: if (number < 0 || number > 1) { send_to_char("Invalid choice! Part type:", CH); return; } } 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 > 6) { 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: 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; case ITEM_GUN_ACCESSORY: if (GET_OBJ_VAL(OBJ, 1) == 3 && (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 < 0 || number > 20) { 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; case ITEM_GUN_CLIP: if (number < 0 || number > 5) { send_to_char("INVALID TYPE!\r\nSelect Type: ", CH); return; } 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_WEAPON: if (number < 1 || (!access_level(CH, LVL_ADMIN) && 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_ADMIN) && 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 || number > 4) { send_to_char("Must be between 1 and 4: ", d->character); iedit_disp_val4_menu(d); } break; case ITEM_SPELL_FORMULA: return; case ITEM_DECK_ACCESSORY: 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 are not in the list number += 2; if (number == 22) { number = SKILL_UNARMED_COMBAT; break; } 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; case ITEM_CYBERDECK: if (number <= 0 || number > (int)(GET_OBJ_VAL(d->edit_obj, 0) / 3)) { send_to_char(CH, "Reaction upgrade must be between 1 and %d. Reaction Upgrade: ", (int)(GET_OBJ_VAL(d->edit_obj, 0) / 3)); return; } 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_ADMIN)) 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_ADMIN)) 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_ADMIN)) 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 ((GET_OBJ_TYPE(d->edit_obj) == ITEM_MOD && (number < 0 || number >= VAFF_MAX)) || (number < 0 || number >= AFF_MAX)) { 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 (struct extra_descr_data *) *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); shutdown(); } *(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 /* Modify this code for new obj formats */ void write_objs_to_disk(int zone) { int counter, counter2, realcounter, count = 0; FILE *fp; struct obj_data *obj; struct extra_descr_data *ex_desc; zone = real_zone(zone); // ideally, this would just fill a VTable with vals...maybe one day 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; if (!strcmp("an unfinished object", obj->text.name)) continue; fprintf(fp, "#%ld\n", GET_OBJ_VNUM(obj)); fprintf(fp, "Keywords:\t%s\n" "Name:\t%s\n" "RoomDesc:$\n%s~\n" "LookDesc:$\n%s~\n", obj->text.keywords? obj->text.keywords : "unnamed", obj->text.name? obj->text.name : "an unnamed object", obj->text.room_desc? obj->text.room_desc : "An unnamed object sits here", obj->text.look_desc? cleanup(buf2, obj->text.look_desc) : "You see an uncreative object.\n"); fprintf(fp, "Type:\t%s\n" "WearFlags:\t%s\n" "ExtraFlags:\t%s\n" "AffFlags:\t%s\n" "Material:\t%s\n", item_types[(int)GET_OBJ_TYPE(obj)], GET_OBJ_WEAR(obj).ToString(), GET_OBJ_EXTRA(obj).ToString(), obj->obj_flags.bitvector.ToString(), material_names[(int)GET_OBJ_MATERIAL(obj)]); fprintf(fp, "[POINTS]\n" "\tWeight:\t%.2f\n" "\tBarrier:\t%d\n" "\tCost:\t%d\n" "\tAvailTN:\t%d\n" "\tAvailDay:\t%.2f\n", GET_OBJ_WEIGHT(obj), GET_OBJ_BARRIER(obj), GET_OBJ_COST(obj), GET_OBJ_AVAILTN(obj), GET_OBJ_AVAILDAY(obj)); bool print_vals = false; int i; for (i = 0; i < 10; i++) if (GET_OBJ_VAL(obj, i) != 0) { print_vals = true; break; } if (print_vals) { fprintf(fp, "[VALUES]\n"); for (i = 0; i < 10; i++) if (GET_OBJ_VAL(obj, i) != 0) fprintf(fp, "\tVal%d:\t%d\n", i, GET_OBJ_VAL(obj, i)); } /* do we have extra descriptions? */ count = 0; if (obj->ex_description) for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc->keyword && ex_desc->description) { fprintf(fp, "[EXTRADESC %d]\n" "\tKeywords:\t%s\n" "\tDesc:$\n%s~\n", count, ex_desc->keyword, cleanup(buf2, ex_desc->description)); count++; } } /* do we have affects? */ for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++) { obj_affected_type *af = obj->affected+counter2; if (af->location != APPLY_NONE && af->modifier != 0) { fprintf(fp, "[AFFECT %d]\n" "\tLocation:\t%s\n" "\tModifier:\t%d\n", counter2, apply_types[(int)af->location], af->modifier); } } fprintf(fp, "BREAK\n"); } } /* write final line, close */ fprintf(fp, "END\n"); fclose(fp); write_index_file("obj"); }