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++)
32 if (hex_spelling(i)) do_spell(REALM_HEX, i, SPELL_STOP);
35 CASTING_HEX_FLAGS(p_ptr) = 0;
36 CASTING_HEX_NUM(p_ptr) = 0;
39 if (p_ptr->action == ACTION_SPELL) set_action(ACTION_NONE);
42 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
43 p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
49 * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する
52 bool stop_hex_spell(void)
62 if (!hex_spelling_any())
65 msg_print("呪文を詠唱していません。");
67 msg_print("You are casting no spell.");
73 else if ((CASTING_HEX_NUM(p_ptr) == 1) || (p_ptr->lev < 35))
75 return stop_hex_spell_all();
80 strnfmt(out_val, 78, "どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)",
81 I2A(0), I2A(CASTING_HEX_NUM(p_ptr) - 1));
83 strnfmt(out_val, 78, "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)",
84 I2A(0), I2A(CASTING_HEX_NUM(p_ptr) - 1));
92 Term_erase(x, y, 255);
94 for (spell = 0; spell < 32; spell++)
96 if (hex_spelling(spell))
98 Term_erase(x, y + n + 1, 255);
99 put_str(format("%c) %s", I2A(n), do_spell(REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2);
104 if (!get_com(out_val, &choice, TRUE)) break;
105 if (isupper(choice)) choice = (char)tolower(choice);
107 if (choice == 'l') /* All */
110 return stop_hex_spell_all();
112 if ((choice < I2A(0)) || (choice > I2A(CASTING_HEX_NUM(p_ptr) - 1))) continue;
121 int n = sp[A2I(choice)];
123 do_spell(REALM_HEX, n, SPELL_STOP);
124 CASTING_HEX_FLAGS(p_ptr) &= ~(1L << n);
125 CASTING_HEX_NUM(p_ptr)--;
129 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
130 p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
137 * @brief 一定時間毎に呪術で消費するMPを処理する /
138 * Upkeeping hex spells Called from dungeon.c
148 /* Spells spelled by player */
149 if (p_ptr->realm1 != REALM_HEX) return;
150 if (!CASTING_HEX_FLAGS(p_ptr) && !p_ptr->magic_num1[1]) return;
152 if (p_ptr->magic_num1[1])
154 p_ptr->magic_num1[0] = p_ptr->magic_num1[1];
155 p_ptr->magic_num1[1] = 0;
159 /* Stop all spells when anti-magic ability is given */
160 if (p_ptr->anti_magic)
162 stop_hex_spell_all();
167 for (spell = 0; spell < 32; spell++)
169 if (hex_spelling(spell))
171 const magic_type *s_ptr;
172 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
173 need_mana += mod_need_mana(s_ptr->smana, spell, REALM_HEX);
178 /* Culcurates final mana cost */
180 s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */
181 need_mana += (CASTING_HEX_NUM(p_ptr) - 1);
184 /* Not enough mana */
185 if (s64b_cmp(p_ptr->csp, p_ptr->csp_frac, need_mana, need_mana_frac) < 0)
187 stop_hex_spell_all();
194 s64b_sub(&(p_ptr->csp), &(p_ptr->csp_frac), need_mana, need_mana_frac);
196 p_ptr->redraw |= PR_MANA;
200 msg_print("詠唱を再開した。");
202 msg_print("You restart spelling.");
204 p_ptr->action = ACTION_SPELL;
206 /* Recalculate bonuses */
207 p_ptr->update |= (PU_BONUS | PU_HP);
209 /* Redraw map and status bar */
210 p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
212 /* Update monsters */
213 p_ptr->update |= (PU_MONSTERS);
216 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
220 /* Gain experiences of spelling spells */
221 for (spell = 0; spell < 32; spell++)
223 const magic_type *s_ptr;
225 if (!hex_spelling(spell)) continue;
227 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
229 if (p_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
230 p_ptr->spell_exp[spell] += 5;
231 else if(p_ptr->spell_exp[spell] < SPELL_EXP_SKILLED)
232 { if (one_in_(2) && (dun_level > 4) && ((dun_level + 10) > p_ptr->lev)) p_ptr->spell_exp[spell] += 1; }
233 else if(p_ptr->spell_exp[spell] < SPELL_EXP_EXPERT)
234 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
235 else if(p_ptr->spell_exp[spell] < SPELL_EXP_MASTER)
236 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
239 /* Do any effects of continual spells */
240 for (spell = 0; spell < 32; spell++)
242 if (hex_spelling(spell))
244 do_spell(REALM_HEX, spell, SPELL_CONT);
250 * @brief プレイヤーの呪術詠唱枠がすでに最大かどうかを返す
251 * @return すでに全枠を利用しているならTRUEを返す
253 bool hex_spell_fully(void)
257 k_max = (p_ptr->lev / 15) + 1;
260 k_max = MIN(k_max, MAX_KEEP);
262 if (CASTING_HEX_NUM(p_ptr) < k_max) return FALSE;
268 * @brief 一定ゲームターン毎に復讐処理の残り期間の判定を行う
271 void revenge_spell(void)
273 if (p_ptr->realm1 != REALM_HEX) return;
274 if (HEX_REVENGE_TURN(p_ptr) <= 0) return;
276 switch(HEX_REVENGE_TYPE(p_ptr))
278 case 1: do_spell(REALM_HEX, HEX_PATIENCE, SPELL_CONT); break;
279 case 2: do_spell(REALM_HEX, HEX_REVENGE, SPELL_CONT); break;
284 * @brief 復讐ダメージの追加を行う
285 * @param dam 蓄積されるダメージ量
288 void revenge_store(HIT_POINT dam)
290 if (p_ptr->realm1 != REALM_HEX) return;
291 if (HEX_REVENGE_TURN(p_ptr) <= 0) return;
293 HEX_REVENGE_POWER(p_ptr) += dam;
298 * @param m_idx 判定の対象となるモンスターID
299 * @return 反テレポートの効果が適用されるならTRUEを返す
301 bool teleport_barrier(MONSTER_IDX m_idx)
303 monster_type *m_ptr = &m_list[m_idx];
304 monster_race *r_ptr = &r_info[m_ptr->r_idx];
306 if (!hex_spelling(HEX_ANTI_TELE)) return FALSE;
307 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
314 * @param m_idx 判定の対象となるモンスターID
315 * @return 反魔法の効果が適用されるならTRUEを返す
317 bool magic_barrier(MONSTER_IDX m_idx)
319 monster_type *m_ptr = &m_list[m_idx];
320 monster_race *r_ptr = &r_info[m_ptr->r_idx];
322 if (!hex_spelling(HEX_ANTI_MAGIC)) return FALSE;
323 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
330 * @param m_idx 判定の対象となるモンスターID
331 * @return 反増殖の効果が適用されるならTRUEを返す
333 bool multiply_barrier(MONSTER_IDX m_idx)
335 monster_type *m_ptr = &m_list[m_idx];
336 monster_race *r_ptr = &r_info[m_ptr->r_idx];
338 if (!hex_spelling(HEX_ANTI_MULTI)) return FALSE;
339 if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;