OSDN Git Service

Bug fix in relation to gaining experience of hex spells
[hengband/hengband.git] / src / hex.c
1 #include "angband.h"
2
3 /* Flag list */
4 /*
5 p_ptr-magic_num1
6 0: Flag bits of spelling spells
7 1: Flag bits of despelled spells
8 2: Revange damage
9 p_ptr->magic_num2
10 0: Number of spelling spells
11 1: Type of revenge
12 2: Turn count for revenge
13 */
14
15 #define MAX_KEEP 4
16
17 bool stop_hex_spell_all(void)
18 {
19         int i;
20
21         for (i = 0; i < 32; i++)
22         {
23                 u32b spell = 1L << i;
24                 if (hex_spelling(spell)) do_spell(REALM_HEX, spell, SPELL_STOP);
25         }
26
27         p_ptr->magic_num1[0] = 0;
28         p_ptr->magic_num2[0] = 0;
29
30         /* Print message */
31         if (p_ptr->action == ACTION_SPELL) set_action(ACTION_NONE);
32
33         /* Redraw status */
34         p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
35         p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
36
37         return TRUE;
38 }
39
40
41 bool stop_hex_spell(void)
42 {
43         int spell;
44         char choice;
45         char out_val[160];
46         bool flag = FALSE;
47         int y = 1;
48         int x = 20;
49         int sp[MAX_KEEP];
50
51         if (!hex_spelling_any())
52         {
53 #ifdef JP
54                 msg_print("¼öʸ¤ò±Ó¾§¤·¤Æ¤¤¤Þ¤»¤ó¡£");
55 #else
56                 msg_print("You are casting no spell.");
57 #endif
58                 return FALSE;
59         }
60
61         /* Stop all spells */
62         else if ((p_ptr->magic_num2[0] == 1) || (p_ptr->lev < 35))
63         {
64                 return stop_hex_spell_all();
65         }
66         else
67         {
68 #ifdef JP
69                 strnfmt(out_val, 78, "¤É¤Î¼öʸ¤Î±Ó¾§¤òÃæÃǤ·¤Þ¤¹¤«¡©(¼öʸ %c-%c, 'l'Á´¤Æ, ESC)",
70                         I2A(0), I2A(p_ptr->magic_num2[0] - 1));
71 #else
72                 strnfmt(out_val, 78, "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)",
73                         I2A(0), I2A(p_ptr->magic_num2[0] - 1));
74 #endif
75
76                 screen_save();
77
78                 while (!flag)
79                 {
80                         int n = 0;
81                         Term_erase(x, y, 255);
82                         prt("     Ì¾Á°", y, x + 5);
83                         for (spell = 0; spell < 32; spell++)
84                         {
85                                 if (hex_spelling(spell))
86                                 {
87                                         Term_erase(x, y + n + 1, 255);
88                                         put_str(format("%c)  %s", I2A(n), do_spell(REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2);
89                                         sp[n++] = spell;
90                                 }
91                         }
92
93                         if (!get_com(out_val, &choice, TRUE)) break;
94                         if (isupper(choice)) choice = tolower(choice);
95
96                         if (choice == 'l')      /* All */
97                         {
98                                 screen_load();
99                                 return stop_hex_spell_all();
100                         }
101                         if ((choice < I2A(0)) || (choice > I2A(p_ptr->magic_num2[0] - 1))) continue;
102                         flag = TRUE;
103                 }
104         }
105
106         screen_load();
107
108         if (flag)
109         {
110                 int n = sp[A2I(choice)];
111
112                 do_spell(REALM_HEX, n, SPELL_STOP);
113                 p_ptr->magic_num1[0] &= ~(1L << n);
114                 p_ptr->magic_num2[0]--;
115         }
116
117         /* Redraw status */
118         p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
119         p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
120
121         return flag;
122 }
123
124
125 /* Upkeeping hex spells
126    Called from dungeon.c */
127 void check_hex(void)
128 {
129         int spell;
130         s32b need_mana;
131         u32b need_mana_frac;
132         bool res = FALSE;
133
134         /* Spells spelled by player */
135         if (p_ptr->realm1 != REALM_HEX) return;
136         if (!p_ptr->magic_num1[0] && !p_ptr->magic_num1[1]) return;
137
138         if (p_ptr->magic_num1[1])
139         {
140                 p_ptr->magic_num1[0] = p_ptr->magic_num1[1];
141                 p_ptr->magic_num1[1] = 0;
142                 res = TRUE;
143         }
144
145         /* Stop all spells when anti-magic ability is given */
146         if (p_ptr->anti_magic)
147         {
148                 stop_hex_spell_all();
149                 return;
150         }
151
152         need_mana = 0;
153         for (spell = 0; spell < 32; spell++)
154         {
155                 if (hex_spelling(spell))
156                 {
157                         const magic_type *s_ptr;
158                         s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
159                         need_mana += mod_need_mana(s_ptr->smana, spell, REALM_HEX);
160                 }
161         }
162
163
164         /* Culcurates final mana cost */
165         need_mana_frac = 0;
166         s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */
167         need_mana += (p_ptr->magic_num2[0] - 1);
168
169
170         /* Not enough mana */
171         if (s64b_cmp(p_ptr->csp, p_ptr->csp_frac, need_mana, need_mana_frac) < 0)
172         {
173                 stop_hex_spell_all();
174                 return;
175         }
176
177         /* Enough mana */
178         else
179         {
180                 s64b_sub(&(p_ptr->csp), &(p_ptr->csp_frac), need_mana, need_mana_frac);
181
182                 p_ptr->redraw |= PR_MANA;
183                 if (res)
184                 {
185 #ifdef JP
186                         msg_print("±Ó¾§¤òºÆ³«¤·¤¿¡£");
187 #else
188                         msg_print("You restart spelling.");
189 #endif
190                         p_ptr->action = ACTION_SPELL;
191
192                         /* Recalculate bonuses */
193                         p_ptr->update |= (PU_BONUS | PU_HP);
194
195                         /* Redraw map and status bar */
196                         p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
197
198                         /* Update monsters */
199                         p_ptr->update |= (PU_MONSTERS);
200
201                         /* Window stuff */
202                         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
203                 }
204         }
205
206         /* Gain experiences of spelling spells */
207         for (spell = 0; spell < 32; spell++)
208         {
209                 const magic_type *s_ptr;
210
211                 if (!hex_spelling(spell)) continue;
212
213                 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
214
215                 if (p_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
216                         p_ptr->spell_exp[spell] += 5;
217                 else if(p_ptr->spell_exp[spell] < SPELL_EXP_SKILLED)
218                 { if (one_in_(2) && (dun_level > 4) && ((dun_level + 10) > p_ptr->lev)) p_ptr->spell_exp[spell] += 1; }
219                 else if(p_ptr->spell_exp[spell] < SPELL_EXP_EXPERT)
220                 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
221                 else if(p_ptr->spell_exp[spell] < SPELL_EXP_MASTER)
222                 { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; }
223         }
224
225         /* Do any effects of continual spells */
226         for (spell = 0; spell < 32; spell++)
227         {
228                 if (hex_spelling(spell))
229                 {
230                         do_spell(REALM_HEX, spell, SPELL_CONT);
231                 }
232         }
233 }
234
235
236 bool hex_spell_fully(void)
237 {
238         int k_max = 0;
239
240         k_max = (p_ptr->lev / 15) + 1;
241
242         /* Paranoia */
243         k_max = MIN(k_max, MAX_KEEP);
244
245         if (p_ptr->magic_num2[0] < k_max) return FALSE;
246
247         return TRUE;
248 }
249
250 void revenge_spell()
251 {
252         if (p_ptr->realm1 != REALM_HEX) return;
253         if (p_ptr->magic_num2[2] <= 0) return;
254
255         switch(p_ptr->magic_num2[1])
256         {
257         case 1: do_spell(REALM_HEX, HEX_PATIENCE, SPELL_CONT); break;
258         case 2: do_spell(REALM_HEX, HEX_REVENGE, SPELL_CONT); break;
259         }
260 }
261
262 void revenge_store(int dam)
263 {
264         if (p_ptr->realm1 != REALM_HEX) return;
265         if (p_ptr->magic_num2[2] <= 0) return;
266
267         p_ptr->magic_num1[2] += dam;
268 }
269
270
271 bool teleport_barrier(int m_idx)
272 {
273         monster_type *m_ptr = &m_list[m_idx];
274         monster_race *r_ptr = &r_info[m_ptr->r_idx];
275
276         if (!hex_spelling(HEX_ANTI_TELE)) return FALSE;
277         if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
278
279         return TRUE;
280 }
281
282
283 bool magic_barrier(int m_idx)
284 {
285         monster_type *m_ptr = &m_list[m_idx];
286         monster_race *r_ptr = &r_info[m_ptr->r_idx];
287
288         if (!hex_spelling(HEX_ANTI_MAGIC)) return FALSE;
289         if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
290
291         return TRUE;
292 }
293
294
295 bool multiply_barrier(int m_idx)
296 {
297         monster_type *m_ptr = &m_list[m_idx];
298         monster_race *r_ptr = &r_info[m_ptr->r_idx];
299
300         if (!hex_spelling(HEX_ANTI_MULTI)) return FALSE;
301         if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
302
303         return TRUE;
304 }