/** * Print an item's flavour text. * * \param tb is the textblock to which we are adding. * \param obj is the object we are describing. * \param ego is whether we're describing an ego template (as opposed to a * real object) */ static void describe_flavor_text(textblock *tb, const struct object *obj, bool ego) { /* Display the known artifact or object description */ if (!OPT(birth_randarts) && obj->artifact && object_is_known(obj) && obj->artifact->text) { textblock_append(tb, "%s\n\n", obj->artifact->text); } else if (object_flavor_is_aware(obj) || object_is_known(obj) || ego) { bool did_desc = false; if (!ego && obj->kind->text) { textblock_append(tb, "%s", obj->kind->text); did_desc = true; } /* Display an additional ego-item description */ if ((ego || object_ego_is_visible(obj)) && obj->ego->text) { if (did_desc) textblock_append(tb, " "); textblock_append(tb, "%s\n\n", obj->ego->text); } else if (did_desc) { textblock_append(tb, "\n\n"); } } }
static void describe_flavor_text(textblock *tb, const object_type *o_ptr) { /* Display the known artifact description */ if (!OPT(birth_randarts) && o_ptr->artifact && object_name_is_visible(o_ptr) && o_ptr->artifact->text) textblock_append(tb, "%s\n\n", o_ptr->artifact->text); /* Display the known object description */ else if (object_flavor_is_aware(o_ptr) || object_is_known(o_ptr)) { bool did_desc = FALSE; if (o_ptr->kind->text) { textblock_append(tb, "%s", o_ptr->kind->text); did_desc = TRUE; } /* Display an additional ego-item description */ if (object_ego_is_visible(o_ptr) && o_ptr->ego->text) { if (did_desc) textblock_append(tb, " "); textblock_append(tb, "%s\n\n", o_ptr->ego->text); } else if (did_desc) { textblock_append(tb, "\n\n"); } } }
/** * Describe stat modifications. */ static bool describe_stats(textblock *tb, const struct object *obj, oinfo_detail_t mode) { size_t count = 0, i; bool detail = false; /* Don't give exact plusses for faked ego items as each real one will * be different */ bool suppress_details = mode & OINFO_EGO ? true : false; /* Fact of but not size of mods is known for egos and flavoured items * the player is aware of */ bool known_effect = false; if (object_ego_is_visible(obj)) known_effect = true; if (tval_can_have_flavor_k(obj->kind) && object_flavor_is_aware(obj)) known_effect = true; /* See what we've got */ for (i = 0; i < N_ELEMENTS(mod_flags); i++) if (obj->modifiers[mod_flags[i].flag] != 0 && mod_flags[i].name[0]) { count++; /* Either all mods are visible, or none are */ if (object_this_mod_is_visible(obj, mod_flags[i].flag)) detail = true; } if (!count) return false; for (i = 0; i < N_ELEMENTS(mod_flags); i++) { const char *desc = mod_flags[i].name; int val = obj->modifiers[mod_flags[i].flag]; if (!val) continue; if (!mod_flags[i].name[0]) continue; if (detail && !suppress_details) { int attr = (val > 0) ? COLOUR_L_GREEN : COLOUR_RED; textblock_append_c(tb, attr, "%+i %s.\n", val, desc); } else if (known_effect) textblock_append(tb, "Affects your %s\n", desc); } return true; }
/** * Format object obj's name into 'buf'. */ static size_t obj_desc_name(char *buf, size_t max, size_t end, const struct object *obj, bool prefix, int mode, bool spoil, bool terse) { bool known = object_is_known(obj) || spoil; bool aware = object_flavor_is_aware(obj) || (mode & ODESC_STORE) || spoil; const char *basename = obj_desc_get_basename(obj, aware, terse, mode); const char *modstr = obj_desc_get_modstr(obj->kind); if (aware && !obj->kind->everseen && !spoil) obj->kind->everseen = TRUE; if (prefix) end = obj_desc_name_prefix(buf, max, end, obj, known, basename, modstr, terse); /* Pluralize if (not forced singular) and * (not a known/visible artifact) and * (not one in stack or forced plural) */ end = obj_desc_name_format(buf, max, end, basename, modstr, !(mode & ODESC_SINGULAR) && !(obj->artifact && (object_name_is_visible(obj) || known)) && (obj->number != 1 || (mode & ODESC_PLURAL))); /** Append extra names of various kinds **/ if ((object_name_is_visible(obj) || known) && obj->artifact) strnfcat(buf, max, &end, " %s", obj->artifact->name); else if (((spoil && obj->ego) || object_ego_is_visible(obj)) && !(mode & ODESC_NOEGO)) strnfcat(buf, max, &end, " %s", obj->ego->name); else if (aware && !obj->artifact && (obj->kind->flavor || obj->kind->tval == TV_SCROLL)) { if (terse) strnfcat(buf, max, &end, " '%s'", obj->kind->name); else strnfcat(buf, max, &end, " of %s", obj->kind->name); } return end; }
/** * Determines if an object is already ignored. */ bool object_is_ignored(const struct object *obj) { byte type; /* Objects that aren't yet known can't be ignored */ if (!obj->known) return false; /* Do ignore individual objects that marked ignore */ if (obj->known->notice & OBJ_NOTICE_IGNORE) return true; /* Don't ignore artifacts unless marked to be ignored */ if (obj->artifact || check_for_inscrip(obj, "!k") || check_for_inscrip(obj, "!*")) return false; /* Do ignoring by kind */ if (object_flavor_is_aware(obj) ? kind_is_ignored_aware(obj->kind) : kind_is_ignored_unaware(obj->kind)) return true; /* Ignore ego items if known */ if (object_ego_is_visible(obj) && ego_is_ignored(obj->ego->eidx, ignore_type_of(obj))) return true; type = ignore_type_of(obj); if (type == ITYPE_MAX) return false; /* Ignore items known not to be special */ if (object_is_known_not_artifact(obj) && ignore_level[type] == IGNORE_ALL) return true; /* Get result based on the feeling and the ignore_level */ if (ignore_level_of(obj) <= ignore_level[type]) return true; else return false; }
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); }
/* * 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, odesc_detail_t 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 (aware && !k_ptr->everseen) k_ptr->everseen = TRUE; 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 ((object_name_is_visible(o_ptr) || 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 "); } } /* * 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 ((object_name_is_visible(o_ptr) || known) && o_ptr->name1) strnfcat(buf, max, &end, " %s", a_name + a_info[o_ptr->name1].name); else if ((spoil && o_ptr->name2) || object_ego_is_visible(o_ptr)) strnfcat(buf, max, &end, " %s", e_name + e_info[o_ptr->name2].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; }