OSDN Git Service

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