OSDN Git Service

Calcuration of magnification of hissatsu technics is devided from tot_dam_aux into...
[hengband/hengband.git] / src / hissatsu.c
1 /* File: mind.c */
2
3 /* Purpose: Mindcrafter code */
4
5 /*
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  */
12
13 #include "angband.h"
14
15 #define TECHNIC_HISSATSU (REALM_HISSATSU - MIN_TECHNIC)
16
17 /*
18  * Allow user to choose a mindcrafter power.
19  *
20  * If a valid spell is chosen, saves it in '*sn' and returns TRUE
21  * If the user hits escape, returns FALSE, and set '*sn' to -1
22  * If there are no legal choices, returns FALSE, and sets '*sn' to -2
23  *
24  * The "prompt" should be "cast", "recite", or "study"
25  * The "known" should be TRUE for cast/pray, FALSE for study
26  *
27  * nb: This function has a (trivial) display bug which will be obvious
28  * when you run it. It's probably easy to fix but I haven't tried,
29  * sorry.
30  */
31 static int get_hissatsu_power(int *sn)
32 {
33         int             i, j = 0;
34         int             num = 0;
35         int             y = 1;
36         int             x = 15;
37         int             plev = p_ptr->lev;
38         int             ask = TRUE;
39         char            choice;
40         char            out_val[160];
41         char sentaku[32];
42 #ifdef JP
43 cptr            p = "ɬ»¦·õ";
44 #else
45         cptr            p = "special attack";
46 #endif
47
48         magic_type spell;
49         bool            flag, redraw;
50         int menu_line = (use_menu ? 1 : 0);
51
52         /* Assume cancelled */
53         *sn = (-1);
54
55 #ifdef ALLOW_REPEAT /* TNB */
56
57         /* Get the spell, if available */
58         if (repeat_pull(sn))
59         {
60                 /* Verify the spell */
61                 if (technic_info[TECHNIC_HISSATSU][*sn].slevel <= plev)
62                 {
63                         /* Success */
64                         return (TRUE);
65                 }
66         }
67
68 #endif /* ALLOW_REPEAT -- TNB */
69
70         /* Nothing chosen yet */
71         flag = FALSE;
72
73         /* No redraw yet */
74         redraw = FALSE;
75
76         for (i = 0; i < 32; i++)
77         {
78                 if (technic_info[TECHNIC_HISSATSU][i].slevel <= PY_MAX_LEVEL)
79                 {
80                         sentaku[num] = i;
81                         num++;
82                 }
83         }
84
85         /* Build a prompt (accept all spells) */
86         (void) strnfmt(out_val, 78, 
87 #ifdef JP
88                        "(%^s %c-%c, '*'¤Ç°ìÍ÷, ESC) ¤É¤Î%s¤ò»È¤¤¤Þ¤¹¤«¡©",
89 #else
90                        "(%^ss %c-%c, *=List, ESC=exit) Use which %s? ",
91 #endif
92                        p, I2A(0), "abcdefghijklmnopqrstuvwxyz012345"[num-1], p);
93
94         if (use_menu) screen_save();
95
96         /* Get a spell from the user */
97
98         choice= always_show_list ? ESCAPE:1 ;
99         while (!flag)
100         {
101                 if(choice==ESCAPE) choice = ' '; 
102                 else if( !get_com(out_val, &choice, FALSE) )break;
103
104                 if (use_menu && choice != ' ')
105                 {
106                         switch(choice)
107                         {
108                                 case '0':
109                                 {
110                                         screen_load();
111                                         return (FALSE);
112                                 }
113
114                                 case '8':
115                                 case 'k':
116                                 case 'K':
117                                 {
118                                         do
119                                         {
120                                                 menu_line += 31;
121                                                 if (menu_line > 32) menu_line -= 32;
122                                         } while(!(p_ptr->spell_learned1 & (1L << (menu_line-1))));
123                                         break;
124                                 }
125
126                                 case '2':
127                                 case 'j':
128                                 case 'J':
129                                 {
130                                         do
131                                         {
132                                                 menu_line++;
133                                                 if (menu_line > 32) menu_line -= 32;
134                                         } while(!(p_ptr->spell_learned1 & (1L << (menu_line-1))));
135                                         break;
136                                 }
137
138                                 case '4':
139                                 case 'h':
140                                 case 'H':
141                                 case '6':
142                                 case 'l':
143                                 case 'L':
144                                 {
145                                         bool reverse = FALSE;
146                                         if ((choice == '4') || (choice == 'h') || (choice == 'H')) reverse = TRUE;
147                                         if (menu_line > 16)
148                                         {
149                                                 menu_line -= 16;
150                                                 reverse = TRUE;
151                                         }
152                                         else menu_line+=16;
153                                         while(!(p_ptr->spell_learned1 & (1L << (menu_line-1))))
154                                         {
155                                                 if (reverse)
156                                                 {
157                                                         menu_line--;
158                                                         if (menu_line < 2) reverse = FALSE;
159                                                 }
160                                                 else
161                                                 {
162                                                         menu_line++;
163                                                         if (menu_line > 31) reverse = TRUE;
164                                                 }
165                                         }
166                                         break;
167                                 }
168
169                                 case 'x':
170                                 case 'X':
171                                 case '\r':
172                                 case '\n':
173                                 {
174                                         i = menu_line - 1;
175                                         ask = FALSE;
176                                         break;
177                                 }
178                         }
179                 }
180                 /* Request redraw */
181                 if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask))
182                 {
183                         /* Show the list */
184                         if (!redraw || use_menu)
185                         {
186                                 char psi_desc[80];
187                                 int line;
188
189                                 /* Show list */
190                                 redraw = TRUE;
191
192                                 /* Save the screen */
193                                 if (!use_menu) screen_save();
194
195                                 /* Display a list of spells */
196                                 prt("", y, x);
197 #ifdef JP
198 put_str("̾Á°              Lv  MP      Ì¾Á°              Lv  MP ", y, x + 5);
199 #else
200 put_str("name              Lv  SP      name              Lv  SP ", y, x + 5);
201 #endif
202                                 prt("", y+1, x);
203                                 /* Dump the spells */
204                                 for (i = 0, line = 0; i < 32; i++)
205                                 {
206                                         spell = technic_info[TECHNIC_HISSATSU][i];
207
208                                         if (spell.slevel > PY_MAX_LEVEL) continue;
209                                         line++;
210                                         if (!(p_ptr->spell_learned1 >> i)) break;
211
212                                         /* Access the spell */
213                                         if (spell.slevel > plev)   continue;
214                                         if (!(p_ptr->spell_learned1 & (1L << i))) continue;
215                                         if (use_menu)
216                                         {
217                                                 if (i == (menu_line-1))
218 #ifdef JP
219                                                         strcpy(psi_desc, "  ¡Õ");
220 #else
221                                                         strcpy(psi_desc, "  > ");
222 #endif
223                                                 else strcpy(psi_desc, "    ");
224                                                 
225                                         }
226                                         else
227                                         {
228                                                 char letter;
229                                                 if (line <= 26)
230                                                         letter = I2A(line-1);
231                                                 else
232                                                         letter = '0' + line - 27;
233                                                 sprintf(psi_desc, "  %c)",letter);
234                                         }
235
236                                         /* Dump the spell --(-- */
237                                         strcat(psi_desc, format(" %-18s%2d %3d",
238                                                 do_spell(REALM_HISSATSU, i, SPELL_NAME),
239                                                 spell.slevel, spell.smana));
240                                         prt(psi_desc, y + (line%17) + (line >= 17), x+(line/17)*30);
241                                         prt("", y + (line%17) + (line >= 17) + 1, x+(line/17)*30);
242                                 }
243                         }
244
245                         /* Hide the list */
246                         else
247                         {
248                                 /* Hide list */
249                                 redraw = FALSE;
250
251                                 /* Restore the screen */
252                                 screen_load();
253                         }
254
255                         /* Redo asking */
256                         continue;
257                 }
258
259                 if (!use_menu)
260                 {
261                         if (isalpha(choice))
262                         {
263                                 /* Note verify */
264                                 ask = (isupper(choice));
265
266                                 /* Lowercase */
267                                 if (ask) choice = tolower(choice);
268
269                                 /* Extract request */
270                                 i = (islower(choice) ? A2I(choice) : -1);
271                         }
272                         else
273                         {
274                                 ask = FALSE; /* Can't uppercase digits */
275
276                                 i = choice - '0' + 26;
277                         }
278                 }
279
280                 /* Totally Illegal */
281                 if ((i < 0) || (i >= 32) || !(p_ptr->spell_learned1 & (1 << sentaku[i])))
282                 {
283                         bell();
284                         continue;
285                 }
286
287                 j = sentaku[i];
288
289                 /* Verify it */
290                 if (ask)
291                 {
292                         char tmp_val[160];
293
294                         /* Prompt */
295 #ifdef JP
296                         (void) strnfmt(tmp_val, 78, "%s¤ò»È¤¤¤Þ¤¹¤«¡©", do_spell(REALM_HISSATSU, j, SPELL_NAME));
297 #else
298                         (void)strnfmt(tmp_val, 78, "Use %s? ", do_spell(REALM_HISSATSU, j, SPELL_NAME));
299 #endif
300
301
302                         /* Belay that order */
303                         if (!get_check(tmp_val)) continue;
304                 }
305
306                 /* Stop the loop */
307                 flag = TRUE;
308         }
309
310         /* Restore the screen */
311         if (redraw) screen_load();
312
313         /* Show choices */
314         p_ptr->window |= (PW_SPELL);
315
316         /* Window stuff */
317         window_stuff();
318
319
320         /* Abort if needed */
321         if (!flag) return (FALSE);
322
323         /* Save the choice */
324         (*sn) = j;
325
326 #ifdef ALLOW_REPEAT /* TNB */
327
328         repeat_push(*sn);
329
330 #endif /* ALLOW_REPEAT -- TNB */
331
332         /* Success */
333         return (TRUE);
334 }
335
336
337 /*
338  * do_cmd_cast calls this function if the player's class
339  * is 'mindcrafter'.
340  */
341 void do_cmd_hissatsu(void)
342 {
343         int             n = 0;
344         magic_type      spell;
345
346
347         /* not if confused */
348         if (p_ptr->confused)
349         {
350 #ifdef JP
351 msg_print("º®Í𤷤Ƥ¤¤Æ½¸Ãæ¤Ç¤­¤Ê¤¤¡ª");
352 #else
353                 msg_print("You are too confused!");
354 #endif
355
356                 return;
357         }
358         if (!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
359         {
360                 if (flush_failure) flush();
361 #ifdef JP
362 msg_print("Éð´ï¤ò»ý¤¿¤Ê¤¤¤Èɬ»¦µ»¤Ï»È¤¨¤Ê¤¤¡ª");
363 #else
364                 msg_print("You need to wield a weapon!");
365 #endif
366
367                 return;
368         }
369         if (!p_ptr->spell_learned1)
370         {
371 #ifdef JP
372 msg_print("²¿¤âµ»¤òÃΤé¤Ê¤¤¡£");
373 #else
374                 msg_print("You don't know any special attacks.");
375 #endif
376
377                 return;
378         }
379
380         if (p_ptr->special_defense & KATA_MASK)
381         {
382                 set_action(ACTION_NONE);
383         }
384
385         /* get power */
386         if (!get_hissatsu_power(&n)) return;
387
388         spell = technic_info[TECHNIC_HISSATSU][n];
389
390         /* Verify "dangerous" spells */
391         if (spell.smana > p_ptr->csp)
392         {
393                 if (flush_failure) flush();
394                 /* Warning */
395 #ifdef JP
396 msg_print("£Í£Ð¤¬Â­¤ê¤Þ¤»¤ó¡£");
397 #else
398                 msg_print("You do not have enough mana to use this power.");
399 #endif
400                 msg_print(NULL);
401                 return;
402         }
403
404         sound(SOUND_ZAP);
405
406         /* Cast the spell */
407         if (!do_spell(REALM_HISSATSU, n, SPELL_CAST)) return;
408
409         /* Take a turn */
410         energy_use = 100;
411
412         /* Use some mana */
413         p_ptr->csp -= spell.smana;
414
415         /* Limit */
416         if (p_ptr->csp < 0) p_ptr->csp = 0;
417
418         /* Redraw mana */
419         p_ptr->redraw |= (PR_MANA);
420
421         /* Window stuff */
422         p_ptr->window |= (PW_PLAYER);
423         p_ptr->window |= (PW_SPELL);
424 }
425
426
427 void do_cmd_gain_hissatsu(void)
428 {
429         int item, i, j;
430
431         object_type *o_ptr;
432         cptr q, s;
433
434         bool gain = FALSE;
435
436         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
437         {
438                 set_action(ACTION_NONE);
439         }
440
441         if (p_ptr->blind || no_lite())
442         {
443 #ifdef JP
444 msg_print("Ìܤ¬¸«¤¨¤Ê¤¤¡ª");
445 #else
446                 msg_print("You cannot see!");
447 #endif
448
449                 return;
450         }
451
452         if (p_ptr->confused)
453         {
454 #ifdef JP
455 msg_print("º®Í𤷤Ƥ¤¤ÆÆɤá¤Ê¤¤¡ª");
456 #else
457                 msg_print("You are too confused!");
458 #endif
459
460                 return;
461         }
462
463         if (!(p_ptr->new_spells))
464         {
465 #ifdef JP
466 msg_print("¿·¤·¤¤É¬»¦µ»¤ò³Ð¤¨¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡ª");
467 #else
468                 msg_print("You cannot learn any new special attacks!");
469 #endif
470
471                 return;
472         }
473
474 #ifdef JP
475         if( p_ptr->new_spells < 10 ){
476                 msg_format("¤¢¤È %d ¤Ä¤Îɬ»¦µ»¤ò³Ø¤Ù¤ë¡£", p_ptr->new_spells);
477         }else{
478                 msg_format("¤¢¤È %d ¸Ä¤Îɬ»¦µ»¤ò³Ø¤Ù¤ë¡£", p_ptr->new_spells);
479         }
480 #else
481         msg_format("You can learn %d new special attack%s.", p_ptr->new_spells,
482                 (p_ptr->new_spells == 1?"":"s"));
483 #endif
484
485         item_tester_tval = TV_HISSATSU_BOOK;
486
487         /* Get an item */
488 #ifdef JP
489 q = "¤É¤Î½ñ¤«¤é³Ø¤Ó¤Þ¤¹¤«? ";
490 #else
491         q = "Study which book? ";
492 #endif
493
494 #ifdef JP
495 s = "Æɤá¤ë½ñ¤¬¤Ê¤¤¡£";
496 #else
497         s = "You have no books that you can read.";
498 #endif
499
500         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
501
502         /* Get the item (in the pack) */
503         if (item >= 0)
504         {
505                 o_ptr = &inventory[item];
506         }
507
508         /* Get the item (on the floor) */
509         else
510         {
511                 o_ptr = &o_list[0 - item];
512         }
513
514         for (i = o_ptr->sval * 8; i < o_ptr->sval * 8 + 8; i++)
515         {
516                 if (p_ptr->spell_learned1 & (1L << i)) continue;
517                 if (technic_info[TECHNIC_HISSATSU][i].slevel > p_ptr->lev) continue;
518
519                 p_ptr->spell_learned1 |= (1L << i);
520                 p_ptr->spell_worked1 |= (1L << i);
521 #ifdef JP
522                 msg_format("%s¤Îµ»¤ò³Ð¤¨¤¿¡£", do_spell(REALM_HISSATSU, i, SPELL_NAME));
523 #else
524                 msg_format("You have learned the special attack of %s.", do_spell(REALM_HISSATSU, i, SPELL_NAME));
525 #endif
526                 for (j = 0; j < 64; j++)
527                 {
528                         /* Stop at the first empty space */
529                         if (p_ptr->spell_order[j] == 99) break;
530                 }
531                 p_ptr->spell_order[j] = i;
532                 gain = TRUE;
533         }
534
535         /* No gain ... */
536         if (!gain)
537 #ifdef JP
538                 msg_print("²¿¤â³Ð¤¨¤é¤ì¤Ê¤«¤Ã¤¿¡£");
539 #else
540                 msg_print("You were not able to learn any special attacks.");
541 #endif
542
543         /* Take a turn */
544         else
545                 energy_use = 100;
546
547         p_ptr->update |= (PU_SPELLS);
548 }
549
550
551 /*
552  * Calcurate magnification of hissatsu technics
553  */
554 s16b mult_hissatsu(int mult, u32b *flgs, monster_type *m_ptr, int mode)
555 {
556         monster_race *r_ptr = &r_info[m_ptr->r_idx];
557
558         /* Burning Strike (Fire) */
559         if (mode == HISSATSU_FIRE)
560         {
561                 /* Notice immunity */
562                 if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)
563                 {
564                         if (is_original_ap_and_seen(m_ptr))
565                         {
566                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
567                         }
568                 }
569
570                 /* Otherwise, take the damage */
571                 else if (have_flag(flgs, TR_BRAND_FIRE))
572                 {
573                         if (r_ptr->flags3 & RF3_HURT_FIRE)
574                         {
575                                 if (mult < 70) mult = 70;
576                                 if (is_original_ap_and_seen(m_ptr))
577                                 {
578                                         r_ptr->r_flags3 |= RF3_HURT_FIRE;
579                                 }
580                         }
581                         else if (mult < 35) mult = 35;
582                 }
583                 else
584                 {
585                         if (r_ptr->flags3 & RF3_HURT_FIRE)
586                         {
587                                 if (mult < 50) mult = 50;
588                                 if (is_original_ap_and_seen(m_ptr))
589                                 {
590                                         r_ptr->r_flags3 |= RF3_HURT_FIRE;
591                                 }
592                         }
593                         else if (mult < 25) mult = 25;
594                 }
595         }
596
597         /* Serpent's Tongue (Poison) */
598         if (mode == HISSATSU_POISON)
599         {
600                 /* Notice immunity */
601                 if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)
602                 {
603                         if (is_original_ap_and_seen(m_ptr))
604                         {
605                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK);
606                         }
607                 }
608
609                 /* Otherwise, take the damage */
610                 else if (have_flag(flgs, TR_BRAND_POIS))
611                 {
612                         if (mult < 35) mult = 35;
613                 }
614                 else
615                 {
616                         if (mult < 25) mult = 25;
617                 }
618         }
619
620         /* Zammaken (Nonliving Evil) */
621         if (mode == HISSATSU_ZANMA)
622         {
623                 if (!monster_living(r_ptr) && (r_ptr->flags3 & RF3_EVIL))
624                 {
625                         if (mult < 15) mult = 25;
626                         else if (mult < 50) mult = MIN(50, mult+20);
627                 }
628         }
629
630         /* Rock Smash (Hurt Rock) */
631         if (mode == HISSATSU_HAGAN)
632         {
633                 if (r_ptr->flags3 & RF3_HURT_ROCK)
634                 {
635                         if (is_original_ap_and_seen(m_ptr))
636                         {
637                                 r_ptr->r_flags3 |= RF3_HURT_ROCK;
638                         }
639                         if (mult == 10) mult = 40;
640                         else if (mult < 60) mult = 60;
641                 }
642         }
643
644         /* Midare-Setsugekka (Cold) */
645         if (mode == HISSATSU_COLD)
646         {
647                 /* Notice immunity */
648                 if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)
649                 {
650                         if (is_original_ap_and_seen(m_ptr))
651                         {
652                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
653                         }
654                 }
655                 /* Otherwise, take the damage */
656                 else if (have_flag(flgs, TR_BRAND_COLD))
657                 {
658                         if (r_ptr->flags3 & RF3_HURT_COLD)
659                         {
660                                 if (mult < 70) mult = 70;
661                                 if (is_original_ap_and_seen(m_ptr))
662                                 {
663                                         r_ptr->r_flags3 |= RF3_HURT_COLD;
664                                 }
665                         }
666                         else if (mult < 35) mult = 35;
667                 }
668                 else
669                 {
670                         if (r_ptr->flags3 & RF3_HURT_COLD)
671                         {
672                                 if (mult < 50) mult = 50;
673                                 if (is_original_ap_and_seen(m_ptr))
674                                 {
675                                         r_ptr->r_flags3 |= RF3_HURT_COLD;
676                                 }
677                         }
678                         else if (mult < 25) mult = 25;
679                 }
680         }
681
682         /* Lightning Eagle (Elec) */
683         if (mode == HISSATSU_ELEC)
684         {
685                 /* Notice immunity */
686                 if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)
687                 {
688                         if (is_original_ap_and_seen(m_ptr))
689                         {
690                                 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
691                         }
692                 }
693
694                 /* Otherwise, take the damage */
695                 else if (have_flag(flgs, TR_BRAND_ELEC))
696                 {
697                         if (mult < 70) mult = 70;
698                 }
699                 else
700                 {
701                         if (mult < 50) mult = 50;
702                 }
703         }
704
705         /* Bloody Maelstrom */
706         if ((mode == HISSATSU_SEKIRYUKA) && p_ptr->cut && monster_living(r_ptr))
707         {
708                 int tmp = MIN(100, MAX(10, p_ptr->cut / 10));
709                 if (mult < tmp) mult = tmp;
710         }
711
712         /* Keiun-Kininken */
713         if (mode == HISSATSU_UNDEAD)
714         {
715                 if (r_ptr->flags3 & RF3_UNDEAD)
716                 {
717                         if (is_original_ap_and_seen(m_ptr))
718                         {
719                                 r_ptr->r_flags3 |= RF3_UNDEAD;
720                         }
721                         if (mult == 10) mult = 70;
722                         else if (mult < 140) mult = MIN(140, mult+60);
723                 }
724                 if (mult == 10) mult = 40;
725                 else if (mult < 60) mult = MIN(60, mult+30);
726         }
727
728         if (mult > 150) mult = 150;
729
730         return mult;
731 }