/* * Check to see if the player can use a rod/wand/staff/activatable object. */ static int check_devices(object_type *o_ptr) { int fail; const char *msg; const char *what = NULL; /* Get the right string */ switch (o_ptr->tval) { case TV_ROD: msg = "zap the rod"; break; case TV_WAND: msg = "use the wand"; what = "wand"; break; case TV_STAFF: msg = "use the staff"; what = "staff"; break; default: msg = "activate it"; break; } /* Figure out how hard the item is to use */ fail = get_use_device_chance(o_ptr); /* Roll for usage */ if (randint1(1000) < fail) { if (OPT(flush_failure)) flush(); msg_format("You failed to %s properly.", msg); return FALSE; } /* Notice empty staffs */ if (what && o_ptr->pval <= 0) { if (OPT(flush_failure)) flush(); msg_format("The %s has no charges left.", what); o_ptr->ident |= (IDENT_EMPTY); return FALSE; } return TRUE; }
/** * Gives the known effects of using the given item. * * Fills in: * - the effect * - whether the effect can be aimed * - the minimum and maximum time in game turns for the item to recharge * (or zero if it does not recharge) * - the percentage chance of the effect failing when used * * Return false if the object has no effect. */ static bool obj_known_effect(const struct object *obj, struct effect **effect, bool *aimed, int *min_recharge, int *max_recharge, int *failure_chance) { random_value timeout = {0, 0, 0, 0}; *effect = 0; *min_recharge = 0; *max_recharge = 0; *failure_chance = 0; *aimed = false; if (object_effect_is_known(obj)) { *effect = object_effect(obj); timeout = obj->time; if (effect_aim(*effect)) *aimed = true;; } else if (object_effect(obj)) { /* Don't know much - be vague */ *effect = NULL; if (!obj->artifact && effect_aim(object_effect(obj))) *aimed = true; return true; } else { /* No effect - no info */ return false; } if (randcalc(timeout, 0, MAXIMISE) > 0) { *min_recharge = randcalc(timeout, 0, MINIMISE); *max_recharge = randcalc(timeout, 0, MAXIMISE); } if (tval_is_edible(obj) || tval_is_potion(obj) || tval_is_scroll(obj)) { *failure_chance = 0; } else { *failure_chance = get_use_device_chance(obj); } return true; }
/** * Gives the known effects of using the given item. * * Fills in: * - the effect id, or OBJ_KNOWN_PRESENT if there is an effect but details * are unknown * - whether the effect can be aimed * - the minimum and maximum time in game turns for the item to recharge * (or zero if it does not recharge) * - the percentage chance of the effect failing when used * * Return FALSE if the object has no effect. */ static bool obj_known_effect(const struct object *obj, int *effect, bool *aimed, int *min_recharge, int *max_recharge, int *failure_chance) { random_value timeout = {0, 0, 0, 0}; *effect = 0; *min_recharge = 0; *max_recharge = 0; *failure_chance = 0; *aimed = FALSE; if (object_effect_is_known(obj)) { *effect = object_effect(obj); timeout = obj->time; } else if (object_effect(obj)) { /* Don't know much - be vague */ *effect = OBJ_KNOWN_PRESENT; if (!obj->artifact && effect_aim(obj->effect)) *aimed = TRUE; return TRUE; } else { /* No effect - no info */ return FALSE; } if (randcalc(timeout, 0, MAXIMISE) > 0) { *min_recharge = randcalc(timeout, 0, MINIMISE); *max_recharge = randcalc(timeout, 0, MAXIMISE); } if (tval_is_food(obj) || tval_is_potion(obj) || tval_is_scroll(obj)) { *failure_chance = 0; } else { *failure_chance = get_use_device_chance(obj); } return TRUE; }
/* * Describe an object's effect, if any. */ static bool describe_effect(textblock *tb, const object_type *o_ptr, bool full, bool only_artifacts, bool subjective) { const char *desc; random_value timeout = {0, 0, 0, 0}; int effect = 0, fail; if (o_ptr->artifact) { if (object_effect_is_known(o_ptr) || full) { effect = o_ptr->artifact->effect; timeout = o_ptr->artifact->time; } else if (object_effect(o_ptr)) { textblock_append(tb, "It can be activated.\n"); return TRUE; } } else { /* Sometimes only print artifact activation info */ if (only_artifacts == TRUE) return FALSE; if (object_effect_is_known(o_ptr) || full) { effect = o_ptr->kind->effect; timeout = o_ptr->kind->time; } else if (object_effect(o_ptr) != 0) { if (effect_aim(o_ptr->kind->effect)) textblock_append(tb, "It can be aimed.\n"); else if (o_ptr->tval == TV_FOOD) textblock_append(tb, "It can be eaten.\n"); else if (o_ptr->tval == TV_POTION) textblock_append(tb, "It can be drunk.\n"); else if (o_ptr->tval == TV_SCROLL) textblock_append(tb, "It can be read.\n"); else textblock_append(tb, "It can be activated.\n"); return TRUE; } } /* Forget it without an effect */ if (!effect) return FALSE; /* Obtain the description */ desc = effect_desc(effect); if (!desc) return FALSE; if (effect_aim(effect)) textblock_append(tb, "When aimed, it "); else if (o_ptr->tval == TV_FOOD) textblock_append(tb, "When eaten, it "); else if (o_ptr->tval == TV_POTION) textblock_append(tb, "When drunk, it "); else if (o_ptr->tval == TV_SCROLL) textblock_append(tb, "When read, it "); else textblock_append(tb, "When activated, it "); /* Print a colourised description */ do { if (isdigit((unsigned char) *desc)) textblock_append_c(tb, TERM_L_GREEN, "%c", *desc); else textblock_append(tb, "%c", *desc); } while (*desc++); textblock_append(tb, ".\n"); if (randcalc(timeout, 0, MAXIMISE) > 0) { int min_time, max_time; /* Sometimes adjust for player speed */ int multiplier = extract_energy[p_ptr->state.speed]; if (!subjective) multiplier = 10; textblock_append(tb, "Takes "); /* Correct for player speed */ min_time = randcalc(timeout, 0, MINIMISE) * multiplier / 10; max_time = randcalc(timeout, 0, MAXIMISE) * multiplier / 10; textblock_append_c(tb, TERM_L_GREEN, "%d", min_time); if (min_time != max_time) { textblock_append(tb, " to "); textblock_append_c(tb, TERM_L_GREEN, "%d", max_time); } textblock_append(tb, " turns to recharge"); if (subjective && p_ptr->state.speed != 110) textblock_append(tb, " at your current speed"); textblock_append(tb, ".\n"); } if (!subjective || o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION || o_ptr->tval == TV_SCROLL) { return TRUE; } else { fail = get_use_device_chance(o_ptr); textblock_append(tb, "Your chance of success is %d.%d%%\n", (1000 - fail) / 10, (1000 - fail) % 10); } return TRUE; }
/* * Display a list of objects. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), and show_floor(). Mode flags are * documented in object.h */ static void show_obj_list(int num_obj, int num_head, char labels[50][80], object_type *objects[50], olist_detail_t mode) { int i, row = 0, col = 0; int attr; size_t max_len = 0; int ex_width = 0, ex_offset, ex_offset_ctr; object_type *o_ptr; char o_name[50][80]; char tmp_val[80]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; bool terse = FALSE; if (in_term) max_len = 40; if (in_term && Term->wid < 40) mode &= ~(OLIST_WEIGHT); if (Term->wid < 50) terse = TRUE; /* Calculate name offset and max name length */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Null objects are used to skip lines, or display only a label */ if (!o_ptr || !o_ptr->kind) { if (i < num_head) strnfmt(o_name[i], sizeof(o_name[i]), ""); else strnfmt(o_name[i], sizeof(o_name[i]), "(nothing)"); } else object_desc(o_name[i], sizeof(o_name[i]), o_ptr, ODESC_PREFIX | ODESC_FULL | (terse ? ODESC_TERSE : 0)); /* Max length of label + object name */ max_len = MAX(max_len, strlen(labels[i]) + strlen(o_name[i])); } /* Take the quiver message into consideration */ if (mode & OLIST_QUIVER && p_ptr->quiver_slots > 0) max_len = MAX(max_len, 24); /* Width of extra fields */ if (mode & OLIST_WEIGHT) ex_width += 9; if (mode & OLIST_PRICE) ex_width += 9; if (mode & OLIST_FAIL) ex_width += 10; /* Determine beginning row and column */ if (in_term) { /* Term window */ row = 0; col = 0; } else { /* Main window */ row = 1; col = Term->wid - 1 - max_len - ex_width; if (col < 3) col = 0; } /* Column offset of the first extra field */ ex_offset = MIN(max_len, (size_t)(Term->wid - 1 - ex_width - col)); /* Output the list */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* If we have no label then we won't display anything */ if (!strlen(labels[i])) continue; /* Print the label */ put_str(labels[i], row + i, col); /* Limit object name */ if (strlen(labels[i]) + strlen(o_name[i]) > (size_t)ex_offset) { int truncate = ex_offset - strlen(labels[i]); if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(o_name[i]) - 1) truncate = sizeof(o_name[i]) - 1; o_name[i][truncate] = '\0'; } /* Item kind determines the color of the output */ if (o_ptr && o_ptr->kind) attr = tval_to_attr[o_ptr->tval % N_ELEMENTS(tval_to_attr)]; else attr = TERM_SLATE; /* Object name */ c_put_str(attr, o_name[i], row + i, col + strlen(labels[i])); /* If we don't have an object, we can skip the rest of the output */ if (!(o_ptr && o_ptr->kind)) continue; /* Extra fields */ ex_offset_ctr = ex_offset; if (mode & OLIST_PRICE) { int price = price_item(o_ptr, TRUE, o_ptr->number); strnfmt(tmp_val, sizeof(tmp_val), "%6d au", price); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } if (mode & OLIST_FAIL && obj_can_fail(o_ptr)) { int fail = (9 + get_use_device_chance(o_ptr)) / 10; if (object_effect_is_known(o_ptr)) strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail); else my_strcpy(tmp_val, " ? fail", sizeof(tmp_val)); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 10; } if (mode & OLIST_WEIGHT) { int weight = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10, weight % 10); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } } /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; /* Quiver may take multiple lines */ for(j = 0; j < p_ptr->quiver_slots; j++, i++) { const char *fmt = "in Quiver: %d missile%s"; char letter = index_to_label(in_term ? i - 1 : i); /* Number of missiles in this "slot" */ if (j == p_ptr->quiver_slots - 1 && p_ptr->quiver_remainder > 0) count = p_ptr->quiver_remainder; else count = MAX_STACK_SIZE-1; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter); c_put_str(TERM_SLATE, tmp_val, row + i, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), fmt, count, count == 1 ? "" : "s"); c_put_str(TERM_L_UMBER, tmp_val, row + i, col + 3); } } /* Clear term windows */ if (in_term) { for (; i < Term->hgt; i++) { prt("", row + i, MAX(col - 2, 0)); } } /* Print a drop shadow for the main window if necessary */ else if (i > 0 && row + i < 24) { prt("", row + i, MAX(col - 2, 0)); } }
/* * Describe an object's effect, if any. */ static bool describe_effect(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { const object_kind *k_ptr = &k_info[o_ptr->k_idx]; const char *desc; random_value timeout = { 0, 0, 0, 0 }; bool full = mode & OINFO_FULL; bool subjective = mode & OINFO_SUBJ; bool terse = mode & OINFO_TERSE; int effect = 0, fail; if (wearable_p(o_ptr)) { /* Wearable + effect <=> activates */ if ((o_ptr->ident & IDENT_WORN) || full) { effect = o_ptr->effect; timeout = o_ptr->time; } else if (object_effect(o_ptr)) { textblock_append(tb, "It can be activated.\n"); return TRUE; } } else { /* Sometimes only print activation info */ if (terse) return FALSE; if ((object_aware_p(o_ptr) && kf_has(k_ptr->flags_kind, KF_EASY_KNOW)) || full) { effect = o_ptr->effect; timeout = o_ptr->time; } else if (object_effect(o_ptr)) { if (effect_aim(k_ptr->effect)) textblock_append(tb, "It can be aimed.\n"); else if (o_ptr->tval == TV_FOOD) textblock_append(tb, "It can be eaten.\n"); else if (o_ptr->tval == TV_POTION) textblock_append(tb, "It can be drunk.\n"); else if (o_ptr->tval == TV_SCROLL) textblock_append(tb, "It can be read.\n"); else textblock_append(tb, "It can be activated.\n"); return TRUE; } } /* Forget it without an effect */ if (!effect) return FALSE; /* Obtain the description */ desc = effect_desc(effect); if (!desc) return FALSE; if (effect_aim(effect)) textblock_append(tb, "When aimed, it "); else if (o_ptr->tval == TV_FOOD) textblock_append(tb, "When eaten, it "); else if (o_ptr->tval == TV_POTION) textblock_append(tb, "When drunk, it "); else if (o_ptr->tval == TV_SCROLL) textblock_append(tb, "When read, it "); else textblock_append(tb, "When activated, it "); /* Print a colourised description */ do { if (isdigit((unsigned char) *desc)) textblock_append_c(tb, TERM_L_GREEN, "%c", *desc); else textblock_append(tb, "%c", *desc); } while (*desc++); textblock_append(tb, ".\n"); if (randcalc(timeout, 0, MAXIMISE) > 0) { int min_time, max_time; /* Sometimes adjust for player speed */ int multiplier = extract_energy[p_ptr->state.pspeed]; if (!subjective) multiplier = 10; textblock_append(tb, "Takes "); /* Correct for player speed */ min_time = randcalc(timeout, 0, MINIMISE) * multiplier / 10; max_time = randcalc(timeout, 0, MAXIMISE) * multiplier / 10; textblock_append_c(tb, TERM_L_GREEN, "%d", min_time); if (min_time != max_time) { textblock_append(tb, " to "); textblock_append_c(tb, TERM_L_GREEN, "%d", max_time); } textblock_append(tb, " turns to recharge"); if (subjective && p_ptr->state.pspeed != 110) textblock_append(tb, " at your current speed"); textblock_append(tb, ".\n"); } if (!subjective || o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION || o_ptr->tval == TV_SCROLL) { return TRUE; } else { fail = get_use_device_chance(o_ptr); textblock_append(tb, "Your chance of success is %d.%d%%\n", (1000 - fail) / 10, (1000 - fail) % 10); } return TRUE; }
/* * Display a list of objects. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), and show_floor(). Mode flags are * documented in object.h */ static void show_obj_list(int num_obj, char labels[50][80], object_type *objects[50], olist_detail_t mode) { int i, row = 0, col = 0; size_t max_len = 0; int ex_width = 0, ex_offset, ex_offset_ctr; object_type *o_ptr; char o_name[50][80]; char tmp_val[80]; bool in_term; in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; if (in_term) max_len = 40; /* Calculate name offset and max name length */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Null objects are used to skip lines, or display only a label */ if (o_ptr == NULL) continue; /* Max length of label + object name */ object_desc(o_name[i], sizeof(o_name[i]), o_ptr, ODESC_PREFIX | ODESC_FULL); max_len = MAX(max_len, strlen(labels[i]) + strlen(o_name[i])); } /* Width of extra fields */ if (mode & OLIST_WEIGHT) ex_width += 9; if (mode & OLIST_PRICE) ex_width += 9; if (mode & OLIST_FAIL) ex_width += 10; /* Determine beginning row and column */ if (in_term) { /* Term window */ row = 0; col = 0; } else { /* Main window */ row = 1; col = Term->wid - 1 - max_len - ex_width; if (col < 3) col = 0; } /* Column offset of the first extra field */ ex_offset = MIN(max_len, (size_t)(Term->wid - 1 - ex_width - col)); /* Output the list */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the label */ put_str(labels[i], row + i, col); /* Print the object */ if (o_ptr != NULL) { /* Limit object name */ if (strlen(labels[i]) + strlen(o_name[i]) > (size_t)ex_offset) { int truncate = ex_offset - strlen(labels[i]); if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(o_name[i]) - 1) truncate = sizeof(o_name[i]) - 1; o_name[i][truncate] = '\0'; } /* Object name */ c_put_str(tval_to_attr[o_ptr->tval % N_ELEMENTS(tval_to_attr)], o_name[i], row + i, col + strlen(labels[i])); /* Extra fields */ ex_offset_ctr = ex_offset; if (mode & OLIST_PRICE) { int price = price_item(o_ptr, TRUE, o_ptr->number); strnfmt(tmp_val, sizeof(tmp_val), "%6d au", price); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } if (mode & OLIST_FAIL) { int fail = (9 + get_use_device_chance(o_ptr)) / 10; if (object_effect_is_known(o_ptr)) strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail); else my_strcpy(tmp_val, " ? fail", sizeof(tmp_val)); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 10; } if (mode & OLIST_WEIGHT) { int weight = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10, weight % 10); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } } } /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; /* Quiver may take multiple lines */ for(j = 0; j < p_ptr->quiver_slots; j++, i++) { /* Number of missiles in this "slot" */ if (j == p_ptr->quiver_slots - 1 && p_ptr->quiver_remainder > 0) count = p_ptr->quiver_remainder; else count = 99; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", index_to_label(i)); c_put_str(TERM_SLATE, tmp_val, row + i, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), "in Quiver: %d missile%s", count, count == 1 ? "" : "s"); c_put_str(TERM_L_UMBER, tmp_val, row + i, col + 3); } } /* Clear term windows */ if (in_term) { for (; i < Term->hgt; i++) { prt("", row + i, MAX(col - 2, 0)); } } /* Print a drop shadow for the main window if necessary */ else if (i > 0 && row + i < 24) { prt("", row + i, MAX(col - 2, 0)); } }
/** * Display an object. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), show_quiver() and show_floor(). * Mode flags are documented in object.h */ static void show_obj(int obj_num, int row, int col, bool cursor, olist_detail_t mode) { int attr; int label_attr = cursor ? COLOUR_L_BLUE : COLOUR_WHITE; int ex_offset_ctr; char buf[80]; struct object *obj = items[obj_num].object; bool show_label = mode & (OLIST_WINDOW | OLIST_DEATH) ? true : false; int label_size = show_label ? strlen(items[obj_num].label) : 0; int equip_label_size = strlen(items[obj_num].equip_label); /* Clear the line */ prt("", row + obj_num, MAX(col - 1, 0)); /* If we have no label then we won't display anything */ if (!strlen(items[obj_num].label)) return; /* Print the label */ if (show_label) c_put_str(label_attr, items[obj_num].label, row + obj_num, col); /* Print the equipment label */ c_put_str(label_attr, items[obj_num].equip_label, row + obj_num, col + label_size); /* Limit object name */ if (label_size + equip_label_size + strlen(items[obj_num].o_name) > (size_t)ex_offset) { int truncate = ex_offset - label_size - equip_label_size; if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(items[obj_num].o_name) - 1) truncate = sizeof(items[obj_num].o_name) - 1; items[obj_num].o_name[truncate] = '\0'; } /* Item kind determines the color of the output */ if (obj) { attr = obj->kind->base->attr; /* Unreadable books are a special case */ if (tval_is_book_k(obj->kind) && (player_object_to_book(player, obj) == NULL)) { attr = COLOUR_SLATE; } } else { attr = COLOUR_SLATE; } /* Object name */ c_put_str(attr, items[obj_num].o_name, row + obj_num, col + label_size + equip_label_size); /* If we don't have an object, we can skip the rest of the output */ if (!obj) return; /* Extra fields */ ex_offset_ctr = ex_offset; /* Price */ if (mode & OLIST_PRICE) { struct store *store = store_at(cave, player->grid); if (store) { int price = price_item(store, obj, true, obj->number); strnfmt(buf, sizeof(buf), "%6d au", price); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 9; } } /* Failure chance for magic devices and activations */ if (mode & OLIST_FAIL && obj_can_fail(obj)) { int fail = (9 + get_use_device_chance(obj)) / 10; if (object_effect_is_known(obj)) strnfmt(buf, sizeof(buf), "%4d%% fail", fail); else my_strcpy(buf, " ? fail", sizeof(buf)); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 10; } /* Failure chances for recharging an item; see effect_handler_RECHARGE */ if (mode & OLIST_RECHARGE) { int fail = 1000 / recharge_failure_chance(obj, player->upkeep->recharge_pow); if (object_effect_is_known(obj)) strnfmt(buf, sizeof(buf), "%2d.%1d%% fail", fail / 10, fail % 10); else my_strcpy(buf, " ? fail", sizeof(buf)); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 10; } /* Weight */ if (mode & OLIST_WEIGHT) { int weight = obj->weight * obj->number; strnfmt(buf, sizeof(buf), "%4d.%1d lb", weight / 10, weight % 10); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 9; } }
/* * Display an object. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), and show_floor(). Mode flags are * documented in object.h */ static void show_obj(int onum, size_t max_len, char label[80], const object_type *object, bool cursor, olist_detail_t mode) { int row = 0, col = 0; int ex_width = 0, ex_offset, ex_offset_ctr; object_type *o_ptr = (object_type *) object; char o_name[160]; char tmp_val[80]; bool in_term; byte attr = proc_list_color_hack(o_ptr); /* Highlight */ if (cursor) attr = get_color(attr, ATTR_HIGH, 1); in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; /* Object name */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Width of extra fields */ if (mode & OLIST_WEIGHT) ex_width += 9; if (mode & OLIST_PRICE) ex_width += 9; if (mode & OLIST_FAIL) ex_width += 10; /* Determine beginning row and column */ if (in_term) { /* Term window */ row = offset; col = 0; } else { /* Main window */ row = 1; col = Term->wid - 3 - max_len - ex_width; col = MIN(col, COL_MAP + tile_width); if (col < 3) col = 0; } /* Column offset of the first extra field */ ex_offset = MIN(max_len, (size_t) (Term->wid - 1 - ex_width - col)); /* Clear the line */ prt("", row + onum, MAX(col - 2, 0)); /* Print the label */ put_str(label, row + onum, col); /* Print the object */ if (o_ptr != NULL) { /* Limit object name */ if (strlen(label) + strlen(o_name) > (size_t) ex_offset) { int truncate = ex_offset - strlen(label); if (truncate < 0) truncate = 0; if ((size_t) truncate > sizeof(o_name) - 1) truncate = sizeof(o_name) - 1; o_name[truncate] = '\0'; } /* Object name */ c_put_str(attr, o_name, row + onum, col + strlen(label)); /* Extra fields */ ex_offset_ctr = ex_offset; if (mode & OLIST_PRICE) { int price = price_item(o_ptr, TRUE, o_ptr->number); strnfmt(tmp_val, sizeof(tmp_val), "%6d au", price); put_str(tmp_val, row + onum, col + ex_offset_ctr); ex_offset_ctr += 9; } if (mode & OLIST_FAIL) { int fail = (9 + get_use_device_chance(o_ptr)) / 10; if (object_aware_p(o_ptr)) strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail); else my_strcpy(tmp_val, " ? fail", sizeof(tmp_val)); put_str(tmp_val, row + onum, col + ex_offset_ctr); ex_offset_ctr += 10; } if (mode & OLIST_WEIGHT) { int weight = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10, weight % 10); put_str(tmp_val, row + onum, col + ex_offset_ctr); ex_offset_ctr += 9; } } }