2 * @brief 自己分析処理/ Self knowledge
6 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7 * This software may be copied and distributed for educational, research,
8 * and not for profit purposes provided that this copyright and statement
9 * are included in all such copies. Other copyrights may also apply.
13 #include "player-info/self-info.h"
14 #include "avatar/avatar.h"
15 #include "io/input-key-acceptor.h"
16 #include "object-enchant/trc-types.h"
17 #include "player-info/base-status-info.h"
18 #include "player-info/body-improvement-info.h"
19 #include "player-info/class-ability-info.h"
20 #include "player-info/mutation-info.h"
21 #include "player-info/race-ability-info.h"
22 #include "player-info/race-info.h"
23 #include "player-info/resistance-info.h"
24 #include "player-info/self-info-util.h"
25 #include "player-info/weapon-effect-info.h"
26 #include "player/attack-defense-types.h"
27 #include "player/player-status-flags.h"
28 #include "player/player-status.h"
29 #include "system/player-type-definition.h"
30 #include "term/gameterm.h"
31 #include "term/screen-processor.h"
32 #include "term/z-form.h"
33 #include "timed-effect/player-blindness.h"
34 #include "timed-effect/player-confusion.h"
35 #include "timed-effect/player-cut.h"
36 #include "timed-effect/player-fear.h"
37 #include "timed-effect/player-hallucination.h"
38 #include "timed-effect/player-poison.h"
39 #include "timed-effect/player-stun.h"
40 #include "timed-effect/timed-effects.h"
41 #include "view/display-self-info.h"
43 static void set_bad_status_info(PlayerType *player_ptr, self_info_type *self_ptr)
45 auto effects = player_ptr->effects();
46 if (effects->blindness()->is_blind()) {
47 self_ptr->info_list.emplace_back(_("あなたは目が見えない。", "You cannot see."));
50 if (effects->confusion()->is_confused()) {
51 self_ptr->info_list.emplace_back(_("あなたは混乱している。", "You are confused."));
54 if (effects->fear()->is_fearful()) {
55 self_ptr->info_list.emplace_back(_("あなたは恐怖に侵されている。", "You are terrified."));
58 if (effects->cut()->is_cut()) {
59 self_ptr->info_list.emplace_back(_("あなたは出血している。", "You are bleeding."));
62 if (effects->stun()->is_stunned()) {
63 self_ptr->info_list.emplace_back(_("あなたはもうろうとしている。", "You are stunned."));
66 if (effects->poison()->is_poisoned()) {
67 self_ptr->info_list.emplace_back(_("あなたは毒に侵されている。", "You are poisoned."));
70 if (effects->hallucination()->is_hallucinated()) {
71 self_ptr->info_list.emplace_back(_("あなたは幻覚を見ている。", "You are hallucinating."));
75 static void set_curse_info(PlayerType *player_ptr, self_info_type *self_ptr)
77 if (player_ptr->cursed.has(CurseTraitType::TY_CURSE)) {
78 self_ptr->info_list.emplace_back(_("あなたは邪悪な怨念に包まれている。", "You carry an ancient foul curse."));
81 if (has_aggravate(player_ptr)) {
82 self_ptr->info_list.emplace_back(_("あなたはモンスターを怒らせている。", "You aggravate monsters."));
85 if (player_ptr->cursed.has(CurseTraitType::DRAIN_EXP)) {
86 self_ptr->info_list.emplace_back(_("あなたは経験値を吸われている。", "You occasionally lose experience for no reason."));
89 if (player_ptr->cursed.has(CurseTraitType::SLOW_REGEN)) {
90 self_ptr->info_list.emplace_back(_("あなたの回復力は非常に遅い。", "You regenerate slowly."));
93 if (player_ptr->cursed.has(CurseTraitType::ADD_L_CURSE)) {
94 self_ptr->info_list.emplace_back(_("あなたの弱い呪いは増える。", "Your weak curses multiply."));
97 if (player_ptr->cursed.has(CurseTraitType::ADD_H_CURSE)) {
98 self_ptr->info_list.emplace_back(_("あなたの強い呪いは増える。", "Your heavy curses multiply."));
101 if (player_ptr->cursed.has(CurseTraitType::CALL_ANIMAL)) {
102 self_ptr->info_list.emplace_back(_("あなたは動物に狙われている。", "You attract animals."));
105 if (player_ptr->cursed.has(CurseTraitType::CALL_DEMON)) {
106 self_ptr->info_list.emplace_back(_("あなたは悪魔に狙われている。", "You attract demons."));
109 if (player_ptr->cursed.has(CurseTraitType::CALL_DRAGON)) {
110 self_ptr->info_list.emplace_back(_("あなたはドラゴンに狙われている。", "You attract dragons."));
113 if (player_ptr->cursed.has(CurseTraitType::COWARDICE)) {
114 self_ptr->info_list.emplace_back(_("あなたは時々臆病になる。", "You are subject to cowardice."));
117 if (player_ptr->cursed.has(CurseTraitType::BERS_RAGE)) {
118 self_ptr->info_list.emplace_back(_("あなたは狂戦士化の発作を起こす。", "You are subject to berserker fits."));
121 if (player_ptr->cursed.has(CurseTraitType::TELEPORT)) {
122 self_ptr->info_list.emplace_back(_("あなたの位置はひじょうに不安定だ。", "Your position is very uncertain."));
125 if (player_ptr->cursed.has(CurseTraitType::LOW_MELEE)) {
126 self_ptr->info_list.emplace_back(_("あなたの武器は攻撃を外しやすい。", "Your weapon causes you to miss blows."));
129 if (player_ptr->cursed.has(CurseTraitType::LOW_AC)) {
130 self_ptr->info_list.emplace_back(_("あなたは攻撃を受けやすい。", "You are subject to be hit."));
133 if (player_ptr->cursed.has(CurseTraitType::HARD_SPELL)) {
134 self_ptr->info_list.emplace_back(_("あなたは魔法を失敗しやすい。", "Your spells fail more frequently."));
137 if (player_ptr->cursed.has(CurseTraitType::FAST_DIGEST)) {
138 self_ptr->info_list.emplace_back(_("あなたはすぐお腹がへる。", "You have a good appetite."));
141 if (player_ptr->cursed.has(CurseTraitType::DRAIN_HP)) {
142 self_ptr->info_list.emplace_back(_("あなたは体力を吸われている。", "You occasionally lose hit points for no reason."));
145 if (player_ptr->cursed.has(CurseTraitType::DRAIN_MANA)) {
146 self_ptr->info_list.emplace_back(_("あなたは魔力を吸われている。", "You occasionally lose spell points for no reason."));
150 static void set_special_attack_info(PlayerType *player_ptr, self_info_type *self_ptr)
152 if (player_ptr->special_attack & ATTACK_CONFUSE) {
153 self_ptr->info_list.emplace_back(_("あなたの手は赤く輝いている。", "Your hands are glowing dull red."));
156 if (player_ptr->special_attack & ATTACK_FIRE) {
157 self_ptr->info_list.emplace_back(_("あなたの手は火炎に覆われている。", "You can strike the enemy with flame."));
160 if (player_ptr->special_attack & ATTACK_COLD) {
161 self_ptr->info_list.emplace_back(_("あなたの手は冷気に覆われている。", "You can strike the enemy with cold."));
164 if (player_ptr->special_attack & ATTACK_ACID) {
165 self_ptr->info_list.emplace_back(_("あなたの手は酸に覆われている。", "You can strike the enemy with acid."));
168 if (player_ptr->special_attack & ATTACK_ELEC) {
169 self_ptr->info_list.emplace_back(_("あなたの手は電撃に覆われている。", "You can strike the enemy with electoric shock."));
172 if (player_ptr->special_attack & ATTACK_POIS) {
173 self_ptr->info_list.emplace_back(_("あなたの手は毒に覆われている。", "You can strike the enemy with poison."));
177 static void set_esp_info(PlayerType *player_ptr, self_info_type *self_ptr)
179 if (player_ptr->telepathy) {
180 self_ptr->info_list.emplace_back(_("あなたはテレパシー能力を持っている。", "You have ESP."));
183 if (player_ptr->esp_animal) {
184 self_ptr->info_list.emplace_back(_("あなたは自然界の生物の存在を感じる能力を持っている。", "You sense natural creatures."));
187 if (player_ptr->esp_undead) {
188 self_ptr->info_list.emplace_back(_("あなたはアンデッドの存在を感じる能力を持っている。", "You sense undead."));
191 if (player_ptr->esp_demon) {
192 self_ptr->info_list.emplace_back(_("あなたは悪魔の存在を感じる能力を持っている。", "You sense demons."));
195 if (player_ptr->esp_orc) {
196 self_ptr->info_list.emplace_back(_("あなたはオークの存在を感じる能力を持っている。", "You sense orcs."));
199 if (player_ptr->esp_troll) {
200 self_ptr->info_list.emplace_back(_("あなたはトロルの存在を感じる能力を持っている。", "You sense trolls."));
203 if (player_ptr->esp_giant) {
204 self_ptr->info_list.emplace_back(_("あなたは巨人の存在を感じる能力を持っている。", "You sense giants."));
207 if (player_ptr->esp_dragon) {
208 self_ptr->info_list.emplace_back(_("あなたはドラゴンの存在を感じる能力を持っている。", "You sense dragons."));
211 if (player_ptr->esp_human) {
212 self_ptr->info_list.emplace_back(_("あなたは人間の存在を感じる能力を持っている。", "You sense humans."));
215 if (player_ptr->esp_evil) {
216 self_ptr->info_list.emplace_back(_("あなたは邪悪な生き物の存在を感じる能力を持っている。", "You sense evil creatures."));
219 if (player_ptr->esp_good) {
220 self_ptr->info_list.emplace_back(_("あなたは善良な生き物の存在を感じる能力を持っている。", "You sense good creatures."));
223 if (player_ptr->esp_nonliving) {
224 self_ptr->info_list.emplace_back(_("あなたは活動する無生物体の存在を感じる能力を持っている。", "You sense non-living creatures."));
227 if (player_ptr->esp_unique) {
228 self_ptr->info_list.emplace_back(_("あなたは特別な強敵の存在を感じる能力を持っている。", "You sense unique monsters."));
233 * @brief 自己分析処理(Nethackからのアイデア) / self-knowledge... idea from nethack.
236 * Useful for determining powers and
237 * resistences of items. It saves the screen, clears it, then starts listing
238 * attributes, a screenful at a time. (There are a LOT of attributes to
239 * list. It will probably take 2 or 3 screens for a powerful character whose
240 * using several artifacts...) -CFT
242 * It is now a lot more efficient. -BEN-
244 * See also "identify_fully()".
246 * Use the "show_file()" method, perhaps.
249 void self_knowledge(PlayerType *player_ptr)
251 self_info_type tmp_si;
252 self_info_type *self_ptr = &tmp_si;
253 display_life_rating(player_ptr, self_ptr);
254 chg_virtue(player_ptr, Virtue::KNOWLEDGE, 1);
255 chg_virtue(player_ptr, Virtue::ENLIGHTEN, 1);
256 display_max_base_status(player_ptr, self_ptr);
257 display_virtue(player_ptr, self_ptr);
258 self_ptr->info_list.emplace_back("");
259 if (player_ptr->mimic_form != MimicKindType::NONE) {
260 display_mimic_race_ability(player_ptr, self_ptr);
262 set_race_ability_info(player_ptr, self_ptr);
265 set_class_ability_info(player_ptr, self_ptr);
266 set_mutation_info(player_ptr, self_ptr);
267 set_bad_status_info(player_ptr, self_ptr);
268 set_curse_info(player_ptr, self_ptr);
269 set_body_improvement_info_1(player_ptr, self_ptr);
270 set_special_attack_info(player_ptr, self_ptr);
271 switch (player_ptr->action) {
273 self_ptr->info_list.emplace_back(_("あなたはひじょうに注意深く周囲を見渡している。", "You are looking around very carefully."));
277 set_body_improvement_info_2(player_ptr, self_ptr);
278 set_esp_info(player_ptr, self_ptr);
279 set_body_improvement_info_3(player_ptr, self_ptr);
280 set_element_resistance_info(player_ptr, self_ptr);
281 set_high_resistance_info(player_ptr, self_ptr);
282 set_body_improvement_info_4(player_ptr, self_ptr);
283 set_status_sustain_info(player_ptr, self_ptr);
284 set_equipment_influence(player_ptr, self_ptr);
285 set_weapon_effect_info(player_ptr, self_ptr);
286 display_self_info(self_ptr);
290 * @brief 魔法効果時間のターン数に基づいて表現IDを返す。
294 static int report_magics_aux(int dur)
298 } else if (dur <= 10) {
300 } else if (dur <= 20) {
302 } else if (dur <= 50) {
304 } else if (dur <= 100) {
306 } else if (dur <= 200) {
313 static concptr report_magic_durations[] = { _("ごく短い間", "for a short time"), _("少しの間", "for a little while"), _("しばらくの間", "for a while"),
314 _("多少長い間", "for a long while"), _("長い間", "for a long time"), _("非常に長い間", "for a very long time"),
315 _("信じ難いほど長い間", "for an incredibly long time"), _("モンスターを攻撃するまで", "until you hit a monster") };
318 * @brief 現在の一時的効果一覧を返す / Report all currently active magical effects.
320 void report_magics(PlayerType *player_ptr)
325 const auto effects = player_ptr->effects();
326 const auto blindness = effects->blindness();
327 if (blindness->is_blind()) {
328 info2[i] = report_magics_aux(blindness->current());
329 info[i++] = _("あなたは目が見えない", "You cannot see");
332 const auto confusion = effects->confusion();
333 if (confusion->is_confused()) {
334 info2[i] = report_magics_aux(confusion->current());
335 info[i++] = _("あなたは混乱している", "You are confused");
338 if (effects->fear()->is_fearful()) {
339 info2[i] = report_magics_aux(effects->fear()->current());
340 info[i++] = _("あなたは恐怖に侵されている", "You are terrified");
343 const auto player_poison = effects->poison();
344 if (player_poison->is_poisoned()) {
345 info2[i] = report_magics_aux(player_poison->current());
346 info[i++] = _("あなたは毒に侵されている", "You are poisoned");
349 auto hallucination = effects->hallucination();
350 if (hallucination->is_hallucinated()) {
351 info2[i] = report_magics_aux(hallucination->current());
352 info[i++] = _("あなたは幻覚を見ている", "You are hallucinating");
355 if (player_ptr->blessed) {
356 info2[i] = report_magics_aux(player_ptr->blessed);
357 info[i++] = _("あなたは高潔さを感じている", "You feel rightous");
360 if (player_ptr->hero) {
361 info2[i] = report_magics_aux(player_ptr->hero);
362 info[i++] = _("あなたはヒーロー気分だ", "You feel heroic");
365 if (is_shero(player_ptr)) {
366 info2[i] = report_magics_aux(player_ptr->shero);
367 info[i++] = _("あなたは戦闘狂だ", "You are in a battle rage");
370 if (player_ptr->protevil) {
371 info2[i] = report_magics_aux(player_ptr->protevil);
372 info[i++] = _("あなたは邪悪なる存在から守られている", "You are protected from evil");
375 if (player_ptr->shield) {
376 info2[i] = report_magics_aux(player_ptr->shield);
377 info[i++] = _("あなたは神秘のシールドで守られている", "You are protected by a mystic shield");
380 if (player_ptr->invuln) {
381 info2[i] = report_magics_aux(player_ptr->invuln);
382 info[i++] = _("あなたは無敵だ", "You are invulnerable");
385 if (player_ptr->wraith_form) {
386 info2[i] = report_magics_aux(player_ptr->wraith_form);
387 info[i++] = _("あなたは幽体化している", "You are incorporeal");
390 if (player_ptr->special_attack & ATTACK_CONFUSE) {
392 info[i++] = _("あなたの手は赤く輝いている", "Your hands are glowing dull red.");
395 if (player_ptr->word_recall) {
396 info2[i] = report_magics_aux(player_ptr->word_recall);
397 info[i++] = _("この後帰還の詔が発動する", "You are waiting to be recalled");
400 if (player_ptr->alter_reality) {
401 info2[i] = report_magics_aux(player_ptr->alter_reality);
402 info[i++] = _("この後現実変容が発動する", "You waiting to be altered");
405 if (player_ptr->oppose_acid) {
406 info2[i] = report_magics_aux(player_ptr->oppose_acid);
407 info[i++] = _("あなたは酸への耐性を持っている", "You are resistant to acid");
410 if (player_ptr->oppose_elec) {
411 info2[i] = report_magics_aux(player_ptr->oppose_elec);
412 info[i++] = _("あなたは電撃への耐性を持っている", "You are resistant to lightning");
415 if (player_ptr->oppose_fire) {
416 info2[i] = report_magics_aux(player_ptr->oppose_fire);
417 info[i++] = _("あなたは火への耐性を持っている", "You are resistant to fire");
420 if (player_ptr->oppose_cold) {
421 info2[i] = report_magics_aux(player_ptr->oppose_cold);
422 info[i++] = _("あなたは冷気への耐性を持っている", "You are resistant to cold");
425 if (player_ptr->oppose_pois) {
426 info2[i] = report_magics_aux(player_ptr->oppose_pois);
427 info[i++] = _("あなたは毒への耐性を持っている", "You are resistant to poison");
432 /* Erase the screen */
433 for (int k = 1; k < MAIN_TERM_MIN_ROWS; k++) {
437 prt(_(" 現在かかっている魔法 :", " Your Current Magic:"), 1, 15);
440 for (int j = 0; j < i; j++) {
441 strnfmt(buf, sizeof(buf), _("%-28s : 期間 - %s ", "%s %s."), info[j], report_magic_durations[info2[j]]);
444 /* Every 20 entries (lines 2 to 21), start over */
445 if ((k == 22) && (j + 1 < i)) {
446 prt(_("-- 続く --", "-- more --"), k, 15);
454 prt(_("[何かキーを押すとゲームに戻ります]", "[Press any key to continue]"), k, 13);