#include #include #include "structs.h" #include #include "interpreter.h" #include "comm.h" #include "spells.h" #include "utils.h" #include "db.h" #include "boards.h" #include "olc.h" #include "screen.h" #include "shop.h" #include "handler.h" #include "iedit.h" /* external variables */ extern OBJ_DATA *obj_proto; extern int top_of_objt; extern OBJ_DATA *object_list; extern struct index_data *obj_index; extern struct zone_data *zone_table; extern int top_of_zone_table; extern char *item_types[]; extern char *wear_bits[]; extern char *extra_bits[]; extern char *drinks[]; extern char *apply_types[]; extern char *container_bits[]; extern char *pcont_bits[]; extern char *spells[]; extern char *lever_action_types[]; extern char *dirs[]; extern char *material_types[]; extern struct board_info_type board_info[NUM_OF_BOARDS]; extern int material_price_modifier[]; extern int material_weight_modifier[]; extern int material_armor_modifier[]; extern int base_copper_price[]; extern int default_item_weight[]; extern int wear_price_modifier[]; extern int drink_cost[]; extern char *affected_bits[]; extern char *immunity_bits[]; extern struct spell_info_type spell_info[]; extern int mini_mud; extern struct shop_data *shop_index; extern int top_shop; extern void init_text (DESCRIPTOR * d); extern int uvfprintf (FILE * stream, const char *format,...); static void iedit_resist_menu (DESCRIPTOR * d); static void iedit_disp_affect_menu (DESCRIPTOR * d); static void iedit_disp_materials_menu (DESCRIPTOR * d); static void iedit_disp_pcont_flags_menu (DESCRIPTOR * d); static void iedit_disp_container_flags_menu (DESCRIPTOR * d); static void iedit_disp_lever_action_menu (DESCRIPTOR * d); static void iedit_disp_drinks_menu (DESCRIPTOR * d); static void iedit_disp_prompt_apply_menu (DESCRIPTOR * d); static void iedit_disp_apply_menu (DESCRIPTOR * d); static void iedit_disp_weapon_menu (DESCRIPTOR * d); void iedit_disp_all_spells_menu (DESCRIPTOR * d); static void iedit_disp_spells_menu (DESCRIPTOR * d); static void iedit_disp_spells2_menu (DESCRIPTOR * d); static void iedit_disp_spells3_menu (DESCRIPTOR * d); static void iedit_disp_val1_menu (DESCRIPTOR * d); static void iedit_disp_val2_menu (DESCRIPTOR * d); static void iedit_disp_val3_menu (DESCRIPTOR * d); static void iedit_disp_val4_menu (DESCRIPTOR * d); static void iedit_disp_type_menu (DESCRIPTOR * d); static void iedit_disp_extra_menu (DESCRIPTOR * d); static void iedit_disp_wear_menu (DESCRIPTOR * d); int calc_max_cp (OBJ_DATA * obj); int calc_create_points (OBJ_DATA * obj); long int calc_obj_cost (OBJ_DATA * obj); int calc_obj_weight (OBJ_DATA * obj); void write_zone_objs (int zone); int weapon_speed (int type, int level); #define DOBJ d->edit_obj void calc_armor (OBJ_DATA * obj) { int ac; ac = (GET_OBJ_LEVEL (obj) + 5); ac = ac * material_armor_modifier[(int) GET_OBJ_MATERIAL (obj)]; ac += GET_OBJ_QUALITY (obj) ? (GET_OBJ_QUALITY (obj) - 5) * 2 : 0; ac = MAX (ac, 1); GET_OBJ_VAL (obj, 0) = ac; } const int weapon_type_modifier[]; void calc_weapon (OBJ_DATA * obj) { int add = 6 + GET_OBJ_LEVEL (obj) * 2; add *= weapon_type_modifier[GET_WEAPON_TYPE (obj)]; add /= 10; add = MAX (2, add); SET_WEAPON_ADD (obj, add); SET_WEAPON_NUMBER (obj, 1); if (GET_OBJ_QUALITY (obj)) { SET_WEAPON_SIZE (obj, GET_OBJ_QUALITY (obj) + 2); } else { SET_WEAPON_SIZE (obj, 7); } SET_WEAPON_SPEED (obj, weapon_speed (GET_WEAPON_TYPE (obj), GET_OBJ_LEVEL (obj))); } void calc_arrow (OBJ_DATA * obj) { int add = 6 + GET_OBJ_LEVEL (obj) * 2; add *= 5; add /= 10; add = MAX (2, add); SET_WEAPON_ADD (obj, add); SET_WEAPON_NUMBER (obj, 1); if (GET_OBJ_QUALITY (obj)) { SET_WEAPON_SIZE (obj, GET_OBJ_QUALITY (obj) + 2); } else { SET_WEAPON_SIZE (obj, 7); } } int weapon_speed (int type, int level) { int speed = 5; switch (type) { case 1: speed = 7; break; /* axe */ case 2: /* whip */ speed = 8; break; case 3: /* sword */ speed = 6; break; case 4: /* spear */ speed = 6; break; case 5: /* mace */ speed = 7; break; case 6: /* staff */ speed = 4; break; case 7: /* blunt polearm */ speed = 9; break; case 9: /* sharp polearm */ speed = 9; break; case 11: /* dagger */ speed = 2; break; case 12: /* dart */ speed = 1; break; } if (level > 10) { speed--; } if (level > 25) { speed--; } if (level > 40) { speed--; } if (speed <= 0) { speed = 1; } return speed; } /* New cost calculation for objects, taking advantage of the base copper price for levels, the # of creation points of the object and material modifiers */ long int calc_obj_cost (OBJ_DATA * obj) { int points, max, temp; long cost = 0, div = 1; /* sphere costs - 1: 120, 2:240, 3: 380, 4: 560, 5: 820, 6: 1240, 7: 1980, 8: 3260, 9: 6020 */ switch (GET_OBJ_TYPE (obj)) { case ITEM_SPELLBOOK: case ITEM_SPELLPAGE: temp = MAX (spell_info[GET_OBJ_VAL (obj, 0)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 0)].sphere[CLASS_CLERIC]); cost = temp * temp * 100; break; case ITEM_PSI_BRACELET: cost = spell_info[GET_OBJ_VAL (obj, 0)].sphere[CLASS_PSIONICIST] * spell_info[GET_OBJ_VAL (obj, 0)].sphere[CLASS_PSIONICIST] * 100; break; case ITEM_POTION: case ITEM_PILL: if (is_potion_spell (GET_OBJ_VAL (obj, 1))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 1)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 1)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } if (is_potion_spell (GET_OBJ_VAL (obj, 2))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 2)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 2)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } if (is_potion_spell (GET_OBJ_VAL (obj, 3))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } break; case ITEM_SCROLL: if (is_target_spell (GET_OBJ_VAL (obj, 1))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 1)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 1)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } if (is_target_spell (GET_OBJ_VAL (obj, 2))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 2)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 2)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } if (is_target_spell (GET_OBJ_VAL (obj, 3))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_CLERIC]); cost += 100 * temp; cost += 10 * (1 << temp); } break; case ITEM_WAND: case ITEM_STAFF: if (is_target_spell (GET_OBJ_VAL (obj, 3))) { temp = MAX (spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (obj, 3)].sphere[CLASS_CLERIC]); cost += 100 * temp; temp = 10 * (1 << temp); cost += GET_OBJ_VAL (obj, 2) * temp; } break; case ITEM_FOOD: /* if the shit's poisoned, who wants it? */ if (GET_OBJ_VAL (obj, 3) != 0) { cost = 0; } else /* 1 copper per hour fed */ { cost = GET_OBJ_VAL (obj, 0); } break; case ITEM_DRINKCON: /* if the shit's poisoned, who wants it? */ if (GET_OBJ_VAL (obj, 3) != 0) { cost = 0; } else if (GET_OBJ_VAL (obj, 1) == -1) { /* 10000 drinks */ cost = 1000 * drink_cost[GET_OBJ_VAL (obj, 2)]; } else { cost = MAX (1, (GET_OBJ_VAL (obj, 1) / 10)) * drink_cost[GET_OBJ_VAL (obj, 2)]; } break; case ITEM_TREASURE: cost = GET_OBJ_VAL (obj, 0); break; case ITEM_ARROW: case ITEM_QUARREL: cost = 1; goto after; case ITEM_BOW: cost = 100; goto after; case ITEM_CROSSBOW: cost = 300; goto after; case ITEM_ARMOR: case ITEM_WORN: case ITEM_MIRROR: cost = 10; goto after; /* fall through */ case ITEM_WEAPON: switch (GET_OBJ_VAL (obj, 3)) { case 1: cost = 5; break; /* axe */ case 2: cost = 1; break; /* whip */ case 3: cost = 15; break; /* sword */ case 4: cost = 5; break; /* spear */ case 5: cost = 8; break; /* mace */ case 6: cost = 1; break; /* staff */ case 7: cost = 10; break; /* polearm */ case 9: cost = 10; break; /* polearm */ case 11: cost = 2; break; /* dagger */ case 12: cost = 1; /* dart */ break; default: cost = 10; break; /* godknowswhat */ } goto after; case ITEM_LIGHT: if (GET_OBJ_VAL (obj, 2) == -1) { cost = 100; } /* cost = 100 hours */ else { cost = GET_OBJ_VAL (obj, 2); } /* 1 coin per hour */ goto after2; case ITEM_CONTAINER: cost = MAX (10, GET_OBJ_VAL (obj, 0)); /* 1 coin per 10 lb */ div *= 10; goto after2; /* insert other cases which need complex crud in here */ after: cost *= base_copper_price[(int) MIN ((GET_OBJ_LEVEL (obj) - 1) / 2, 25)]; /* Now modify this base cost by location on body modifier.. */ cost *= wear_price_modifier[get_wear (obj)]; div *= 10; after2: /* modify by material stuff modifier.. */ cost *= material_price_modifier[(int) GET_OBJ_MATERIAL (obj)]; div *= 10; if (GET_OBJ_QUALITY (obj) != 0 && GET_OBJ_QUALITY (obj) != 5) { cost *= 5 + GET_OBJ_QUALITY (obj); div *= 10; } points = calc_create_points (obj); max = calc_max_cp (obj); if (points <= 0) ; else if (points < (max / 2)) { cost *= 2; } else if (points < (max * 2 / 3)) { cost *= 4; } else if (points <= max) { cost *= 8; } else { cost *= 16; } /* Divide by a 1000 (because modifiers were 10 x, each */ cost = (long int) ((double) cost / (double) div); cost = MAX (cost, 1); break; case ITEM_LEVER: case ITEM_PORTAL: case ITEM_FOUNTAIN: case ITEM_PPLATE: case ITEM_PEOPLECON: case ITEM_VOCAL: case ITEM_RADIO: case ITEM_OTHER: case ITEM_GUN: case ITEM_KEY: return 0; } return cost; } /* Function to calculate weight of stuff */ int calc_obj_weight (OBJ_DATA * obj) { int base; /* Get the light things over with */ switch (GET_OBJ_TYPE (obj)) { /* trash is .. */ case ITEM_TRASH: return 5; /* trivial things */ case ITEM_KEY: case ITEM_SCROLL: case ITEM_PILL: case ITEM_NOTE: case ITEM_PEN: case ITEM_SPELLPAGE: case ITEM_ARROW: case ITEM_QUARREL: case ITEM_MIRROR: case ITEM_TREASURE: /* hopefully jewels and crap */ case ITEM_AMMO: case ITEM_EXPLOSIVE: case ITEM_SUMMON: return 1; break; case ITEM_CONTAINER: base = 5; /* mod by material */ return MAX (1, base * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10); break; case ITEM_FOOD: /* for every five hours that the food satisfies person, 1 pounds (so in one day, need roughly 5 pounds of food) */ return (MAX (1, GET_OBJ_VAL (obj, 0) / 5)); break; case ITEM_DRINKCON: /* one pound per every 3 charge plus base 2 except for infinite duration */ if (GET_OBJ_VAL (obj, 1) == -1) { return 2; } else { return 2 + (GET_OBJ_VAL (obj, 1) / 3); } break; /* 2 pound wands */ case ITEM_WAND: return 2; break; /* 3 pound lanterns */ case ITEM_LIGHT: return 3; break; /* 4 pound staves */ case ITEM_STAFF: return 5; break; case ITEM_BOW: base = 3; /* mod by material */ return MAX (3, base * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10); break; case ITEM_CROSSBOW: base = 7; /* mod by material */ return MAX (7, base * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10); break; case ITEM_GUN: base = 2; /* mod by material */ return MAX (2, base * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10); break; /* weapons are tricky .. */ case ITEM_WEAPON: switch (GET_OBJ_VAL (obj, 3)) { case 1: base = 8; break; /* axe */ case 2: base = 2; break; /* whip */ case 3: base = 6; break; /* sword */ case 4: base = 5; break; /* spear */ case 5: base = 10; break; /* mace */ case 6: base = 5; break; /* staff */ case 7: base = 12; break; /* polearm */ case 9: base = 12; break; /* polearm */ case 11: base = 1; break; /* dagger */ default: base = 5; break; /* godknowswhat */ } /* mod by material */ return MAX (1, base * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10); break; /* armor is even worse! */ case ITEM_ARMOR: case ITEM_WORN: base = default_item_weight[(int) get_wear (obj)] * material_weight_modifier[(int) GET_OBJ_MATERIAL (obj)] / 10; if (GET_OBJ_QUALITY (obj)) { base += (GET_OBJ_QUALITY (obj) - 5); } base = MAX (1, base); return base; break; case ITEM_LEVER: case ITEM_PORTAL: case ITEM_FOUNTAIN: case ITEM_PPLATE: case ITEM_PEOPLECON: case ITEM_VOCAL: case ITEM_RADIO: return 10000; break; case ITEM_OTHER: default: return 1; } } /* resist menu */ static void iedit_resist_menu (DESCRIPTOR * d) { int i; send_to_char (DCH, ""); for (i = 0; i < 30; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), immunity_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n");; sprintbit (DOBJ->affected[d->edit_number2].modifier, immunity_bits, buf2); send_to_char (DCH, "Resistances/Immunities: %s%s%s\r\n", HLCYN (DCH), buf2, CCNRM (DCH)); send_to_char (DCH, "Enter resistances or 0 to quit:\r\n"); d->edit_mode = IEDIT_APPLYIMM; } /* display affect menu */ static void iedit_disp_affect_menu (DESCRIPTOR * d) { int i; send_to_char (DCH, ""); for (i = 0; i < NUM_MOB_AFFECTS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), affected_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); sprintbit (DOBJ->affected[d->edit_number2].modifier, affected_bits, buf1); send_to_char (DCH, "Affect Flags: %s%s%s\r\n", HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "Enter affect flags, or 0 to quit:\r\n"); d->edit_mode = IEDIT_APPLYAFF; } static void iedit_disp_materials_menu (DESCRIPTOR * d) { int i; for (i = 0; i < NUM_OBJ_MATERIALS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), material_types[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter material type:"); } static void iedit_disp_pcont_flags_menu (DESCRIPTOR * d) { int i; for (i = 0; i < NUM_OBJ_PCONT_FLAGS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), pcont_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); sprintbit (GET_OBJ_VAL (DOBJ, 1), pcont_bits, buf1); send_to_char (DCH, "People container flags: %s%s%s\r\n", HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "Enter people container flags, 0 to quit:"); } static void iedit_disp_container_flags_menu (DESCRIPTOR * d) { send_to_char (DCH, "%s1%s) Closeable\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s2%s) Pickproof\r\n", HLMAG (DCH), CCNRM (DCH)); sprintbit (GET_OBJ_VAL (DOBJ, 1), container_bits, buf1); send_to_char (DCH, "Container flags: %s%s%s\r\n", HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "Enter flag, 0 to quit:"); } static void iedit_disp_lever_action_menu (DESCRIPTOR * d) { int i; for (i = 0; i < MAX_LEVER_ACTIONS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), lever_action_types[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter lever action type:\r\n"); } static void iedit_disp_drinks_menu (DESCRIPTOR * d) { int i; for (i = 0; i < NUM_OBJ_DRINKS; i++) { send_to_char (DCH, "%s%2d)%s %20.20s ", HLMAG (DCH), i, CCNRM (DCH), drinks[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter drink type:\r\n"); } /* For extra descriptions */ void iedit_disp_extradesc_menu (DESCRIPTOR * d) { struct extra_descr_data *extra_desc = (struct extra_descr_data *) *d->misc_data; send_to_char (DCH, "%s0%s) Quit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s1%s) Keyword : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), extra_desc->keyword ? extra_desc->keyword : "", CCNRM (DCH)); send_to_char (DCH, "%s2%s) Description:\r\n%s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), extra_desc->description ? extra_desc->description : "", CCNRM (DCH)); if (!extra_desc->next) { send_to_char (DCH, "%s3%s) \r\n", HLMAG (DCH), CCNRM (DCH)); } else { send_to_char (DCH, "%s3%s) Set. \r\n", HLMAG (DCH), CCNRM (DCH)); } send_to_char (DCH, "Enter choice:\r\n"); d->edit_mode = IEDIT_EXTRADESC_MENU; } static void iedit_disp_prompt_apply_menu (DESCRIPTOR * d) { int i; send_to_char (DCH, "Creation points : %s%d%s/%s%d%s\r\n", HLRED (DCH), calc_create_points (DOBJ), CCNRM (DCH), HLCYN (DCH), calc_max_cp (DOBJ), CCNRM (DCH)); for (i = 0; i < MAX_OBJ_AFFECT; i++) { if (DOBJ->affected[i].modifier) { sprinttype (DOBJ->affected[i].location, apply_types, buf2); send_to_char (DCH, " %s%d%s) %s%+ld%s to %s\r\n", HLMAG (DCH), i + 1, CCNRM (DCH), HLCYN (DCH), DOBJ->affected[i].modifier, CCNRM (DCH), buf2); } else { send_to_char (DCH, " %s%d%s) None.\r\n", HLMAG (DCH), i + 1, CCNRM (DCH)); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter affection to modify (0 to quit):"); d->edit_mode = IEDIT_PROMPT_APPLY; } /* The actual apply to set */ char iedit_apply_mapping[] = {APPLY_NONE, APPLY_STR, APPLY_DEX, APPLY_MAG, APPLY_INT, APPLY_CON, APPLY_AGE, APPLY_MANA, APPLY_HIT, APPLY_MOVE, APPLY_PSP, APPLY_AC, APPLY_HITROLL, APPLY_DAMROLL, APPLY_SPELL, APPLY_EVADE, APPLY_SKILL }; char iedit_apply_valid[] = { true, true, true, false, true, true, true, false, false, true, false, false, true, true, true, true, false, true, true, true, false, false, false, false, false, false, false, true, true, true }; static void iedit_disp_apply_menu (DESCRIPTOR * d) { int i, j = 1; for (i = 0; i < NUM_OBJ_APPLIES; i++) { if (iedit_apply_valid[i]) { sprintf (buf, "%s%2d%s) %20.20s ", HLMAG (DCH), j - 1, CCNRM (DCH), apply_types[i]); j++; send_to_char (DCH, buf); if (j % 2 == 1) { send_to_char (DCH, "\r\n"); } } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter apply type (0 is no apply):"); d->edit_mode = IEDIT_APPLY; } static void iedit_disp_weapon_menu (DESCRIPTOR * d) { send_to_char (DCH, "%s1%s) axe\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s2%s) whip\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s3%s) sword\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s4%s) spear\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s5%s) mace\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s6%s) staff\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s7%s) blunt polearm\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s8%s) UNUSED\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s9%s) sharp polearm\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s10%s) UNUSED\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s11%s) dagger\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s12%s) dart\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "Enter weapon type:\r\n"); } void iedit_disp_all_spells_menu (DESCRIPTOR * d) { int i, j = 0; for (i = 1; i < NUM_SPELLS; i++) { if ((spell_info[i].min_level[CLASS_MAGIC_USER] != LVL_IMPL + 1) || (spell_info[i].min_level[CLASS_CLERIC] != LVL_IMPL + 1)) { send_to_char (DCH, "%s%3d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), spells[i]); j++; if (j == 3) { j = 0; send_to_char (DCH, "\r\n"); } } } send_to_char (DCH, "\r\n"); } static void iedit_disp_skills_menu (DESCRIPTOR * d) { int i, j = 0, k, l; for (i = MAX_SPELLS; i < MAX_PC_SKILLS; i++) { l = 60; for (k = 0; k < 6; k++) { if (l > spell_info[i].min_level[k]) { l = spell_info[i].min_level[k]; } } if (DOBJ && GET_OBJ_LEVEL (DOBJ) >= l) { send_to_char (DCH, "%s%3d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), spells[i]); j++; } if (j == 3) { j = 0; send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter skill choice (0 for none):\r\n"); } /* spell type */ static void iedit_disp_spells_menu (DESCRIPTOR * d) { int i, j = 0; for (i = 1; i < NUM_SPELLS; i++) { /* For personal items: only show spells which are - TAR_CHAR_ROOM or TAR_SELF_ONLY, and - not MAG_DAMAGE and not MAG_POINTS (mag_points are all the healing spells) and not MAG_MANUAL and not MAG_UNAFFECTS. Whew! Violent things are NOT ruled out, to make life interesting. this should rule out all stupidity */ if (is_personal_spell (i) && DOBJ && GET_OBJ_LEVEL (DOBJ) >= MIN (spell_info[i].min_level[CLASS_MAGIC_USER], MIN (spell_info[i].min_level[CLASS_CLERIC], spell_info[i].min_level[CLASS_PSIONICIST]))) { send_to_char (DCH, "%s%3d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), spells[i]); j++; } if (j == 3) { j = 0; send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); } /* spell type */ static void iedit_disp_spells2_menu (DESCRIPTOR * d) { int i, j = 0; for (i = 1; i < NUM_SPELLS; i++) { /* For wands/staves/scrolls: show spells which are not TAR_OTHER (because they have extra args). Also show spells which have actually been INSTALLED!! this should rule out all stupidity */ if (is_target_spell (i) && DOBJ && GET_OBJ_LEVEL (DOBJ) >= MIN (spell_info[i].min_level[CLASS_MAGIC_USER], MIN (spell_info[i].min_level[CLASS_CLERIC], spell_info[i].min_level[CLASS_PSIONICIST]))) { send_to_char (DCH, "%s%3d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), spells[i]); j++; } if (j == 3) { j = 0; send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); } /* spell type */ static void iedit_disp_spells3_menu (DESCRIPTOR * d) { int i, j = 0; for (i = 1; i < NUM_SPELLS; i++) { /* For potions: no damage spells (fireballing yourself is just stupid), no object spells (doh) */ if (is_potion_spell (i) && DOBJ && GET_OBJ_LEVEL (DOBJ) >= MIN (spell_info[i].min_level[CLASS_MAGIC_USER], MIN (spell_info[i].min_level[CLASS_CLERIC], spell_info[i].min_level[CLASS_PSIONICIST]))) { send_to_char (DCH, "%s%3d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), spells[i]); j++; } if (j == 3) { j = 0; send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); } /* object value 1 */ static void iedit_disp_val1_menu (DESCRIPTOR * d) { d->edit_mode = IEDIT_VALUE_1; switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_TREASURE: /* stored in val 1 (copied to cost!) */ send_to_char (DCH, "Enter cost of treasure:"); break; case ITEM_PORTAL: send_to_char (DCH, "Room to portal to:"); break; case ITEM_RADIO: send_to_char (DCH, "Do you want this radio to trigger on entry? (Y/N):"); break; case ITEM_KEY: send_to_char (DCH, "Number of uses (0 is infinite):"); break; case ITEM_SUMMON: send_to_char (DCH, "Number of charges:"); break; 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: case ITEM_PILL: case ITEM_ARROW: case ITEM_QUARREL: /* value 0 will be filled in later, or unused */ iedit_disp_val2_menu (d); break; case ITEM_WEAPON: iedit_disp_weapon_menu (d); break; case ITEM_ARMOR: if (ADVANCED_BUILDER (DCH)) { calc_armor (DOBJ); send_to_char (DCH, "Apply to AC (Recommended: %ld):", GET_OBJ_VAL (DOBJ, 0)); } else { send_to_char (DCH, "Enter the quality modifier of this armor (1 to 9):\r\n"); } break; case ITEM_CONTAINER: send_to_char (DCH, "Max weight to contain:"); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: send_to_char (DCH, "Max drink units:"); break; case ITEM_FOOD: send_to_char (DCH, "Hours to fill stomach:"); break; case ITEM_MONEY: send_to_char (DCH, "Number of gold coins:"); break; case ITEM_NOTE: /* this is supposed to be language, but it's unused */ break; case ITEM_GUN: send_to_char (DCH, "Ammo number:"); break; case ITEM_AMMO: send_to_char (DCH, "Ammo number:"); break; case ITEM_PPLATE: case ITEM_LEVER: case ITEM_VOCAL: iedit_disp_lever_action_menu (d); break; case ITEM_SPELLPAGE: iedit_disp_all_spells_menu (d); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); break; case ITEM_PEOPLECON: send_to_char (DCH, "Room vnum to link to for interior:"); break; case ITEM_SPELLBOOK: iedit_disp_val2_menu (d); break; default: iedit_disp_menu (d); } } /* object value 2 */ static void iedit_disp_val2_menu (DESCRIPTOR * d) { d->edit_mode = IEDIT_VALUE_2; switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_RADIO: send_to_char (DCH, "# of 10 second intervals between possible radio repetitions:\r\n"); break; case ITEM_SPELLPAGE: iedit_disp_all_spells_menu (d); send_to_char (DCH, "Disappear after use (0 for yes, any other for no):\r\n"); break; case ITEM_SPELLBOOK: send_to_char ( DCH, "Enter capacity of spellbook:\r\n"); break; case ITEM_SUMMON: send_to_char ( DCH, "Enter virtual number of mob to summon:\r\n"); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: send_to_char (DCH, "Current number of drinks in container (0 empty, -1 infinite):"); break; case ITEM_SCROLL: iedit_disp_spells2_menu (d); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); break; case ITEM_POTION: case ITEM_PILL: iedit_disp_spells3_menu (d); break; case ITEM_WAND: case ITEM_STAFF: send_to_char (DCH, "Max number of charges:"); break; case ITEM_QUARREL: case ITEM_ARROW: case ITEM_WEAPON: if (ADVANCED_BUILDER (DCH)) { send_to_char (DCH, "Number of damage dice (Recommended: %ld):", GET_OBJ_VAL (DOBJ, 1)); } else { send_to_char (DCH, "Enter the quality modifier on damage (1 to 9):\r\n"); } break; case ITEM_FOOD: /* values 2 and 3 are unused, jump to 4. how odd */ iedit_disp_val4_menu (d); break; case ITEM_PORTAL: case ITEM_CONTAINER: /* these are flags, needs a bit of special handling */ iedit_disp_container_flags_menu (d); break; case ITEM_GUN: send_to_char (DCH, "Gun recoil delay:"); break; case ITEM_AMMO: send_to_char (DCH, "Number of charges:"); break; case ITEM_PEOPLECON: /* these are flags, needs a bit of special handling */ iedit_disp_pcont_flags_menu (d); break; case ITEM_PPLATE: case ITEM_LEVER: case ITEM_VOCAL: switch (GET_OBJ_VAL (DOBJ, 0)) { case ACTION_OPEN: case ACTION_CLOSE: case ACTION_LOCK: case ACTION_UNLOCK: send_to_char (DCH, "In which room:"); break; case ACTION_TELEPORT: send_to_char (DCH, "To which room:"); break; case ACTION_CURRENT: iedit_disp_val3_menu (d); break; default: iedit_disp_val4_menu (d); break; } break; default: iedit_disp_menu (d); } } /* object value 3 */ static void iedit_disp_val3_menu (DESCRIPTOR * d) { d->edit_mode = IEDIT_VALUE_3; switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_RADIO: send_to_char (DCH, "Percentage chance of radio trigger (%):"); break; case ITEM_PEOPLECON: send_to_char (DCH, "Maximum people capacity:"); break; case ITEM_LIGHT: send_to_char (DCH, "Number of hours (0 = burnt, -1 is infinite):"); break; case ITEM_SCROLL: iedit_disp_spells2_menu (d); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); break; case ITEM_SUMMON: send_to_char ( DCH, "Enter chance of summon failure (mob attacks):\r\n"); break; case ITEM_POTION: case ITEM_PILL: iedit_disp_spells3_menu (d); break; case ITEM_WAND: case ITEM_STAFF: send_to_char (DCH, "Number of charges remaining:"); break; case ITEM_QUARREL: case ITEM_ARROW: case ITEM_WEAPON: send_to_char (DCH, "Size of damage dice (Recommended: %ld):", GET_OBJ_VAL (DOBJ, 2)); break; case ITEM_PORTAL: case ITEM_CONTAINER: send_to_char (DCH, "Vnum of key to open (-1 for no key):"); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: iedit_disp_drinks_menu (d); break; case ITEM_GUN: send_to_char (DCH, "Damage bonus:"); break; case ITEM_AMMO: send_to_char (DCH, "Number of damage dice:"); break; case ITEM_PPLATE: case ITEM_LEVER: case ITEM_VOCAL: switch (GET_OBJ_VAL (DOBJ, 0)) { case ACTION_OPEN: case ACTION_CLOSE: case ACTION_LOCK: case ACTION_UNLOCK: case ACTION_CURRENT: send_to_char (DCH, "Which direction:"); break; default: iedit_disp_val4_menu (d); break; } break; default: iedit_disp_menu (d); } } /* object value 4 */ static void iedit_disp_val4_menu (DESCRIPTOR * d) { d->edit_mode = IEDIT_VALUE_4; switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_RADIO: send_to_char (DCH, "Enter volume (0 for same room, -1 for zone wide, other values indicate\r\n radius of rooms which hear message:"); break; case ITEM_SCROLL: case ITEM_WAND: case ITEM_STAFF: iedit_disp_spells2_menu (d); send_to_char (DCH, "Enter spell choice (0 for none):\r\n"); break; case ITEM_POTION: case ITEM_PILL: iedit_disp_spells3_menu (d); break; case ITEM_WEAPON: send_to_char (DCH, "Weapon speed (Recommended: %d):", weapon_speed (GET_WEAPON_TYPE (DOBJ), GET_OBJ_LEVEL (DOBJ))); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: case ITEM_FOOD: send_to_char (DCH, "Poisoned (0 = not poison)"); break; case ITEM_GUN: send_to_char (DCH, "Number of bullets per round:"); break; case ITEM_AMMO: send_to_char (DCH, "Size of damage dice:"); break; case ITEM_LEVER: send_to_char (DCH, "1) Pullable (action on pull)\n"); send_to_char (DCH, "2) Pushable (action on push)\n"); send_to_char (DCH, "3) Both (action on pull/push or both)\n"); d->edit_mode = IEDIT_LEVER_MOVE_FLAGS; break; #ifdef undef case ITEM_PPLATE: send_to_char (DCH, "Enter weight needed to activate\r\n(Negative value indicates triggered when weight becomes LESS):"); break; #endif default: iedit_disp_menu (d); } } /* object type */ char iedit_type_mapping[] = { ITEM_LIGHT, ITEM_SCROLL, ITEM_WAND, ITEM_STAFF, ITEM_WEAPON, ITEM_PPLATE, ITEM_ARROW, ITEM_TREASURE, ITEM_ARMOR, ITEM_POTION, ITEM_WORN, ITEM_OTHER, ITEM_PILL, ITEM_CONTAINER, ITEM_DRINKCON, ITEM_KEY, ITEM_FOOD, ITEM_PORTAL, ITEM_FOUNTAIN, ITEM_MIRROR, ITEM_QUARREL, ITEM_BOW, ITEM_CROSSBOW, ITEM_LEVER, ITEM_SUMMON, ITEM_RADIO, ITEM_VOCAL }; char iedit_type_valid[] = {false, /* undef */ true, true, true, true, true, true, /* pplate */ true, /* missile */ true, true, true, true, true, /* other */ false, /* trash */ true, true, false, /* note */ true, true, true, false, /* money */ false, /* pen */ true, true, false, /* corpse */ true, /* mirror??? */ true, /* quarrel */ true, /* bow */ true, /* crossbow */ false, /* doorblock */ true, false, false, false, true, true, false, true, false, false, false}; static void iedit_disp_type_menu (DESCRIPTOR * d) { int i, j = 1; if (ADVANCED_BUILDER (DCH)) { for (i = 0; i < NUM_OBJ_ITEM_TYPES; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), item_types[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } } else for (i = 0; i < NUM_OBJ_ITEM_TYPES; i++) { if (iedit_type_valid[i]) { sprintf (buf, "%s%2d%s) %20.20s ", HLMAG (DCH), j, CCNRM (DCH), item_types[i]); j++; send_to_char (DCH, buf); if (j % 2 == 1) { send_to_char (DCH, "\r\n"); } } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter object type:"); } char iedit_extra_mapping[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 19 }; char iedit_extra_valid[] = { true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, true, false, false, true }; /* object extra flags */ static void iedit_disp_extra_menu (DESCRIPTOR * d) { int i, j = 1; for (i = 0; i < NUM_OBJ_EXTRA_FLAGS; i++) { if (iedit_extra_valid[i]) { sprintf (buf, "%s%2d%s) %20.20s ", HLMAG (DCH), j, CCNRM (DCH), extra_bits[i]); j++; send_to_char (DCH, buf); if (j % 2 == 1) { send_to_char (DCH, "\r\n"); } } } send_to_char (DCH, "\r\n"); sprintbit (GET_OBJ_EXTRA (DOBJ), extra_bits, buf1); send_to_char (DCH, "Object flags: %s\r\n", buf1); send_to_char (DCH, "Enter object extra flag, 0 to quit:"); } /* object wear flags */ static void iedit_disp_wear_menu (DESCRIPTOR * d) { int i; for (i = 0; i < NUM_OBJ_WEAR_FLAGS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), wear_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); sprintbit (GET_OBJ_WEAR (DOBJ), wear_bits, buf1); send_to_char (DCH, "Wear flags: %s\r\n", buf1); send_to_char (DCH, "Enter wear flag, 0 to quit:"); } /* display main menu */ void iedit_disp_menu (DESCRIPTOR * d) { send_to_char (DCH, ""); send_to_char (DCH, "Creation points : %s%d%s/%s%d%s\r\n", HLRED (DCH), calc_create_points (DOBJ), CCNRM (DCH), HLCYN (DCH), calc_max_cp (DOBJ), CCNRM (DCH)); send_to_char (DCH, "Item number : %s%d%s\r\n", HLRED (DCH), d->edit_number, CCNRM (DCH)); send_to_char (DCH, "%s1%s) Namelist : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->name, CCNRM (DCH)); send_to_char (DCH, "%s2%s) Short desc : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->short_description, CCNRM (DCH)); send_to_char (DCH, "%s3%s) Long desc : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->description, CCNRM (DCH)); send_to_char (DCH, "%s4%s) Extra descriptions\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s5%s) Min level : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), GET_OBJ_LEVEL (DOBJ), CCNRM (DCH)); sprinttype (GET_OBJ_MATERIAL (DOBJ), material_types, buf1); send_to_char (DCH, "%s6%s) Material : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf1, CCNRM (DCH)); sprinttype (GET_OBJ_TYPE (DOBJ), item_types, buf1); send_to_char (DCH, "%s7%s) Type : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf1, CCNRM (DCH)); sprintbit (GET_OBJ_EXTRA (DOBJ), extra_bits, buf1); send_to_char (DCH, "%s8%s) Extra flags : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf1, CCNRM (DCH)); sprintbit (GET_OBJ_WEAR (DOBJ), wear_bits, buf1); send_to_char (DCH, "%s9%s) Wear flags : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "%sa%s) Applies\r\n", HLMAG (DCH), CCNRM (DCH)); if (ADVANCED_BUILDER (DCH)) { send_to_char (DCH, "%sb%s) Cost : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), GET_OBJ_COST (DOBJ), CCNRM (DCH)); send_to_char (DCH, "%sc%s) Weight : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), GET_OBJ_WEIGHT (DOBJ), CCNRM (DCH)); send_to_char (DCH, "%sd%s) Timer : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), GET_OBJ_TIMER (DOBJ), CCNRM (DCH)); } if (NEEDS_ACTION_DESC (DOBJ)) { if (ADVANCED_BUILDER (DCH)) { sprintf (buf, "%se%s) Act desc : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->action_description ? DOBJ->action_description : "NOT SET", CCNRM (DCH)); } else { sprintf (buf, "%sb%s) Act desc : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->action_description ? DOBJ->action_description : "NOT SET", CCNRM (DCH)); } send_to_char (DCH, buf); } if (NEEDS_ACTION_WORD (DOBJ)) { if (ADVANCED_BUILDER (DCH)) { sprintf (buf, "%sf%s) Action word : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->action_word ? DOBJ->action_word : "NONE", CCNRM (DCH)); } else { sprintf (buf, "%sc%s) Action word : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DOBJ->action_word ? DOBJ->action_word : "NONE", CCNRM (DCH)); } send_to_char (DCH, buf); } send_to_char (DCH, "%sq%s) Quit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "Enter your choice:\r\n"); d->edit_mode = IEDIT_MAIN_MENU; } int calc_max_cp (OBJ_DATA * obj) { return (int) ((float) GET_OBJ_LEVEL (obj) * 2.0 / 5.0); } int calc_create_points (OBJ_DATA * obj) { int points = 0, mod; int i; /* Calculates the "creation points" of an object; basically a measure of how powerful an object is. Check each affect and add to the running total. These numbers are quite prone to change, obviously. However the current standard is: with 50 mortal levels, every 5 mort levels gives 2 creation points (for a max 20 creation points for a level 50 object). Thus the maximum str modifier is by +4, for example. */ for (i = 0; i < MAX_OBJ_AFFECT; i++) { mod = 0; if (obj->affected[i].modifier) { switch (obj->affected[i].location) { case APPLY_STR: case APPLY_DEX: case APPLY_INT: case APPLY_MAG: case APPLY_CON: mod = 5 * obj->affected[i].modifier; break; case APPLY_PSP: mod = obj->affected[i].modifier; break; case APPLY_MANA: case APPLY_HIT: case APPLY_MOVE: mod = obj->affected[i].modifier / 5; break; case APPLY_AC: if (GET_OBJ_TYPE (obj) == ITEM_WEAPON || GET_OBJ_TYPE (obj) == ITEM_BOW || GET_OBJ_TYPE (obj) == ITEM_CROSSBOW) { mod = 10 * obj->affected[i].modifier; } else if (GET_OBJ_TYPE (obj) == ITEM_ARMOR) { mod = 5 * obj->affected[i].modifier; } else { mod = 7 * obj->affected[i].modifier; } break; case APPLY_DAMROLL: if (GET_OBJ_TYPE (obj) == ITEM_WEAPON || GET_OBJ_TYPE (obj) == ITEM_BOW || GET_OBJ_TYPE (obj) == ITEM_CROSSBOW) { mod = 3 * obj->affected[i].modifier; } else if (GET_OBJ_TYPE (obj) == ITEM_ARMOR) { mod = 10 * obj->affected[i].modifier; } else { mod = 7 * obj->affected[i].modifier; } break; case APPLY_EVADE: mod = 6 * obj->affected[i].modifier; break; case APPLY_HITROLL: if (GET_OBJ_TYPE (obj) == ITEM_WEAPON || GET_OBJ_TYPE (obj) == ITEM_BOW || GET_OBJ_TYPE (obj) == ITEM_CROSSBOW) { mod = 3 * obj->affected[i].modifier; } else if (GET_OBJ_TYPE (obj) == ITEM_ARMOR) { mod = 9 * obj->affected[i].modifier; } else { mod = 6 * obj->affected[i].modifier; } break; case APPLY_SPELL: mod = 5 + MAX (MAX (spell_info[obj->affected[i].modifier].sphere[CLASS_MAGIC_USER], spell_info[obj->affected[i].modifier].sphere[CLASS_MAGIC_USER]), spell_info[obj->affected[i].modifier].sphere[CLASS_PSIONICIST]); if (spell_info[obj->affected[i].modifier].violent) { mod = -mod; } break; } if (mod < 0) { mod = mod * 2 / 3; } points += mod; } } return points; } void iedit_parse (DESCRIPTOR * d, char *arg) { int i; int obj_number; /* the RNUM */ switch (d->edit_mode) { case IEDIT_CONFIRM_EDIT: /* if player hits 'Y' then edit obj */ switch (*arg) { case 'y': case 'Y': iedit_disp_menu (d); break; case 'n': case 'N': sprintf (buf, "%s has exited iedit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; /* free up the editing object */ if (DOBJ) { free_obj (DOBJ); } DOBJ = null; d->edit_number = 0; REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); break; default: send_to_char (DCH, "That's not a valid choice!\r\n"); send_to_char (DCH, "Do you wish to edit it? "); break; } break; /* end of IEDIT_CONFIRM_EDIT */ case IEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': { int j, k; /* before saving - if we are not superbuild, then calc cost and weight, and set quality to non zero */ if (!ADVANCED_BUILDER (DCH)) { if (DOBJ->obj_flags.quality == 0) { DOBJ->obj_flags.quality = 5; } GET_OBJ_COST (DOBJ) = calc_obj_cost (DOBJ); GET_OBJ_WEIGHT (DOBJ) = calc_obj_weight (DOBJ); } /* write to internal tables */ /* NOTE USE OF REAL_OBJECT_REGARDLESS! */ obj_number = real_object_regardless (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 */ OBJ_DATA *it; struct extra_descr_data *this, *next_one; int deleted = OBJ_DELETED (obj_number); for (it = object_list; it; it = it->next) { if (it->item_number == obj_number) { it->name = DOBJ->name; it->description = DOBJ->description; it->short_description = DOBJ->short_description; it->action_description = DOBJ->action_description; it->action_word = DOBJ->action_word; it->ex_description = DOBJ->ex_description; } } /* now safe to free old proto and write over */ if (obj_proto[obj_number].action_word) { free (obj_proto[obj_number].action_word); } if (obj_proto[obj_number].name) { free (obj_proto[obj_number].name); } if (obj_proto[obj_number].description) { free (obj_proto[obj_number].description); } if (obj_proto[obj_number].short_description) { free (obj_proto[obj_number].short_description); } if (obj_proto[obj_number].action_description) { free (obj_proto[obj_number].action_description); } if (obj_proto[obj_number].ex_description) for (this = obj_proto[obj_number].ex_description; this; this = next_one) { next_one = this->next; if (this->keyword) { free (this->keyword); } if (this->description) { free (this->description); } free (this); } obj_proto[obj_number] = *DOBJ; if (deleted) { obj_index[obj_number].deleted = false; obj_index[obj_number].virtual = d->edit_number; obj_index[obj_number].number = 0; /* It is also necessary to mark DOBJ's item number, so that when it gets freed it doesn't screw up the obj_proto table with it */ DOBJ->item_number = obj_number; } obj_proto[obj_number].item_number = obj_number; } else { /* uhoh.. need to make a new place in the object prototype table */ int found = false; OBJ_DATA *new_obj_proto; struct index_data *new_obj_index; OBJ_DATA *temp_obj; /* + 2.. strange but true */ CREATE (new_obj_index, struct index_data, top_of_objt + 2); CREATE (new_obj_proto, OBJ_DATA, top_of_objt + 2); /* start counting through both tables */ for (i = 0; i < top_of_objt + 1; i++) { /* if we haven't found it */ if (!found) { /* check if current virtual is bigger than our virtual */ if (obj_index[i].virtual > d->edit_number) { /* eureka. insert now */ /*---------*/ new_obj_index[i].virtual = d->edit_number; new_obj_index[i].number = 0; new_obj_index[i].func = null; /*---------*/ new_obj_proto[i] = *(DOBJ); new_obj_proto[i].in_room = NOWHERE; /* it is now safe (and necessary!) to assign real number to * the edit_obj, which has been -1 all this time */ DOBJ->item_number = i; /* and assign to prototype as well */ new_obj_proto[i].item_number = i; found = true; /* insert the other proto at this point */ new_obj_index[i + 1] = obj_index[i]; new_obj_proto[i + 1] = obj_proto[i]; new_obj_proto[i + 1].item_number = i + 1; } else { /* just copy from old to new, no num change */ new_obj_proto[i] = obj_proto[i]; new_obj_index[i] = obj_index[i]; } } else { /* we HAVE already found it.. therefore copy to object + 1 */ new_obj_index[i + 1] = obj_index[i]; new_obj_proto[i + 1] = obj_proto[i]; new_obj_proto[i + 1].item_number = i + 1; } } /* if we STILL haven't found it, means the object was > than all * the other objects.. so insert at end */ if (!found) { new_obj_index[top_of_objt + 1].virtual = d->edit_number; new_obj_index[top_of_objt + 1].number = 0; new_obj_index[top_of_objt + 1].func = null; clear_object (new_obj_proto + top_of_objt + 1); new_obj_proto[top_of_objt + 1] = *(DOBJ); 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 */ DOBJ->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! */ for (temp_obj = object_list; temp_obj; temp_obj = temp_obj->next) /* we have no way of accessing vnums/rnums.. so we do a increment if after insertion point */ if (GET_OBJ_RNUM (temp_obj) >= DOBJ->item_number) { GET_OBJ_RNUM (temp_obj)++; } /* free and replace old tables */ free (obj_proto); free (obj_index); obj_proto = new_obj_proto; obj_index = new_obj_index; if (!mini_mud) { for (i = 0; i < top_shop; i++) { if (shop_index[i].producing) { for (j = 0; SHOP_PRODUCT (i, j) != NOTHING; j++) if (SHOP_PRODUCT (i, j) >= DOBJ->item_number) { SHOP_PRODUCT (i, j)++; } } } } for (i = 0; i <= top_of_zone_table; i++) for (j = 0; zone_table[i].cmd[j].command != 'S'; j++) switch (zone_table[i].cmd[j].command) { case 'O': case 'Z': case 'G': case 'E': if (zone_table[i].cmd[j].arg1 >= DOBJ->item_number) { zone_table[i].cmd[j].arg1++; } break; case 'P': case 'c': if (zone_table[i].cmd[j].arg1 >= DOBJ->item_number) { zone_table[i].cmd[j].arg1++; } if (zone_table[i].cmd[j].arg3 >= DOBJ->item_number) { zone_table[i].cmd[j].arg3++; } break; case 'R': if (zone_table[i].cmd[j].arg2 >= DOBJ->item_number) { zone_table[i].cmd[j].arg2++; } break; case 'm': if (zone_table[i].cmd[j].arg3 >= DOBJ->item_number) { zone_table[i].cmd[j].arg3++; } } /* this fixes the creeping board problems */ k = real_object (d->edit_number); for (i = 0; i < NUM_OF_BOARDS; i++) { if (BOARD_RNUM (i) >= k) { BOARD_RNUM (i) = BOARD_RNUM (i) + 1; } } } send_to_char (DCH, "Writing object to disk.."); write_zone_objs (d->edit_zone); if (DOBJ) { free_obj (DOBJ); } DOBJ = null; REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); send_to_char (DCH, "Done.\r\n"); sprintf (buf, "%s has exited iedit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; } break; case 'n': case 'N': send_to_char (DCH, "Object not saved, aborting.\r\n"); sprintf (buf, "%s has exited iedit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; /* free up the editing object. free_obj *is* safe since it checks against prototype table */ if (DOBJ) { free_obj (DOBJ); } DOBJ = null; d->edit_number = 0; REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); break; default: send_to_char (DCH, "Invalid choice!\r\n"); send_to_char (DCH, "Do you wish to save this object?\r\n"); 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': send_to_char (DCH, "Do you wish to save this object?\r\n"); d->edit_mode = IEDIT_CONFIRM_SAVESTRING; break; case '1': send_to_char (DCH, "Enter namelist:"); d->edit_mode = IEDIT_EDIT_NAMELIST; break; case '2': send_to_char (DCH, "Enter short desc:"); d->edit_mode = IEDIT_SHORTDESC; break; case '3': send_to_char (DCH, "Enter long desc:\r\n"); d->edit_mode = IEDIT_LONGDESC; break; case '4': /* if extra desc doesn't exist . */ if (!DOBJ->ex_description) { CREATE (DOBJ->ex_description, struct extra_descr_data, 1); DOBJ->ex_description->next = null; } /* There is a reason I need the double pointer. If at the extra desc menu user presses '0' then I need to free the extra description. Since it's at the end of list it's pointer must be pointing to * null.. thus the double pointer */ d->misc_data = (void **) &(DOBJ->ex_description); iedit_disp_extradesc_menu (d); break; case '5': send_to_char (DCH, "NOTE: object level is only relevant for things that are held or worn.\r\nEnter object level:"); d->edit_mode = IEDIT_LEVEL; break; case '7': iedit_disp_type_menu (d); d->edit_mode = IEDIT_TYPE; break; case '6': iedit_disp_materials_menu (d); d->edit_mode = IEDIT_MATERIAL; break; case '8': iedit_disp_extra_menu (d); d->edit_mode = IEDIT_EXTRAS; break; case '9': iedit_disp_wear_menu (d); d->edit_mode = IEDIT_WEAR; break; case 'a': case 'A': iedit_disp_prompt_apply_menu (d); break; case 'b': case 'B': if (ADVANCED_BUILDER (DCH)) { send_to_char (DCH, "Enter cost (recommended %ld):", calc_obj_cost (DOBJ)); d->edit_mode = IEDIT_COST; } else if (NEEDS_ACTION_DESC (DOBJ)) { send_to_char (DCH, "Enter action desc:\r\n"); d->edit_mode = IEDIT_ACTDESC; } else { goto fail; } break; case 'c': case 'C': if (ADVANCED_BUILDER (DCH)) { send_to_char (DCH, "Enter weight (recommended %d):", calc_obj_weight (DOBJ)); d->edit_mode = IEDIT_WEIGHT; } else if (NEEDS_ACTION_WORD (DOBJ)) { send_to_char (DCH, "Enter action word:"); d->edit_mode = IEDIT_ACTION_WORD; } else { goto fail; } break; case 'd': case 'D': if (ADVANCED_BUILDER (DCH)) { send_to_char (DCH, "Enter timer:"); d->edit_mode = IEDIT_TIMER; } else { goto fail; } break; case 'e': case 'E': if (ADVANCED_BUILDER (DCH) && NEEDS_ACTION_DESC (DOBJ)) { send_to_char (DCH, "Enter action desc:\r\n"); d->edit_mode = IEDIT_ACTDESC; } else { goto fail; } break; case 'f': case 'F': if (ADVANCED_BUILDER (DCH) && NEEDS_ACTION_WORD (DOBJ)) { send_to_char (DCH, "Enter action word:"); d->edit_mode = IEDIT_ACTION_WORD; } else { goto fail; } break; default: fail: iedit_disp_menu (d); break; } break; /* end of IEDIT_MAIN_MENU */ case IEDIT_LEVEL: i = atoi (arg); if (i < 1 || i > 60) { send_to_char (DCH, "Invalid level!\r\nEnter object level:"); return; } GET_OBJ_LEVEL (DOBJ) = i; switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_QUARREL: case ITEM_ARROW: calc_arrow (DOBJ); break; case ITEM_WEAPON: calc_weapon (DOBJ); break; case ITEM_ARMOR: calc_armor (DOBJ); break; } iedit_disp_menu (d); break; case IEDIT_EDIT_NAMELIST: if (!*arg) { send_to_char (DCH, "Invalid namelist!\r\nEnter namelist:"); return; } if (DOBJ->name) { free (DOBJ->name); } DOBJ->name = strdup (arg); iedit_disp_menu (d); break; case IEDIT_SHORTDESC: if (!*arg) { send_to_char (DCH, "Invalid short desc!\r\nEnter short desc:"); return; } if (DOBJ->short_description) { free (DOBJ->short_description); } DOBJ->short_description = strdup (arg); iedit_disp_menu (d); break; case IEDIT_LONGDESC: if (!*arg) { send_to_char (DCH, "Invalid long desc!\r\nEnter long desc:"); return; } if (DOBJ->description) { free (DOBJ->description); } DOBJ->description = strdup (arg); iedit_disp_menu (d); break; case IEDIT_ACTDESC: if (!*arg) { if (DOBJ->action_description) { free (DOBJ->action_description); } DOBJ->action_description = null; iedit_disp_menu (d); break; } if (DOBJ->action_description) { free (DOBJ->action_description); } delete_doubledollar (arg); delete_doublebackquote (arg); DOBJ->action_description = strdup (arg); iedit_disp_menu (d); break; case IEDIT_MATERIAL: i = atoi (arg); if ((i < 0) || (i >= NUM_OBJ_MATERIALS)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_materials_menu (d); } else { GET_OBJ_MATERIAL (DOBJ) = i; /* Modify armor stat by material */ if (!ADVANCED_BUILDER (DCH) && GET_OBJ_TYPE (DOBJ) == ITEM_ARMOR) { calc_armor (DOBJ); } iedit_disp_menu (d); } break; case IEDIT_TYPE: i = atoi (arg); if (ADVANCED_BUILDER (DCH)) { if ((i < 1) || (i >= NUM_OBJ_ITEM_TYPES)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_type_menu (d); return; } } else { if ((i < 1) || (i > 27)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_type_menu (d); return; } i = iedit_type_mapping[i - 1]; } GET_OBJ_TYPE (DOBJ) = i; /* When I select a object type, edit the object values based on level of object. */ /* First clear all obj vals */ GET_OBJ_VAL (DOBJ, 0) = 0; GET_OBJ_VAL (DOBJ, 1) = 0; GET_OBJ_VAL (DOBJ, 2) = 0; GET_OBJ_VAL (DOBJ, 3) = 0; GET_OBJ_VAL (DOBJ, 4) = 0; switch (i) { case ITEM_QUARREL: case ITEM_ARROW: calc_arrow (DOBJ); break; case ITEM_WEAPON: calc_weapon (DOBJ); break; case ITEM_ARMOR: calc_armor (DOBJ); break; } iedit_disp_val1_menu (d); break; case IEDIT_EXTRAS: i = atoi (arg); if (i < 0 || i > 16) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_extra_menu (d); } else { /* if 0, quit */ if (i == 0) { iedit_disp_menu (d); return; } i = iedit_extra_mapping[i - 1]; /* if already set.. remove */ TOGGLE_BIT (GET_OBJ_EXTRA (DOBJ), 1 << i); iedit_disp_extra_menu (d); } break; case IEDIT_WEAR: i = atoi (arg); if ((i < 0) || (i > NUM_OBJ_WEAR_FLAGS)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_wear_menu (d); } else { /* if 0, quit */ if (i == 0) { iedit_disp_menu (d); } /* if already set.. remove */ else { TOGGLE_BIT (GET_OBJ_WEAR (DOBJ), 1 << (i - 1)); iedit_disp_wear_menu (d); } } break; case IEDIT_WEIGHT: i = atoi (arg); GET_OBJ_WEIGHT (DOBJ) = i; iedit_disp_menu (d); break; case IEDIT_COST: i = atoi (arg); GET_OBJ_COST (DOBJ) = i; iedit_disp_menu (d); break; case IEDIT_TIMER: i = atoi (arg); GET_OBJ_TIMER (DOBJ) = i; iedit_disp_menu (d); break; case IEDIT_VALUE_1: i = atoi (arg); if (GET_OBJ_TYPE (DOBJ) == ITEM_RADIO) { /* Y/y if we want the radio to trigger on entry */ GET_OBJ_VAL (DOBJ, 0) = (UPPER (*arg) == 'Y'); /* if so, then value_2 is unused; skip to value 3 */ if (GET_OBJ_VAL (DOBJ, 0)) { iedit_disp_val3_menu (d); return; } /* Otherwise, blithely continue */ iedit_disp_val2_menu (d); return; } if (GET_OBJ_TYPE (DOBJ) == ITEM_SPELLPAGE) if (i < 0 || i >= NUM_SPELLS) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val2_menu (d); return; } if (GET_OBJ_TYPE (DOBJ) == ITEM_LEVER || GET_OBJ_TYPE (DOBJ) == ITEM_PPLATE || GET_OBJ_TYPE (DOBJ) == ITEM_VOCAL) { if (i < 0 || i >= MAX_LEVER_ACTIONS) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_lever_action_menu (d); return; } } if (GET_OBJ_TYPE (DOBJ) == ITEM_ARMOR) { if (!ADVANCED_BUILDER (DCH)) { if (i < 1 || i > 9) { send_to_char (DCH, "Invalid choice!\r\nEnter the quality modifier on this stat (1 to 9):\r\n"); return; } GET_OBJ_QUALITY (DOBJ) = i; calc_armor (DOBJ); } else { GET_OBJ_VAL (DOBJ, 0) = i; GET_OBJ_QUALITY (DOBJ) = 0; } } else if (GET_OBJ_TYPE (DOBJ) == ITEM_WEAPON) { if (i < 1 || i > 12 || i == 10) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_weapon_menu (d); return; } GET_WEAPON_TYPE (DOBJ) = i; calc_weapon (DOBJ); } else { GET_OBJ_VAL (DOBJ, 0) = i; } /* proceed to menu 2 */ iedit_disp_val2_menu (d); break; case IEDIT_VALUE_2: /* here, I do need to check for outofrange values */ i = atoi (arg); switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_QUARREL: case ITEM_ARROW: case ITEM_WEAPON: if (!ADVANCED_BUILDER (DCH)) { if (i < 1 || i > 9) { send_to_char (DCH, "Invalid choice!\r\nEnter the quality modifier on this stat (1 to 9):\r\n"); return; } else { GET_OBJ_QUALITY (DOBJ) = i; if (GET_OBJ_TYPE (DOBJ) == ITEM_WEAPON) { calc_weapon (DOBJ); } else { calc_arrow (DOBJ); } /* done with weapon */ iedit_disp_menu (d); } } else { GET_OBJ_QUALITY (DOBJ) = 0; GET_OBJ_VAL (DOBJ, 1) = i; iedit_disp_val3_menu (d); } break; case ITEM_SCROLL: if (i != 0 && !is_target_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val2_menu (d); return; } else { GET_OBJ_VAL (DOBJ, 1) = i; iedit_disp_val3_menu (d); } break; case ITEM_POTION: case ITEM_PILL: if (i != 0 && !is_potion_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val2_menu (d); return; } else { GET_OBJ_VAL (DOBJ, 1) = i; iedit_disp_val3_menu (d); } break; case ITEM_PORTAL: case ITEM_CONTAINER: /* needs some special handling since we are dealing with flag values * here */ /* if 0, quit */ i = atoi (arg); if (i < 0 || i > 2) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_container_flags_menu (d); return; } else { /* if 0, quit */ if (i != 0) { TOGGLE_BIT (GET_OBJ_VAL (DOBJ, 1), 1 << (i - 1)); iedit_disp_val2_menu (d); } else { iedit_disp_val3_menu (d); } } break; case ITEM_PEOPLECON: /* needs some special handling since we are dealing with flag values * here */ /* if 0, quit */ i = atoi (arg); if (i < 0 || i > NUM_OBJ_PCONT_FLAGS) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_pcont_flags_menu (d); return; } else { /* if 0, quit */ if (i != 0) { TOGGLE_BIT (GET_OBJ_VAL (DOBJ, 1), 1 << (i - 1)); iedit_disp_val2_menu (d); } else { iedit_disp_val3_menu (d); } } break; default: GET_OBJ_VAL (DOBJ, 1) = i; iedit_disp_val3_menu (d); } /* i think that's all that needs checking */ break; case IEDIT_VALUE_3: i = atoi (arg); switch (GET_OBJ_TYPE (DOBJ)) { /* direction */ case ITEM_PPLATE: case ITEM_LEVER: case ITEM_VOCAL: if (GET_OBJ_VAL (DOBJ, 0) == ACTION_OPEN || GET_OBJ_VAL (DOBJ, 0) == ACTION_CLOSE || GET_OBJ_VAL (DOBJ, 0) == ACTION_LOCK || GET_OBJ_VAL (DOBJ, 0) == ACTION_UNLOCK || GET_OBJ_VAL (DOBJ, 0) == ACTION_CURRENT) { int dir; if ((dir = search_block (arg, dirs, false)) < 0) { send_to_char ( DCH, "That isn't a direction.\r\n"); return; } i = dir; } break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: if (i < 0 || i >= NUM_OBJ_DRINKS) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val3_menu (d); return; } break; case ITEM_SCROLL: if (i != 0 && !is_target_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val3_menu (d); return; } break; case ITEM_POTION: case ITEM_PILL: if (i != 0 && !is_potion_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val3_menu (d); return; } break; } GET_OBJ_VAL (DOBJ, 2) = i; iedit_disp_val4_menu (d); break; case IEDIT_VALUE_4: i = atoi (arg); switch (GET_OBJ_TYPE (DOBJ)) { case ITEM_WAND: case ITEM_STAFF: if (!is_target_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val4_menu (d); return; } GET_OBJ_VAL (DOBJ, 3) = i; GET_OBJ_VAL (DOBJ, 0) = MIN (spell_info[i].min_level[CLASS_MAGIC_USER], spell_info[i].min_level[CLASS_CLERIC]); break; case ITEM_SCROLL: if (i != 0 && !is_target_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val4_menu (d); return; } GET_OBJ_VAL (DOBJ, 3) = i; GET_OBJ_VAL (DOBJ, 0) = MAX ( MAX ( MIN (spell_info[GET_OBJ_VAL (DOBJ, 1)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 1)].min_level[CLASS_CLERIC]), MIN (spell_info[GET_OBJ_VAL (DOBJ, 2)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 2)].min_level[CLASS_CLERIC])), MIN (spell_info[GET_OBJ_VAL (DOBJ, 3)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 3)].min_level[CLASS_CLERIC])); break; case ITEM_POTION: case ITEM_PILL: if (i != 0 && !is_potion_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_val4_menu (d); return; } GET_OBJ_VAL (DOBJ, 3) = i; GET_OBJ_VAL (DOBJ, 0) = MAX ( MAX ( MIN (spell_info[GET_OBJ_VAL (DOBJ, 1)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 1)].min_level[CLASS_CLERIC]), MIN (spell_info[GET_OBJ_VAL (DOBJ, 2)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 2)].min_level[CLASS_CLERIC])), MIN (spell_info[GET_OBJ_VAL (DOBJ, 3)].min_level[CLASS_MAGIC_USER], spell_info[GET_OBJ_VAL (DOBJ, 3)].min_level[CLASS_CLERIC])); break; case ITEM_WEAPON: SET_WEAPON_SPEED (DOBJ, i); /* restrict weapon spell mangling to CIMP or greater */ if (GET_LEVEL (DCH) >= LVL_CIMP) { /* weapon speed */ iedit_disp_spells2_menu (d); send_to_char (DCH, "Enter weapon spell (discharged on each successful hit): "); d->edit_mode = IEDIT_WEAPON_SPELL; return; } break; default: GET_OBJ_VAL (DOBJ, 3) = i; break; } iedit_disp_menu (d); break; case IEDIT_WEAPON_SPELL: { extern void medit_race_menu (DESCRIPTOR * d); i = atoi (arg); if (i != 0 && !is_target_spell (i)) { send_to_char (DCH, "Invalid choice!\r\n"); return; } else { SET_WEAPON_SPELL (DOBJ, i); } medit_race_menu (d); send_to_char (DCH, "Enter the race that this weapon has a bonus against: "); d->edit_mode = IEDIT_WEAPON_RACE; break; } case IEDIT_WEAPON_RACE: { i = atoi (arg); if (i < 0 || i >= NUM_MOB_RACES) { send_to_char (DCH, "Invalid choice!\r\n"); send_to_char (DCH, "Enter race:\r\n"); return; } else { SET_WEAPON_RACE (DOBJ, i); } if (i > 0) { send_to_char (DCH, "Enter the multiplier to use against this race (2-5): "); d->edit_mode = IEDIT_WEAPON_MULTIPLIER; } else { iedit_disp_menu (d); } break; } case IEDIT_WEAPON_MULTIPLIER: { i = atoi (arg); if (i < 2 || i > 5) { send_to_char (DCH, "Invalid choice!\r\n"); send_to_char (DCH, "Enter the multiplier to use against this race (2-5): "); return; } else { SET_WEAPON_MULTIPLIER (DOBJ, i); } iedit_disp_menu (d); break; } case IEDIT_LEVER_MOVE_FLAGS: i = atoi (arg); if (i < 0 || i > 3) { send_to_char (DCH, "Invalid choice!\r\n"); send_to_char (DCH, "1) Pullable (action on pull)\n"); send_to_char (DCH, "2) Pushable (action on push)\n"); send_to_char (DCH, "3) Both (action on pull/push or both)\n"); return; } REMOVE_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PULLABLE); REMOVE_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PUSHABLE); REMOVE_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_REVERSE); REMOVE_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_DOUBLE); switch (i) { case 1: SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PULLABLE); iedit_disp_menu (d); return; break; case 2: SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PUSHABLE); iedit_disp_menu (d); return; break; case 3: SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PULLABLE); SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_PUSHABLE); send_to_char (DCH, "Do you want the action on a pull (0) or a push (anything else?\r\n"); d->edit_mode = IEDIT_LEVER_REVERSE_PROMPT; break; } break; case IEDIT_LEVER_REVERSE_PROMPT: i = atoi (arg); if (i != 0) { SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_REVERSE); if (GET_OBJ_VAL (DOBJ, 0) != ACTION_TELEPORT) { if (GET_OBJ_VAL (DOBJ, 0) == ACTION_CLOSE) { send_to_char (DCH, "Do you want the lever to open on a pull (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_OPEN) { send_to_char (DCH, "Do you want the lever to close on a pull (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_LOCK) { send_to_char (DCH, "Do you want the lever to unlock on a pull (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_UNLOCK) { send_to_char (DCH, "Do you want the lever to lock on a pull (0) or do nothing (anything else?)\r\n"); } d->edit_mode = IEDIT_LEVER_DOUBLE_PROMPT; return; } } else if (GET_OBJ_VAL (DOBJ, 0) != ACTION_TELEPORT) { if (GET_OBJ_VAL (DOBJ, 0) == ACTION_CLOSE) { send_to_char (DCH, "Do you want the lever to open on a push (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_OPEN) { send_to_char (DCH, "Do you want the lever to close on a push (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_LOCK) { send_to_char (DCH, "Do you want the lever to unlock on a push (0) or do nothing (anything else?)\r\n"); } if (GET_OBJ_VAL (DOBJ, 0) == ACTION_UNLOCK) { send_to_char (DCH, "Do you want the lever to lock on a push (0) or do nothing (anything else?)\r\n"); } d->edit_mode = IEDIT_LEVER_DOUBLE_PROMPT; return; } break; case IEDIT_LEVER_DOUBLE_PROMPT: i = atoi (arg); if (i == 0) { SET_BIT (GET_OBJ_VAL (DOBJ, 3), LEVER_DOUBLE); } iedit_disp_menu (d); break; case IEDIT_PROMPT_APPLY: i = atoi (arg); if (i == 0) { iedit_disp_menu (d); return; } else if (i < 0 || i >= MAX_OBJ_AFFECT) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_prompt_apply_menu (d); return; } d->edit_number2 = i - 1; d->edit_mode = IEDIT_APPLY; iedit_disp_apply_menu (d); break; case IEDIT_APPLY: i = atoi (arg); if (i == 0) { DOBJ->affected[d->edit_number2].location = 0; DOBJ->affected[d->edit_number2].modifier = 0; iedit_disp_prompt_apply_menu (d); return; } /* APRIL 13 1998 - CHANGED TO 15 FROM 16 TEMPORARILY!! */ if (i < 0 || i > 15) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_apply_menu (d); return; } DOBJ->affected[d->edit_number2].location = iedit_apply_mapping[i]; if (iedit_apply_mapping[i] == APPLY_SPELL) { iedit_disp_spells_menu (d); d->edit_mode = IEDIT_APPLYMOD; } else if (iedit_apply_mapping[i] == APPLY_SKILL) { iedit_disp_skills_menu (d); d->edit_mode = IEDIT_APPLYMOD; } else { send_to_char (DCH, "Modifier:"); d->edit_mode = IEDIT_APPLYMOD; } break; case IEDIT_APPLYAFF: i = atoi (arg); if ((i < 0) || (i > NUM_MOB_AFFECTS)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_disp_affect_menu (d); } else { /* if 0, quit */ if (i == 0) { iedit_disp_prompt_apply_menu (d); } /* if already set.. remove */ else { if (IS_SET (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1))) { REMOVE_BIT (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1)); } else /* set */ { SET_BIT (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1)); } iedit_disp_affect_menu (d); } } break; case IEDIT_APPLYIMM: i = atoi (arg); if ((i < 0) || (i > 29)) { send_to_char (DCH, "That's not a valid choice!\r\n"); iedit_resist_menu (d); return; } if (i == 0) { iedit_disp_prompt_apply_menu (d); return; } if (IS_SET (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1))) { REMOVE_BIT (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1)); } else { SET_BIT (DOBJ->affected[d->edit_number2].modifier, 1 << (i - 1)); } iedit_resist_menu (d); break; case IEDIT_APPLYMOD: i = atoi (arg); if (d->edit_number2 == APPLY_SPELL) { if (!is_personal_spell) { send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_spells_menu (d); return; } } else { } DOBJ->affected[d->edit_number2].modifier = i; iedit_disp_prompt_apply_menu (d); break; case IEDIT_EXTRADESC_KEY: if (!*arg) { send_to_char (DCH, "Invalid keyword list!\r\nEnter keywords, separated by spaces:"); return; } if (((struct extra_descr_data *) *d->misc_data)->keyword) { free (((struct extra_descr_data *) *d->misc_data)->keyword); } ((struct extra_descr_data *) *d->misc_data)->keyword = strdup (arg); iedit_disp_extradesc_menu (d); break; case IEDIT_ACTION_WORD: if (!*arg) { if (DOBJ->action_word) { free (DOBJ->action_word); } DOBJ->action_word = null; iedit_disp_menu (d); break; } if (DOBJ->action_word) { free (DOBJ->action_word); } delete_doublebackquote (arg); delete_doubledollar (arg); DOBJ->action_word = strdup (arg); iedit_disp_menu (d); break; case IEDIT_EXTRADESC_MENU: i = atoi (arg); switch (i) { case 0: { /* if something got left out */ if (!((struct extra_descr_data *) *d->misc_data)->keyword || !((struct extra_descr_data *) *d->misc_data)->description) { if (((struct extra_descr_data *) *d->misc_data)->keyword) { free (((struct extra_descr_data *) *d->misc_data)->keyword); } if (((struct extra_descr_data *) *d->misc_data)->description) { free (((struct extra_descr_data *) *d->misc_data)->description); } free (*d->misc_data); *d->misc_data = null; } /* else, we don't need to do anything.. jump to menu */ iedit_disp_menu (d); } break; case 1: d->edit_mode = IEDIT_EXTRADESC_KEY; send_to_char (DCH, "Enter keywords, separated by spaces:"); break; case 2: d->edit_mode = IEDIT_EXTRADESC_DESCRIPTION; send_to_char (DCH, "Enter description:\r\n"); /* send out to modify.c */ d->str = (char **) malloc (sizeof (char *)); if (((struct extra_descr_data *) *d->misc_data)->description) { *(d->str) = strdup (((struct extra_descr_data *) *d->misc_data)->description); init_text (d); } else { *(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 (DCH, "You can't edit the next extra desc without completing this one.\r\n"); iedit_disp_extradesc_menu (d); } else { struct extra_descr_data *new_extra; if (((struct extra_descr_data *) *d->misc_data)->next) { d->misc_data = (void **) &((struct extra_descr_data *) *d->misc_data)->next; } else { /* make new extra, attach at end */ CREATE (new_extra, struct extra_descr_data, 1); ((struct extra_descr_data *) *d->misc_data)->next = new_extra; /* edit new extra, we NEED double pointer because i will set * *d->misc_data to null later */ d->misc_data = (void **) &((struct extra_descr_data *) *d->misc_data)->next; } iedit_disp_extradesc_menu (d); } break; default: send_to_char (DCH, "Invalid choice!\r\n"); iedit_disp_extradesc_menu (d); break; } break; default: break; } } int is_same_keyword_list(char* s1, char* s2) { char token1[256]; char token2[256]; char* ts2; // if s1 and s2 share ANY keyword, consider these to be the // same keyword list while (*s1) { s1 = one_argument(s1, token1); ts2 = s2; while (*ts2) { ts2 = one_argument(ts2, token2); if (strcmp(token1, token2) == 0) { return 1; } } } return 0; } void write_zone_objs (int zone) { OBJ_DATA *obj; int i, j, k; FILE *fp, *fp2; struct extra_descr_data *ex_desc; /* i want to use "obj" instead of just obj_proto[] because some of * the macros assume it's a pointer instead of just a struct as * obj_proto is, plus it's short to type in :P */ CREATE (obj, OBJ_DATA, 1); sprintf (buf, "%s/%d.obj.bak", OBJ_PREFIX, zone_table[zone].number); fp = fopen (buf, "w+"); sprintf (buf, "%s/%d.obj.ept", OBJ_PREFIX, zone_table[zone].number); fp2 = fopen (buf, "w+"); /* start running through all objects in this zone */ for (i = zone_table[zone].number * 100; i <= zone_table[zone].top; i++) { /* write object to disk */ k = real_object (i); if (k >= 0 && !OBJ_DELETED (k)) { *obj = obj_proto[k]; switch(GET_OBJ_TYPE(obj)) { case ITEM_PORTAL: uvfprintf(fp2, "Type Portal\n"); uvfprintf(fp2, "StartPortal\n"); break; case ITEM_TREASURE: uvfprintf(fp2, "Type Treasure\n"); uvfprintf(fp2, "StartTreasure\n"); break; case ITEM_WORN: case ITEM_ARMOR: uvfprintf(fp2, "Type Armor\n"); uvfprintf(fp2, "StartArmor\n"); break; case ITEM_KEY: uvfprintf(fp2, "Type Key\n"); uvfprintf(fp2, "StartKey\n"); break; case ITEM_FOOD: uvfprintf(fp2, "Type Food\n"); uvfprintf(fp2, "StartFood\n"); break; case ITEM_FOUNTAIN: uvfprintf(fp2, "Type Fountain\n"); uvfprintf(fp2, "StartFountain\n"); uvfprintf(fp2, "StartDrink\n"); break; case ITEM_DRINKCON: uvfprintf(fp2, "Type Drink\n"); uvfprintf(fp2, "StartDrink\n"); break; case ITEM_WEAPON: uvfprintf(fp2, "Type Weapon\n"); uvfprintf(fp2, "StartWeapon\n"); break; case ITEM_PILL: uvfprintf(fp2, "Type Pill\n"); uvfprintf(fp2, "StartPill\n"); break; case ITEM_SCROLL: uvfprintf(fp2, "Type Scroll\n"); uvfprintf(fp2, "StartScroll\n"); break; case ITEM_POTION: uvfprintf(fp2, "Type Potion\n"); uvfprintf(fp2, "StartPotion\n"); break; case ITEM_LIGHT: uvfprintf(fp2, "Type Light\n"); uvfprintf(fp2, "StartLight\n"); break; case ITEM_CROSSBOW: case ITEM_BOW: uvfprintf(fp2, "Type Bow\n"); uvfprintf(fp2, "StartBow\n"); break; case ITEM_QUARREL: case ITEM_ARROW: uvfprintf(fp2, "Type Arrow\n"); uvfprintf(fp2, "StartArrow\n"); break; case ITEM_RADIO: uvfprintf(fp2, "Type Radio\n"); uvfprintf(fp2, "StartRadio\n"); break; case ITEM_CONTAINER: uvfprintf(fp2, "Type Container\n"); uvfprintf(fp2, "StartContainer\n"); break; case ITEM_VOCAL: uvfprintf(fp2, "Type VocalTrigger\n"); uvfprintf(fp2, "StartVocalTrigger\n"); uvfprintf(fp2, "StartEffector\n"); break; case ITEM_LEVER: uvfprintf(fp2, "Type Lever\n"); uvfprintf(fp2, "StartLever\n"); uvfprintf(fp2, "StartEffector\n"); break; case 0: case ITEM_NOTE: case ITEM_OTHER: case ITEM_TRASH: // if takeable, it's misc; // otherwise it's furniture if (!IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_TAKE)) { uvfprintf(fp2, "Type Furniture\n"); uvfprintf(fp2, "StartFurniture\n"); } else { uvfprintf(fp2, "Type Misc\n"); uvfprintf(fp2, "StartMisc\n"); } break; case ITEM_STAFF: case ITEM_WAND: uvfprintf(fp2, "Type Wand\n"); uvfprintf(fp2, "StartWand\n"); break; case ITEM_SUMMON: uvfprintf(fp2, "Type Summoner\n"); uvfprintf(fp2, "StartSummoner\n"); break; default: goto next; break; } /* Common to all items.*/ uvfprintf(fp2, "StartItem\n"); uvfprintf(fp2, "StartEntity\n"); uvfprintf(fp2, "Name %s\n", obj->short_description); /* ugh! */ if (obj->ex_description) { for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description && is_same_keyword_list(ex_desc->keyword, obj->name)) { uvfprintf(fp2, "Description\n%s~\n", ex_desc->description); break; } } } uvfprintf(fp2, "EndEntity\n"); uvfprintf(fp2, "ID %d\n", i); if (obj->description) fprintf(fp2, "ShortDescription %s\n", obj->description); uvfprintf(fp2, "Weight %d\n", GET_OBJ_WEIGHT(obj)); uvfprintf(fp2, "MaxLoad %d\n", MAX(obj_index[GET_OBJ_RNUM(obj)].max_number, obj_index[GET_OBJ_RNUM(obj)].number)); { // map 60 levels to 15 int level = MIN(15, MAX(1, (GET_OBJ_LEVEL(obj) + 1) / 4)); uvfprintf(fp2, "Level %d\n", level); } uvfprintf(fp2, "Cost %d\n", GET_OBJ_COST(obj)); uvfprintf(fp2, "Wearable "); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_HEAD) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_FACE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_NECK) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_BODY) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_ARMS) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_WRIST) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_HANDS) ? 1 : 0); uvfprintf(fp2, "%d", (IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_HOLD) || IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_SHIELD) || IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_WIELD)) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_FINGER) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_WAIST) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_LEGS) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_FEET) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_ABOUT) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_IOUN) ? 1 : 0); uvfprintf(fp2, "\n"); uvfprintf(fp2, "Attributes "); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_GLOW) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_HUM) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_CRACKLE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_PULSATE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_NORENT) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_NODONATE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_NOINVIS) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_NOSELL) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_INVISIBLE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_MAGIC) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_NODROP) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_BLESS) ? 1 : 0); #ifdef WHATWASITHINKING uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_ANTI_GOOD) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_ANTI_EVIL) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_ANTI_NEUTRAL) ? 1 : 0); #endif uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_INDESTRUCTABLE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_HIDDEN) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_EXTRA(obj), ITEM_TEMPORARY) ? 1 : 0); uvfprintf(fp2, "0"); // two handed uvfprintf(fp2, "\n"); uvfprintf(fp2, "Aliases %s\n", obj->name); for (j = 0; j < MAX_OBJ_AFFECT; j++) { if (obj->affected[j].modifier) { switch(obj->affected[j].location) { case APPLY_STR: uvfprintf(fp2, "Apply statistic\n13 %d\n", obj->affected[j].modifier); break; case APPLY_DEX: uvfprintf(fp2, "Apply statistic\n15 %d\n", obj->affected[j].modifier); break; case APPLY_MAG: break; case APPLY_INT: uvfprintf(fp2, "Apply statistic\n16 %d\n", obj->affected[j].modifier); break; case APPLY_CON: uvfprintf(fp2, "Apply statistic\n14 %d\n", obj->affected[j].modifier); break; case APPLY_MANA: uvfprintf(fp2, "Apply statistic\n3 %d\n", obj->affected[j].modifier); break; case APPLY_HIT: uvfprintf(fp2, "Apply statistic\n1 %d\n", obj->affected[j].modifier * 10); break; case APPLY_MOVE: uvfprintf(fp2, "Apply statistic\n5 %d\n", obj->affected[j].modifier); break; case APPLY_PSP: uvfprintf(fp2, "Apply statistic\n7 %d\n", obj->affected[j].modifier); break; case APPLY_AC: uvfprintf(fp2, "Apply statistic\n8 %d\n", obj->affected[j].modifier); break; case APPLY_HITROLL: uvfprintf(fp2, "Apply statistic\n10 %d\n", (obj->affected[j].modifier + 1) / 2); break; case APPLY_DAMROLL: uvfprintf(fp2, "Apply statistic\n11 %d\n", 5 * obj->affected[j].modifier); break; case APPLY_EVADE: uvfprintf(fp2, "Apply statistic\n9 %d\n", obj->affected[j].modifier); break; case APPLY_SPELL: uvfprintf(fp2, "Apply spell\n%s\n", spells[obj->affected[j].modifier]); break; } } } uvfprintf(fp2, "Material %s\n", material_types[GET_OBJ_MATERIAL(obj)]); if (obj->ex_description) { int count = 0; for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description && !is_same_keyword_list(ex_desc->keyword, obj->name)) { count++; } } if (count) { uvfprintf(fp2, "ExtraDescriptions %d\n", count); for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description && !is_same_keyword_list(ex_desc->keyword, obj->name)) { uvfprintf(fp2, "StartExtraDescription\n"); uvfprintf(fp2, "Aliases %s\n", ex_desc->keyword); uvfprintf(fp2, "Description\n%s~\n", ex_desc->description); uvfprintf(fp2, "EndExtraDescription\n"); } } } } uvfprintf(fp2, "EndItem\n"); switch(GET_OBJ_TYPE(obj)) { case ITEM_VOCAL: if (obj->action_description) { uvfprintf(fp2, "ActionDescription %s\n", obj->action_description); } uvfprintf(fp2, "Action %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "Values %d %d\n", GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndEffector\n"); if (obj->action_word) { uvfprintf(fp2, "Trigger %s\n", obj->action_word); } uvfprintf(fp2, "EndVocalTrigger\n"); break; case ITEM_LEVER: if (obj->action_description) { uvfprintf(fp2, "ActionDescription %s\n", obj->action_description); } uvfprintf(fp2, "Action %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "Values %d %d\n", GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndEffector\n"); if (IS_SET(GET_OBJ_VAL(obj, 3), LEVER_PULLABLE) && !IS_SET(GET_OBJ_VAL(obj, 3), LEVER_REVERSE)) { uvfprintf(fp2, "Primary pull\n"); if (IS_SET(GET_OBJ_VAL(obj, 3), LEVER_PUSHABLE)) { uvfprintf(fp2, "ReverseableState 1\n"); if (IS_SET(GET_OBJ_VAL(obj, 3), LEVER_DOUBLE)) { uvfprintf(fp2, "ReverseableAction 1\n"); } else { uvfprintf(fp2, "ReverseableAction 0\n"); } uvfprintf(fp2, "State push\n"); } else { uvfprintf(fp2, "ReverseableState 0\n"); uvfprintf(fp2, "ReverseableAction 0\n"); } } else { uvfprintf(fp2, "Primary push\n"); if (IS_SET(GET_OBJ_VAL(obj, 3), LEVER_PULLABLE)) { uvfprintf(fp2, "ReverseableState 1\n"); if (IS_SET(GET_OBJ_VAL(obj, 3), LEVER_DOUBLE)) { uvfprintf(fp2, "ReverseableAction 1\n"); } else { uvfprintf(fp2, "ReverseableAction 0\n"); } } else { uvfprintf(fp2, "ReverseableState 0\n"); uvfprintf(fp2, "ReverseableAction 0\n"); } uvfprintf(fp2, "State pull\n"); } uvfprintf(fp2, "EndLever\n"); break; case ITEM_PORTAL: uvfprintf(fp2, "RoomID %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "EndPortal\n"); break; case ITEM_TREASURE: uvfprintf(fp2, "TreasureCost %d\n", GET_OBJ_COST(obj)); uvfprintf(fp2, "EndTreasure\n"); break; case ITEM_WORN: uvfprintf(fp2, "Quality 0\n"); uvfprintf(fp2, "EndArmor\n"); break; case ITEM_QUARREL: uvfprintf(fp2, "Quarrel 1\n"); case ITEM_ARROW: uvfprintf(fp2, "Quality %d\n", GET_OBJ_QUALITY (obj)); uvfprintf(fp2, "EndArrow\n"); break; case ITEM_RADIO: if (obj->action_description) uvfprintf(fp2, "Sound %s\n", obj->action_description); uvfprintf(fp2, "OnEntry %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "Chance %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "Volume %d\n", GET_OBJ_VAL(obj, 3)); uvfprintf(fp2, "Ticks %d\n", GET_OBJ_VAL(obj, 1)); uvfprintf(fp2, "EndRadio\n"); break; case ITEM_CROSSBOW: uvfprintf(fp2, "Crossbow 1\n"); case ITEM_BOW: uvfprintf(fp2, "Quality %d\n", GET_OBJ_QUALITY (obj)); uvfprintf(fp2, "EndBow\n"); break; case ITEM_ARMOR: if (GET_OBJ_QUALITY(obj) == 0) { uvfprintf(fp2, "Quality 5\n"); } else { uvfprintf(fp2, "Quality %d\n", GET_OBJ_QUALITY (obj)); } uvfprintf(fp2, "EndArmor\n"); break; case ITEM_KEY: uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "EndKey\n"); break; case ITEM_FOOD: if (obj->action_description) uvfprintf(fp2, "TasteDescription %s\n", obj->action_description); uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "EndFood\n"); break; case ITEM_DRINKCON: if (obj->action_description) uvfprintf(fp2, "TasteDescription %s\n", obj->action_description); uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "MaxCharges %d\n", GET_OBJ_VAL(obj, 1)); uvfprintf(fp2, "Type %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndDrink\n"); break; case ITEM_FOUNTAIN: if (obj->action_description) uvfprintf(fp2, "TasteDescription %s\n", obj->action_description); uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "MaxCharges %d\n", GET_OBJ_VAL(obj, 1)); uvfprintf(fp2, "Type %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndDrink\n"); uvfprintf(fp2, "EndFountain\n"); break; case ITEM_WEAPON: uvfprintf(fp2, "Quality %d\n", GET_OBJ_QUALITY(obj) ? GET_OBJ_QUALITY(obj) : 3); switch(GET_OBJ_VAL(obj, 3)) { case 1: uvfprintf(fp2, "Type 0\n"); break; case 2: uvfprintf(fp2, "Type 1\n"); break; case 3: default: uvfprintf(fp2, "Type 2\n"); break; case 4: uvfprintf(fp2, "Type 3\n"); break; case 5: uvfprintf(fp2, "Type 4\n"); break; case 6: uvfprintf(fp2, "Type 5\n"); break; case 7: uvfprintf(fp2, "Type 6\n"); break; case 9: uvfprintf(fp2, "Type 7\n"); break; case 11: uvfprintf(fp2, "Type 8\n"); break; case 12: uvfprintf(fp2, "Type 9\n"); break; } uvfprintf(fp2, "EndWeapon\n"); break; case ITEM_PILL: if (GET_OBJ_VAL (obj, 1) && GET_OBJ_VAL(obj, 1) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 1)]); } if (GET_OBJ_VAL (obj, 2) && GET_OBJ_VAL(obj, 2) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 2)]); } if (GET_OBJ_VAL (obj, 3) && GET_OBJ_VAL(obj, 3) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 3)]); } uvfprintf(fp2, "EndPill\n"); break; case ITEM_SCROLL: if (GET_OBJ_VAL (obj, 1) && GET_OBJ_VAL(obj, 1) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 1)]); } if (GET_OBJ_VAL (obj, 2) && GET_OBJ_VAL(obj, 2) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 2)]); } if (GET_OBJ_VAL (obj, 3) && GET_OBJ_VAL(obj, 3) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 3)]); } uvfprintf(fp2, "EndScroll\n"); break; case ITEM_POTION: if (GET_OBJ_VAL (obj, 1) && GET_OBJ_VAL(obj, 1) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 1)]); } if (GET_OBJ_VAL (obj, 2) && GET_OBJ_VAL(obj, 2) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 2)]); } if (GET_OBJ_VAL (obj, 3) && GET_OBJ_VAL(obj, 3) > 0) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 3)]); } uvfprintf(fp2, "EndPotion\n"); break; case ITEM_CONTAINER: uvfprintf(fp2, "ContainerAttributes "); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_VAL(obj, 1), CONT_CLOSEABLE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(GET_OBJ_VAL(obj, 1), CONT_PICKPROOF) ? 1 : 0); uvfprintf(fp2, "\n"); uvfprintf(fp2, "Key %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "Capacity %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "EndContainer\n"); break; case ITEM_LIGHT: uvfprintf(fp2, "Duration %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "MaxDuration %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndLight\n"); break; case 0: case ITEM_OTHER: case ITEM_TRASH: case ITEM_NOTE: if (!IS_SET(GET_OBJ_WEAR(obj), ITEM_WEAR_TAKE)) { uvfprintf(fp2, "EndFurniture\n"); } else { uvfprintf(fp2, "EndMisc\n"); } break; case ITEM_STAFF: case ITEM_WAND: uvfprintf(fp2, "MaxCharges %d\n", GET_OBJ_VAL(obj, 1)); uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 2)); if (GET_OBJ_VAL (obj, 3)) { uvfprintf(fp2, "Spell %s\n", spells[GET_OBJ_VAL (obj, 3)]); } uvfprintf(fp2, "EndWand\n"); break; case ITEM_SUMMON: if (obj->action_description) uvfprintf(fp2, "ActionDescription %s\n", obj->action_description); uvfprintf(fp2, "Charges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "MaxCharges %d\n", GET_OBJ_VAL(obj, 0)); uvfprintf(fp2, "MobID %d\n", GET_OBJ_VAL(obj, 1)); uvfprintf(fp2, "Attack %d\n", GET_OBJ_VAL(obj, 2)); uvfprintf(fp2, "EndSummoner\n"); break; default: break; } next: fprintf (fp, "#%d\n", GET_OBJ_VNUM (obj)); /* paranoid checks */ if (obj->name) { fprintf (fp, "%s~\n", obj->name); } else { fprintf (fp, "~\n"); } if (obj->short_description) { fprintf (fp, "%s~\n", obj->short_description); } else { fprintf (fp, "~\n"); } if (obj->description) { uvfprintf (fp, "%s~\n", obj->description); } else { fprintf (fp, "~\n"); } if (obj->action_description) { uvfprintf (fp, "%s~\n", obj->action_description); } else { fprintf (fp, "~\n"); } /* new item level goes at end */ fprintf (fp, "%d %d %d %d\n", GET_OBJ_TYPE (obj), GET_OBJ_EXTRA (obj), GET_OBJ_WEAR (obj), GET_OBJ_LEVEL (obj)); fprintf (fp, "%ld %ld %ld %ld %d\n", GET_OBJ_VAL (obj, 0), GET_OBJ_VAL (obj, 1), GET_OBJ_VAL (obj, 2), GET_OBJ_VAL (obj, 3), GET_OBJ_MATERIAL (obj)); fprintf (fp, "V5 %ld\n", GET_OBJ_VAL (obj, 4)); fprintf (fp, "%d %d %d\n", GET_OBJ_WEIGHT (obj), GET_OBJ_COST (obj), GET_OBJ_COST (obj) / 10); /* action word */ if (obj->action_word) { fprintf (fp, "K\n"); fprintf (fp, "%s~\n", obj->action_word); } if (obj->obj_flags.quality != 0) { fprintf (fp, "Q\n%d\n", obj->obj_flags.quality); } /* do we have extra descriptions? */ if (obj->ex_description) { for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description) { fprintf (fp, "E\n"); fprintf (fp, "%s~\n", ex_desc->keyword); uvfprintf (fp, "%s~\n", ex_desc->description); } } } /* do we have affects? */ for (j = 0; j < MAX_OBJ_AFFECT; j++) { if (obj->affected[j].modifier && /* skip 25/26 */ obj->affected[j].location != APPLY_AFFECT && obj->affected[j].location != APPLY_IMMUNE) { fprintf (fp, "A\n"); fprintf (fp, "%d %ld\n", obj->affected[j].location, obj->affected[j].modifier); } } } } /* write final line, close */ fprintf (fp, "$~\n"); fclose (fp); fclose(fp2); /* nuke temp object */ free (obj); }