1 #include "spell-realm/spells-hex.h"
2 #include "core/asking-player.h"
3 #include "floor/floor.h"
4 #include "monster-race/monster-race.h"
5 #include "player/player-effects.h" // todo 相互参照している.
6 #include "player/player-skill.h"
7 #include "realm/realm-hex-numbers.h"
8 #include "spell/spells3.h"
9 #include "spell/spells-execution.h"
10 #include "term/screen-processor.h"
11 #include "util/int-char-converter.h"
12 #include "view/display-messages.h"
14 #define MAX_KEEP 4 /*!<呪術の最大詠唱数 */
17 * @brief プレイヤーが詠唱中の全呪術を停止する
20 bool stop_hex_spell_all(player_type *caster_ptr)
24 for (i = 0; i < 32; i++) {
25 if (hex_spelling(caster_ptr, i))
26 exe_spell(caster_ptr, REALM_HEX, i, SPELL_STOP);
29 casting_hex_flags(caster_ptr) = 0;
30 casting_hex_num(caster_ptr) = 0;
32 if (caster_ptr->action == ACTION_SPELL)
33 set_action(caster_ptr, ACTION_NONE);
35 caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
36 caster_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
42 * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する
45 bool stop_hex_spell(player_type *caster_ptr)
55 if (!hex_spelling_any(caster_ptr)) {
56 msg_print(_("呪文を詠唱していません。", "You are casting no spell."));
61 else if ((casting_hex_num(caster_ptr) == 1) || (caster_ptr->lev < 35)) {
62 return stop_hex_spell_all(caster_ptr);
64 strnfmt(out_val, 78, _("どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)", "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)"),
65 I2A(0), I2A(casting_hex_num(caster_ptr) - 1));
71 Term_erase(x, y, 255);
72 prt(_(" 名前", " Name"), y, x + 5);
73 for (spell = 0; spell < 32; spell++) {
74 if (hex_spelling(caster_ptr, spell)) {
75 Term_erase(x, y + n + 1, 255);
76 put_str(format("%c) %s", I2A(n), exe_spell(caster_ptr, REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2);
81 if (!get_com(out_val, &choice, TRUE))
84 choice = (char)tolower(choice);
86 if (choice == 'l') /* All */
89 return stop_hex_spell_all(caster_ptr);
91 if ((choice < I2A(0)) || (choice > I2A(casting_hex_num(caster_ptr) - 1)))
100 int n = sp[A2I(choice)];
102 exe_spell(caster_ptr, REALM_HEX, n, SPELL_STOP);
103 casting_hex_flags(caster_ptr) &= ~(1L << n);
104 casting_hex_num(caster_ptr)--;
107 caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
108 caster_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
114 * @brief 一定時間毎に呪術で消費するMPを処理する /
115 * Upkeeping hex spells Called from dungeon.c
118 void check_hex(player_type *caster_ptr)
121 MANA_POINT need_mana;
125 /* Spells spelled by player */
126 if (caster_ptr->realm1 != REALM_HEX)
128 if (!casting_hex_flags(caster_ptr) && !caster_ptr->magic_num1[1])
131 if (caster_ptr->magic_num1[1]) {
132 caster_ptr->magic_num1[0] = caster_ptr->magic_num1[1];
133 caster_ptr->magic_num1[1] = 0;
137 /* Stop all spells when anti-magic ability is given */
138 if (caster_ptr->anti_magic) {
139 stop_hex_spell_all(caster_ptr);
144 for (spell = 0; spell < 32; spell++) {
145 if (hex_spelling(caster_ptr, spell)) {
146 const magic_type *s_ptr;
147 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
148 need_mana += mod_need_mana(caster_ptr, s_ptr->smana, spell, REALM_HEX);
152 /* Culcurates final mana cost */
154 s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */
155 need_mana += (casting_hex_num(caster_ptr) - 1);
157 /* Not enough mana */
158 if (s64b_cmp(caster_ptr->csp, caster_ptr->csp_frac, need_mana, need_mana_frac) < 0) {
159 stop_hex_spell_all(caster_ptr);
165 s64b_sub(&(caster_ptr->csp), &(caster_ptr->csp_frac), need_mana, need_mana_frac);
167 caster_ptr->redraw |= PR_MANA;
169 msg_print(_("詠唱を再開した。", "You restart casting."));
171 caster_ptr->action = ACTION_SPELL;
173 caster_ptr->update |= (PU_BONUS | PU_HP);
174 caster_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
175 caster_ptr->update |= (PU_MONSTERS);
176 caster_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
180 /* Gain experiences of spelling spells */
181 for (spell = 0; spell < 32; spell++) {
182 const magic_type *s_ptr;
184 if (!hex_spelling(caster_ptr, spell))
187 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
189 if (caster_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
190 caster_ptr->spell_exp[spell] += 5;
191 else if (caster_ptr->spell_exp[spell] < SPELL_EXP_SKILLED) {
192 if (one_in_(2) && (caster_ptr->current_floor_ptr->dun_level > 4) && ((caster_ptr->current_floor_ptr->dun_level + 10) > caster_ptr->lev))
193 caster_ptr->spell_exp[spell] += 1;
194 } else if (caster_ptr->spell_exp[spell] < SPELL_EXP_EXPERT) {
195 if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev)
196 && ((caster_ptr->current_floor_ptr->dun_level + 5) > s_ptr->slevel))
197 caster_ptr->spell_exp[spell] += 1;
198 } else if (caster_ptr->spell_exp[spell] < SPELL_EXP_MASTER) {
199 if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev) && (caster_ptr->current_floor_ptr->dun_level > s_ptr->slevel))
200 caster_ptr->spell_exp[spell] += 1;
204 /* Do any effects of continual spells */
205 for (spell = 0; spell < 32; spell++) {
206 if (hex_spelling(caster_ptr, spell)) {
207 exe_spell(caster_ptr, REALM_HEX, spell, SPELL_CONT);
213 * @brief プレイヤーの呪術詠唱枠がすでに最大かどうかを返す
214 * @return すでに全枠を利用しているならTRUEを返す
216 bool hex_spell_fully(player_type *caster_ptr)
219 k_max = (caster_ptr->lev / 15) + 1;
220 k_max = MIN(k_max, MAX_KEEP);
221 if (casting_hex_num(caster_ptr) < k_max)
227 * @brief 一定ゲームターン毎に復讐処理の残り期間の判定を行う
230 void revenge_spell(player_type *caster_ptr)
232 if (caster_ptr->realm1 != REALM_HEX)
234 if (hex_revenge_turn(caster_ptr) <= 0)
237 switch (hex_revenge_type(caster_ptr)) {
239 exe_spell(caster_ptr, REALM_HEX, HEX_PATIENCE, SPELL_CONT);
242 exe_spell(caster_ptr, REALM_HEX, HEX_REVENGE, SPELL_CONT);
248 * @brief 復讐ダメージの追加を行う
249 * @param dam 蓄積されるダメージ量
252 void revenge_store(player_type *caster_ptr, HIT_POINT dam)
254 if (caster_ptr->realm1 != REALM_HEX)
256 if (hex_revenge_turn(caster_ptr) <= 0)
259 hex_revenge_power(caster_ptr) += dam;
264 * @param m_idx 判定の対象となるモンスターID
265 * @return 反テレポートの効果が適用されるならTRUEを返す
267 bool teleport_barrier(player_type *caster_ptr, MONSTER_IDX m_idx)
269 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
270 monster_race *r_ptr = &r_info[m_ptr->r_idx];
272 if (!hex_spelling(caster_ptr, HEX_ANTI_TELE))
274 if ((caster_ptr->lev * 3 / 2) < randint1(r_ptr->level))
282 * @param m_idx 判定の対象となるモンスターID
283 * @return 反魔法の効果が適用されるならTRUEを返す
285 bool magic_barrier(player_type *target_ptr, MONSTER_IDX m_idx)
287 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
288 monster_race *r_ptr = &r_info[m_ptr->r_idx];
290 if (!hex_spelling(target_ptr, HEX_ANTI_MAGIC))
292 if ((target_ptr->lev * 3 / 2) < randint1(r_ptr->level))
300 * @param m_idx 判定の対象となるモンスターID
301 * @return 反増殖の効果が適用されるならTRUEを返す
303 bool multiply_barrier(player_type *caster_ptr, MONSTER_IDX m_idx)
305 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
306 monster_race *r_ptr = &r_info[m_ptr->r_idx];
308 if (!hex_spelling(caster_ptr, HEX_ANTI_MULTI))
310 if ((caster_ptr->lev * 3 / 2) < randint1(r_ptr->level))
316 bool hex_spelling(player_type *caster_ptr, int hex) { return (caster_ptr->realm1 == REALM_HEX) && (caster_ptr->magic_num1[0] & (1L << (hex))); }