/** * 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 combat advantages. */ static bool describe_combat(textblock *tb, const object_type *o_ptr, oinfo_detail_t mode) { bool full = mode & OINFO_FULL; object_type *bow = &p_ptr->inventory[INVEN_BOW]; bitflag f[OF_SIZE]; bool weapon = (wield_slot(o_ptr) == INVEN_WIELD); bool ammo = (p_ptr->state.ammo_tval == o_ptr->tval) && (bow->kind); /* The player's hypothetical state, were they to wield this item */ player_state state; /* Abort if we've nothing to say */ if (mode & OINFO_DUMMY) return FALSE; if (!weapon && !ammo) { /* Potions can have special text */ if (o_ptr->tval != TV_POTION || o_ptr->dd == 0 || o_ptr->ds == 0 || !object_flavor_is_aware(o_ptr)) return FALSE; textblock_append(tb, "It can be thrown at creatures with damaging effect.\n"); return TRUE; } if (full) object_flags(o_ptr, f); else object_flags_known(o_ptr, f); textblock_append_c(tb, TERM_L_WHITE, "Combat info:\n"); if (weapon) { object_type inven[INVEN_TOTAL]; memcpy(inven, p_ptr->inventory, INVEN_TOTAL * sizeof(object_type)); inven[INVEN_WIELD] = *o_ptr; if (full) object_know_all_flags(&inven[INVEN_WIELD]); /* Calculate the player's hypothetical state */ calc_bonuses(inven, &state, TRUE); /* Warn about heavy weapons */ if (adj_str_hold[state.stat_ind[A_STR]] < o_ptr->weight / 10) textblock_append_c(tb, TERM_L_RED, "You are too weak to use this weapon.\n"); /* Describe blows */ describe_blows(tb, o_ptr, state, f); } else { /* Ammo */ /* Range of the weapon */ int tdis = 6 + 2 * p_ptr->state.ammo_mult; /* Output the range */ textblock_append(tb, "Hits targets up to "); textblock_append_c(tb, TERM_L_GREEN, format("%d", tdis * 10)); textblock_append(tb, " feet away.\n"); } /* Describe damage */ describe_damage(tb, o_ptr, state, f, mode); /* Note the impact flag */ if (of_has(f, OF_IMPACT)) textblock_append(tb, "Sometimes creates earthquakes on impact.\n"); /* Add breakage chance */ if (ammo) { int chance = breakage_chance(o_ptr, TRUE); textblock_append_c(tb, TERM_L_GREEN, "%d%%", chance); textblock_append(tb, " chance of breaking upon contact.\n"); } /* Something has been said */ return TRUE; }