OSDN Git Service

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