3 * @brief 呪術の処理実装 / Hex code
6 * 2014 Deskull rearranged comment for Doxygen.\n
9 * 0: Flag bits of spelling spells\n
10 * 1: Flag bits of despelled spells\n
13 * 0: Number of spelling spells\n
14 * 1: Type of revenge\n
15 * 2: Turn count for revenge\n
20 #define MAX_KEEP 4 /*!<呪術の最大詠唱数 */
23 * @brief プレイヤーが詠唱中の全呪術を停止する
26 bool stop_hex_spell_all(void)
30 for (i = 0; i < 32; i++)
33 if (hex_spelling(spell)) do_spell(REALM_HEX, spell, SPELL_STOP);
36 p_ptr->magic_num1[0] = 0;
37 p_ptr->magic_num2[0] = 0;
40 if (p_ptr->action == ACTION_SPELL) set_action(ACTION_NONE);
43 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
44 p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
50 * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する
53 bool stop_hex_spell(void)
63 if (!hex_spelling_any())
66 msg_print("呪文を詠唱していません。");
68 msg_print("You are casting no spell.");
74 else if ((p_ptr->magic_num2[0] == 1) || (p_ptr->lev < 35))
76 return stop_hex_spell_all();
81 strnfmt(out_val, 78, "どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)",
82 I2A(0), I2A(p_ptr->magic_num2[0] - 1));
84 strnfmt(out_val, 78, "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)",
85 I2A(0), I2A(p_ptr->magic_num2[0] - 1));
93 Term_erase(x, y, 255);
95 for (spell = 0; spell < 32; spell++)
97 if (hex_spelling(spell))
99 Term_erase(x, y + n + 1, 255);
100 put_str(format("%c) %s", I2A(n), do_spell(REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2);
105 if (!get_com(out_val, &choice, TRUE)) break;
106 if (isupper(choice)) choice = tolower(choice);
108 if (choice == 'l') /* All */
111 return stop_hex_spell_all();
113 if ((choice < I2A(0)) || (choice > I2A(p_ptr->magic_num2[0] - 1))) continue;
122 int n = sp[A2I(choice)];
124 do_spell(REALM_HEX, n, SPELL_STOP);
125 p_ptr->magic_num1[0] &= ~(1L << n);
126 p_ptr->magic_num2[0]--;
130 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
131 p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
138 * @brief 一定時間毎に呪術で消費するMPを処理する /
139 * Upkeeping hex spells Called from dungeon.c
149 /* Spells spelled by player */
150 if (p_ptr->realm1 != REALM_HEX) return;
151 if (!p_ptr->magic_num1[0] && !p_ptr->magic_num1[1]) return;
153 if (p_ptr->magic_num1[1])
155 p_ptr->magic_num1[0] = p_ptr->magic_num1[1];
156 p_ptr->magic_num1[1] = 0;
160 /* Stop all spells when anti-magic ability is given */
161 if (p_ptr->anti_magic)
163 stop_hex_spell_all();
168 for (spell = 0; spell < 32; spell++)
170 if (hex_spelling(spell))
172 const magic_type *s_ptr;
173 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
174 need_mana += mod_need_mana(s_ptr->smana, spell, REALM_HEX);
179 /* Culcurates final mana cost */
181 s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */
182 need_mana += (p_ptr->magic_num2[0] - 1);
185 /* Not enough mana */
186 if (s64b_cmp(p_ptr->csp, p_ptr->csp_frac, need_mana, need_mana_frac) < 0)
188 stop_hex_spell_all();
195 s64b_sub(&(p_ptr->csp), &(p_ptr->csp_frac), need_mana, need_mana_frac);
197 p_ptr->redraw |= PR_MANA;
201 msg_print("詠唱を再開した。");
203 msg_print("You restart spelling.");
205 p_ptr->action = ACTION_SPELL;
207 /* Recalculate bonuses */
208 p_ptr->update |= (PU_BONUS | PU_HP);
210 /* Redraw map and status bar */
211 p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
213 /* Update monsters */
214 p_ptr->update |= (PU_MONSTERS);
217 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
221 /* Gain experiences of spelling spells */
222 for (spell = 0; spell < 32; spell++)
224 const magic_type *s_ptr;
226 if (!hex_spelling(spell)) continue;
228 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
230 if (p_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
231 p_ptr->spell_exp[spell] += 5;
232 else if(p_ptr->spell_exp[spell] < SPELL_EXP_SKILLED)
233 { if (one_in_(2) && (dun_level > 4) && ((dun_level + 10) > p_ptr->lev)) p_ptr->spell_exp[spell] += 1; }
234 else if(p_ptr->spell_exp[spell] < SPELL_EXP_EXPERT)
235 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
236 else if(p_ptr->spell_exp[spell] < SPELL_EXP_MASTER)
237 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
240 /* Do any effects of continual spells */
241 for (spell = 0; spell < 32; spell++)
243 if (hex_spelling(spell))
245 do_spell(REALM_HEX, spell, SPELL_CONT);
251 * @brief プレイヤーの呪術詠唱枠がすでに最大かどうかを返す
252 * @return すでに全枠を利用しているならTRUEを返す
254 bool hex_spell_fully(void)
258 k_max = (p_ptr->lev / 15) + 1;
261 k_max = MIN(k_max, MAX_KEEP);
263 if (p_ptr->magic_num2[0] < k_max) return FALSE;
269 * @brief 一定ゲームターン毎に復讐処理の残り期間の判定を行う
272 void revenge_spell(void)
274 if (p_ptr->realm1 != REALM_HEX) return;
275 if (p_ptr->magic_num2[2] <= 0) return;
277 switch(p_ptr->magic_num2[1])
279 case 1: do_spell(REALM_HEX, HEX_PATIENCE, SPELL_CONT); break;
280 case 2: do_spell(REALM_HEX, HEX_REVENGE, SPELL_CONT); break;
285 * @brief 復讐ダメージの追加を行う
286 * @param dam 蓄積されるダメージ量
289 void revenge_store(int dam)
291 if (p_ptr->realm1 != REALM_HEX) return;
292 if (p_ptr->magic_num2[2] <= 0) return;
294 p_ptr->magic_num1[2] += dam;
299 * @param m_idx 判定の対象となるモンスターID
300 * @return 反テレポートの効果が適用されるならTRUEを返す
302 bool teleport_barrier(int m_idx)
304 monster_type *m_ptr = &m_list[m_idx];
305 monster_race *r_ptr = &r_info[m_ptr->r_idx];
307 if (!hex_spelling(HEX_ANTI_TELE)) return FALSE;
308 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
315 * @param m_idx 判定の対象となるモンスターID
316 * @return 反魔法の効果が適用されるならTRUEを返す
318 bool magic_barrier(int m_idx)
320 monster_type *m_ptr = &m_list[m_idx];
321 monster_race *r_ptr = &r_info[m_ptr->r_idx];
323 if (!hex_spelling(HEX_ANTI_MAGIC)) return FALSE;
324 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
331 * @param m_idx 判定の対象となるモンスターID
332 * @return 反増殖の効果が適用されるならTRUEを返す
334 bool multiply_barrier(int m_idx)
336 monster_type *m_ptr = &m_list[m_idx];
337 monster_race *r_ptr = &r_info[m_ptr->r_idx];
339 if (!hex_spelling(HEX_ANTI_MULTI)) return FALSE;
340 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;