/* * Checks for additional knowledge implied by what the player already knows. * * \param o_ptr is the object to check * * returns whether it calls object_notice_everyting */ bool object_check_for_ident(object_type *o_ptr) { bitflag flags[OF_SIZE], known_flags[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, known_flags); /* Some flags are irrelevant or never learned or too hard to learn */ flags_clear(flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); flags_clear(known_flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); if (!of_is_equal(flags, known_flags)) return FALSE; /* If we know attack bonuses, and defence bonuses, and effect, then * we effectively know everything, so mark as such */ if ((object_attack_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_h == 0 && o_ptr->to_d == 0)) && (object_defence_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_a == 0)) && (object_effect_is_known(o_ptr) || !object_effect(o_ptr))) { object_notice_everything(o_ptr); return TRUE; } /* We still know all the flags, so we still know if it's an ego */ else if (ego_item_p(o_ptr)) { /* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */ if (object_was_worn(o_ptr)) object_notice_ego(o_ptr); } return FALSE; }
/** * Clear the dungeon, ready for generation to begin. */ static void cave_clear(struct chunk *c, struct player *p) { int x, y; /* Clear the monsters */ wipe_mon_list(c, p); /* Deal with artifacts */ for (y = 0; y < c->height; y++) { for (x = 0; x < c->width; x++) { struct object *obj = square_object(c, y, x); while (obj) { if (obj->artifact) { if (!OPT(birth_no_preserve) && !object_was_sensed(obj)) obj->artifact->created = FALSE; else history_lose_artifact(obj->artifact); } obj = obj->next; } } } /* Free the chunk */ cave_free(c); }
static size_t obj_desc_combat(const object_type *o_ptr, char *buf, size_t max, size_t end, bool spoil) { bitflag flags[OF_SIZE]; bitflag flags_known[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, flags_known); if (of_has(flags, OF_SHOW_DICE)) { /* Only display the real damage dice if the combat stats are known */ if (spoil || object_attack_plusses_are_visible(o_ptr)) strnfcat(buf, max, &end, " (%dd%d)", o_ptr->dd, o_ptr->ds); else strnfcat(buf, max, &end, " (%dd%d)", o_ptr->kind->dd, o_ptr->kind->ds); } if (of_has(flags, OF_SHOW_MULT)) { /* Display shooting power as part of the multiplier */ if (of_has(flags, OF_MIGHT) && (spoil || object_flag_is_known(o_ptr, OF_MIGHT))) strnfcat(buf, max, &end, " (x%d)", (o_ptr->sval % 10) + o_ptr->pval[which_pval(o_ptr, OF_MIGHT)]); else strnfcat(buf, max, &end, " (x%d)", o_ptr->sval % 10); } /* Show weapon bonuses */ if (spoil || object_attack_plusses_are_visible(o_ptr)) { if (wield_slot(o_ptr) == INVEN_WIELD || wield_slot(o_ptr) == INVEN_BOW || obj_is_ammo(o_ptr) || o_ptr->to_d || o_ptr->to_h) { /* Make an exception for body armor with only a to-hit penalty */ if (o_ptr->to_h < 0 && o_ptr->to_d == 0 && (o_ptr->tval == TV_SOFT_ARMOR || o_ptr->tval == TV_HARD_ARMOR || o_ptr->tval == TV_DRAG_ARMOR)) strnfcat(buf, max, &end, " (%+d)", o_ptr->to_h); /* Otherwise, always use the full tuple */ else strnfcat(buf, max, &end, " (%+d,%+d)", o_ptr->to_h, o_ptr->to_d); } } /* Show armor bonuses */ if (spoil || object_defence_plusses_are_visible(o_ptr)) { if (obj_desc_show_armor(o_ptr)) strnfcat(buf, max, &end, " [%d,%+d]", o_ptr->ac, o_ptr->to_a); else if (o_ptr->to_a) strnfcat(buf, max, &end, " [%+d]", o_ptr->to_a); } else if (obj_desc_show_armor(o_ptr)) strnfcat(buf, max, &end, " [%d]", object_was_sensed(o_ptr) ? o_ptr->ac : o_ptr->kind->ac); return end; }
/** * Describe combat properties of an item - damage dice, to-hit, to-dam, armor * class, missile multipler */ static size_t obj_desc_combat(const struct object *obj, char *buf, size_t max, size_t end, bool spoil) { bitflag flags_known[OF_SIZE]; object_flags_known(obj, flags_known); if (kf_has(obj->kind->kind_flags, KF_SHOW_DICE)) { /* Only display the real damage dice if the combat stats are known */ if (spoil || object_attack_plusses_are_visible(obj)) strnfcat(buf, max, &end, " (%dd%d)", obj->dd, obj->ds); else strnfcat(buf, max, &end, " (%dd%d)", obj->kind->dd, obj->kind->ds); } if (kf_has(obj->kind->kind_flags, KF_SHOW_MULT)) { /* Display shooting power as part of the multiplier */ if ((obj->modifiers[OBJ_MOD_MIGHT] > 0) && (spoil || object_this_mod_is_visible(obj, OBJ_MOD_MIGHT))) strnfcat(buf, max, &end, " (x%d)", obj->pval + obj->modifiers[OBJ_MOD_MIGHT]); else strnfcat(buf, max, &end, " (x%d)", obj->pval); } /* Show weapon bonuses */ if (spoil || object_attack_plusses_are_visible(obj)) { if (tval_is_weapon(obj) || obj->to_d || obj->to_h) { /* Make an exception for body armor with only a to-hit penalty */ if (obj->to_h < 0 && obj->to_d == 0 && tval_is_body_armor(obj)) strnfcat(buf, max, &end, " (%+d)", obj->to_h); /* Otherwise, always use the full tuple */ else strnfcat(buf, max, &end, " (%+d,%+d)", obj->to_h, obj->to_d); } } /* Show armor bonuses */ if (spoil || object_defence_plusses_are_visible(obj)) { if (obj_desc_show_armor(obj)) strnfcat(buf, max, &end, " [%d,%+d]", obj->ac, obj->to_a); else if (obj->to_a) strnfcat(buf, max, &end, " [%+d]", obj->to_a); } else if (obj_desc_show_armor(obj)) strnfcat(buf, max, &end, " [%d]", object_was_sensed(obj) ? obj->ac : obj->kind->ac); 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; }
/* * Mark an object as sensed. */ void object_notice_sensing(object_type *o_ptr) { artifact_type *a_ptr = artifact_of(o_ptr); if (object_was_sensed(o_ptr)) return; if (a_ptr) { a_ptr->seen = a_ptr->everseen = TRUE; o_ptr->ident |= IDENT_NAME; } object_notice_curses(o_ptr); if (object_add_ident_flags(o_ptr, IDENT_SENSE)) object_check_for_ident(o_ptr); }
/** * Return the price of an item including plusses (and charges). * * This function returns the "value" of the given item (qty one). * * Never notice unknown bonuses or properties, including curses, * since that would give the player information they did not have. */ s32b object_value(const object_type *obj, int qty, int verbose) { s32b value; /* Known items use the actual value */ if (object_is_known(obj)) { if (cursed_p((bitflag *)obj->flags)) return (0L); value = object_value_real(obj, qty, verbose, TRUE); } else if (tval_has_variable_power(obj)) { /* Variable power items are assessed by what is known about them */ object_type object_type_body; object_type *j_ptr = &object_type_body; /* Hack -- Felt cursed items */ if (object_was_sensed(obj) && cursed_p((bitflag *)obj->flags)) return (0L); memcpy(j_ptr, obj, sizeof(object_type)); /* give j_ptr only the flags known to be in obj */ object_flags_known(obj, j_ptr->flags); if (!object_attack_plusses_are_visible(obj)) j_ptr->to_h = j_ptr->to_d = 0; if (!object_defence_plusses_are_visible(obj)) j_ptr->to_a = 0; value = object_value_real(j_ptr, qty, verbose, FALSE); } else /* Unknown constant-price items just get a base value */ value = object_value_base(obj) * qty; /* Return the final value */ return (value); }
/* * Determine the squelch level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ byte squelch_level_of(const object_type *o_ptr) { byte value; bitflag f[OF_SIZE], f2[OF_SIZE]; int i; object_flags_known(o_ptr, f); /* Deal with jewelry specially. */ if (object_is_jewelry(o_ptr)) { /* CC: average jewelry has at least one known positive pval */ for (i = 0; i < o_ptr->num_pvals; i++) if ((object_this_pval_is_visible(o_ptr, i)) && (o_ptr->pval[i] > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_AVERAGE; if ((object_attack_plusses_are_visible(o_ptr) && ((o_ptr->to_h < 0) || (o_ptr->to_d < 0))) || (object_defence_plusses_are_visible(o_ptr) && o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* And lights */ if (o_ptr->tval == TV_LIGHT) { create_mask(f2, TRUE, OFID_WIELD, OFT_MAX); if (of_is_inter(f, f2)) return SQUELCH_ALL; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_GOOD; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* CC: we need to redefine "bad" with multiple pvals * At the moment we use "all pvals known and negative" */ for (i = 0; i < o_ptr->num_pvals; i++) { if (!object_this_pval_is_visible(o_ptr, i) || (o_ptr->pval[i] > 0)) break; if (i == (o_ptr->num_pvals - 1)) return SQUELCH_BAD; } if (object_was_sensed(o_ptr)) { obj_pseudo_t pseudo = object_pseudo(o_ptr); switch (pseudo) { case INSCRIP_AVERAGE: { value = SQUELCH_AVERAGE; break; } case INSCRIP_EXCELLENT: { /* have to assume splendid until you have tested it */ if (object_was_worn(o_ptr)) { if (object_high_resist_is_possible(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; else value = SQUELCH_EXCELLENT_NO_HI; } else { value = SQUELCH_ALL; } break; } case INSCRIP_SPLENDID: value = SQUELCH_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = SQUELCH_MAX; break; /* This is the interesting case */ case INSCRIP_STRANGE: case INSCRIP_MAGICAL: { value = SQUELCH_GOOD; if ((object_attack_plusses_are_visible(o_ptr) || randcalc_valid(o_ptr->kind->to_h, o_ptr->to_h) || randcalc_valid(o_ptr->kind->to_d, o_ptr->to_d)) && (object_defence_plusses_are_visible(o_ptr) || randcalc_valid(o_ptr->kind->to_a, o_ptr->to_a))) { int isgood = is_object_good(o_ptr); if (isgood > 0) { value = SQUELCH_GOOD; } else if (isgood < 0) { value = SQUELCH_BAD; } else { value = SQUELCH_AVERAGE; } } break; } default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(o_ptr)) value = SQUELCH_ALL; else value = SQUELCH_MAX; } return value; }
void textui_cmd_ignore_menu(struct object *obj) { char out_val[160]; struct menu *m; region r; int selected; if (!obj) return; m = menu_dynamic_new(); m->selections = lower_case; /* Basic ignore option */ if (!obj->ignore) { menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM); } else { menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM); } /* Flavour-aware ignore */ if (ignore_tval(obj->tval) && (!obj->artifact || !object_flavor_is_aware(obj))) { bool ignored = kind_is_ignored_aware(obj->kind) || kind_is_ignored_unaware(obj->kind); char tmp[70]; object_desc(tmp, sizeof(tmp), obj, ODESC_BASE | ODESC_PLURAL); if (!ignored) { strnfmt(out_val, sizeof out_val, "All %s", tmp); menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp); menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR); } } /* Ego ignoring */ if (object_ego_is_visible(obj)) { ego_desc choice; struct ego_item *ego = obj->ego; char tmp[80] = ""; choice.e_idx = ego->eidx; choice.itype = ignore_type_of(obj); choice.short_name = ""; (void) ego_item_name(tmp, sizeof(tmp), &choice); if (!ego_is_ignored(choice.e_idx, choice.itype)) { strnfmt(out_val, sizeof out_val, "All %s", tmp + 4); menu_dynamic_add(m, out_val, IGNORE_THIS_EGO); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp + 4); menu_dynamic_add(m, out_val, UNIGNORE_THIS_EGO); } } /* Quality ignoring */ if (object_was_sensed(obj) || object_was_worn(obj) || object_is_known_not_artifact(obj)) { byte value = ignore_level_of(obj); int type = ignore_type_of(obj); if (tval_is_jewelry(obj) && ignore_level_of(obj) != IGNORE_BAD) value = IGNORE_MAX; if (value != IGNORE_MAX && type != ITYPE_MAX) { strnfmt(out_val, sizeof out_val, "All %s %s", quality_values[value].name, ignore_name_for_type(type)); menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY); } } /* Work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = 80 - r.width; r.row = 1; r.page_rows = m->count; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Ignore:", 0, 0); selected = menu_dynamic_select(m); screen_load(); if (selected == IGNORE_THIS_ITEM) { obj->ignore = TRUE; } else if (selected == UNIGNORE_THIS_ITEM) { obj->ignore = FALSE; } else if (selected == IGNORE_THIS_FLAVOR) { object_ignore_flavor_of(obj); } else if (selected == UNIGNORE_THIS_FLAVOR) { kind_ignore_clear(obj->kind); } else if (selected == IGNORE_THIS_EGO) { ego_ignore(obj); } else if (selected == UNIGNORE_THIS_EGO) { ego_ignore_clear(obj); } else if (selected == IGNORE_THIS_QUALITY) { byte value = ignore_level_of(obj); int type = ignore_type_of(obj); ignore_level[type] = value; } player->upkeep->notice |= PN_IGNORE; menu_dynamic_free(m); }
/** * Determine the ignore level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ byte ignore_level_of(const struct object *obj) { byte value = 0; bitflag f[OF_SIZE], f2[OF_SIZE]; int i; bool negative_mod = FALSE; object_flags_known(obj, f); /* Deal with jewelry specially. */ if (tval_is_jewelry(obj)) { /* CC: average jewelry has at least one known positive modifier */ for (i = 0; i < OBJ_MOD_MAX; i++) if ((object_this_mod_is_visible(obj, i)) && (obj->modifiers[i] > 0)) return IGNORE_AVERAGE; if ((obj->to_h > 0) || (obj->to_d > 0) || (obj->to_a > 0)) return IGNORE_AVERAGE; if ((object_attack_plusses_are_visible(obj) && ((obj->to_h < 0) || (obj->to_d < 0))) || (object_defence_plusses_are_visible(obj) && obj->to_a < 0)) return IGNORE_BAD; return IGNORE_AVERAGE; } /* And lights */ if (tval_is_light(obj)) { create_mask(f2, TRUE, OFID_WIELD, OFT_MAX); if (of_is_inter(f, f2)) return IGNORE_ALL; if ((obj->to_h > 0) || (obj->to_d > 0) || (obj->to_a > 0)) return IGNORE_GOOD; if ((obj->to_h < 0) || (obj->to_d < 0) || (obj->to_a < 0)) return IGNORE_BAD; return IGNORE_AVERAGE; } /* We need to redefine "bad" * At the moment we use "all modifiers known and negative" */ for (i = 0; i < OBJ_MOD_MAX; i++) { if (!object_this_mod_is_visible(obj, i) || (obj->modifiers[i] > 0)) break; if (obj->modifiers[i] < 0) negative_mod = TRUE; } if ((i == OBJ_MOD_MAX) && negative_mod) return IGNORE_BAD; if (object_was_sensed(obj)) { obj_pseudo_t pseudo = object_pseudo(obj); switch (pseudo) { case INSCRIP_AVERAGE: { value = IGNORE_AVERAGE; break; } case INSCRIP_EXCELLENT: { /* have to assume splendid until you have tested it */ if (object_was_worn(obj)) { if (object_high_resist_is_possible(obj)) value = IGNORE_EXCELLENT_NO_SPL; else value = IGNORE_EXCELLENT_NO_HI; } else { value = IGNORE_ALL; } break; } case INSCRIP_SPLENDID: value = IGNORE_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = IGNORE_MAX; break; /* This is the interesting case */ case INSCRIP_STRANGE: case INSCRIP_MAGICAL: { value = IGNORE_GOOD; if ((object_attack_plusses_are_visible(obj) || randcalc_valid(obj->kind->to_h, obj->to_h) || randcalc_valid(obj->kind->to_d, obj->to_d)) && (object_defence_plusses_are_visible(obj) || randcalc_valid(obj->kind->to_a, obj->to_a))) { int isgood = is_object_good(obj); if (isgood > 0) { value = IGNORE_GOOD; } else if (isgood < 0) { value = IGNORE_BAD; } else { value = IGNORE_AVERAGE; } } break; } default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(obj)) value = IGNORE_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(obj)) value = IGNORE_ALL; else value = IGNORE_MAX; } return value; }
/** * Deletes a monster by index. * * When a monster is deleted, all of its objects are deleted. */ void delete_monster_idx(int m_idx) { int x, y; s16b this_o_idx, next_o_idx = 0; monster_type *m_ptr; assert(m_idx > 0); m_ptr = cave_monster(cave, m_idx); /* Monster location */ y = m_ptr->fy; x = m_ptr->fx; /* Hack -- Reduce the racial counter */ m_ptr->race->cur_num--; /* Hack -- count the number of "reproducers" */ if (rf_has(m_ptr->race->flags, RF_MULTIPLY)) num_repro--; /* Hack -- remove target monster */ if (target_get_monster() == m_ptr) target_set_monster(NULL); /* Hack -- remove tracked monster */ if (p_ptr->health_who == m_ptr) health_track(p_ptr, NULL); /* Monster is gone */ cave->m_idx[y][x] = 0; /* Delete objects */ for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Get the object */ o_ptr = object_byid(this_o_idx); /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /* Preserve unseen artifacts (we assume they were created as this * monster's drop) - this will cause unintended behaviour in preserve * off mode if monsters can pick up artifacts */ if (o_ptr->artifact && !object_was_sensed(o_ptr)) o_ptr->artifact->created = FALSE; /* Clear held_m_idx now to avoid wasting time in delete_object_idx */ o_ptr->held_m_idx = 0; /* Delete the object */ delete_object_idx(this_o_idx); } /* Delete mimicked objects */ if (m_ptr->mimicked_o_idx > 0) delete_object_idx(m_ptr->mimicked_o_idx); /* Wipe the Monster */ (void)WIPE(m_ptr, monster_type); /* Count monsters */ cave->mon_cnt--; /* Visual update */ cave_light_spot(cave, y, x); }
/* * Sense the inventory */ void sense_inventory(void) { int i; char o_name[80]; unsigned int rate; /* No ID when confused in a bad state */ if (p_ptr->timed[TMD_CONFUSED]) return; /* Notice some things after a while */ if (turn >= (object_last_wield + 3000)) { object_notice_after_time(); object_last_wield = 0; } /* Get improvement rate */ if (player_has(PF_PSEUDO_ID_IMPROV)) rate = cp_ptr->sense_base / (p_ptr->lev * p_ptr->lev + cp_ptr->sense_div); else rate = cp_ptr->sense_base / (p_ptr->lev + cp_ptr->sense_div); if (!one_in_(rate)) return; /* Check everything */ for (i = 0; i < ALL_INVEN_TOTAL; i++) { const char *text = NULL; object_type *o_ptr = &p_ptr->inventory[i]; obj_pseudo_t feel; bool cursed; bool okay = FALSE; /* Skip empty slots */ if (!o_ptr->k_idx) continue; /* Valid "tval" codes */ switch (o_ptr->tval) { case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW: case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN: case TV_SHIELD: case TV_CLOAK: case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR: { okay = TRUE; break; } } /* Skip non-sense machines */ if (!okay) continue; /* It is known, no information needed */ if (object_is_known(o_ptr)) continue; /* It has already been sensed, do not sense it again */ if (object_was_sensed(o_ptr)) { /* Small chance of wielded, sensed items getting complete ID */ if (!o_ptr->name1 && (i >= INVEN_WIELD) && one_in_(1000)) do_ident_item(i, o_ptr); continue; } /* Occasional failure on inventory items */ if ((i < INVEN_WIELD) && one_in_(5)) continue; /* Sense the object */ object_notice_sensing(o_ptr); cursed = object_notice_curses(o_ptr); /* Get the feeling */ feel = object_pseudo(o_ptr); /* Stop everything */ disturb(0, 0); if (cursed) text = "cursed"; else text = inscrip_text[feel]; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); /* Average pseudo-ID means full ID */ if (feel == INSCRIP_AVERAGE) { object_notice_everything(o_ptr); message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) %s %s average...", o_name, index_to_label(i),((i >= INVEN_WIELD) ? "you are using" : "in your pack"), ((o_ptr->number == 1) ? "is" : "are")); } else { if (i >= INVEN_WIELD) { message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) you are %s %s %s...", o_name, index_to_label(i), describe_use(i), ((o_ptr->number == 1) ? "is" : "are"), text); } else { message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) in your pack %s %s...", o_name, index_to_label(i), ((o_ptr->number == 1) ? "is" : "are"), text); } } /* Set squelch flag as appropriate */ if (i < INVEN_WIELD) p_ptr->notice |= PN_SQUELCH; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER); /* Redraw stuff */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); } }
/* * Given an object, return a short identifier which gives some idea of what * the item is. */ obj_pseudo_t object_pseudo(const object_type *o_ptr) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bitflag flags[OF_SIZE]; /* Get the known and obvious flags on the object, * not including curses or properties of the kind */ object_flags_known(o_ptr, flags); /* MEGA-hack : there needs to be a table of what is obvious in each slot perhaps for each class */ /* FA on gloves is obvious to mage casters */ if (object_FA_would_be_obvious(o_ptr)) flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, OF_FREE_ACT, FLAG_END); else flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); flags_clear(flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_diff(flags, k_ptr->flags); if (o_ptr->ident & IDENT_INDESTRUCT) return INSCRIP_SPECIAL; if ((object_was_sensed(o_ptr) || object_was_worn(o_ptr)) && artifact_p(o_ptr)) return INSCRIP_SPECIAL; /* jewelry does not pseudo */ if (object_is_jewelry(o_ptr)) return INSCRIP_NULL; /* XXX Eddie should also check for flags with pvals where the pval exceeds * the base pval for things like picks of digging, though for now acid brand gets those */ if (!of_is_empty(flags)) return INSCRIP_SPLENDID; if (!object_is_known(o_ptr) && !object_was_sensed(o_ptr)) return INSCRIP_NULL; if (ego_item_p(o_ptr)) { /* uncursed bad egos are not excellent */ if (flags_test(e_info[o_ptr->name2].flags, OF_SIZE, OF_CURSE_MASK, FLAG_END)) return INSCRIP_STRANGE; /* XXX Eddie need something worse */ else return INSCRIP_EXCELLENT; } if (o_ptr->to_a == randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h == randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d == randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_AVERAGE; if (o_ptr->to_a >= randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h >= randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d >= randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_MAGICAL; if (o_ptr->to_a <= randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h <= randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d <= randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_MAGICAL; return INSCRIP_STRANGE; }
/* * Determine the squelch level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ static byte squelch_level_of(const object_type *o_ptr) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; byte value; bitflag f[OF_SIZE]; object_flags_known(o_ptr, f); if ((object_pval_is_visible(o_ptr)) && (o_ptr->pval < 0)) return SQUELCH_BAD; /* Deal with jewelry specially. */ if (object_is_jewelry(o_ptr)) { if ((object_pval_is_visible(o_ptr)) && (o_ptr->pval > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* And lights */ if (o_ptr->tval == TV_LIGHT) { if (flags_test(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END)) return SQUELCH_ALL; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_GOOD; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } if (object_was_sensed(o_ptr)) { obj_pseudo_t pseudo = object_pseudo(o_ptr); switch (pseudo) { case INSCRIP_AVERAGE: value = SQUELCH_AVERAGE; break; case INSCRIP_EXCELLENT: /* have to assume splendid until you have tested it */ if (object_was_worn(o_ptr)) { if (object_high_resist_is_possible(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; else value = SQUELCH_EXCELLENT_NO_HI; } else { value = SQUELCH_ALL; } break; case INSCRIP_STRANGE: /* XXX Eddie perhaps some strange count as something else */ case INSCRIP_SPLENDID: value = SQUELCH_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = SQUELCH_MAX; break; /* This is the interesting case */ case INSCRIP_MAGICAL: value = SQUELCH_GOOD; if ((object_attack_plusses_are_visible(o_ptr) || (randcalc_valid(k_ptr->to_h, o_ptr->to_h) && randcalc_valid(k_ptr->to_d, o_ptr->to_d))) && (object_defence_plusses_are_visible(o_ptr) || (randcalc_valid(k_ptr->to_a, o_ptr->to_a))) && (o_ptr->to_h <= randcalc(k_ptr->to_h, 0, MINIMISE)) && (o_ptr->to_d <= randcalc(k_ptr->to_d, 0, MINIMISE)) && (o_ptr->to_a <= randcalc(k_ptr->to_a, 0, MINIMISE))) value = SQUELCH_BAD; break; default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(o_ptr)) value = SQUELCH_ALL; else value = SQUELCH_MAX; } return value; }
/* * Output object information */ static textblock *object_info_out(const object_type *o_ptr, oinfo_detail_t mode) { bitflag flags[OF_SIZE]; bitflag pval_flags[MAX_PVALS][OF_SIZE]; bool something = FALSE; bool known = object_is_known(o_ptr); bool full = mode & OINFO_FULL; bool terse = mode & OINFO_TERSE; bool subjective = mode & OINFO_SUBJ; bool ego = mode & OINFO_EGO; textblock *tb = textblock_new(); /* Grab the object flags */ if (full) { object_flags(o_ptr, flags); object_pval_flags(o_ptr, pval_flags); } else { object_flags_known(o_ptr, flags); object_pval_flags_known(o_ptr, pval_flags); } if (subjective) describe_origin(tb, o_ptr); if (!terse) describe_flavor_text(tb, o_ptr); if (!full && !known) { textblock_append(tb, "You do not know the full extent of this item's powers.\n"); if (SENSING_REVEALS_FLAG_COUNT) { if (object_was_sensed(o_ptr)) { int unlearned = object_num_unlearned_flags(o_ptr); switch(unlearned) { case 0: textblock_append(tb, "It has no unknown flags.\n"); break; case 1: textblock_append(tb, "It has 1 unknown flag.\n", unlearned); break; default: textblock_append(tb, "It has %d unknown flags.\n", unlearned); break; } } } something = TRUE; } if (describe_curses(tb, o_ptr, flags)) something = TRUE; if (describe_stats(tb, o_ptr, pval_flags, mode)) something = TRUE; if (describe_slays(tb, flags, o_ptr->tval)) something = TRUE; if (describe_immune(tb, flags)) something = TRUE; if (describe_ignores(tb, flags)) something = TRUE; if (describe_sustains(tb, flags)) something = TRUE; if (describe_misc_magic(tb, flags)) something = TRUE; if (ego && describe_ego(tb, o_ptr->ego)) something = TRUE; if (something) textblock_append(tb, "\n"); if (describe_effect(tb, o_ptr, full, terse, subjective)) { something = TRUE; textblock_append(tb, "\n"); } if (subjective && describe_combat(tb, o_ptr, mode)) { something = TRUE; textblock_append(tb, "\n"); } if (!terse && describe_food(tb, o_ptr, subjective, full)) something = TRUE; if (describe_light(tb, o_ptr, flags, terse)) something = TRUE; if (!terse && subjective && describe_digger(tb, o_ptr, mode)) something = TRUE; if (!something) textblock_append(tb, "\n\nThis item does not seem to possess any special abilities."); return tb; }
/** * \returns whether the object is known to be an artifact */ bool object_is_known_artifact(const object_type *o_ptr) { return (o_ptr.ident & IDENT_INDESTRUCT) || (o_ptr.artifact && object_was_sensed(o_ptr)); }
void textui_cmd_destroy(void) { int item; object_type *o_ptr; char out_val[160]; menu_type *m; region r; int selected; /* Get an item */ const char *q = "Ignore which item? "; const char *s = "You have nothing to ignore."; if (!get_item(&item, q, s, CMD_DESTROY, USE_INVEN | USE_EQUIP | USE_FLOOR)) return; o_ptr = object_from_item_idx(item); m = menu_dynamic_new(); m->selections = lower_case; /* Basic ignore option */ if (!o_ptr->ignore) { menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM); } else { menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM); } /* Flavour-aware squelch */ if (squelch_tval(o_ptr->tval) && (!o_ptr->artifact || !object_flavor_is_aware(o_ptr))) { bool squelched = kind_is_squelched_aware(o_ptr->kind) || kind_is_squelched_unaware(o_ptr->kind); char tmp[70]; object_desc(tmp, sizeof(tmp), o_ptr, ODESC_BASE | ODESC_PLURAL); if (!squelched) { strnfmt(out_val, sizeof out_val, "All %s", tmp); menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp); menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR); } } /* Quality squelching */ 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); if (object_is_jewelry(o_ptr) && squelch_level_of(o_ptr) != SQUELCH_BAD) value = SQUELCH_MAX; if (value != SQUELCH_MAX && type != TYPE_MAX) { strnfmt(out_val, sizeof out_val, "All %s %s", quality_values[value].name, quality_choices[type].name); menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY); } } /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = 80 - r.width; r.row = 1; r.page_rows = m->count; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Ignore:", 0, 0); selected = menu_dynamic_select(m); screen_load(); if (selected == IGNORE_THIS_ITEM) { cmd_insert(CMD_DESTROY); cmd_set_arg_item(cmd_get_top(), 0, item); } else if (selected == UNIGNORE_THIS_ITEM) { o_ptr->ignore = FALSE; } else if (selected == IGNORE_THIS_FLAVOR) { object_squelch_flavor_of(o_ptr); } else if (selected == UNIGNORE_THIS_FLAVOR) { kind_squelch_clear(o_ptr->kind); } else if (selected == IGNORE_THIS_QUALITY) { byte value = squelch_level_of(o_ptr); int type = squelch_type_of(o_ptr); squelch_level[type] = value; } p_ptr->notice |= PN_SQUELCH; menu_dynamic_free(m); }