/** * Given an array of strings, as so: * { "intelligence", "fish", "lens", "prime", "number" }, * * ... output a list like "intelligence, fish, lens, prime, number.\n". */ static void info_out_list(textblock *tb, const char *list[], size_t count) { size_t i; for (i = 0; i < count; i++) { textblock_append(tb, list[i]); if (i != (count - 1)) textblock_append(tb, ", "); } textblock_append(tb, ".\n"); }
/* * Describe immunities granted by an object. */ static bool describe_immune(textblock *tb, const bitflag flags[OF_SIZE]) { const char *i_descs[N_ELEMENTS(immunity_flags)]; const char *r_descs[N_ELEMENTS(resist_flags)]; const char *p_descs[N_ELEMENTS(protect_flags)]; const char *v_descs[N_ELEMENTS(vuln_flags)]; size_t count; bool prev = FALSE; /* Immunities */ count = info_collect(tb, immunity_flags, N_ELEMENTS(immunity_flags), flags, i_descs); if (count) { textblock_append(tb, "Provides immunity to "); info_out_list(tb, i_descs, count); prev = TRUE; } /* Resistances */ count = info_collect(tb, resist_flags, N_ELEMENTS(resist_flags), flags, r_descs); if (count) { textblock_append(tb, "Provides resistance to "); info_out_list(tb, r_descs, count); prev = TRUE; } /* Protections */ count = info_collect(tb, protect_flags, N_ELEMENTS(protect_flags), flags, p_descs); if (count) { textblock_append(tb, "Provides protection from "); info_out_list(tb, p_descs, count); prev = TRUE; } /* Vulnerabilities */ count = info_collect(tb, vuln_flags, N_ELEMENTS(vuln_flags), flags, v_descs); if (count) { textblock_append(tb, "Makes you vulnerable to "); info_out_list(tb, v_descs, count); prev = TRUE; } return prev; }
/** * Describe random properties that an ego item may have */ static bool describe_ego(textblock *tb, const struct ego_item *ego) { if (kf_has(ego->kind_flags, KF_RAND_HI_RES)) textblock_append(tb, "It provides one random higher resistance. "); else if (kf_has(ego->kind_flags, KF_RAND_SUSTAIN)) textblock_append(tb, "It provides one random sustain. "); else if (kf_has(ego->kind_flags, KF_RAND_POWER)) textblock_append(tb, "It provides one random ability. "); else if (kf_has(ego->kind_flags, KF_RAND_RES_POWER)) textblock_append(tb, "It provides one random ability or base resistance. "); else return false; return true; }
bool describe_set(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { bool full = mode & OINFO_FULL; if (!full && !object_known_p(o_ptr)) return FALSE; if (!o_ptr->name1) return FALSE; else { artifact_type *a_ptr = &a_info[o_ptr->name1]; /* Is it a set item? */ if (a_ptr->set_no) { set_type *set_ptr = &set_info[a_ptr->set_no]; /* Description */ textblock_append(tb, "\n"); textblock_append_c(tb, TERM_BLUE, set_ptr->text); /* End sentence */ textblock_append_c(tb, TERM_BLUE, "."); } else return FALSE; } return TRUE; }
/* * Output object information */ static textblock *object_info_out(const object_type *o_ptr, oinfo_detail_t mode) { bool something = FALSE; bool full = mode & OINFO_FULL; bool terse = mode & OINFO_TERSE; bool subjective = mode & OINFO_SUBJ; bool ego = mode & OINFO_EGO; bool dummy = mode & OINFO_DUMMY; textblock *tb = textblock_new(); if (subjective) describe_origin(tb, o_ptr); if (!terse) describe_flavor_text(tb, o_ptr); if (describe_set(tb, o_ptr, mode)) something = TRUE; if (describe_stats(tb, o_ptr, mode)) something = TRUE; if (describe_bonus(tb, o_ptr, mode)) something = TRUE; if (describe_slays(tb, o_ptr, mode)) something = TRUE; if (describe_brands(tb, o_ptr, mode)) something = TRUE; if (describe_immune(tb, o_ptr, mode)) something = TRUE; if (describe_sustains(tb, o_ptr, mode)) something = TRUE; if (describe_misc_magic(tb, o_ptr, mode)) something = TRUE; if (ego && describe_ego(tb, o_ptr)) something = TRUE; if (describe_ignores(tb, o_ptr, mode)) something = TRUE; if (describe_curses(tb, o_ptr, mode)) something = TRUE; if (describe_effect(tb, o_ptr, mode)) something = TRUE; 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, terse)) something = TRUE; if (!terse && subjective && describe_digger(tb, o_ptr, mode)) something = TRUE; //if (!something) // textblock_append(tb, "\n"); if (!terse && !dummy) { textblock_append(tb, "\n"); textblock_append(tb, obj_class_info[o_ptr->tval]); textblock_append(tb, "\n"); } return tb; }
/** * Describe an item's origin */ static bool describe_origin(textblock *tb, const struct object *obj, bool terse) { char loot_spot[80]; char name[80]; const char *droppee; const char *article; /* Only give this info in chardumps if wieldable */ if (terse && !obj_can_wear(obj)) return FALSE; /* Name the place of origin */ if (obj->origin_depth) strnfmt(loot_spot, sizeof(loot_spot), "at %d feet (level %d)", obj->origin_depth * 50, obj->origin_depth); else my_strcpy(loot_spot, "in town", sizeof(loot_spot)); /* Name the monster of origin */ if (r_info[obj->origin_xtra].ridx) droppee = r_info[obj->origin_xtra].name; else droppee = "monster lost to history"; article = is_a_vowel(droppee[0]) ? "an " : "a "; if (rf_has(r_info[obj->origin_xtra].flags, RF_UNIQUE)) my_strcpy(name, droppee, sizeof(name)); else { my_strcpy(name, article, sizeof(name)); my_strcat(name, droppee, sizeof(name)); } /* Print an appropriate description */ switch (origins[obj->origin].args) { case -1: return FALSE; case 0: textblock_append(tb, origins[obj->origin].desc); break; case 1: textblock_append(tb, origins[obj->origin].desc, loot_spot); break; case 2: textblock_append(tb, origins[obj->origin].desc, name, loot_spot); break; } textblock_append(tb, "\n\n"); return TRUE; }
/** * Describe combat advantages. */ static bool describe_combat(textblock *tb, const struct object *obj) { struct object *bow = equipped_item_by_slot_name(player, "shooting"); bool weapon = tval_is_melee_weapon(obj); bool ammo = (player->state.ammo_tval == obj->tval) && (bow); int range, break_chance; bool impactful, thrown_effect, too_heavy; obj_known_misc_combat(obj, &thrown_effect, &range, &impactful, &break_chance, &too_heavy); if (!weapon && !ammo) { if (thrown_effect) { textblock_append(tb, "It can be thrown at creatures with damaging effect.\n"); return true; } else return false; } textblock_append_c(tb, COLOUR_L_WHITE, "Combat info:\n"); if (too_heavy) textblock_append_c(tb, COLOUR_L_RED, "You are too weak to use this weapon.\n"); describe_blows(tb, obj); if (!weapon) { /* Ammo */ textblock_append(tb, "Hits targets up to "); textblock_append_c(tb, COLOUR_L_GREEN, format("%d", range)); textblock_append(tb, " feet away.\n"); } describe_damage(tb, obj); if (impactful) textblock_append(tb, "Sometimes creates earthquakes on impact.\n"); if (ammo) { textblock_append_c(tb, COLOUR_L_GREEN, "%d%%", break_chance); textblock_append(tb, " chance of breaking upon contact.\n"); } /* Something has been said */ return true; }
/* * Describe stat modifications. */ static bool describe_stats(textblock *tb, const object_type *o_ptr, bitflag flags[MAX_PVALS][OF_SIZE], oinfo_detail_t mode) { const char *descs[N_ELEMENTS(pval_flags)]; size_t count, i; bool full = mode & OINFO_FULL; bool dummy = mode & OINFO_DUMMY; bool search = FALSE; if (!o_ptr->num_pvals && !dummy) return FALSE; for (i = 0; i < o_ptr->num_pvals; i++) { count = info_collect(tb, pval_flags, N_ELEMENTS(pval_flags), flags[i], descs); if (count) { if ((object_this_pval_is_visible(o_ptr, i) || full) && !dummy) textblock_append_c(tb, (o_ptr->pval[i] > 0) ? TERM_L_GREEN : TERM_RED, "%+i ", o_ptr->pval[i]); else textblock_append(tb, "Affects your "); info_out_list(tb, descs, count); } if (of_has(flags[i], OF_SEARCH)) search = TRUE; } if (search) { if ((object_this_pval_is_visible(o_ptr, which_pval(o_ptr, OF_SEARCH)) || full) && !dummy) { textblock_append_c(tb, (o_ptr->pval[which_pval(o_ptr, OF_SEARCH)] > 0) ? TERM_L_GREEN : TERM_RED, "%+i%% ", o_ptr->pval[which_pval(o_ptr, OF_SEARCH)] * 5); textblock_append(tb, "to searching.\n"); } else if (count) textblock_append(tb, "Also affects your searching skill.\n"); else textblock_append(tb, "Affects your searching skill.\n"); } return TRUE; }
/** * Describe immunities, resistances and vulnerabilities granted by an object. */ static bool describe_elements(textblock *tb, const struct element_info el_info[]) { const char *i_descs[N_ELEMENTS(elements)]; const char *r_descs[N_ELEMENTS(elements)]; const char *v_descs[N_ELEMENTS(elements)]; size_t i, count; bool list[N_ELEMENTS(elements)], prev = FALSE; /* Immunities */ for (i = 0; i < N_ELEMENTS(elements); i++) list[i] = (el_info[i].res_level == 3); count = element_info_collect(list, i_descs); if (count) { textblock_append(tb, "Provides immunity to "); info_out_list(tb, i_descs, count); prev = TRUE; } /* Resistances */ for (i = 0; i < N_ELEMENTS(elements); i++) list[i] = (el_info[i].res_level == 1); count = element_info_collect(list, r_descs); if (count) { textblock_append(tb, "Provides resistance to "); info_out_list(tb, r_descs, count); prev = TRUE; } /* Vulnerabilities */ for (i = 0; i < N_ELEMENTS(elements); i++) list[i] = (el_info[i].res_level == -1); count = element_info_collect(list, v_descs); if (count) { textblock_append(tb, "Makes you vulnerable to "); info_out_list(tb, v_descs, count); prev = TRUE; } return prev; }
/** * Display the damage done with a multiplier */ static void output_dam(textblock * tb, player_state * state, const object_type * o_ptr, int mult, const char *against, bool * first, oinfo_detail_t mode) { int dam, die_average, add = 0, i, deadliness, crit, chance; bool full = mode & OINFO_FULL; /* Average damage for one standard side (x10) */ die_average = (10 * (o_ptr->ds + 1)) / 2; /* Multiply by slay or brand (x10) */ die_average *= mult; /* Record the addend */ if (mult > MULTIPLE_BASE) add = (mult - MULTIPLE_BASE); /* Multiply by deadliness (x100) */ deadliness = state->dis_to_d; if (if_has(o_ptr->id_other, IF_TO_D) || full) deadliness += o_ptr->to_d; if (deadliness > 150) deadliness = 150; if (deadliness < -150) deadliness = -150; if (deadliness >= 0) die_average *= (100 + deadliness_conversion[deadliness]); else { i = deadliness_conversion[ABS(deadliness)]; if (i >= 100) die_average = 0; else die_average *= (100 - i); } /* Factor in criticals (x 10) */ chance = state->skills[SKILL_TO_HIT_MELEE] + state->dis_to_h; if (object_known_p(o_ptr)) chance += o_ptr->to_h; chance = (100 * chance) / (chance + 240); if (player_has(PF_ARMSMAN)) chance = 100 - (83 * (100 - chance)) / 100; crit = 259 * chance; crit /= 1000; /* Multiply by number of sides */ dam = die_average * (o_ptr->dd * 10 + crit); CHECK_FIRST("", *first); if ((dam > 50000) || (add > 0)) textblock_append_c(tb, TERM_L_GREEN, "%d", add + dam / 100000); else textblock_append_c(tb, TERM_L_RED, "0"); textblock_append(tb, " against %s", against); }
/* * Describe miscellaneous powers. */ static bool describe_misc_magic(textblock *tb, const bitflag flags[OF_SIZE]) { size_t i; bool printed = FALSE; for (i = 0; i < N_ELEMENTS(misc_flags); i++) { if (of_has(flags, misc_flags[i].flag)) { textblock_append(tb, "%s. ", misc_flags[i].name); printed = TRUE; } } if (printed) textblock_append(tb, "\n"); return printed; }
/** * Describe miscellaneous powers. */ static bool describe_misc_magic(textblock *tb, const bitflag flags[OF_SIZE]) { int i; bool printed = false; for (i = 1; i < OF_MAX; i++) { struct obj_property *prop = lookup_obj_property(OBJ_PROPERTY_FLAG, i); if ((prop->subtype != OFT_MISC) && (prop->subtype != OFT_MELEE) && (prop->subtype != OFT_BAD)) continue; if (of_has(flags, prop->index)) { textblock_append(tb, "%s. ", prop->desc); printed = true; } } if (printed) textblock_append(tb, "\n"); return printed; }
/* * Describe stat modifications. */ static bool describe_stats(textblock *tb, const object_type *o_ptr, oinfo_detail_t mode) { int j, min = 0, max = 0, count = 0; bool full = mode & OINFO_FULL; bool dummy = mode & OINFO_DUMMY; bool terse = mode & OINFO_TERSE; if (((o_ptr->ident) & IDENT_WORN) || dummy || full) { for (j = 0; j < A_MAX; j++) { if (o_ptr->bonus_stat[j] != 0) count++; if (o_ptr->bonus_stat[j] < min) min = o_ptr->bonus_stat[j]; if (o_ptr->bonus_stat[j] > max) max = o_ptr->bonus_stat[j]; } } if (count > 0) { byte attr = (o_ptr->bonus_stat[A_STR] > 0 ? TERM_L_GREEN : TERM_ORANGE); if (!terse) { textblock_append(tb, "It gives "); if (dummy) textblock_append(tb, "up to "); } /* Special case: all stats */ if (min == max) textblock_append_c(tb, attr, "%d to all your stats.", min); /* Some stats */ else { for (j = 0; j < A_MAX; j++) { if (o_ptr->bonus_stat[j] == 0) continue; attr = (o_ptr->bonus_stat[j] > 0 ? TERM_L_GREEN : TERM_ORANGE); textblock_append_c(tb, attr, "%d ", o_ptr->bonus_stat[j]); if (!terse) textblock_append(tb, "to your "); textblock_append_c(tb, attr, statname[j]); if (count >= (terse ? 2 : 3)) textblock_append(tb, ", "); if ((count == 2) && !terse) textblock_append(tb, " and "); if (count == 1) textblock_append(tb, ". "); count--; } } textblock_append(tb, "\n"); return TRUE; } return FALSE; }
/* * Describe stat sustains. */ static bool describe_sustains(textblock *tb, const object_type *o_ptr, oinfo_detail_t mode) { bool full = mode & OINFO_FULL; const char *descs[N_ELEMENTS(sustain_flags)]; size_t count = info_collect(sustain_flags, N_ELEMENTS(sustain_flags), full ? o_ptr->flags_obj : o_ptr->id_obj, descs); if (!count) return FALSE; if (count == 6) textblock_append(tb, "It sustains all your stats. "); else { textblock_append(tb, "Sustains "); info_out_list(tb, descs, count); } return TRUE; }
/** * Describe an item's curses. */ static bool describe_curses(textblock *tb, const struct object *obj, const bitflag flags[OF_SIZE]) { int i; struct curse_data *c = obj->known->curses; if (!c) return false; for (i = 1; i < z_info->curse_max; i++) { if (c[i].power) { textblock_append(tb, "It "); textblock_append_c(tb, COLOUR_L_RED, curses[i].desc); if (c[i].power == 100) { textblock_append(tb, "; this curse cannot be removed"); } textblock_append(tb, ".\n"); } } return true; }
/** * Describe slays and brands on weapons */ static bool describe_brands(textblock *tb, const struct object *obj) { struct brand *known_brands = brand_collect(obj, NULL, TRUE); struct brand *b; if (!known_brands) return FALSE; if (tval_is_weapon(obj) || tval_is_fuel(obj)) textblock_append(tb, "Branded with "); else textblock_append(tb, "It brands your melee attacks with "); b = known_brands; while (b) { if (b->multiplier < 3) textblock_append(tb, "weak "); textblock_append(tb, b->name); if (b->next) textblock_append(tb, ", "); else textblock_append(tb, ".\n"); b = b->next; } free_brand(known_brands); return TRUE; }
/** * Describe slays and brands on weapons */ static bool describe_slays(textblock *tb, const struct object *obj) { struct slay *known_slays = slay_collect(obj, NULL, TRUE); struct slay *s; if (!known_slays) return FALSE; if (tval_is_weapon(obj) || tval_is_fuel(obj)) textblock_append(tb, "Slays "); else textblock_append(tb, "It causes your melee attacks to slay "); s = known_slays; while (s) { textblock_append(tb, s->name); if (s->multiplier > 3) textblock_append(tb, " (powerfully)"); if (s->next) textblock_append(tb, ", "); else textblock_append(tb, ".\n"); s = s->next; } free_slay(known_slays); return TRUE; }
/** * Describe slays and brands on weapons */ static bool describe_brands(textblock *tb, const struct object *obj) { int i, count = 0; bool *b = obj->known->brands; if (!b) return false; if (tval_is_weapon(obj) || tval_is_fuel(obj)) textblock_append(tb, "Branded with "); else textblock_append(tb, "It brands your melee attacks with "); for (i = 1; i < z_info->brand_max; i++) { if (b[i]) { count++; } } assert(count >= 1); for (i = 1; i < z_info->brand_max; i++) { if (!b[i]) continue; if (brands[i].multiplier < 3) textblock_append(tb, "weak "); textblock_append(tb, brands[i].name); if (count > 1) textblock_append(tb, ", "); else textblock_append(tb, ".\n"); count--; } return true; }
/** * Describe slays and brands on weapons */ static bool describe_slays(textblock *tb, const struct object *obj) { int i, count = 0; bool *s = obj->known->slays; if (!s) return false; if (tval_is_weapon(obj) || tval_is_fuel(obj)) textblock_append(tb, "Slays "); else textblock_append(tb, "It causes your melee attacks to slay "); for (i = 1; i < z_info->slay_max; i++) { if (s[i]) { count++; } } assert(count >= 1); for (i = 1; i < z_info->slay_max; i++) { if (!s[i]) continue; textblock_append(tb, slays[i].name); if (slays[i].multiplier > 3) textblock_append(tb, " (powerfully)"); if (count > 1) textblock_append(tb, ", "); else textblock_append(tb, ".\n"); count--; } return true; }
/** * Describe things that look like lights. */ static bool describe_light(textblock *tb, const struct object *obj, oinfo_detail_t mode) { int rad = 0; bool uses_fuel = false; int refuel_turns = 0; bool terse = mode & OINFO_TERSE ? true : false; if (!obj_known_light(obj, mode, &rad, &uses_fuel, &refuel_turns)) return false; textblock_append(tb, "Radius "); textblock_append_c(tb, COLOUR_L_GREEN, format("%d", rad)); textblock_append(tb, " light."); if (tval_is_light(obj)) { if (!obj->artifact && !uses_fuel) textblock_append(tb, " No fuel required."); if (!terse) { if (refuel_turns) textblock_append(tb, " Refills other lanterns up to %d turns of fuel.", refuel_turns); else textblock_append(tb, " Cannot be refueled."); } } textblock_append(tb, "\n"); return true; }
static bool describe_ego(textblock *tb, const struct ego_item *ego) { if (ego && ego->xtra) { const char *xtra[] = { "sustain", "higher resistance", "ability" }; textblock_append(tb, "It provides one random %s. ", xtra[ego->xtra - 1]); return TRUE; } return FALSE; }
/* * Describe things that look like lights. */ static bool describe_light(textblock *tb, const object_type *o_ptr, const bitflag flags[OF_SIZE], oinfo_detail_t mode) { int rad = 0; bool artifact = o_ptr->artifact ? TRUE : FALSE; bool no_fuel = of_has(flags, OF_NO_FUEL) ? TRUE : FALSE; bool is_light = (o_ptr->tval == TV_LIGHT) ? TRUE : FALSE; bool terse = mode & OINFO_TERSE; if (!is_light && !of_has(flags, OF_LIGHT)) return FALSE; /* Work out radius */ if (of_has(flags, OF_LIGHT)) rad = o_ptr->pval[which_pval(o_ptr, OF_LIGHT)]; /* Describe here */ textblock_append(tb, "Radius "); textblock_append_c(tb, TERM_L_GREEN, format("%d", rad)); if (no_fuel && !artifact) textblock_append(tb, " light. No fuel required."); /* else if (is_light && o_ptr->sval == SV_LIGHT_TORCH) textblock_append(tb, " light, reduced when running out of fuel."); */ else textblock_append(tb, " light."); if (!terse && is_light && !no_fuel && o_ptr->sval != SV_LIGHT_TORCH) { 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; }
/* * Describe throwability. */ static bool describe_throws(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { bool terse = mode & OINFO_TERSE; if (of_has(o_ptr->flags_obj, OF_THROWING)) { if (of_has(o_ptr->id_obj, OF_PERFECT_BALANCE)) { if (terse) textblock_append(tb, "Well-balanced.\n"); else textblock_append(tb, "It can be thrown hard and fast.\n"); } else { if (terse) textblock_append(tb, "Throwable.\n"); else textblock_append(tb, "It can be thrown effectively.\n"); } return TRUE; } return FALSE; }
/* * Describe slays and brands on weapons */ static bool describe_slays(textblock *tb, const bitflag flags[OF_SIZE], int tval) { bool printed = FALSE; const char *slay_descs[SL_MAX] = { 0 }; bitflag slay_mask[OF_SIZE], kill_mask[OF_SIZE], brand_mask[OF_SIZE]; size_t count; bool fulldesc; create_mask(slay_mask, FALSE, OFT_SLAY, OFT_MAX); create_mask(kill_mask, FALSE, OFT_KILL, OFT_MAX); create_mask(brand_mask, FALSE, OFT_BRAND, OFT_MAX); if (tval == TV_SWORD || tval == TV_HAFTED || tval == TV_POLEARM || tval == TV_DIGGING || tval == TV_BOW || tval == TV_SHOT || tval == TV_ARROW || tval == TV_BOLT || tval == TV_FLASK) fulldesc = FALSE; else fulldesc = TRUE; /* Slays */ count = list_slays(flags, slay_mask, slay_descs, NULL, NULL, TRUE); if (count) { if (fulldesc) textblock_append(tb, "It causes your melee attacks to slay "); else textblock_append(tb, "Slays "); info_out_list(tb, slay_descs, count); printed = TRUE; } /* Kills */ count = list_slays(flags, kill_mask, slay_descs, NULL, NULL, TRUE); if (count) { if (fulldesc) textblock_append(tb, "It causes your melee attacks to *slay* "); else textblock_append(tb, "*Slays* "); info_out_list(tb, slay_descs, count); printed = TRUE; } /* Brands */ count = list_slays(flags, brand_mask, NULL, slay_descs, NULL, TRUE); if (count) { if (fulldesc) textblock_append(tb, "It brands your melee attacks with "); else textblock_append(tb, "Branded with "); info_out_list(tb, slay_descs, count); printed = TRUE; } return printed; }
/* * Describe stat sustains. */ static bool describe_sustains(textblock *tb, const bitflag flags[OF_SIZE]) { const char *descs[N_ELEMENTS(sustain_flags)]; size_t count = info_collect(tb, sustain_flags, N_ELEMENTS(sustain_flags), flags, descs); if (!count) return FALSE; textblock_append(tb, "Sustains "); info_out_list(tb, descs, count); return TRUE; }
/* * Describe 'ignores' of an object. */ static bool describe_ignores(textblock *tb, const bitflag flags[OF_SIZE]) { const char *descs[N_ELEMENTS(ignore_flags)]; size_t count = info_collect(tb, ignore_flags, N_ELEMENTS(ignore_flags), flags, descs); if (!count) return FALSE; textblock_append(tb, "Cannot be harmed by "); info_out_list(tb, descs, count); return TRUE; }
/* * Describe things that look like lights. */ static bool describe_light(textblock *tb, const object_type *o_ptr, const bitflag flags[OF_SIZE], oinfo_detail_t mode) { bool artifact = o_ptr->artifact ? TRUE : FALSE; bool no_fuel = of_has(flags, OF_NO_FUEL) ? TRUE : FALSE; bool is_light = (o_ptr->tval == TV_LIGHT) ? TRUE : FALSE; bool terse = mode & OINFO_TERSE; if (no_fuel && !artifact) textblock_append(tb, "No fuel required. "); if (!terse && is_light && !no_fuel && o_ptr->sval != SV_LIGHT_TORCH) { 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; }
/** * Describes a food item */ static bool describe_food(textblock *tb, const struct object *obj, bool subjective) { int nourishment = obj_known_food(obj); if (nourishment) { /* Sometimes adjust for player speed */ int multiplier = turn_energy(player->state.speed); if (!subjective) multiplier = 10; if (nourishment == OBJ_KNOWN_PRESENT) { textblock_append(tb, "Provides some nourishment.\n"); } else { textblock_append(tb, "Nourishes for around "); textblock_append_c(tb, COLOUR_L_GREEN, "%d", nourishment * multiplier / 10); textblock_append(tb, " turns.\n"); } return TRUE; } return FALSE; }
/* * Describe other bonuses. */ static bool describe_bonus(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { int j, count = 0; bool full = mode & OINFO_FULL; bool dummy = mode & OINFO_DUMMY; bool terse = mode & OINFO_TERSE; if (((o_ptr->ident) & IDENT_WORN) || dummy || full) { for (j = 0; j < MAX_P_BONUS; j++) { if (o_ptr->bonus_other[j] != 0) count++; } } if (count > 0) { byte attr = (o_ptr->bonus_other[0] > 0 ? TERM_L_GREEN : TERM_ORANGE); if (!terse) { textblock_append(tb, "It gives "); if (dummy) textblock_append(tb, "up to "); } /* Bonuses */ for (j = 0; j < MAX_P_BONUS; j++) { if (o_ptr->bonus_other[j] == 0) continue; attr = (o_ptr->bonus_other[j] > 0 ? TERM_L_GREEN : TERM_ORANGE); textblock_append_c(tb, attr, "%d ", o_ptr->bonus_other[j]); if (!terse) textblock_append(tb, "to your "); textblock_append_c(tb, attr, othername[j]); if (count >= (terse ? 2 : 3)) textblock_append(tb, ", "); if ((count == 2) && !terse) textblock_append(tb, " and "); if (count == 1) textblock_append(tb, ". "); count--; } textblock_append(tb, "\n"); return TRUE; } return FALSE; }
/* * Describe 'ignores' of an object. */ static bool describe_ignores(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { bool full = mode & OINFO_FULL; const char *descs[N_ELEMENTS(ignore_flags)]; size_t count = info_collect(ignore_flags, N_ELEMENTS(ignore_flags), full ? o_ptr->flags_obj : o_ptr->id_obj, descs); if (!count) return FALSE; textblock_append(tb, "Cannot be harmed by "); info_out_list(tb, descs, count); return TRUE; }