OSDN Git Service

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