void display_shooter_info(doc_ptr doc) { object_type *bow_ptr = NULL; int slot = equip_find_object(TV_BOW, SV_ANY); char o_name[MAX_NLEN]; int mult; int num_fire = 0; int to_h = 0; int to_d = 0; int i, j; if (!slot || prace_is_(RACE_MON_JELLY) || p_ptr->shooter_info.tval_ammo == TV_NO_AMMO) return; bow_ptr = equip_obj(slot); assert(bow_ptr); mult = bow_mult(bow_ptr); if (p_ptr->shooter_info.num_fire) num_fire = p_ptr->shooter_info.num_fire * 100 * 100 / bow_energy(bow_ptr->sval); if (object_is_known(bow_ptr)) { to_h = bow_ptr->to_h; to_d = bow_ptr->to_d; if (weaponmaster_is_(WEAPONMASTER_CROSSBOWS) && p_ptr->lev >= 15) to_d += 1 + p_ptr->lev/10; } /* Shooter */ object_desc(o_name, bow_ptr, OD_OMIT_INSCRIPTION | OD_COLOR_CODED); doc_printf(doc, " <color:y>Shooting</color>: <indent><style:indent>%s</style></indent>\n", o_name); doc_printf(doc, " %-8.8s: %d'\n", "Range", (bow_range(bow_ptr) + 1) * 10); doc_printf(doc, " %-8.8s: %d.%02d\n", "Shots", num_fire/100, num_fire%100); doc_printf(doc, " %-8.8s: %d.%02dx\n", "Mult", mult/100, mult%100); doc_printf(doc, " %-8.8s: %d + %d = %d\n", "To Hit", to_h, p_ptr->shooter_info.dis_to_h, to_h + p_ptr->shooter_info.dis_to_h); doc_printf(doc, " %-8.8s: %d (%s)\n", "To Dam", to_d, "Multiplier Applies"); doc_printf(doc, " %-8.8s: %d (%s)\n", "Xtra Dam", p_ptr->shooter_info.dis_to_d, "Multiplier Does Not Apply"); doc_newline(doc); /* Ammo */ j = 0; for (i = 0; i < INVEN_PACK; i++) { if (inventory[i].tval == p_ptr->shooter_info.tval_ammo) _shooter_info_aux(doc, bow_ptr, &inventory[i], ++j); } }
static void _shooter_info_aux(doc_ptr doc, object_type *bow, object_type *arrow, int ct) { char o_name[MAX_NLEN]; u32b flgs[TR_FLAG_SIZE]; int mult; int to_h = 0; int to_d = 0; int to_h_bow = 0; int to_d_bow = 0; int to_h_xtra = p_ptr->shooter_info.dis_to_h; int to_d_xtra = p_ptr->shooter_info.dis_to_d; int dd = arrow->dd; int ds = arrow->ds; critical_t crit = {0}; int num_fire = 0; doc_ptr cols[2] = {0}; cols[0] = doc_alloc(60); cols[1] = doc_alloc(10); missile_flags_known(arrow, flgs); mult = bow_mult(bow); if (object_is_artifact(arrow)) num_fire = 100; else if (p_ptr->shooter_info.num_fire) num_fire = p_ptr->shooter_info.num_fire * 100 * 100 / bow_energy(bow->sval); if (object_is_known(bow)) { to_h_bow = bow->to_h; to_d_bow = bow->to_d; if (weaponmaster_is_(WEAPONMASTER_CROSSBOWS) && p_ptr->lev >= 15) to_d_bow += 1 + p_ptr->lev/10; } if (object_is_known(arrow)) { to_h = arrow->to_h; to_d = arrow->to_d; } if (p_ptr->big_shot) dd *= 2; { const int ct = 10 * 1000; int i; /* Compute Average Effects of Criticals by sampling */ for (i = 0; i < ct; i++) { critical_t tmp = critical_shot(arrow->weight, arrow->to_h); if (tmp.desc) { crit.mul += tmp.mul; crit.to_d += tmp.to_d; } else crit.mul += 100; } crit.mul = crit.mul / ct; crit.to_d = crit.to_d * 100 / ct; } /* First Column */ object_desc(o_name, arrow, OD_OMIT_INSCRIPTION | OD_COLOR_CODED); doc_printf(cols[0], "<color:u> Ammo #%-2d</color>: <indent><style:indent>%s</style></indent>\n", ct, o_name); doc_printf(cols[0], " %-8.8s: %d.%d lbs\n", "Weight", arrow->weight/10, arrow->weight%10); doc_printf(cols[0], " %-8.8s: %d + %d = %d\n", "To Hit", to_h, to_h_bow + to_h_xtra, to_h + to_h_bow + to_h_xtra); doc_printf(cols[0], " %-8.8s: %d + %d = %d (%s)\n", "To Dam", to_d, to_d_bow, to_d + to_d_bow, "Multiplier Applies"); doc_printf(cols[0], " <color:G>%-8.8s</color>\n", "Damage"); if (crit.to_d) { doc_printf(cols[0], " %-8.8s: %d.%02dx + %d.%02d\n", "Crits", crit.mul/100, crit.mul%100, crit.to_d/100, crit.to_d%100); } else { doc_printf(cols[0], " %-8.8s: %d.%02dx\n", "Crits", crit.mul/100, crit.mul%100); } to_d = to_d + to_d_bow; mult = mult * crit.mul / 100; to_d_xtra = to_d_xtra + crit.to_d/100; _display_missile_slay(mult, 100, num_fire, dd, ds, to_d, to_d_xtra, "Normal", TERM_WHITE, cols[0]); if (p_ptr->tim_force && p_ptr->csp > (p_ptr->msp / 30)) { mult = mult * 3 / 2; _display_missile_slay(mult, 100, num_fire, dd, ds, to_d, to_d_xtra, "Force", TERM_L_BLUE, cols[0]); } if (have_flag(flgs, TR_KILL_ANIMAL)) _display_missile_slay(mult, 270, num_fire, dd, ds, to_d, to_d_xtra, "Animals", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ANIMAL)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Animals", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_EVIL)) _display_missile_slay(mult, 250, num_fire, dd, ds, to_d, to_d_xtra, "Evil", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_EVIL)) _display_missile_slay(mult, 150, num_fire, dd, ds, to_d, to_d_xtra, "Evil", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_HUMAN)) _display_missile_slay(mult, 270, num_fire, dd, ds, to_d, to_d_xtra, "Human", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_HUMAN)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Human", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_UNDEAD)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Undead", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_UNDEAD)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Undead", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DEMON)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Demons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DEMON)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Demons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ORC)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Orcs", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ORC)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Orcs", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_TROLL)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Trolls", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_TROLL)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Trolls", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_GIANT)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Giants", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_GIANT)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Giants", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DRAGON)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Dragons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DRAGON)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Dragons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_BRAND_ACID)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Acid", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_ELEC)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Elec", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_FIRE)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Fire", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_COLD)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Cold", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_POIS)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Poison", TERM_RED, cols[0]); /* Second Column */ to_h = to_h + to_h_bow + to_h_xtra; doc_insert(cols[1], " <color:G>AC Hit</color>\n"); doc_printf(cols[1], "%3d %2d%%\n", 25, bow_hit_chance(bow->sval, to_h, 25)); doc_printf(cols[1], "%3d %2d%%\n", 50, bow_hit_chance(bow->sval, to_h, 50)); doc_printf(cols[1], "%3d %2d%%\n", 100, bow_hit_chance(bow->sval, to_h, 100)); doc_printf(cols[1], "%3d %2d%%\n", 150, bow_hit_chance(bow->sval, to_h, 150)); doc_printf(cols[1], "%3d %2d%%\n", 175, bow_hit_chance(bow->sval, to_h, 175)); doc_printf(cols[1], "%3d %2d%%\n", 200, bow_hit_chance(bow->sval, to_h, 200)); doc_insert_cols(doc, cols, 2, 1); doc_free(cols[0]); doc_free(cols[1]); }
/* * Creates a description of the item "o_ptr", and stores it in "out_val". * * One can choose the "verbosity" of the description, including whether * or not the "number" of items should be described, and how much detail * should be used when describing the item. * * The given "buf" must be MAX_NLEN chars long to hold the longest possible * description, which can get pretty long, including incriptions, such as: * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)". * Note that the inscription will be clipped to keep the total description * under MAX_NLEN-1 chars (plus a terminator). * * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient, * portable, versions of some common "sprintf()" commands. * * Note that all ego-items (when known) append an "Ego-Item Name", unless * the item is also an artifact, which should NEVER happen. * * Note that all artifacts (when known) append an "Artifact Name", so we * have special processing for "Specials" (artifact Lites, Rings, Amulets). * The "Specials" never use "modifiers" if they are "known", since they * have special "descriptions", such as "The Necklace of the Dwarves". * * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone), * plus the artifact name, just like any other artifact, if known. * * Special Ring's and Amulet's, if not "aware", use the same code as normal * rings and amulets, and if "aware", use the "k_info" base-name (Ring or * Amulet or Necklace). They will NEVER "append" the "k_info" name. But, * they will append the artifact name, just like any artifact, if known. * * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware. * * Mode: * OD_NAME_ONLY : The Cloak of Death * OD_NAME_AND_ENCHANT : The Cloak of Death [1,+3] * OD_OMIT_INSCRIPTION : The Cloak of Death [1,+3] (+2 to Stealth) * 0 : The Cloak of Death [1,+3] (+2 to Stealth) {nifty} * * OD_OMIT_PREFIX : Forbidden numeric prefix * OD_NO_PLURAL : Forbidden use of plural * OD_STORE : Assume to be aware and known * OD_NO_FLAVOR : Allow to hidden flavor * OD_FORCE_FLAVOR : Get un-shuffled flavor name */ void object_desc(char *buf, const object_type *o_ptr, u32b mode) { /* Extract object kind name */ cptr kindname = get_object_name(o_ptr); /* Extract default "base" string */ cptr basenm = kindname; /* Assume no "modifier" string */ cptr modstr = ""; int power; bool aware = FALSE; bool known = FALSE; bool flavor = TRUE; bool show_weapon = FALSE; bool show_armour = FALSE; cptr s, s0; char *t; char p1 = '(', p2 = ')'; char b1 = '[', b2 = ']'; char c1 = '{', c2 = '}'; char tmp_val[MAX_NLEN+160]; char tmp_val2[MAX_NLEN+10]; char fake_insc_buf[30]; u32b f1, f2, f3; bool fullname = FALSE; object_type *bow_ptr; object_kind *k_ptr = &k_info[o_ptr->k_idx]; object_kind *flavor_k_ptr = &k_info[k_ptr->flavor]; /* Extract some flags */ object_flags(o_ptr, &f1, &f2, &f3); /* See if the object is "aware" */ if (object_aware_p(o_ptr)) aware = TRUE; /* See if the object is "known" */ if (object_known_p(o_ptr)) known = TRUE; /* Allow flavors to be hidden when aware */ if (aware && ((mode & OD_NO_FLAVOR) || plain_descriptions)) flavor = FALSE; /* Object is in the inventory of a store or spoiler */ if ((mode & OD_STORE) || (o_ptr->ident & IDENT_STORE)) { /* Don't show flavors */ flavor = FALSE; /* Pretend known and aware */ aware = TRUE; known = TRUE; } /* Force to be flavor name only */ if (mode & OD_FORCE_FLAVOR) { aware = FALSE; flavor = TRUE; known = FALSE; /* Cancel shuffling */ flavor_k_ptr = k_ptr; } /* Analyze the object */ switch (o_ptr->tval) { /* Some objects are easy to describe */ case TV_SKELETON: case TV_BOTTLE: case TV_JUNK: case TV_SPIKE: case TV_FLASK: case TV_CHEST: case TV_FOOD: { break; } /* Figurines/Statues */ case TV_FIGURINE: case TV_STATUE: { monster_race *r_ptr = &r_info[o_ptr->pval]; #ifdef JP modstr = r_name + r_ptr->name; #else cptr t = r_name + r_ptr->name; if (!(r_ptr->flags1 & RF1_UNIQUE)) { sprintf(tmp_val2, "%s%s", (is_a_vowel(*t) ? "an " : "a "), t); modstr = tmp_val2; } else { modstr = t; } #endif break; } /* Corpses */ case TV_CORPSE: { monster_race *r_ptr = &r_info[o_ptr->pval]; modstr = r_name + r_ptr->name; #ifdef JP basenm = "#%"; #else if (r_ptr->flags1 & RF1_UNIQUE) basenm = "& % of #"; else basenm = "& # %"; #endif break; } /* Missiles/ Bows/ Weapons */ case TV_SHOT: case TV_BOLT: case TV_ARROW: case TV_BOW: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING: { show_weapon = TRUE; break; } /* Armour */ case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN: case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR: { show_armour = TRUE; break; } /* Lites (including a few "Specials") */ case TV_LITE: { break; } /* Amulets (including a few "Specials") */ case TV_AMULET: { /* Known artifacts */ if (aware) { if (artifact_p(o_ptr)) break; if (k_ptr->gen_flags & TRG_INSTA_ART) break; } /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%のアミュレット"; else if (aware) basenm = "%の#アミュレット"; else basenm = "#アミュレット"; #else if (!flavor) basenm = "& Amulet~ of %"; else if (aware) basenm = "& # Amulet~ of %"; else basenm = "& # Amulet~"; #endif break; } /* Rings (including a few "Specials") */ case TV_RING: { /* Known artifacts */ if (aware) { if (artifact_p(o_ptr)) break; if (k_ptr->gen_flags & TRG_INSTA_ART) break; } /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%の指輪"; else if (aware) basenm = "%の#指輪"; else basenm = "#指輪"; #else if (!flavor) basenm = "& Ring~ of %"; else if (aware) basenm = "& # Ring~ of %"; else basenm = "& # Ring~"; #endif if (!k_ptr->to_h && !k_ptr->to_d && (o_ptr->to_h || o_ptr->to_d)) show_weapon = TRUE; break; } case TV_STAFF: { /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%のスタッフ"; else if (aware) basenm = "%の#スタッフ"; else basenm = "#スタッフ"; #else if (!flavor) basenm = "& Staff~ of %"; else if (aware) basenm = "& # Staff~ of %"; else basenm = "& # Staff~"; #endif break; } case TV_WAND: { /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%のワンド"; else if (aware) basenm = "%の#ワンド"; else basenm = "#ワンド"; #else if (!flavor) basenm = "& Wand~ of %"; else if (aware) basenm = "& # Wand~ of %"; else basenm = "& # Wand~"; #endif break; } case TV_ROD: { /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%のロッド"; else if (aware) basenm = "%の#ロッド"; else basenm = "#ロッド"; #else if (!flavor) basenm = "& Rod~ of %"; else if (aware) basenm = "& # Rod~ of %"; else basenm = "& # Rod~"; #endif break; } case TV_SCROLL: { /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%の巻物"; else if (aware) basenm = "\"#\"と書かれた%の巻物"; else basenm = "\"#\"と書かれた巻物"; #else if (!flavor) basenm = "& Scroll~ of %"; else if (aware) basenm = "& Scroll~ titled \"#\" of %"; else basenm = "& Scroll~ titled \"#\""; #endif break; } case TV_POTION: { /* Color the object */ modstr = k_name + flavor_k_ptr->flavor_name; #ifdef JP if (!flavor) basenm = "%の薬"; else if (aware) basenm = "%の#薬"; else basenm = "#薬"; #else if (!flavor) basenm = "& Potion~ of %"; else if (aware) basenm = "& # Potion~ of %"; else basenm = "& # Potion~"; #endif break; } /* Magic Books */ case TV_LIFE_BOOK: { #ifdef JP basenm = "生命の魔法書%"; #else if (mp_ptr->spell_type == ST_PRAYER) basenm = "& Book~ of Life Magic %"; else basenm = "& Life Spellbook~ %"; #endif break; } case TV_SORCERY_BOOK: { #ifdef JP basenm = "仙術の魔法書%"; #else if (mp_ptr->spell_type == ST_PRAYER) basenm = "& Book~ of Sorcery %"; else basenm = "& Sorcery Spellbook~ %"; #endif break; } /* Hack -- Gold/Gems */ case TV_GOLD: { strcpy(buf, basenm); return; } /* Used in the "inventory" routine */ default: { #ifdef JP strcpy(buf, "(なし)"); #else strcpy(buf, "(nothing)"); #endif return; } } /* Use full name from a_info */ if (known && o_ptr->name1) { artifact_type *a_ptr = &a_info[o_ptr->name1]; if (prefix(a_name + a_ptr->name, "$")) { basenm = a_name + a_info[o_ptr->name1].name + 1; fullname = TRUE; } } /* Start dumping the result */ t = tmp_val; #ifdef JP if (basenm[0] == '&') s = basenm + 2; else s = basenm; /* No prefix */ if (mode & OD_OMIT_PREFIX) { /* Nothing */ } else if (o_ptr->number > 1) { t = object_desc_kosuu(t, o_ptr); t = object_desc_str(t, "の "); } /* 英語の場合アーティファクトは The が付くので分かるが * 日本語では分からないのでマークをつける */ if (known) { if (artifact_p(o_ptr)) t = object_desc_str(t, "★"); else if (o_ptr->art_name) t = object_desc_str(t, "☆"); } #else /* The object "expects" a "number" */ if (basenm[0] == '&') { /* Skip the ampersand (and space) */ s = basenm + 2; /* No prefix */ if (mode & OD_OMIT_PREFIX) { /* Nothing */ } /* Hack -- None left */ else if (o_ptr->number <= 0) { t = object_desc_str(t, "no more "); } /* Extract the number */ else if (o_ptr->number > 1) { t = object_desc_num(t, o_ptr->number); t = object_desc_chr(t, ' '); } /* Hack -- The only one of its kind */ else if ((known && (artifact_p(o_ptr) || o_ptr->art_name)) || ((o_ptr->tval == TV_CORPSE) && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))) { t = object_desc_str(t, "The "); } /* A single one */ else { bool vowel; switch (*s) { case '#': vowel = is_a_vowel(modstr[0]); break; case '%': vowel = is_a_vowel(*kindname); break; default: vowel = is_a_vowel(*s); break; } if (vowel) { /* A single one, with a vowel */ t = object_desc_str(t, "an "); } else { /* A single one, without a vowel */ t = object_desc_str(t, "a "); } } } /* Hack -- objects that "never" take an article */ else { /* No ampersand */ s = basenm; /* No pref */ if (mode & OD_OMIT_PREFIX) { /* Nothing */ } /* Hack -- all gone */ else if (o_ptr->number <= 0) { t = object_desc_str(t, "no more "); } /* Prefix a number if required */ else if (o_ptr->number > 1) { t = object_desc_num(t, o_ptr->number); t = object_desc_chr(t, ' '); } /* Hack -- The only one of its kind */ else if (known && (artifact_p(o_ptr) || o_ptr->art_name)) { t = object_desc_str(t, "The "); } /* Hack -- single items get no prefix */ else { /* Nothing */ } } #endif /* Paranoia -- skip illegal tildes */ /* while (*s == '~') s++; */ #ifdef JP /* 伝説のアイテム、名のあるアイテムの名前を付加する */ if (known) { /* ランダム・アーティファクト */ if (o_ptr->art_name) { cptr temp = quark_str(o_ptr->art_name); /* '『' から始まらない伝説のアイテムの名前は最初に付加する */ /* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */ if (strncmp(temp, "of ", 3) == 0) { t = object_desc_str(t, &temp[3]); t = object_desc_str(t, "の"); } else if ((strncmp(temp, "『", 2) != 0) && (temp[0] != '\'')) t = object_desc_str(t, temp); } /* 伝説のアイテム */ else if (o_ptr->name1 && !fullname) { artifact_type *a_ptr = &a_info[o_ptr->name1]; /* '『' から始まらない伝説のアイテムの名前は最初に付加する */ if (strncmp(a_name + a_ptr->name, "『", 2) != 0) { t = object_desc_str(t, a_name + a_ptr->name); } } /* 名のあるアイテム */ else if (o_ptr->name2) { ego_item_type *e_ptr = &e_info[o_ptr->name2]; t = object_desc_str(t, e_name + e_ptr->name); } } #endif /* Copy the string */ for (s0 = NULL; *s || s0; ) { /* The end of the flavour/kind string. */ if (!*s) { s = s0 + 1; s0 = NULL; } /* Begin to append the modifier (flavor) */ else if ((*s == '#') && !s0) { s0 = s; s = modstr; /* Paranoia -- Never append multiple modstrs */ modstr = ""; } /* Begin to append the kind name */ else if ((*s == '%') && !s0) { s0 = s; s = kindname; /* Paranoia -- Never append multiple kindnames */ kindname = ""; } #ifndef JP /* Pluralizer */ else if (*s == '~') { /* Add a plural if needed */ if (!(mode & OD_NO_PLURAL) && (o_ptr->number != 1)) { char k = t[-1]; /* XXX XXX XXX Mega-Hack */ /* Hack -- "Cutlass-es" and "Torch-es" */ if ((k == 's') || (k == 'h')) *t++ = 'e'; /* Add an 's' */ *t++ = 's'; } s++; } #endif /* Normal */ else { /* Copy */ *t++ = *s++; } } /* Terminate */ *t = '\0'; #ifdef JP /* '『'から始まる伝説のアイテムの名前は最後に付加する */ if (known) { /* ランダムアーティファクトの名前はセーブファイルに記録 されるので、英語版の名前もそれらしく変換する */ if (o_ptr->art_name) { char temp[256]; int itemp; strcpy(temp, quark_str(o_ptr->art_name)); /* MEGA HACK by ita */ if (strncmp(temp, "『", 2) == 0) t = object_desc_str(t, temp); else if (temp[0] == '\'') { itemp = strlen(temp); temp[itemp - 1] = 0; t = object_desc_str(t, "『"); t = object_desc_str(t, &temp[1]); t = object_desc_str(t, "』"); } } else if (o_ptr->name1) { artifact_type *a_ptr = &a_info[o_ptr->name1]; if (strncmp(a_name + a_ptr->name, "『", 2) == 0) { t = object_desc_str(t, a_name + a_ptr->name); } } else if (o_ptr->ego_name) { t = object_desc_str(t, quark_str(o_ptr->ego_name)); } else if (o_ptr->inscription) { cptr str = quark_str(o_ptr->inscription); while(*str) { if (iskanji(*str)) { str += 2; continue; } if (*str == '#') break; str++; } if (*str) { /* Find the '#' */ cptr str = my_strchr(quark_str(o_ptr->inscription), '#'); /* Add the false name */ t = object_desc_str(t,"『"); t = object_desc_str(t, &str[1]); t = object_desc_str(t,"』"); } } } #else /* Hack -- Append "Artifact" or "Special" names */ if (known && !fullname) { /* Is it a new random artifact ? */ if (o_ptr->art_name) { t = object_desc_chr(t, ' '); t = object_desc_str(t, quark_str(o_ptr->art_name)); } /* Grab any artifact name */ else if (o_ptr->name1) { artifact_type *a_ptr = &a_info[o_ptr->name1]; t = object_desc_chr(t, ' '); t = object_desc_str(t, a_name + a_ptr->name); } /* Grab any ego-item name */ else { if (o_ptr->name2) { ego_item_type *e_ptr = &e_info[o_ptr->name2]; t = object_desc_chr(t, ' '); t = object_desc_str(t, e_name + e_ptr->name); } if (o_ptr->ego_name) { t = object_desc_chr(t, ' '); t = object_desc_str(t, quark_str(o_ptr->ego_name)); } else if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '#')) { /* Find the '#' */ cptr str = my_strchr(quark_str(o_ptr->inscription), '#'); /* Add the false name */ t = object_desc_chr(t, ' '); t = object_desc_str(t, &str[1]); } } } #endif /* No more details wanted */ if (mode & OD_NAME_ONLY) goto object_desc_done; /* Hack -- Chests must be described in detail */ if (o_ptr->tval == TV_CHEST) { /* Not searched yet */ if (!known) { /* Nothing */ } /* May be "empty" */ else if (!o_ptr->pval) { #ifdef JP t = object_desc_str(t, "(空)"); #else t = object_desc_str(t, " (empty)"); #endif } /* May be "disarmed" */ else if (o_ptr->pval < 0) { if (chest_traps[0 - o_ptr->pval]) { #ifdef JP t = object_desc_str(t, "(解除済)"); #else t = object_desc_str(t, " (disarmed)"); #endif } else { #ifdef JP t = object_desc_str(t, "(非施錠)"); #else t = object_desc_str(t, " (unlocked)"); #endif } } /* Describe the traps, if any */ else { /* Describe the traps */ switch (chest_traps[o_ptr->pval]) { case 0: { #ifdef JP t = object_desc_str(t, "(施錠)"); #else t = object_desc_str(t, " (Locked)"); #endif break; } case CHEST_LOSE_STR: { #ifdef JP t = object_desc_str(t, "(毒針)"); #else t = object_desc_str(t, " (Poison Needle)"); #endif break; } case CHEST_LOSE_CON: { #ifdef JP t = object_desc_str(t, "(毒針)"); #else t = object_desc_str(t, " (Poison Needle)"); #endif break; } case CHEST_POISON: { #ifdef JP t = object_desc_str(t, "(ガス・トラップ)"); #else t = object_desc_str(t, " (Gas Trap)"); #endif break; } case CHEST_PARALYZE: { #ifdef JP t = object_desc_str(t, "(ガス・トラップ)"); #else t = object_desc_str(t, " (Gas Trap)"); #endif break; } case CHEST_EXPLODE: { #ifdef JP t = object_desc_str(t, "(爆発装置)"); #else t = object_desc_str(t, " (Explosion Device)"); #endif break; } case CHEST_SUMMON: { #ifdef JP t = object_desc_str(t, "(召喚のルーン)"); #else t = object_desc_str(t, " (Summoning Runes)"); #endif break; } default: { #ifdef JP t = object_desc_str(t, "(マルチ・トラップ)"); #else t = object_desc_str(t, " (Multiple Traps)"); #endif break; } } } } /* Display the item like a weapon */ if (f3 & TR3_SHOW_MODS) show_weapon = TRUE; /* Display the item like a weapon */ if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE; /* Display the item like armour */ if (o_ptr->ac) show_armour = TRUE; /* Dump base weapon info */ switch (o_ptr->tval) { /* Missiles and Weapons */ case TV_SHOT: case TV_BOLT: case TV_ARROW: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING: /* Append a "damage" string */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_num(t, o_ptr->dd); t = object_desc_chr(t, 'd'); t = object_desc_num(t, o_ptr->ds); t = object_desc_chr(t, p2); /* All done */ break; /* Bows get a special "damage string" */ case TV_BOW: /* Mega-Hack -- Extract the "base power" */ power = bow_tmul(o_ptr->sval); /* Apply the "Extra Might" flag */ if (f3 & TR3_XTRA_MIGHT) power++; /* Append a special "damage" string */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_chr(t, 'x'); t = object_desc_num(t, power); t = object_desc_chr(t, p2); /* All done */ break; } /* Add the weapon bonuses */ if (known) { /* Show the tohit/todam on request */ if (show_weapon) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_int(t, o_ptr->to_h); t = object_desc_chr(t, ','); t = object_desc_int(t, o_ptr->to_d); t = object_desc_chr(t, p2); } /* Show the tohit if needed */ else if (o_ptr->to_h) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_int(t, o_ptr->to_h); t = object_desc_chr(t, p2); } /* Show the todam if needed */ else if (o_ptr->to_d) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_int(t, o_ptr->to_d); t = object_desc_chr(t, p2); } } bow_ptr = &inventory[INVEN_BOW]; /* If have a firing weapon + ammo matches bow */ if (bow_ptr->k_idx && (o_ptr->tval == p_ptr->tval_ammo)) { int avgdam = o_ptr->dd * (o_ptr->ds + 1) * 10 / 2; int tmul = bow_tmul(bow_ptr->sval); s16b energy_fire = bow_energy(bow_ptr->sval); /* See if the bow is "known" - then set damage bonus */ if (object_known_p(bow_ptr)) avgdam += (bow_ptr->to_d * 10); /* Effect of ammo */ if (known) avgdam += (o_ptr->to_d * 10); /* Get extra "power" from "extra might" */ if (p_ptr->xtra_might) tmul++; tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128); /* Launcher multiplier */ avgdam *= tmul; avgdam /= (100 * 10); if (avgdam < 0) avgdam = 0; /* Display (shot damage/ avg damage) */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); t = object_desc_num(t, avgdam); t = object_desc_chr(t, '/'); if (p_ptr->num_fire == 0) { t = object_desc_chr(t, '0'); } else { /* Calc effects of energy */ avgdam *= (p_ptr->num_fire * 100); avgdam /= energy_fire * 100; t = object_desc_num(t, avgdam); } t = object_desc_chr(t, p2); } /* Add the armor bonuses */ if (known) { /* Show the armor class info */ if (show_armour) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, b1); t = object_desc_num(t, o_ptr->ac); t = object_desc_chr(t, ','); t = object_desc_int(t, o_ptr->to_a); t = object_desc_chr(t, b2); } /* No base armor, but does increase armor */ else if (o_ptr->to_a) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, b1); t = object_desc_int(t, o_ptr->to_a); t = object_desc_chr(t, b2); } } /* Hack -- always show base armor */ else if (show_armour) { t = object_desc_chr(t, ' '); t = object_desc_chr(t, b1); t = object_desc_num(t, o_ptr->ac); t = object_desc_chr(t, b2); } /* No more details wanted */ if (mode & OD_NAME_AND_ENCHANT) goto object_desc_done; if (known) /* Known item only */ { /* * Hack -- Wands and Staffs have charges. Make certain how many charges * a stack of staffs really has is clear. -LM- */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND))) { /* Dump " (N charges)" */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); /* Clear explaination for staffs. */ if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1)) { t = object_desc_num(t, o_ptr->number); t = object_desc_str(t, "x "); } t = object_desc_num(t, o_ptr->pval); #ifdef JP t = object_desc_str(t, "回分"); #else t = object_desc_str(t, " charge"); if (o_ptr->pval != 1) t = object_desc_chr(t, 's'); #endif t = object_desc_chr(t, p2); } /* Hack -- Rods have a "charging" indicator. Now that stacks of rods may * be in any state of charge or discharge, this now includes a number. -LM- */ else if (o_ptr->tval == TV_ROD) { /* Hack -- Dump " (# charging)" if relevant */ if (o_ptr->timeout) { /* Stacks of rods display an exact count of charging rods. */ if (o_ptr->number > 1) { /* Paranoia. */ if (k_ptr->pval == 0) k_ptr->pval = 1; /* Find out how many rods are charging, by dividing * current timeout by each rod's maximum timeout. * Ensure that any remainder is rounded up. Display * very discharged stacks as merely fully discharged. */ power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval; if (power > o_ptr->number) power = o_ptr->number; /* Display prettily. */ t = object_desc_str(t, " ("); t = object_desc_num(t, power); #ifdef JP t = object_desc_str(t, "本 充填中)"); #else t = object_desc_str(t, " charging)"); #endif } /* "one Rod of Perception (1 charging)" would look tacky. */ else { #ifdef JP t = object_desc_str(t, "(充填中)"); #else t = object_desc_str(t, " (charging)"); #endif } } } /* Dump "pval" flags for wearable items */ if (f1 & TR1_PVAL_MASK) { /* Start the display */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, p1); /* Dump the "pval" itself */ t = object_desc_int(t, o_ptr->pval); /* Do not display the "pval" flags */ if (f3 & TR3_HIDE_TYPE) { /* Nothing */ } /* Speed */ else if (f1 & TR1_SPEED) { /* Dump " to speed" */ #ifdef JP t = object_desc_str(t, "加速"); #else t = object_desc_str(t, " to speed"); #endif } /* Attack speed */ else if (f1 & TR1_BLOWS) { /* Add " attack" */ #ifdef JP t = object_desc_str(t, "攻撃"); #else t = object_desc_str(t, " attack"); /* Add "attacks" */ if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's'); #endif } /* Stealth */ else if (f1 & TR1_STEALTH) { /* Dump " to stealth" */ #ifdef JP t = object_desc_str(t, "隠密"); #else t = object_desc_str(t, " to stealth"); #endif } /* Search */ else if (f1 & TR1_SEARCH) { /* Dump " to searching" */ #ifdef JP t = object_desc_str(t, "探索"); #else t = object_desc_str(t, " to searching"); #endif } /* Infravision */ else if (f1 & TR1_INFRA) { /* Dump " to infravision" */ #ifdef JP t = object_desc_str(t, "赤外線視力"); #else t = object_desc_str(t, " to infravision"); #endif } /* Finish the display */ t = object_desc_chr(t, p2); } /* Hack -- Process Lanterns/Torches */ if ((o_ptr->tval == TV_LITE) && ((o_ptr->sval == SV_LITE_TORCH) || (o_ptr->sval == SV_LITE_LANTERN))) { /* Hack -- Turns of light for normal lites */ #ifdef JP t = object_desc_chr(t, '('); #else t = object_desc_str(t, " (with "); #endif t = object_desc_num(t, o_ptr->xtra3); #ifdef JP t = object_desc_str(t, "ターンの寿命)"); #else t = object_desc_str(t, " turns of light)"); #endif } /* Indicate charging objects, but not rods. */ if (o_ptr->timeout && (o_ptr->tval != TV_ROD)) { /* Hack -- Dump " (charging)" if relevant */ #ifdef JP t = object_desc_str(t, "(充填中)"); #else t = object_desc_str(t, " (charging)"); #endif } } /* No more details wanted */ if (mode & OD_OMIT_INSCRIPTION) goto object_desc_done; /* Prepare real inscriptions in a buffer */ tmp_val2[0] = '\0'; /* Auto abbreviation inscribe */ if ((abbrev_extra || abbrev_all) && (o_ptr->ident & IDENT_MENTAL)) { if (!o_ptr->inscription || !my_strchr(quark_str(o_ptr->inscription), '%')) { bool kanji, all; #ifdef JP kanji = TRUE; #else kanji = FALSE; #endif all = abbrev_all; get_ability_abbreviation(tmp_val2, o_ptr, kanji, all, FALSE); } } /* Use the standard inscription if available */ if (o_ptr->inscription) { char buff[1024]; if (tmp_val2[0]) strcat(tmp_val2, ", "); /* Get inscription and convert {%} */ get_inscription(buff, o_ptr); /* strcat with correct treating of kanji */ my_strcat(tmp_val2, buff, sizeof(tmp_val2)); } /* No fake inscription yet */ fake_insc_buf[0] = '\0'; /* Use the game-generated "feeling" otherwise, if available */ if (o_ptr->feeling) { strcpy(fake_insc_buf, game_inscriptions[o_ptr->feeling]); } /* Note "cursed" if the item is known to be cursed */ else if (cursed_p(o_ptr) && (known || (o_ptr->ident & IDENT_SENSE))) { #ifdef JP strcpy(fake_insc_buf, "呪われている"); #else strcpy(fake_insc_buf, "cursed"); #endif } /* Note "unidentified" if the item is unidentified */ else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET) || (o_ptr->tval == TV_LITE) || (o_ptr->tval == TV_FIGURINE)) && aware && !known && !(o_ptr->ident & IDENT_SENSE)) { #ifdef JP strcpy(fake_insc_buf, "未鑑定"); #else strcpy(fake_insc_buf, "unidentified"); #endif } /* Mega-Hack -- note empty wands/staffs */ else if (!known && (o_ptr->ident & IDENT_EMPTY)) { #ifdef JP strcpy(fake_insc_buf, "空"); #else strcpy(fake_insc_buf, "empty"); #endif } /* Note "tried" if the object has been tested unsuccessfully */ else if (!aware && object_tried_p(o_ptr)) { #ifdef JP strcpy(fake_insc_buf, "未判明"); #else strcpy(fake_insc_buf, "tried"); #endif } /* Note the discount, if any */ if (o_ptr->discount) { /* Hidden by real inscription unless in a store */ if (!tmp_val2[0] || (o_ptr->ident & IDENT_STORE)) { char discount_num_buf[4]; /* Append to other fake inscriptions if any */ if (fake_insc_buf[0]) strcat(fake_insc_buf, ", "); (void)object_desc_num(discount_num_buf, o_ptr->discount); strcat(fake_insc_buf, discount_num_buf); #ifdef JP strcat(fake_insc_buf, "%引き"); #else strcat(fake_insc_buf, "% off"); #endif } } /* Append the inscription, if any */ if (fake_insc_buf[0] || tmp_val2[0]) { /* Append the inscription */ t = object_desc_chr(t, ' '); t = object_desc_chr(t, c1); /* Append fake inscriptions */ if (fake_insc_buf[0]) { t = object_desc_str(t, fake_insc_buf); } /* Append a separater */ if (fake_insc_buf[0] && tmp_val2[0]) { t = object_desc_chr(t, ','); t = object_desc_chr(t, ' '); } /* Append real inscriptions */ if (tmp_val2[0]) { t = object_desc_str(t, tmp_val2); } t = object_desc_chr(t, c2); } object_desc_done: my_strcpy(buf, tmp_val, MAX_NLEN); }