OSDN Git Service

[Refactor] #40514 player_type の two_handed_weapon を廃止して have_two_handed_weapons(...
[hengband/hengband.git] / src / window / display-sub-window-spells.c
1 #include "window/display-sub-window-spells.h"
2 #include "core/window-redrawer.h"
3 #include "game-option/option-flags.h"
4 #include "mind/mind-sniper.h"
5 #include "mind/mind-explanations-table.h"
6 #include "mind/mind-info.h"
7 #include "mind/mind-types.h"
8 #include "player/player-class.h"
9 #include "realm/realm-names-table.h"
10 #include "spell/spells-execution.h"
11 #include "spell/technic-info-table.h"
12 #include "term/gameterm.h"
13 #include "term/screen-processor.h"
14 #include "term/term-color-types.h"
15 #include "util/int-char-converter.h"
16 #include "view/display-messages.h"
17
18 /*!
19  * @brief クリーチャー全既知呪文を表示する /
20  * Hack -- Display all known spells in a window
21  * @param caster_ptr 術者の参照ポインタ
22  * return なし
23  * @details
24  * Need to analyze size of the window.
25  * Need more color coding.
26  */
27 static void display_spell_list(player_type *caster_ptr)
28 {
29     TERM_LEN y, x;
30     int m[9];
31     const magic_type *s_ptr;
32     GAME_TEXT name[MAX_NLEN];
33     char out_val[160];
34
35     clear_from(0);
36
37     if (caster_ptr->pclass == CLASS_SORCERER)
38         return;
39     if (caster_ptr->pclass == CLASS_RED_MAGE)
40         return;
41     if (caster_ptr->pclass == CLASS_SNIPER) {
42         display_snipe_list(caster_ptr);
43         return;
44     }
45
46     if ((caster_ptr->pclass == CLASS_MINDCRAFTER) || (caster_ptr->pclass == CLASS_BERSERKER) || (caster_ptr->pclass == CLASS_NINJA)
47         || (caster_ptr->pclass == CLASS_MIRROR_MASTER) || (caster_ptr->pclass == CLASS_FORCETRAINER)) {
48         PERCENTAGE minfail = 0;
49         PLAYER_LEVEL plev = caster_ptr->lev;
50         PERCENTAGE chance = 0;
51         mind_type spell;
52         char comment[80];
53         char psi_desc[80];
54         int use_mind;
55         bool use_hp = FALSE;
56
57         y = 1;
58         x = 1;
59
60         prt("", y, x);
61         put_str(_("名前", "Name"), y, x + 5);
62         put_str(_("Lv   MP 失率 効果", "Lv Mana Fail Info"), y, x + 35);
63
64         switch (caster_ptr->pclass) {
65         case CLASS_MINDCRAFTER:
66             use_mind = MIND_MINDCRAFTER;
67             break;
68         case CLASS_FORCETRAINER:
69             use_mind = MIND_KI;
70             break;
71         case CLASS_BERSERKER:
72             use_mind = MIND_BERSERKER;
73             use_hp = TRUE;
74             break;
75         case CLASS_MIRROR_MASTER:
76             use_mind = MIND_MIRROR_MASTER;
77             break;
78         case CLASS_NINJA:
79             use_mind = MIND_NINJUTSU;
80             use_hp = TRUE;
81             break;
82         default:
83             use_mind = 0;
84             break;
85         }
86
87         for (int i = 0; i < MAX_MIND_POWERS; i++) {
88             byte a = TERM_WHITE;
89             spell = mind_powers[use_mind].info[i];
90             if (spell.min_lev > plev)
91                 break;
92
93             chance = spell.fail;
94             chance -= 3 * (caster_ptr->lev - spell.min_lev);
95             chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
96             if (!use_hp) {
97                 if (spell.mana_cost > caster_ptr->csp) {
98                     chance += 5 * (spell.mana_cost - caster_ptr->csp);
99                     a = TERM_ORANGE;
100                 }
101             } else {
102                 if (spell.mana_cost > caster_ptr->chp) {
103                     chance += 100;
104                     a = TERM_RED;
105                 }
106             }
107
108             minfail = adj_mag_fail[caster_ptr->stat_ind[mp_ptr->spell_stat]];
109             if (chance < minfail)
110                 chance = minfail;
111
112             if (caster_ptr->stun > 50)
113                 chance += 25;
114             else if (caster_ptr->stun)
115                 chance += 15;
116
117             if (chance > 95)
118                 chance = 95;
119
120             mindcraft_info(caster_ptr, comment, use_mind, i);
121             sprintf(psi_desc, "  %c) %-30s%2d %4d %3d%%%s", I2A(i), spell.name, spell.min_lev, spell.mana_cost, chance, comment);
122
123             term_putstr(x, y + i + 1, -1, a, psi_desc);
124         }
125
126         return;
127     }
128
129     if (REALM_NONE == caster_ptr->realm1)
130         return;
131
132     for (int j = 0; j < ((caster_ptr->realm2 > REALM_NONE) ? 2 : 1); j++) {
133         m[j] = 0;
134         y = (j < 3) ? 0 : (m[j - 3] + 2);
135         x = 27 * (j % 3);
136         int n = 0;
137         for (int i = 0; i < 32; i++) {
138             byte a = TERM_WHITE;
139
140             if (!is_magic((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2)) {
141                 s_ptr = &technic_info[((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2) - MIN_TECHNIC][i % 32];
142             } else {
143                 s_ptr = &mp_ptr->info[((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2) - 1][i % 32];
144             }
145
146             strcpy(name, exe_spell(caster_ptr, (j < 1) ? caster_ptr->realm1 : caster_ptr->realm2, i % 32, SPELL_NAME));
147
148             if (s_ptr->slevel >= 99) {
149                 strcpy(name, _("(判読不能)", "(illegible)"));
150                 a = TERM_L_DARK;
151             } else if ((j < 1) ? ((caster_ptr->spell_forgotten1 & (1L << i))) : ((caster_ptr->spell_forgotten2 & (1L << (i % 32))))) {
152                 a = TERM_ORANGE;
153             } else if (!((j < 1) ? (caster_ptr->spell_learned1 & (1L << i)) : (caster_ptr->spell_learned2 & (1L << (i % 32))))) {
154                 a = TERM_RED;
155             } else if (!((j < 1) ? (caster_ptr->spell_worked1 & (1L << i)) : (caster_ptr->spell_worked2 & (1L << (i % 32))))) {
156                 a = TERM_YELLOW;
157             }
158
159             sprintf(out_val, "%c/%c) %-20.20s", I2A(n / 8), I2A(n % 8), name);
160
161             m[j] = y + n;
162             term_putstr(x, m[j], -1, a, out_val);
163             n++;
164         }
165     }
166 }
167
168 /*!
169  * @brief 現在の習得済魔法をサブウィンドウに表示する /
170  * @param player_ptr プレーヤーへの参照ポインタ
171  * Hack -- display spells in sub-windows
172  * @return なし
173  */
174 void fix_spell(player_type *player_ptr)
175 {
176     for (int j = 0; j < 8; j++) {
177         term_type *old = Term;
178         if (!angband_term[j])
179             continue;
180
181         if (!(window_flag[j] & (PW_SPELL)))
182             continue;
183
184         term_activate(angband_term[j]);
185         display_spell_list(player_ptr);
186         term_fresh();
187         term_activate(old);
188     }
189 }