/** * Destroy all {squelch}able items. * * Imported, with thanks, from Ey... much cleaner than the original. */ void squelch_items(void) { int floor_list[MAX_FLOOR_STACK]; int floor_num, n; int count = 0; object_type *o_ptr; /* Set the hook and scan the floor */ item_tester_hook = squelch_item_ok; floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), p_ptr->py, p_ptr->px, 0x01); if (floor_num) { for (n = 0; n < floor_num; n++) { o_ptr = &o_list[floor_list[n]]; /* Avoid artifacts */ if (artifact_p(o_ptr)) continue; if (item_tester_okay(o_ptr)) { /* Destroy item */ floor_item_increase(floor_list[n], -o_ptr->number); floor_item_optimize(floor_list[n]); count++; } } } /* Scan through the slots backwards */ for (n = INVEN_PACK - 1; n >= 0; n--) { o_ptr = &p_ptr->inventory[n]; /* Skip non-objects and artifacts */ if (!o_ptr->k_idx) continue; if (artifact_p(o_ptr)) continue; if (item_tester_okay(o_ptr)) { /* Destroy item */ inven_item_increase(n, -o_ptr->number); inven_item_optimize(n); count++; } } item_tester_hook = NULL; /* Mention casualties */ if (count > 0) { msgt(MSG_GENERIC, "%d item%s squelched.", count, ((count > 1) ? "s" : "")); /* Combine/reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER); } }
/** * Cheat -- describe a created object for the user */ static void object_mention(object_type * o_ptr) { char o_name[120]; /* Describe */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE | ODESC_SPOIL); /* Artifact */ if (artifact_p(o_ptr)) { /* Silly message */ msg("Artifact (%s)", o_name); } /* Ego-item */ else if (ego_item_p(o_ptr)) { /* Silly message */ msg("Ego-item (%s)", o_name); } /* Normal item */ else { /* Silly message */ msg("Object (%s)", o_name); } }
/* Returns percent chance of an object breaking after throwing or shooting. */ int breakage_chance(const object_type *o_ptr) { /* Artifacts never break */ if (artifact_p(o_ptr)) return 0; switch (o_ptr->tval) { case TV_FLASK: case TV_POTION: case TV_BOTTLE: case TV_FOOD: case TV_JUNK: return 100; case TV_LIGHT: case TV_SCROLL: case TV_SKELETON: return 50; case TV_ARROW: return 35; case TV_WAND: case TV_SHOT: case TV_BOLT: case TV_SPIKE: return 25; default: return 10; } }
/* * The "Squelch on walk-on" function. */ void do_squelch_pile(int y, int x) { s16b o_idx, next_o_idx; object_type *o_ptr; bool sq_flag = FALSE; for (o_idx = cave_o_idx[y][x]; o_idx; o_idx = next_o_idx) { o_ptr = &(o_list[o_idx]); next_o_idx = o_ptr->next_o_idx; /* Always squelch "¬hing" */ if (!o_ptr->k_idx) sq_flag = TRUE; /* Hack - never squelch artifacts */ else if (artifact_p(o_ptr)) sq_flag = FALSE; /* Squelch it? */ else sq_flag = (k_info[o_ptr->k_idx].squelch & k_info[o_ptr->k_idx].aware); /* Unwanted and unloved */ if (sq_flag) { /* Actual Squelch */ if (strong_squelch) delete_object_idx(o_idx); /* Or inscription */ else o_ptr->note = quark_add("SQUELCH"); } } }
/** * Determines if an object is eligable for squelching. */ extern bool squelch_item_ok(const object_type * o_ptr) { size_t i; int num = -1; object_kind *k_ptr = &k_info[o_ptr->k_idx]; bool fullid = object_known_p(o_ptr); bool sensed = (o_ptr->ident & IDENT_SENSE) || fullid; byte feel = fullid ? value_check_aux1((object_type *) o_ptr) : o_ptr->feel; int quality_squelch = SQUELCH_NONE; /* Don't squelch artifacts */ if (artifact_p(o_ptr)) return FALSE; /* Don't squelch stuff inscribed not to be destroyed (!k) */ if (check_for_inscrip(o_ptr, "!k") || check_for_inscrip(o_ptr, "!*")) { return FALSE; } /* Auto-squelch dead chests */ if (o_ptr->tval == TV_CHEST && o_ptr->pval == 0) return TRUE; /* Do squelching by sval, if we 'know' the flavour. */ if (k_ptr->squelch && (k_ptr->flavor == 0 || k_ptr->aware)) { if (squelch_tval(k_info[o_ptr->k_idx].tval)) return TRUE; } /* Squelch some ego items if known */ if (has_ego_properties(o_ptr) && (e_info[o_ptr->name2].squelch)) { return TRUE; } /* Don't check pseudo-ID for nonsensed things */ if (!sensed) return FALSE; /* Find the appropriate squelch group */ for (i = 0; i < N_ELEMENTS(quality_choices); i++) { if (quality_choices[i].tval == o_ptr->tval) { num = i; break; } } /* Never squelched */ if (num == -1) return FALSE; /* Get result based on the feeling and the squelch_profile */ quality_squelch = feel_to_squelch_level(feel); if (quality_squelch == SQUELCH_NONE) return FALSE; else return squelch_profile[num][quality_squelch]; }
/* * Cheat -- describe a created object for the user */ static void object_mention(object_type *o_ptr) { char o_name[80]; /* Describe */ object_desc_store(o_name, o_ptr, FALSE, 0); /* Artifact */ if (artifact_p(o_ptr)) { /* Silly message */ msg_format("Artifact (%s)", o_name); } /* Random Artifact */ else if (o_ptr->art_name) { msg_print("Random artifact"); } /* Ego-item */ else if (ego_item_p(o_ptr)) { /* Silly message */ msg_format("Ego-item (%s)", o_name); } /* Normal item */ else { /* Silly message */ msg_format("Object (%s)", o_name); } }
/* * Sense artifacts */ void object_sense_artifact(object_type *o_ptr) { if (artifact_p(o_ptr)) object_notice_sensing(o_ptr); else o_ptr->ident |= IDENT_NOTART; }
/* * Tweak an item */ static void wiz_tweak_item(object_type *o_ptr) { cptr p; char tmp_val[80]; /* Hack -- leave artifacts alone */ if (artifact_p(o_ptr)) return; p = "Enter new 'pval' setting: "; sprintf(tmp_val, "%d", o_ptr->pval); if (!get_string(p, tmp_val, 6)) return; o_ptr->pval = atoi(tmp_val); wiz_display_item(o_ptr); p = "Enter new 'to_a' setting: "; sprintf(tmp_val, "%d", o_ptr->to_a); if (!get_string(p, tmp_val, 6)) return; o_ptr->to_a = atoi(tmp_val); wiz_display_item(o_ptr); p = "Enter new 'to_h' setting: "; sprintf(tmp_val, "%d", o_ptr->to_h); if (!get_string(p, tmp_val, 6)) return; o_ptr->to_h = atoi(tmp_val); wiz_display_item(o_ptr); p = "Enter new 'to_d' setting: "; sprintf(tmp_val, "%d", o_ptr->to_d); if (!get_string(p, tmp_val, 6)) return; o_ptr->to_d = atoi(tmp_val); wiz_display_item(o_ptr); }
static size_t obj_desc_light(const object_type * o_ptr, char *buf, size_t max, size_t end) { /* Fuelled light sources get number of remaining turns appended */ if ((o_ptr->tval == TV_LIGHT) && !artifact_p(o_ptr)) strnfcat(buf, max, &end, " (%d turns)", o_ptr->pval); return end; }
/* * Inquire whether the player wishes to squelch items similar to an object * * Returns whether the item is now squelched. */ bool squelch_interactive(const object_type *o_ptr) { char out_val[70]; if (squelch_tval(o_ptr->tval)) { char sval_name[50]; /* Obtain plural form without a quantity */ object_desc(sval_name, sizeof sval_name, o_ptr, ODESC_BASE | ODESC_PLURAL); /* XXX Eddie while correct in a sense, to squelch all torches on torch of brightness you get the message "Ignore Wooden Torches of Brightness in future? " */ strnfmt(out_val, sizeof out_val, "Ignore %s in future? ", sval_name); if (!artifact_p(o_ptr) || !object_flavor_is_aware(o_ptr)) { if (get_check(out_val)) { object_squelch_flavor_of(o_ptr); msg_format("Ignoring %s from now on.", sval_name); return TRUE; } } /* XXX Eddie need to add generalized squelching, e.g. con rings with pval < 3 */ if (!object_is_jewelry(o_ptr) || (squelch_level_of(o_ptr) != SQUELCH_BAD)) return FALSE; } if (object_was_sensed(o_ptr) || object_was_worn(o_ptr) || object_is_known_not_artifact(o_ptr)) { byte value = squelch_level_of(o_ptr); int type = squelch_type_of(o_ptr); /* XXX Eddie on pseudoed cursed artifact, only showed {cursed}, asked to ignore artifacts */ if ((value != SQUELCH_MAX) && ((value == SQUELCH_BAD) || !object_is_jewelry(o_ptr))) { strnfmt(out_val, sizeof out_val, "Ignore all %s that are %s in future? ", quality_choices[type].name, quality_values[value].name); if (get_check(out_val)) { squelch_level[type] = value; return TRUE; } } } return FALSE; }
/** * Return a "feeling" (or FEEL_NONE) about an item. Method 1 (Heavy). */ int value_check_aux1(object_type * o_ptr) { int slot = wield_slot(o_ptr); /* Wieldable? */ if (slot < 0) return FEEL_NONE; /* No pseudo for lights */ if (slot == INVEN_LIGHT) return FEEL_NONE; /* Artifacts */ if (artifact_p(o_ptr)) { /* All return special now */ return FEEL_SPECIAL; } /* Ego-Items */ if (ego_item_p(o_ptr)) { /* Dubious egos (including jewellery) */ if (item_dubious(o_ptr, TRUE)) return FEEL_PERILOUS; /* Normal */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); return FEEL_EXCELLENT; } /* Dubious items */ if (item_dubious(o_ptr, TRUE)) return FEEL_DUBIOUS_STRONG; /* Known not cursed now */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); /* No average jewellery */ if ((slot >= INVEN_LEFT) && (slot <= INVEN_NECK)) return FEEL_GOOD_STRONG; /* Good "armor" bonus */ if (o_ptr->to_a > 0) return FEEL_GOOD_STRONG; /* Good "weapon" bonus */ if (o_ptr->to_h + o_ptr->to_d > 0) return FEEL_GOOD_STRONG; /* Default to "average" */ return FEEL_AVERAGE; }
/* * Cheat -- describe a created object for the user */ static void object_mention(const object_type *o_ptr) { char o_name[80]; /* Describe */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE | ODESC_SPOIL); /* Provide a silly message */ if (artifact_p(o_ptr)) msg_format("Artifact (%s)", o_name); else if (ego_item_p(o_ptr)) msg_format("Ego-item (%s)", o_name); else msg_format("Object (%s)", o_name); }
/* * Determines if an object is eligible for squelching. */ bool squelch_item_ok(const object_type *o_ptr) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; byte type; /* Don't squelch artifacts unless marked to be squelched */ if (artifact_p(o_ptr)) return FALSE; /* Don't squelch stuff inscribed not to be destroyed (!k) */ if (check_for_inscrip(o_ptr, "!k") || check_for_inscrip(o_ptr, "!*")) return FALSE; /* Auto-squelch dead chests */ if (o_ptr->tval == TV_CHEST && o_ptr->pval == 0) return TRUE; /* check option for worthless kinds */ if (OPT(squelch_worthless) && o_ptr->tval != TV_GOLD) { if (object_flavor_is_aware(o_ptr) && k_ptr->cost == 0) return TRUE; if (object_is_known_cursed(o_ptr)) return TRUE; } /* Do squelching by kind */ if (object_flavor_is_aware(o_ptr) ? kind_is_squelched_aware(k_ptr) : kind_is_squelched_unaware(k_ptr)) return TRUE; type = squelch_type_of(o_ptr); if (type == TYPE_MAX) return FALSE; /* Squelch items known not to be special */ if (object_is_known_not_artifact(o_ptr) && squelch_level[type] == SQUELCH_ALL) return TRUE; /* Get result based on the feeling and the squelch_level */ if (squelch_level_of(o_ptr) <= squelch_level[type]) return TRUE; else return FALSE; }
/* * Describe things that look like lights. */ static bool describe_light(textblock * tb, const object_type * o_ptr, bool terse) { int rad = 0; bool artifact = artifact_p(o_ptr); bool is_light = (o_ptr->tval == TV_LIGHT) ? TRUE : FALSE; if (o_ptr->tval != TV_LIGHT && !of_has(o_ptr->flags_obj, OF_LIGHT)) return FALSE; /* Work out radius */ if (artifact && is_light) rad = 3; else if (is_light) rad = 2; if (of_has(o_ptr->flags_obj, OF_LIGHT)) rad++; /* Describe here */ if (!terse) textblock_append(tb, "It provides radius "); else textblock_append(tb, "Radius "); textblock_append_c(tb, TERM_L_GREEN, format("%d", rad)); if (artifact) textblock_append(tb, " light forever."); else textblock_append(tb, " light."); if (!terse && is_light && !artifact) { const char *name = (o_ptr->sval == SV_LIGHT_TORCH) ? "torches" : "lanterns"; int turns = (o_ptr->sval == SV_LIGHT_TORCH) ? FUEL_TORCH : FUEL_LAMP; textblock_append(tb, " Refills other %s up to %d turns of fuel. ", name, turns); } textblock_append(tb, "\n"); return TRUE; }
static size_t obj_desc_charges(const object_type * o_ptr, char *buf, size_t max, size_t end) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bool aware = object_aware_p(o_ptr); /* Wands and Staffs have charges */ if (aware && (o_ptr->tval == TV_STAFF || o_ptr->tval == TV_WAND)) strnfcat(buf, max, &end, " (%d charge%s)", o_ptr->pval, PLURAL(o_ptr->pval)); /* Charging things */ else if (o_ptr->timeout > 0) { if (o_ptr->tval == TV_ROD && o_ptr->number > 1) { int power; int time_base = randcalc(k_ptr->time, 0, MINIMISE); if (!time_base) time_base = 1; /* * Find out how many rods are charging, by dividing * current timeout by each rod's maximum timeout. * Ensure that any remainder is rounded up. Display * very discharged stacks as merely fully discharged. */ power = (o_ptr->timeout + (time_base - 1)) / time_base; if (power > o_ptr->number) power = o_ptr->number; /* Display prettily */ strnfcat(buf, max, &end, " (%d charging)", power); } /* Artifacts, single rods */ else if (!(o_ptr->tval == TV_LIGHT && !artifact_p(o_ptr))) { strnfcat(buf, max, &end, " (charging)"); } } return end; }
/** * Return a "feeling" (or FEEL_NONE) about an item. Method 2 (Light). */ int value_check_aux2(object_type * o_ptr) { int slot = wield_slot(o_ptr); /* Wieldable? */ if (slot < 0) return FEEL_NONE; /* No pseudo for lights */ if (slot == INVEN_LIGHT) return FEEL_NONE; /* Dubious items (all of them) */ if (item_dubious(o_ptr, TRUE)) return FEEL_DUBIOUS_WEAK; /* Known not cursed now */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); /* Artifacts -- except dubious ones */ if (artifact_p(o_ptr)) return FEEL_GOOD_WEAK; /* Ego-Items -- except dubious ones */ if (ego_item_p(o_ptr)) return FEEL_GOOD_WEAK; /* Good armor bonus */ if (o_ptr->to_a > 0) return FEEL_GOOD_WEAK; /* Good weapon bonuses */ if (o_ptr->to_h + o_ptr->to_d > 0) return FEEL_GOOD_WEAK; /* SJGU */ /* Default to "average" */ return FEEL_AVERAGE; }
/* * Change the quantity of a the item */ static void wiz_quantity_item(object_type *o_ptr, bool carried) { int tmp_int; char tmp_val[3]; /* Never duplicate artifacts */ if (artifact_p(o_ptr)) return; /* Default */ strnfmt(tmp_val, sizeof(tmp_val), "%d", o_ptr->number); /* Query */ if (get_string("Quantity: ", tmp_val, 3)) { /* Extract */ tmp_int = atoi(tmp_val); /* Paranoia */ if (tmp_int < 1) tmp_int = 1; if (tmp_int > 99) tmp_int = 99; /* Adjust total weight being carried */ if (carried) { /* Remove the weight of the old number of objects */ p_ptr->total_weight -= (o_ptr->number * o_ptr->weight); /* Add the weight of the new number of objects */ p_ptr->total_weight += (tmp_int * o_ptr->weight); } /* Adjust charges/timeouts for devices */ reduce_charges(o_ptr, (o_ptr->number - tmp_int)); /* Accept modifications */ o_ptr->number = tmp_int; } }
/* Preserve arts if needed */ void preserve_artifacts_in_inven(flags_type *inven) { if (p_ptr->preserve) { for_inventory_slot_ro(inven, o_ptr); { /* Hack -- Preserve unknown artifacts */ if (artifact_p(o_ptr) && !object_known_p(o_ptr)) { /* Mega-Hack -- Preserve the artifact */ if (has_flag(&k_info[o_ptr->k_idx], FLAG_NORM_ART)) { k_info[o_ptr->k_idx].artifact = FALSE; } else { a_info[o_ptr->artifact_id].cur_num = 0; } } } end_inventory(); } }
/* * Return a "feeling" (or NULL) about an item. Method 1 (Heavy). */ static int value_check_aux1(object_type *o_ptr) { /* Artifacts */ if (artifact_p(o_ptr)) { /* Cursed/Broken */ if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_TERRIBLE); /* Normal */ return (FEEL_SPECIAL); } /* Ego-Items */ if (ego_item_p(o_ptr)) { /* Cursed/Broken */ if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_WORTHLESS); /* Normal */ return (FEEL_EXCELLENT); } /* Cursed items */ if (cursed_p(o_ptr)) return (FEEL_CURSED); /* Broken items */ if (broken_p(o_ptr)) return (FEEL_BROKEN); /* Good "armor" bonus */ if (o_ptr->to_a > 0) return (FEEL_GOOD); /* Good "weapon" bonus */ if (o_ptr->to_h + o_ptr->to_d > 0) return (FEEL_GOOD); /* Default to "average" */ return (FEEL_AVERAGE); }
/* * Tweak an item */ static void wiz_tweak_item(object_type *o_ptr) { cptr p; char tmp_val[80]; /* Hack -- leave artifacts alone */ if (artifact_p(o_ptr)) return; #define WIZ_TWEAK(attribute) do {\ p = "Enter new '" #attribute "' setting: ";\ strnfmt(tmp_val, sizeof(tmp_val), "%d", o_ptr->attribute);\ if (!get_string(p, tmp_val, 6)) return;\ o_ptr->attribute = atoi(tmp_val);\ wiz_display_item(o_ptr, TRUE);\ } while (0) WIZ_TWEAK(pval); WIZ_TWEAK(to_a); WIZ_TWEAK(to_h); WIZ_TWEAK(to_d); WIZ_TWEAK(name1); WIZ_TWEAK(name2); }
/* * Recurse through an object's flags. If any objects are encountered, * if the item is an artifact its dropped on the ground, otherwise its * deleted as well. Also checks through the inventory of any monster * embeded in the item. */ static void delete_obj_recurse_on_flags(flags_type *flags, byte iy, byte ix, byte number) { s32b i; for (i = 0; i < flags->size; i++) { flag_node* n = &flags->node[i]; /* Not used */ if (!(n->flags & FLAG_FLAG_USED)) continue; if (n->flags & FLAG_FLAG_FLAGS) delete_obj_recurse_on_flags(n->vals.flags, iy, ix, number); else if (n->flags & FLAG_FLAG_PTR) { if (n->vals.ptr.type == FLAG_TYPE_OBJ) { object_type *o_ptr = (object_type*) n->vals.ptr.ptr; if (number && artifact_p(o_ptr) && o_ptr->held_m_idx == 0) { object_type *copy = new_object(); object_copy(copy, o_ptr); o_ptr->number = number; drop_near(copy, -1, iy, ix); } } else if (n->vals.ptr.type == FLAG_TYPE_MONSTER) { monster_type *m_ptr = (monster_type*) n->vals.ptr.ptr; delete_obj_recurse_on_flags(&(m_ptr->inventory), iy, ix, number); } } /* else if (n->flags & FLAG_FLAG_PTR) */ } /* for (i = 0; i < flags->size; i++) */ } /* delete_obj_recurse_on_flags() */
/** * Change the quantity of an item */ static void wiz_quantity_item(object_type * o_ptr) { int tmp_int, tmp_qnt; char tmp_val[100]; /* Never duplicate artifacts */ if (artifact_p(o_ptr)) return; /* Store old quantity. */ tmp_qnt = o_ptr->number; /* Default */ sprintf(tmp_val, "%d", o_ptr->number); /* Query */ if (get_string("Quantity: ", tmp_val, 3)) { /* Extract */ tmp_int = atoi(tmp_val); /* Paranoia */ if (tmp_int < 1) tmp_int = 1; if (tmp_int > 99) tmp_int = 99; /* Accept modifications */ o_ptr->number = tmp_int; /* Hack -- Rod total timeouts increase with stack size. */ if (o_ptr->tval == TV_ROD) o_ptr->pval = o_ptr->pval * o_ptr->number / tmp_qnt; } }
/* * Copy 'src' into 'buf, replacing '#' with 'modstr' (if found), putting a plural * in the place indicated by '~' if required, or using alterate... */ static size_t obj_desc_name(char *buf, size_t max, size_t end, const object_type *o_ptr, bool prefix, byte mode, bool spoil) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bool known = object_is_known(o_ptr) || (o_ptr->ident & IDENT_STORE) || spoil; bool aware = object_flavor_is_aware(o_ptr) || (o_ptr->ident & IDENT_STORE) || spoil; const char *basename = obj_desc_get_basename(o_ptr, aware); const char *modstr = obj_desc_get_modstr(o_ptr); bool pluralise = (mode & ODESC_PLURAL) ? TRUE : FALSE; if (o_ptr->number > 1) pluralise = TRUE; if (mode & ODESC_SINGULAR) pluralise = FALSE; /* Add a pseudo-numerical prefix if desired */ if (prefix) { if (o_ptr->number <= 0) { strnfcat(buf, max, &end, "no more "); /* Pluralise for grammatical correctness */ pluralise = TRUE; } else if (o_ptr->number > 1) strnfcat(buf, max, &end, "%d ", o_ptr->number); else if ((known) && artifact_p(o_ptr)) strnfcat(buf, max, &end, "The "); else if (*basename == '&') { bool an = FALSE; const char *lookahead = basename + 1; while (*lookahead == ' ') lookahead++; if (*lookahead == '#') { if (modstr && is_a_vowel(*modstr)) an = TRUE; } else if (is_a_vowel(*lookahead)) { an = TRUE; } if (an) strnfcat(buf, max, &end, "an "); else strnfcat(buf, max, &end, "a "); } } /* Perfectly balanced throwing weapons are indicated. */ if ((known) && (o_ptr->ident & IDENT_PERFECT_BALANCE)) { strnfcat(buf, max, &end, "Well-balanced "); } /* * Names have the following elements: * * '~' indicates where to place an 's' or an 'es'. Other plural forms should * be handled with the syntax '|singular|plural|', e.g. "kni|fe|ves|". * * '#' indicates the position of the "modifier", e.g. the flavour or spellbook * name. */ /* Copy the string */ while (*basename) { if (*basename == '&') { while (*basename == ' ' || *basename == '&') basename++; continue; } /* Pluralizer (regular English plurals) */ else if (*basename == '~') { char prev = *(basename - 1); if (!pluralise) { basename++; continue; } /* e.g. cutlass-e-s, torch-e-s, box-e-s */ if (prev == 's' || prev == 'h' || prev == 'x') strnfcat(buf, max, &end, "es"); else strnfcat(buf, max, &end, "s"); } /* Special plurals */ else if (*basename == '|') { /* e.g. & Wooden T|o|e|rch~ * ^ ^^ */ const char *singular = basename + 1; const char *plural = strchr(singular, '|'); const char *endmark = NULL; if (plural) { plural++; endmark = strchr(plural, '|'); } if (!singular || !plural || !endmark) return end; if (!pluralise) strnfcat(buf, max, &end, "%.*s", plural - singular - 1, singular); else strnfcat(buf, max, &end, "%.*s", endmark - plural, plural); basename = endmark; } /* Handle pluralisation in the modifier XXX */ else if (*basename == '#') { const char *basename = modstr; while (basename && *basename && (end < max - 1)) { /* Special plurals */ if (*basename == '|') { /* e.g. & Wooden T|o|e|rch~ * ^ ^^ */ const char *singular = basename + 1; const char *plural = strchr(singular, '|'); const char *endmark = NULL; if (plural) { plural++; endmark = strchr(plural, '|'); } if (!singular || !plural || !endmark) return end; if (!pluralise) strnfcat(buf, max, &end, "%.*s", plural - singular - 1, singular); else strnfcat(buf, max, &end, "%.*s", endmark - plural, plural); basename = endmark; } else buf[end++] = *basename; basename++; } } else buf[end++] = *basename; basename++; } /* 0-terminate, just in case XXX */ buf[end] = 0; /** Append extra names of various kinds **/ if ((known) && o_ptr->art_num) strnfcat(buf, max, &end, " %s", a_info[o_ptr->art_num].name); else if ((o_ptr->ego_num) && (known || spoil)) { strnfcat(buf, max, &end, " %s", e_name + e_info[o_ptr->ego_num].name); } else if (aware && !artifact_p(o_ptr) && (k_ptr->flavor || k_ptr->tval == TV_SCROLL)) strnfcat(buf, max, &end, " of %s", k_name + k_ptr->name); return end; }
/* * Try to create an item again. Output some statistics. -Bernd- * * The statistics are correct now. We acquire a clean grid, and then * repeatedly place an object in this grid, copying it into an item * holder, and then deleting the object. We fiddle with the artifact * counter flags to prevent weirdness. We use the items to collect * statistics on item creation relative to the initial item. */ static void wiz_statistics(object_type *o_ptr) { long i, matches, better, worse, other; char ch; char *quality; bool good, great; object_type *i_ptr; object_type object_type_body; cptr q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld"; /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].cur_num = 0; /* Interact */ while (TRUE) { cptr pmt = "Roll for [n]ormal, [g]ood, or [e]xcellent treasure? "; /* Display item */ wiz_display_item(o_ptr); /* Get choices */ if (!get_com(pmt, &ch)) break; if (ch == 'n' || ch == 'N') { good = FALSE; great = FALSE; quality = "normal"; } else if (ch == 'g' || ch == 'G') { good = TRUE; great = FALSE; quality = "good"; } else if (ch == 'e' || ch == 'E') { good = TRUE; great = TRUE; quality = "excellent"; } else { #if 0 /* unused */ good = FALSE; great = FALSE; #endif /* unused */ break; } /* Let us know what we are doing */ msg_format("Creating a lot of %s items. Base level = %d.", quality, p_ptr->depth); message_flush(); /* Set counters to zero */ matches = better = worse = other = 0; /* Let's rock and roll */ for (i = 0; i <= TEST_ROLL; i++) { /* Output every few rolls */ if ((i < 100) || (i % 100 == 0)) { /* Do not wait */ inkey_scan = TRUE; /* Allow interupt */ if (inkey()) { /* Flush */ flush(); /* Stop rolling */ break; } /* Dump the stats */ prt(format(q, i, matches, better, worse, other), 0, 0); Term_fresh(); } /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Create an object */ make_object(i_ptr, good, great); /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(i_ptr)) a_info[i_ptr->name1].cur_num = 0; /* Test for the same tval and sval. */ if ((o_ptr->tval) != (i_ptr->tval)) continue; if ((o_ptr->sval) != (i_ptr->sval)) continue; /* Check for match */ if ((i_ptr->pval == o_ptr->pval) && (i_ptr->to_a == o_ptr->to_a) && (i_ptr->to_h == o_ptr->to_h) && (i_ptr->to_d == o_ptr->to_d)) { matches++; } /* Check for better */ else if ((i_ptr->pval >= o_ptr->pval) && (i_ptr->to_a >= o_ptr->to_a) && (i_ptr->to_h >= o_ptr->to_h) && (i_ptr->to_d >= o_ptr->to_d)) { better++; } /* Check for worse */ else if ((i_ptr->pval <= o_ptr->pval) && (i_ptr->to_a <= o_ptr->to_a) && (i_ptr->to_h <= o_ptr->to_h) && (i_ptr->to_d <= o_ptr->to_d)) { worse++; } /* Assume different */ else { other++; } } /* Final dump */ msg_format(q, i, matches, better, worse, other); message_flush(); } /* Hack -- Normally only make a single artifact */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].cur_num = 1; }
/** * Carry an object and delete it. */ extern void py_pickup_aux(int o_idx, bool msg) { int slot, quiver_slot = 0; char o_name[120]; object_type *o_ptr = &o_list[o_idx]; object_type *i_ptr = &p_ptr->inventory[INVEN_LIGHT]; bitflag f[OF_SIZE], obvious_mask[OF_SIZE]; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); of_copy(f, o_ptr->flags_obj); /* Carry the object */ slot = inven_carry(p_ptr, o_ptr); /* Handle errors (paranoia) */ if (slot < 0) return; /* If we have picked up ammo which matches something in the quiver, note * that it so that we can wield it later (and suppress pick up message) */ if (obj_is_quiver_obj(o_ptr)) { int i; for (i = QUIVER_START; i < QUIVER_END; i++) { if (!p_ptr->inventory[i].k_idx) continue; if (!object_similar(&p_ptr->inventory[i], o_ptr, OSTACK_QUIVER)) continue; quiver_slot = i; break; } } /* Get the object again */ o_ptr = &p_ptr->inventory[slot]; /* Set squelch status */ p_ptr->notice |= PN_SQUELCH; /* Stone of Lore gives id on pickup */ if (!object_known_p(o_ptr)) { if (i_ptr->sval == SV_STONE_LORE) identify_object(o_ptr); /* Otherwise pseudo-ID */ else { bool heavy = FALSE; int feel; /* Heavy sensing */ heavy = (player_has(PF_PSEUDO_ID_HEAVY)); /* Type of feeling */ feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr)); /* We have "felt" it */ o_ptr->ident |= (IDENT_SENSE); /* Inscribe it textually */ o_ptr->feel = feel; /* Set squelch flag as appropriate */ p_ptr->notice |= PN_SQUELCH; } } /* Log artifacts if found */ if (artifact_p(o_ptr)) history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE); /* Notice dice and other obvious stuff */ notice_other(IF_DD_DS, slot + 1); (void) of_inter(f, obvious_mask); of_union(o_ptr->id_obj, f); /* Average things are average */ if ((o_ptr->feel == FEEL_AVERAGE) && (is_weapon(o_ptr) || is_armour(o_ptr))){ notice_other(IF_AC, slot + 1); notice_other(IF_TO_A, slot + 1); notice_other(IF_TO_H, slot + 1); notice_other(IF_TO_D, slot + 1); } /* Recalculate the bonuses */ p_ptr->update |= (PU_BONUS); /* Optionally, display a message */ if (msg && !quiver_slot) { /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ msg_format("You have %s (%c).", o_name, index_to_label(slot)); } /* Delete the object */ delete_object_idx(o_idx); /* If we have a quiver slot that this item matches, use it */ if (quiver_slot) wield_item(o_ptr, slot, quiver_slot); }
/* * Destroy an item */ void do_cmd_destroy(void) { int item, amt; int old_number; object_type *o_ptr; char o_name[80]; char out_val[160]; cptr q, s; /* Get an item */ q = "Destroy which item? "; s = "You have nothing to destroy."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Get a quantity */ amt = get_quantity(NULL, o_ptr->number); /* Allow user abort */ if (amt <= 0) return; /* Describe the object */ old_number = o_ptr->number; o_ptr->number = amt; object_desc(o_name, o_ptr, TRUE, 3); o_ptr->number = old_number; /* Verify destruction */ if (verify_destroy) { sprintf(out_val, "Really destroy %s? ", o_name); if (!get_check(out_val)) return; } /* Take a turn */ p_ptr->energy_use = 100; /* Artifacts cannot be destroyed */ if (artifact_p(o_ptr)) { /* Message */ msg_format("You cannot destroy %s.", o_name); /* Don't mark id'ed objects */ if (object_known_p(o_ptr)) return; /* It has already been sensed */ if (o_ptr->ident & (IDENT_SENSE)) { /* Already sensed objects always get improved feelings */ if (cursed_p(o_ptr) || broken_p(o_ptr)) o_ptr->discount = INSCRIP_TERRIBLE; else o_ptr->discount = INSCRIP_SPECIAL; } else { /* Mark the object as indestructible */ o_ptr->discount = INSCRIP_INDESTRUCTIBLE; } /* Combine the pack */ p_ptr->notice |= (PN_COMBINE); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); p_ptr->redraw |= (PR_EQUIPPY); /* Done */ return; } /* Message */ msg_format("You destroy %s.", o_name); /* Eliminate the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); } /* Eliminate the item (from the floor) */ else { floor_item_increase(0 - item, -amt); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/* * Attack the player via physical attacks. */ bool make_attack_normal(int m_idx) { monster_type *m_ptr = &mon_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; monster_lore *l_ptr = &l_list[m_ptr->r_idx]; int ap_cnt; int i, k, tmp, ac, rlev; int do_cut, do_stun; s32b gold; object_type *o_ptr; char o_name[80]; char m_name[80]; char ddesc[80]; bool blinked; /* Not allowed to attack */ if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; /* Extract the effective monster level */ rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0); /* Get the "died from" information (i.e. "a kobold") */ monster_desc(ddesc, sizeof(ddesc), m_ptr, 0x88); /* Assume no blink */ blinked = FALSE; /* Scan through all blows */ for (ap_cnt = 0; ap_cnt < MONSTER_BLOW_MAX; ap_cnt++) { bool visible = FALSE; bool obvious = FALSE; int power = 0; int damage = 0; cptr act = NULL; /* Extract the attack infomation */ int effect = r_ptr->blow[ap_cnt].effect; int method = r_ptr->blow[ap_cnt].method; int d_dice = r_ptr->blow[ap_cnt].d_dice; int d_side = r_ptr->blow[ap_cnt].d_side; /* Hack -- no more attacks */ if (!method) break; /* Handle "leaving" */ if (p_ptr->leaving) break; /* Extract visibility (before blink) */ if (m_ptr->ml) visible = TRUE; /* Extract the attack "power" */ switch (effect) { case RBE_HURT: power = 60; break; case RBE_POISON: power = 5; break; case RBE_UN_BONUS: power = 20; break; case RBE_UN_POWER: power = 15; break; case RBE_EAT_GOLD: power = 5; break; case RBE_EAT_ITEM: power = 5; break; case RBE_EAT_FOOD: power = 5; break; case RBE_EAT_LITE: power = 5; break; case RBE_ACID: power = 0; break; case RBE_ELEC: power = 10; break; case RBE_FIRE: power = 10; break; case RBE_COLD: power = 10; break; case RBE_BLIND: power = 2; break; case RBE_CONFUSE: power = 10; break; case RBE_TERRIFY: power = 10; break; case RBE_PARALYZE: power = 2; break; case RBE_LOSE_STR: power = 0; break; case RBE_LOSE_DEX: power = 0; break; case RBE_LOSE_CON: power = 0; break; case RBE_LOSE_INT: power = 0; break; case RBE_LOSE_WIS: power = 0; break; case RBE_LOSE_CHR: power = 0; break; case RBE_LOSE_ALL: power = 2; break; case RBE_SHATTER: power = 60; break; case RBE_EXP_10: power = 5; break; case RBE_EXP_20: power = 5; break; case RBE_EXP_40: power = 5; break; case RBE_EXP_80: power = 5; break; case RBE_HALLU: power = 10; break; } /* Monster hits player */ if (!effect || check_hit(power, rlev)) { /* Always disturbing */ disturb(1, 0); /* Hack -- Apply "protection from evil" */ if ((p_ptr->protevil > 0) && (r_ptr->flags3 & (RF3_EVIL)) && (p_ptr->lev >= rlev) && ((rand_int(100) + p_ptr->lev) > 50)) { /* Remember the Evil-ness */ if (m_ptr->ml) { l_ptr->flags3 |= (RF3_EVIL); } /* Message */ msg_format("%^s is repelled.", m_name); /* Hack -- Next attack */ continue; } /* Assume no cut or stun */ do_cut = do_stun = 0; /* Describe the attack method */ switch (method) { case RBM_HIT: { act = "hits you."; do_cut = do_stun = 1; break; } case RBM_TOUCH: { act = "touches you."; break; } case RBM_PUNCH: { act = "punches you."; do_stun = 1; break; } case RBM_KICK: { act = "kicks you."; do_stun = 1; break; } case RBM_CLAW: { act = "claws you."; do_cut = 1; break; } case RBM_BITE: { act = "bites you."; do_cut = 1; break; } case RBM_STING: { act = "stings you."; break; } case RBM_XXX1: { act = "XXX1's you."; break; } case RBM_BUTT: { act = "butts you."; do_stun = 1; break; } case RBM_CRUSH: { act = "crushes you."; do_stun = 1; break; } case RBM_ENGULF: { act = "engulfs you."; break; } case RBM_XXX2: { act = "XXX2's you."; break; } case RBM_CRAWL: { act = "crawls on you."; break; } case RBM_DROOL: { act = "drools on you."; break; } case RBM_SPIT: { act = "spits on you."; break; } case RBM_XXX3: { act = "XXX3's on you."; break; } case RBM_GAZE: { act = "gazes at you."; break; } case RBM_WAIL: { act = "wails at you."; break; } case RBM_SPORE: { act = "releases spores at you."; break; } case RBM_XXX4: { act = "projects XXX4's at you."; break; } case RBM_BEG: { act = "begs you for money."; break; } case RBM_INSULT: { act = desc_insult[rand_int(MAX_DESC_INSULT)]; break; } case RBM_MOAN: { act = desc_moan[rand_int(MAX_DESC_MOAN)]; break; } case RBM_XXX5: { act = "XXX5's you."; break; } } /* Message */ if (act) msg_format("%^s %s", m_name, act); /* Hack -- assume all attacks are obvious */ obvious = TRUE; /* Roll out the damage */ damage = damroll(d_dice, d_side); /* Apply appropriate damage */ switch (effect) { case 0: { /* Hack -- Assume obvious */ obvious = TRUE; /* Hack -- No damage */ damage = 0; break; } case RBE_HURT: { /* Obvious */ obvious = TRUE; /* Hack -- Player armor reduces total damage */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); /* Take damage */ take_hit(damage, ddesc); break; } case RBE_POISON: { /* Take damage */ take_hit(damage, ddesc); /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_POIS); break; } case RBE_UN_BONUS: { /* Take damage */ take_hit(damage, ddesc); /* Allow complete resist */ if (!p_ptr->resist_disen) { /* Apply disenchantment */ if (apply_disenchant(0)) obvious = TRUE; } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_DISEN); break; } case RBE_UN_POWER: { /* Take damage */ take_hit(damage, ddesc); /* Find an item */ for (k = 0; k < 10; k++) { /* Pick an item */ i = rand_int(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Drain charged wands/staffs */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval > 0)) { /* Calculate healed hitpoints */ int heal = rlev * o_ptr->pval * o_ptr->number; /* Don't heal more than max hp */ heal = MIN(heal, m_ptr->maxhp - m_ptr->hp); /* Message */ msg_print("Energy drains from your pack!"); /* Obvious */ obvious = TRUE; /* Heal */ m_ptr->hp += heal; /* Redraw (later) if needed */ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); /* Uncharge */ o_ptr->pval = 0; /* Combine / Reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ p_ptr->window |= (PW_INVEN); /* Done */ break; } } break; } case RBE_EAT_GOLD: { /* Take damage */ take_hit(damage, ddesc); /* Obvious */ obvious = TRUE; /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + p_ptr->lev))) { /* Saving throw message */ msg_print("You quickly protect your money pouch!"); /* Occasional blink anyway */ if (rand_int(3)) blinked = TRUE; } /* Eat gold */ else { gold = (p_ptr->au / 10) + randint(25); if (gold < 2) gold = 2; if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000); if (gold > p_ptr->au) gold = p_ptr->au; p_ptr->au -= gold; if (gold <= 0) { msg_print("Nothing was stolen."); } else if (p_ptr->au) { msg_print("Your purse feels lighter."); msg_format("%ld coins were stolen!", (long)gold); } else { msg_print("Your purse feels lighter."); msg_print("All of your coins were stolen!"); } /* Redraw gold */ p_ptr->redraw |= (PR_GOLD); /* Window stuff */ p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Blink away */ blinked = TRUE; } break; } case RBE_EAT_ITEM: { /* Take damage */ take_hit(damage, ddesc); /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + p_ptr->lev))) { /* Saving throw message */ msg_print("You grab hold of your backpack!"); /* Occasional "blink" anyway */ blinked = TRUE; /* Obvious */ obvious = TRUE; /* Done */ break; } /* Find an item */ for (k = 0; k < 10; k++) { object_type *i_ptr; object_type object_type_body; /* Pick an item */ i = rand_int(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Skip artifacts */ if (artifact_p(o_ptr)) continue; /* Get a description */ object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 3); /* Message */ msg_format("%sour %s (%c) was stolen!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i)); /* Get local object */ i_ptr = &object_type_body; /* Obtain local object */ object_copy(i_ptr, o_ptr); /* Modify number */ i_ptr->number = 1; /* Carry the object */ (void)monster_carry(m_idx, i_ptr); /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Blink away */ blinked = TRUE; /* Done */ break; } break; } case RBE_EAT_FOOD: { /* Take damage */ take_hit(damage, ddesc); /* Steal some food */ for (k = 0; k < 10; k++) { /* Pick an item from the pack */ i = rand_int(INVEN_PACK); /* Get the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Skip non-food objects */ if (o_ptr->tval != TV_FOOD) continue; /* Get a description */ object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 0); /* Message */ msg_format("%sour %s (%c) was eaten!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i)); /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Done */ break; } break; } case RBE_EAT_LITE: { /* Take damage */ take_hit(damage, ddesc); /* Get the lite */ o_ptr = &inventory[INVEN_LITE]; /* Drain fuel */ if ((o_ptr->pval > 0) && (!artifact_p(o_ptr))) { /* Reduce fuel */ o_ptr->pval -= (250 + randint(250)); if (o_ptr->pval < 1) o_ptr->pval = 1; /* Notice */ if (!p_ptr->blind) { msg_print("Your light dims."); obvious = TRUE; } /* Window stuff */ p_ptr->window |= (PW_EQUIP); } break; } case RBE_ACID: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are covered in acid!"); /* Special damage */ acid_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_ACID); break; } case RBE_ELEC: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are struck by electricity!"); /* Take damage (special) */ elec_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_ELEC); break; } case RBE_FIRE: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are enveloped in flames!"); /* Take damage (special) */ fire_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_FIRE); break; } case RBE_COLD: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are covered with frost!"); /* Take damage (special) */ cold_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_COLD); break; } case RBE_BLIND: { /* Take damage */ take_hit(damage, ddesc); /* Increase "blind" */ if (!p_ptr->resist_blind) { if (set_blind(p_ptr->blind + 10 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_BLIND); break; } case RBE_CONFUSE: { /* Take damage */ take_hit(damage, ddesc); /* Increase "confused" */ if (!p_ptr->resist_confu) { if (set_confused(p_ptr->confused + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_CONFU); break; } case RBE_TERRIFY: { /* Take damage */ take_hit(damage, ddesc); /* Increase "afraid" */ if (p_ptr->resist_fear) { msg_print("You stand your ground!"); obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You stand your ground!"); obvious = TRUE; } else { if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_FEAR); break; } case RBE_PARALYZE: { /* Hack -- Prevent perma-paralysis via damage */ if (p_ptr->paralyzed && (damage < 1)) damage = 1; /* Take damage */ take_hit(damage, ddesc); /* Increase "paralyzed" */ if (p_ptr->free_act) { msg_print("You are unaffected!"); obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You resist the effects!"); obvious = TRUE; } else { if (set_paralyzed(p_ptr->paralyzed + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_FREE); break; } case RBE_LOSE_STR: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_STR)) obvious = TRUE; break; } case RBE_LOSE_INT: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_INT)) obvious = TRUE; break; } case RBE_LOSE_WIS: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_WIS)) obvious = TRUE; break; } case RBE_LOSE_DEX: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_DEX)) obvious = TRUE; break; } case RBE_LOSE_CON: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CON)) obvious = TRUE; break; } case RBE_LOSE_CHR: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CHR)) obvious = TRUE; break; } case RBE_LOSE_ALL: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stats) */ if (do_dec_stat(A_STR)) obvious = TRUE; if (do_dec_stat(A_DEX)) obvious = TRUE; if (do_dec_stat(A_CON)) obvious = TRUE; if (do_dec_stat(A_INT)) obvious = TRUE; if (do_dec_stat(A_WIS)) obvious = TRUE; if (do_dec_stat(A_CHR)) obvious = TRUE; break; } case RBE_SHATTER: { /* Obvious */ obvious = TRUE; /* Hack -- Reduce damage based on the player armor class */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); /* Take damage */ take_hit(damage, ddesc); /* Radius 8 earthquake centered at the monster */ if (damage > 23) earthquake(m_ptr->fy, m_ptr->fx, 8); break; } case RBE_EXP_10: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 95)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(10, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d/10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_20: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 90)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_40: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 75)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_80: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 50)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_HALLU: { /* Take damage */ take_hit(damage, ddesc); /* Increase "image" */ if (!p_ptr->resist_chaos) { if (set_image(p_ptr->image + 3 + randint(rlev / 2))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_CHAOS); break; } } /* Hack -- only one of cut or stun */ if (do_cut && do_stun) { /* Cancel cut */ if (rand_int(100) < 50) { do_cut = 0; } /* Cancel stun */ else { do_stun = 0; } } /* Handle cut */ if (do_cut) { int k; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint(5); break; case 2: k = randint(5) + 5; break; case 3: k = randint(20) + 20; break; case 4: k = randint(50) + 50; break; case 5: k = randint(100) + 100; break; case 6: k = 300; break; default: k = 500; break; } /* Apply the cut */ if (k) (void)set_cut(p_ptr->cut + k); } /* Handle stun */ if (do_stun) { int k; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint(5); break; case 2: k = randint(10) + 10; break; case 3: k = randint(20) + 20; break; case 4: k = randint(30) + 30; break; case 5: k = randint(40) + 40; break; case 6: k = 100; break; default: k = 200; break; } /* Apply the stun */ if (k) (void)set_stun(p_ptr->stun + k); } } /* Monster missed player */ else { /* Analyze failed attacks */ switch (method) { case RBM_HIT: case RBM_TOUCH: case RBM_PUNCH: case RBM_KICK: case RBM_CLAW: case RBM_BITE: case RBM_STING: case RBM_XXX1: case RBM_BUTT: case RBM_CRUSH: case RBM_ENGULF: case RBM_XXX2: /* Visible monsters */ if (m_ptr->ml) { /* Disturbing */ disturb(1, 0); /* Message */ msg_format("%^s misses you.", m_name); } break; } } /* Analyze "visible" monsters only */ if (visible) { /* Count "obvious" attacks (and ones that cause damage) */ if (obvious || damage || (l_ptr->blows[ap_cnt] > 10)) { /* Count attacks of this type */ if (l_ptr->blows[ap_cnt] < MAX_UCHAR) { l_ptr->blows[ap_cnt]++; } } } } /* Blink away */ if (blinked) { msg_print("There is a puff of smoke!"); teleport_away(m_idx, MAX_SIGHT * 2 + 5); } /* Always notice cause of death */ if (p_ptr->is_dead && (l_ptr->deaths < MAX_SHORT)) { l_ptr->deaths++; } /* Assume we attacked */ return (TRUE); }
/** * Determines if an object is eligable for squelching. */ extern bool squelch_item_ok(const object_type * o_ptr) { size_t i; int num = -1; object_kind *k_ptr = &k_info[o_ptr->k_idx]; bool fullid = object_known_p(o_ptr); bool sensed = (o_ptr->ident & IDENT_SENSE) || fullid; byte feel = fullid ? value_check_aux1((object_type *) o_ptr) : o_ptr->feel; /* Don't squelch artifacts */ if (artifact_p(o_ptr)) return FALSE; /* Don't squelch stuff inscribed not to be destroyed (!k) */ if (check_for_inscrip(o_ptr, "!k") || check_for_inscrip(o_ptr, "!*")) { return FALSE; } /* Auto-squelch dead chests */ if (o_ptr->tval == TV_CHEST && o_ptr->pval == 0) return TRUE; /* Do squelching by sval, if we 'know' the flavour. */ if (k_ptr->squelch && (k_ptr->flavor == 0 || k_ptr->aware)) { if (squelch_tval(k_info[o_ptr->k_idx].tval)) return TRUE; } /* Squelch some ego items if known */ if (has_ego_properties(o_ptr) && (e_info[o_ptr->name2].squelch)) { return TRUE; } /* Don't check pseudo-ID for nonsensed things */ if (!sensed) return FALSE; /* Find the appropriate squelch group */ for (i = 0; i < N_ELEMENTS(quality_choices); i++) { if (quality_choices[i].enum_val == o_ptr->tval) { num = i; break; } } /* Never squelched */ if (num == -1) return FALSE; /* Get result based on the feeling and the squelch_level */ switch (squelch_level[num]) { case SQUELCH_CURSED: { if (o_ptr->ident & IDENT_CURSED) { return TRUE; } break; } case SQUELCH_DUBIOUS: { if ((feel == FEEL_DUBIOUS_WEAK) || (feel == FEEL_PERILOUS) || (feel == FEEL_DUBIOUS_STRONG)) { return TRUE; } break; } case SQUELCH_DUBIOUS_NON: { if (feel == FEEL_DUBIOUS_STRONG) { return TRUE; } break; } case SQUELCH_NON_EGO: { if ((feel == FEEL_DUBIOUS_STRONG) || (feel == FEEL_AVERAGE) || (feel == FEEL_GOOD_STRONG)) { return TRUE; } break; } case SQUELCH_AVERAGE: { if ((feel == FEEL_DUBIOUS_WEAK) || (feel == FEEL_PERILOUS) || (feel == FEEL_DUBIOUS_STRONG) || (feel == FEEL_AVERAGE)) { return TRUE; } break; } case SQUELCH_GOOD_STRONG: { if ((feel == FEEL_PERILOUS) || (feel == FEEL_DUBIOUS_STRONG) || (feel == FEEL_AVERAGE) || (feel == FEEL_GOOD_STRONG)) { return TRUE; } break; } case SQUELCH_GOOD_WEAK: { if ((feel == FEEL_PERILOUS) || (feel == FEEL_DUBIOUS_STRONG) || (feel == FEEL_AVERAGE) || (feel == FEEL_GOOD_WEAK) || (feel == FEEL_GOOD_STRONG)) { return TRUE; } break; } case SQUELCH_ALL: { return TRUE; break; } } /* Failure */ return FALSE; }
static const char *obj_desc_get_basename(const object_type *o_ptr, bool aware) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bool show_flavor = k_ptr->flavor ? TRUE : FALSE; if (o_ptr->ident & IDENT_STORE) show_flavor = FALSE; if (aware && !show_flavors) show_flavor = FALSE; /* Known artifacts get special treatment */ if (artifact_p(o_ptr) && aware) { /* An exception for unidentified special artifacts */ if (!k_ptr->flavor || object_is_known(o_ptr)) return (k_name + k_ptr->name); } /* Analyze the object */ switch (o_ptr->tval) { case TV_SKELETON: case TV_BOTTLE: case TV_JUNK: case TV_SPIKE: case TV_FLASK: case TV_CHEST: case TV_SHOT: case TV_BOLT: case TV_ARROW: case TV_BOW: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING: case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN: case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR: case TV_DRAG_SHIELD: case TV_LIGHT: case TV_PARCHMENT: return (k_name + k_ptr->name); case TV_AMULET: return (show_flavor ? "& # Amulet~" : "& Amulet~"); case TV_RING: return (show_flavor ? "& # Ring~" : "& Ring~"); case TV_STAFF: return (show_flavor ? "& # Sta|ff|ves|" : "& Sta|ff|ves|"); case TV_WAND: return (show_flavor ? "& # Wand~" : "& Wand~"); case TV_ROD: return (show_flavor ? "& # Rod~" : "& Rod~"); case TV_POTION: return (show_flavor ? "& # Potion~" : "& Potion~"); case TV_SCROLL: return (show_flavor ? "& Scroll~ titled \"#\"" : "& Scroll~"); case TV_MAGIC_BOOK: return "& Book~ of Magic Spells #"; case TV_PRAYER_BOOK: return "& Holy Book~ of Prayers #"; case TV_DRUID_BOOK: return "& Book~ of Druid Spells #"; case TV_FOOD: if (o_ptr->sval < SV_FOOD_MIN_FOOD) return (show_flavor ? "& # Mushroom~" : "& Mushroom~"); else return (k_name + k_ptr->name); } return "(nothing)"; }
/* * Apply magic to an item or turn it into an artifact. -Bernd- */ static void wiz_reroll_item(object_type *o_ptr) { object_type *i_ptr; object_type object_type_body; char ch; bool changed = FALSE; /* Hack -- leave artifacts alone */ if (artifact_p(o_ptr)) return; /* Get local object */ i_ptr = &object_type_body; /* Copy the object */ object_copy(i_ptr, o_ptr); /* Main loop. Ask for magification and artifactification */ while (TRUE) { /* Display full item debug information */ wiz_display_item(i_ptr); /* Ask wizard what to do. */ if (!get_com("[a]ccept, [n]ormal, [g]ood, [e]xcellent? ", &ch)) break; /* Create/change it! */ if (ch == 'A' || ch == 'a') { changed = TRUE; break; } /* Apply normal magic, but first clear object */ else if (ch == 'n' || ch == 'N') { object_prep(i_ptr, o_ptr->k_idx); apply_magic(i_ptr, p_ptr->depth, FALSE, FALSE, FALSE); } /* Apply good magic, but first clear object */ else if (ch == 'g' || ch == 'g') { object_prep(i_ptr, o_ptr->k_idx); apply_magic(i_ptr, p_ptr->depth, FALSE, TRUE, FALSE); } /* Apply great magic, but first clear object */ else if (ch == 'e' || ch == 'e') { object_prep(i_ptr, o_ptr->k_idx); apply_magic(i_ptr, p_ptr->depth, FALSE, TRUE, TRUE); } } /* Notice change */ if (changed) { /* Restore the position information */ i_ptr->iy = o_ptr->iy; i_ptr->ix = o_ptr->ix; i_ptr->next_o_idx = o_ptr->next_o_idx; i_ptr->marked = o_ptr->marked; /* Apply changes */ object_copy(o_ptr, i_ptr); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } }