* Return TRUE if a spell was picked, with the spell index in the return * parameter. Otherwise return FALSE. */
| 712 | * parameter. Otherwise return FALSE. |
| 713 | */ |
| 714 | staticfn boolean |
| 715 | getspell(int *spell_no) |
| 716 | { |
| 717 | int nspells, idx, retry_limit; |
| 718 | char ilet, lets[BUFSZ], qbuf[QBUFSZ]; |
| 719 | struct _cmd_queue cq, *cmdq; |
| 720 | |
| 721 | nspells = num_spells(); |
| 722 | if (!nspells) { |
| 723 | You("don't know any spells right now."); |
| 724 | return FALSE; |
| 725 | } |
| 726 | if (rejectcasting()) |
| 727 | return FALSE; /* no spell chosen */ |
| 728 | |
| 729 | if ((cmdq = cmdq_pop()) != 0) { |
| 730 | cq = *cmdq; |
| 731 | free(cmdq); |
| 732 | if (cq.typ == CMDQ_KEY) { |
| 733 | idx = spell_let_to_idx(cq.key); |
| 734 | if (idx < 0 || idx >= nspells) |
| 735 | return FALSE; |
| 736 | *spell_no = idx; |
| 737 | return TRUE; |
| 738 | } else { |
| 739 | return FALSE; |
| 740 | } |
| 741 | } |
| 742 | |
| 743 | if (flags.menu_style == MENU_TRADITIONAL) { |
| 744 | /* if we get here, we know there is at least 1 known spell */ |
| 745 | if (nspells == 1) |
| 746 | Strcpy(lets, "a"); |
| 747 | else if (nspells < 27) |
| 748 | Sprintf(lets, "a-%c", 'a' + nspells - 1); |
| 749 | else if (nspells == 27) |
| 750 | Strcpy(lets, "a-zA"); |
| 751 | /* this assumes that there are at most 52 spells... */ |
| 752 | else |
| 753 | Sprintf(lets, "a-zA-%c", 'A' + nspells - 27); |
| 754 | |
| 755 | Snprintf(qbuf, sizeof qbuf, "Cast which spell? [%s *?]", lets); |
| 756 | for (retry_limit = 0; ; ++retry_limit) { |
| 757 | if (retry_limit == 10) { |
| 758 | /* limit is mainly to prevent the fuzzer from getting stuck |
| 759 | since hangup should hit the 'quitchars' case; fuzzer |
| 760 | would too, but after an arbitrary number of attempts */ |
| 761 | pline("That's enough tries."); |
| 762 | return FALSE; |
| 763 | } |
| 764 | ilet = yn_function(qbuf, (char *) 0, '\0', TRUE); |
| 765 | if (ilet == '*' || ilet == '?') |
| 766 | break; /* use menu mode */ |
| 767 | if (strchr(quitchars, ilet)) { |
| 768 | pline1(Never_mind); |
| 769 | return FALSE; |
| 770 | } |
| 771 |
no test coverage detected