OSDN Git Service

[Refactor] #40567 Renamed Term_*() to term_*()
[hengband/hengband.git] / src / autopick / autopick-editor-command.c
1 /*!
2  * todo これ単体で750行を超えているので要分割
3  * @brief 自動拾いエディタ画面でキーを押した時の挙動一式
4  * @date 2020/04/26
5  * @author Hourier
6  */
7
8 #include "autopick/autopick-editor-command.h"
9 #include "autopick/autopick-commands-table.h"
10 #include "autopick/autopick-dirty-flags.h"
11 #include "autopick/autopick-drawer.h"
12 #include "autopick/autopick-editor-util.h"
13 #include "autopick/autopick-entry.h"
14 #include "autopick/autopick-finder.h"
15 #include "autopick/autopick-flags-table.h"
16 #include "autopick/autopick-inserter-killer.h"
17 #include "autopick/autopick-methods-table.h"
18 #include "autopick/autopick-reader-writer.h"
19 #include "core/asking-player.h"
20 #include "core/show-file.h"
21 #include "game-option/input-options.h"
22 #include "game-option/keymap-directory-getter.h"
23 #include "player/player-class.h"
24 #include "player/player-race.h"
25 #include "term/term-color-types.h"
26
27 /*
28  * @brief
29  * @param player_ptr プレーヤーへの参照ポインタ
30  * @param tb 自動拾いの構文
31  * @param com_id エディタ内で打ったコマンド
32  * @return 
33  * @details Execute a single editor command
34  */
35 ape_quittance do_editor_command(player_type *player_ptr, text_body_type *tb, int com_id)
36 {
37         switch (com_id)
38         {
39         case EC_QUIT:
40         {
41                 if (tb->changed)
42                 {
43                         if (!get_check(_("全ての変更を破棄してから終了します。よろしいですか? ",
44                                 "Discard all changes and quit. Are you sure? "))) break;
45                 }
46
47                 return APE_QUIT_WITHOUT_SAVE;
48         }
49         case EC_SAVEQUIT:
50                 return APE_QUIT_AND_SAVE;
51         case EC_REVERT:
52         {
53                 if (!get_check(_("全ての変更を破棄して元の状態に戻します。よろしいですか? ",
54                         "Discard all changes and revert to original file. Are you sure? "))) break;
55
56                 free_text_lines(tb->lines_list);
57                 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
58                 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
59                 tb->cx = tb->cy = 0;
60                 tb->mark = 0;
61                 tb->changed = FALSE;
62                 break;
63         }
64         case EC_HELP:
65         {
66                 (void)show_file(player_ptr, TRUE, _("jeditor.txt", "editor.txt"), NULL, 0, 0);
67                 tb->dirty_flags |= DIRTY_SCREEN;
68                 break;
69         }
70         case EC_RETURN:
71         {
72                 if (tb->mark)
73                 {
74                         tb->mark = 0;
75                         tb->dirty_flags |= DIRTY_ALL;
76                 }
77
78                 insert_return_code(tb);
79                 tb->cy++;
80                 tb->cx = 0;
81                 tb->dirty_flags |= DIRTY_ALL;
82                 break;
83         }
84         case EC_LEFT:
85         {
86                 if (0 < tb->cx)
87                 {
88                         int len;
89 #ifdef JP
90                         int i;
91 #endif
92                         tb->cx--;
93                         len = strlen(tb->lines_list[tb->cy]);
94                         if (len < tb->cx) tb->cx = len;
95 #ifdef JP
96                         for (i = 0; tb->lines_list[tb->cy][i]; i++)
97                         {
98                                 if (iskanji(tb->lines_list[tb->cy][i]))
99                                 {
100                                         i++;
101                                         if (i == tb->cx)
102                                         {
103                                                 tb->cx--;
104                                                 break;
105                                         }
106                                 }
107                         }
108 #endif
109                 }
110                 else if (tb->cy > 0)
111                 {
112                         tb->cy--;
113                         tb->cx = strlen(tb->lines_list[tb->cy]);
114                 }
115
116                 break;
117         }
118         case EC_DOWN:
119         {
120                 if (!tb->lines_list[tb->cy + 1])
121                 {
122                         if (!add_empty_line(tb)) break;
123                 }
124
125                 tb->cy++;
126                 break;
127         }
128         case EC_UP:
129                 if (tb->cy > 0) tb->cy--;
130                 break;
131         case EC_RIGHT:
132         {
133 #ifdef JP
134                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
135 #endif
136                 tb->cx++;
137                 int len = strlen(tb->lines_list[tb->cy]);
138                 if (len < tb->cx)
139                 {
140                         tb->cx = len;
141                         if (!tb->lines_list[tb->cy + 1])
142                         {
143                                 if (!add_empty_line(tb)) break;
144                         }
145
146                         tb->cy++;
147                         tb->cx = 0;
148                 }
149
150                 break;
151         }
152         case EC_BOL:
153                 tb->cx = 0;
154                 break;
155         case EC_EOL:
156                 tb->cx = strlen(tb->lines_list[tb->cy]);
157                 break;
158         case EC_PGUP:
159                 while (0 < tb->cy && tb->upper <= tb->cy)
160                         tb->cy--;
161
162                 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
163                         tb->upper--;
164
165                 break;
166         case EC_PGDOWN:
167                 while (tb->cy < tb->upper + tb->hgt)
168                 {
169                         if (!tb->lines_list[tb->cy + 1])
170                         {
171                                 if (!add_empty_line(tb)) break;
172                         }
173
174                         tb->cy++;
175                 }
176
177                 tb->upper = tb->cy;
178                 break;
179         case EC_TOP:
180                 tb->cy = 0;
181                 break;
182         case EC_BOTTOM:
183                 while (TRUE)
184                 {
185                         if (!tb->lines_list[tb->cy + 1])
186                         {
187                                 if (!add_empty_line(tb)) break;
188                         }
189
190                         tb->cy++;
191                 }
192
193                 tb->cx = 0;
194                 break;
195         case EC_CUT:
196         {
197                 copy_text_to_yank(tb);
198                 if (tb->my == tb->cy)
199                 {
200                         int bx1 = MIN(tb->mx, tb->cx);
201                         int bx2 = MAX(tb->mx, tb->cx);
202                         int len = strlen(tb->lines_list[tb->cy]);
203                         if (bx2 > len) bx2 = len;
204
205                         kill_line_segment(tb, tb->cy, bx1, bx2, TRUE);
206                         tb->cx = bx1;
207                 }
208                 else
209                 {
210                         int by1 = MIN(tb->my, tb->cy);
211                         int by2 = MAX(tb->my, tb->cy);
212
213                         for (int y = by2; y >= by1; y--)
214                         {
215                                 int len = strlen(tb->lines_list[y]);
216
217                                 kill_line_segment(tb, y, 0, len, TRUE);
218                         }
219
220                         tb->cy = by1;
221                         tb->cx = 0;
222                 }
223
224                 tb->mark = 0;
225                 tb->dirty_flags |= DIRTY_ALL;
226                 tb->changed = TRUE;
227                 break;
228         }
229         case EC_COPY:
230         {
231                 copy_text_to_yank(tb);
232
233                 /*
234                  * Move cursor position to the end of the selection
235                  *
236                  * Pressing ^C ^V correctly duplicates the selection.
237                  */
238                 if (tb->my != tb->cy)
239                 {
240                         tb->cy = MAX(tb->cy, tb->my);
241                         if (!tb->lines_list[tb->cy + 1])
242                         {
243                                 if (!add_empty_line(tb)) break;
244                         }
245
246                         tb->cy++;
247                         break;
248                 }
249
250                 tb->cx = MAX(tb->cx, tb->mx);
251                 if (!tb->lines_list[tb->cy][tb->cx])
252                 {
253                         if (!tb->lines_list[tb->cy + 1])
254                         {
255                                 if (!add_empty_line(tb)) break;
256                         }
257
258                         tb->cy++;
259                         tb->cx = 0;
260                 }
261
262                 break;
263         }
264         case EC_PASTE:
265         {
266                 chain_str_type *chain = tb->yank;
267                 int len = strlen(tb->lines_list[tb->cy]);
268                 if (!chain) break;
269                 if (tb->cx > len) tb->cx = len;
270
271                 if (tb->mark)
272                 {
273                         tb->mark = 0;
274                         tb->dirty_flags |= DIRTY_ALL;
275                 }
276
277                 while (chain)
278                 {
279                         concptr yank_str = chain->s;
280                         char buf[MAX_LINELEN];
281                         int i;
282                         char rest[MAX_LINELEN], *rest_ptr = rest;
283                         for (i = 0; i < tb->cx; i++)
284                                 buf[i] = tb->lines_list[tb->cy][i];
285
286                         strcpy(rest, &(tb->lines_list[tb->cy][i]));
287                         while (*yank_str && i < MAX_LINELEN - 1)
288                         {
289                                 buf[i++] = *yank_str++;
290                         }
291
292                         buf[i] = '\0';
293                         chain = chain->next;
294                         if (chain || tb->yank_eol)
295                         {
296                                 insert_return_code(tb);
297                                 string_free(tb->lines_list[tb->cy]);
298                                 tb->lines_list[tb->cy] = string_make(buf);
299                                 tb->cx = 0;
300                                 tb->cy++;
301
302                                 continue;
303                         }
304
305                         tb->cx = strlen(buf);
306                         while (*rest_ptr && i < MAX_LINELEN - 1)
307                         {
308                                 buf[i++] = *rest_ptr++;
309                         }
310
311                         buf[i] = '\0';
312                         string_free(tb->lines_list[tb->cy]);
313                         tb->lines_list[tb->cy] = string_make(buf);
314                         break;
315                 }
316
317                 tb->dirty_flags |= DIRTY_ALL;
318                 tb->dirty_flags |= DIRTY_EXPRESSION;
319                 tb->changed = TRUE;
320                 break;
321         }
322         case EC_BLOCK:
323         {
324                 if (tb->mark)
325                 {
326                         tb->mark = 0;
327                         tb->dirty_flags |= DIRTY_ALL;
328                         break;
329                 }
330
331                 tb->mark = MARK_MARK;
332                 if (com_id == tb->old_com_id)
333                 {
334                         int tmp = tb->cy;
335                         tb->cy = tb->my;
336                         tb->my = tmp;
337                         tmp = tb->cx;
338                         tb->cx = tb->mx;
339                         tb->mx = tmp;
340                         tb->dirty_flags |= DIRTY_ALL;
341                         break;
342                 }
343
344                 int len = strlen(tb->lines_list[tb->cy]);
345
346                 tb->my = tb->cy;
347                 tb->mx = tb->cx;
348                 if (tb->cx > len) tb->mx = len;
349                 break;
350         }
351         case EC_KILL_LINE:
352         {
353                 int len = strlen(tb->lines_list[tb->cy]);
354                 if (tb->cx > len) tb->cx = len;
355
356                 if (tb->mark)
357                 {
358                         tb->mark = 0;
359                         tb->dirty_flags |= DIRTY_ALL;
360                 }
361
362                 if (tb->old_com_id != com_id)
363                 {
364                         kill_yank_chain(tb);
365                         tb->yank = NULL;
366                 }
367
368                 if (tb->cx < len)
369                 {
370                         add_str_to_yank(tb, &(tb->lines_list[tb->cy][tb->cx]));
371                         kill_line_segment(tb, tb->cy, tb->cx, len, FALSE);
372                         tb->dirty_line = tb->cy;
373                         break;
374                 }
375
376                 if (tb->yank_eol) add_str_to_yank(tb, "");
377
378                 tb->yank_eol = TRUE;
379                 do_editor_command(player_ptr, tb, EC_DELETE_CHAR);
380                 break;
381         }
382         case EC_DELETE_CHAR:
383         {
384                 if (tb->mark)
385                 {
386                         tb->mark = 0;
387                         tb->dirty_flags |= DIRTY_ALL;
388                 }
389
390 #ifdef JP
391                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
392 #endif
393                 tb->cx++;
394                 int len = strlen(tb->lines_list[tb->cy]);
395                 if (len >= tb->cx)
396                 {
397                         do_editor_command(player_ptr, tb, EC_BACKSPACE);
398                         break;
399                 }
400
401                 if (tb->lines_list[tb->cy + 1])
402                 {
403                         tb->cy++;
404                         tb->cx = 0;
405                 }
406                 else
407                 {
408                         tb->cx = len;
409                         break;
410                 }
411
412                 do_editor_command(player_ptr, tb, EC_BACKSPACE);
413                 break;
414         }
415         case EC_BACKSPACE:
416         {
417                 int len, i, j, k;
418                 char buf[MAX_LINELEN];
419                 if (tb->mark)
420                 {
421                         tb->mark = 0;
422                         tb->dirty_flags |= DIRTY_ALL;
423                 }
424
425                 len = strlen(tb->lines_list[tb->cy]);
426                 if (len < tb->cx) tb->cx = len;
427
428                 if (tb->cx == 0)
429                 {
430                         if (tb->cy == 0) break;
431                         tb->cx = strlen(tb->lines_list[tb->cy - 1]);
432                         strcpy(buf, tb->lines_list[tb->cy - 1]);
433                         strcat(buf, tb->lines_list[tb->cy]);
434                         string_free(tb->lines_list[tb->cy - 1]);
435                         string_free(tb->lines_list[tb->cy]);
436                         tb->lines_list[tb->cy - 1] = string_make(buf);
437
438                         for (i = tb->cy; tb->lines_list[i + 1]; i++)
439                                 tb->lines_list[i] = tb->lines_list[i + 1];
440
441                         tb->lines_list[i] = NULL;
442                         tb->cy--;
443                         tb->dirty_flags |= DIRTY_ALL;
444                         tb->dirty_flags |= DIRTY_EXPRESSION;
445                         tb->changed = TRUE;
446                         break;
447                 }
448
449                 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
450                 {
451                         k = j;
452 #ifdef JP
453                         if (iskanji(tb->lines_list[tb->cy][i]))
454                                 buf[j++] = tb->lines_list[tb->cy][i++];
455 #endif
456                         buf[j++] = tb->lines_list[tb->cy][i];
457                 }
458
459                 while (j > k)
460                 {
461                         tb->cx--;
462                         j--;
463                 }
464
465                 for (; tb->lines_list[tb->cy][i]; i++)
466                 {
467                         buf[j++] = tb->lines_list[tb->cy][i];
468                 }
469
470                 buf[j] = '\0';
471                 string_free(tb->lines_list[tb->cy]);
472                 tb->lines_list[tb->cy] = string_make(buf);
473                 tb->dirty_line = tb->cy;
474                 check_expression_line(tb, tb->cy);
475                 tb->changed = TRUE;
476                 break;
477         }
478         case EC_SEARCH_STR:
479         {
480                 byte search_dir;
481                 tb->dirty_flags |= DIRTY_SCREEN;
482                 search_dir = get_string_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str);
483
484                 if (!search_dir) break;
485
486                 if (search_dir == 1) do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
487                 else do_editor_command(player_ptr, tb, EC_SEARCH_BACK);
488
489                 break;
490         }
491         case EC_SEARCH_FORW:
492                 if (tb->search_o_ptr)
493                 {
494                         search_for_object(player_ptr, tb, tb->search_o_ptr, TRUE);
495                         break;
496                 }
497
498                 if (tb->search_str && tb->search_str[0])
499                 {
500                         search_for_string(tb, tb->search_str, TRUE);
501                         break;
502                 }
503
504                 tb->dirty_flags |= DIRTY_NO_SEARCH;
505                 break;
506
507         case EC_SEARCH_BACK:
508         {
509                 if (tb->search_o_ptr)
510                 {
511                         search_for_object(player_ptr, tb, tb->search_o_ptr, FALSE);
512                         break;
513                 }
514
515                 if (tb->search_str && tb->search_str[0])
516                 {
517                         search_for_string(tb, tb->search_str, FALSE);
518                         break;
519                 }
520
521                 tb->dirty_flags |= DIRTY_NO_SEARCH;
522                 break;
523         }
524         case EC_SEARCH_OBJ:
525         {
526                 tb->dirty_flags |= DIRTY_SCREEN;
527
528                 if (!get_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str)) break;
529
530                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
531                 break;
532         }
533         case EC_SEARCH_DESTROYED:
534         {
535                 if (!get_destroyed_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str))
536                 {
537                         tb->dirty_flags |= DIRTY_NO_SEARCH;
538                         break;
539                 }
540
541                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
542                 break;
543         }
544         case EC_INSERT_OBJECT:
545         {
546                 autopick_type an_entry, *entry = &an_entry;
547                 if (!entry_from_choosed_object(player_ptr, entry))
548                 {
549                         tb->dirty_flags |= DIRTY_SCREEN;
550                         break;
551                 }
552
553                 tb->cx = 0;
554                 insert_return_code(tb);
555                 string_free(tb->lines_list[tb->cy]);
556                 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
557                 tb->dirty_flags |= DIRTY_SCREEN;
558                 break;
559         }
560         case EC_INSERT_DESTROYED:
561         {
562                 if (!tb->last_destroyed) break;
563
564                 tb->cx = 0;
565                 insert_return_code(tb);
566                 string_free(tb->lines_list[tb->cy]);
567                 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
568                 tb->dirty_flags |= DIRTY_ALL;
569                 tb->changed = TRUE;
570                 break;
571         }
572         case EC_INSERT_BLOCK:
573         {
574                 char expression[80];
575                 sprintf(expression, "?:[AND [EQU $RACE %s] [EQU $CLASS %s] [GEQ $LEVEL %02d]]",
576 #ifdef JP
577                         rp_ptr->E_title, cp_ptr->E_title,
578 #else
579                         rp_ptr->title, cp_ptr->title,
580 #endif
581                         player_ptr->lev);
582                 tb->cx = 0;
583                 insert_return_code(tb);
584                 string_free(tb->lines_list[tb->cy]);
585                 tb->lines_list[tb->cy] = string_make(expression);
586                 tb->cy++;
587                 insert_return_code(tb);
588                 string_free(tb->lines_list[tb->cy]);
589                 tb->lines_list[tb->cy] = string_make("?:1");
590                 tb->dirty_flags |= DIRTY_ALL;
591                 tb->changed = TRUE;
592                 break;
593         }
594         case EC_INSERT_MACRO:
595         {
596                 draw_text_editor(player_ptr, tb);
597                 term_erase(0, tb->cy - tb->upper + 1, tb->wid);
598                 term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, _("P:<トリガーキー>: ", "P:<Trigger key>: "));
599                 if (!insert_macro_line(tb)) break;
600
601                 tb->cx = 2;
602                 tb->dirty_flags |= DIRTY_ALL;
603                 tb->changed = TRUE;
604                 break;
605         }
606         case EC_INSERT_KEYMAP:
607         {
608                 draw_text_editor(player_ptr, tb);
609                 term_erase(0, tb->cy - tb->upper + 1, tb->wid);
610                 term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW,
611                         format(_("C:%d:<コマンドキー>: ", "C:%d:<Keypress>: "), (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
612
613                 if (!insert_keymap_line(tb)) break;
614
615                 tb->cx = 2;
616                 tb->dirty_flags |= DIRTY_ALL;
617                 tb->changed = TRUE;
618                 break;
619         }
620         case EC_CL_AUTOPICK:
621                 toggle_command_letter(tb, DO_AUTOPICK);
622                 break;
623         case EC_CL_DESTROY:
624                 toggle_command_letter(tb, DO_AUTODESTROY);
625                 break;
626         case EC_CL_LEAVE:
627                 toggle_command_letter(tb, DONT_AUTOPICK);
628                 break;
629         case EC_CL_QUERY:
630                 toggle_command_letter(tb, DO_QUERY_AUTOPICK);
631                 break;
632         case EC_CL_NO_DISP:
633                 toggle_command_letter(tb, DO_DISPLAY);
634                 break;
635         case EC_IK_UNAWARE:
636                 toggle_keyword(tb, FLG_UNAWARE);
637                 break;
638         case EC_IK_UNIDENTIFIED:
639                 toggle_keyword(tb, FLG_UNIDENTIFIED);
640                 break;
641         case EC_IK_IDENTIFIED:
642                 toggle_keyword(tb, FLG_IDENTIFIED);
643                 break;
644         case EC_IK_STAR_IDENTIFIED:
645                 toggle_keyword(tb, FLG_STAR_IDENTIFIED);
646                 break;
647         case EC_KK_WEAPONS:
648                 toggle_keyword(tb, FLG_WEAPONS);
649                 break;
650         case EC_KK_FAVORITE_WEAPONS:
651                 toggle_keyword(tb, FLG_FAVORITE_WEAPONS);
652                 break;
653         case EC_KK_ARMORS:
654                 toggle_keyword(tb, FLG_ARMORS);
655                 break;
656         case EC_KK_MISSILES:
657                 toggle_keyword(tb, FLG_MISSILES);
658                 break;
659         case EC_KK_DEVICES:
660                 toggle_keyword(tb, FLG_DEVICES);
661                 break;
662         case EC_KK_LIGHTS:
663                 toggle_keyword(tb, FLG_LIGHTS);
664                 break;
665         case EC_KK_JUNKS:
666                 toggle_keyword(tb, FLG_JUNKS);
667                 break;
668         case EC_KK_CORPSES:
669                 toggle_keyword(tb, FLG_CORPSES);
670                 break;
671         case EC_KK_SPELLBOOKS:
672                 toggle_keyword(tb, FLG_SPELLBOOKS);
673                 break;
674         case EC_KK_SHIELDS:
675                 toggle_keyword(tb, FLG_SHIELDS);
676                 break;
677         case EC_KK_BOWS:
678                 toggle_keyword(tb, FLG_BOWS);
679                 break;
680         case EC_KK_RINGS:
681                 toggle_keyword(tb, FLG_RINGS);
682                 break;
683         case EC_KK_AMULETS:
684                 toggle_keyword(tb, FLG_AMULETS);
685                 break;
686         case EC_KK_SUITS:
687                 toggle_keyword(tb, FLG_SUITS);
688                 break;
689         case EC_KK_CLOAKS:
690                 toggle_keyword(tb, FLG_CLOAKS);
691                 break;
692         case EC_KK_HELMS:
693                 toggle_keyword(tb, FLG_HELMS);
694                 break;
695         case EC_KK_GLOVES:
696                 toggle_keyword(tb, FLG_GLOVES);
697                 break;
698         case EC_KK_BOOTS:
699                 toggle_keyword(tb, FLG_BOOTS);
700                 break;
701         case EC_OK_COLLECTING:
702                 toggle_keyword(tb, FLG_COLLECTING);
703                 break;
704         case EC_OK_BOOSTED:
705                 toggle_keyword(tb, FLG_BOOSTED);
706                 break;
707         case EC_OK_MORE_DICE:
708                 toggle_keyword(tb, FLG_MORE_DICE);
709                 break;
710         case EC_OK_MORE_BONUS:
711                 toggle_keyword(tb, FLG_MORE_BONUS);
712                 break;
713         case EC_OK_WORTHLESS:
714                 toggle_keyword(tb, FLG_WORTHLESS);
715                 break;
716         case EC_OK_ARTIFACT:
717                 toggle_keyword(tb, FLG_ARTIFACT);
718                 break;
719         case EC_OK_EGO:
720                 toggle_keyword(tb, FLG_EGO);
721                 break;
722         case EC_OK_GOOD:
723                 toggle_keyword(tb, FLG_GOOD);
724                 break;
725         case EC_OK_NAMELESS:
726                 toggle_keyword(tb, FLG_NAMELESS);
727                 break;
728         case EC_OK_AVERAGE:
729                 toggle_keyword(tb, FLG_AVERAGE);
730                 break;
731         case EC_OK_RARE:
732                 toggle_keyword(tb, FLG_RARE);
733                 break;
734         case EC_OK_COMMON:
735                 toggle_keyword(tb, FLG_COMMON);
736                 break;
737         case EC_OK_WANTED:
738                 toggle_keyword(tb, FLG_WANTED);
739                 break;
740         case EC_OK_UNIQUE:
741                 toggle_keyword(tb, FLG_UNIQUE);
742                 break;
743         case EC_OK_HUMAN:
744                 toggle_keyword(tb, FLG_HUMAN);
745                 break;
746         case EC_OK_UNREADABLE:
747                 toggle_keyword(tb, FLG_UNREADABLE);
748                 add_keyword(tb, FLG_SPELLBOOKS);
749                 break;
750         case EC_OK_REALM1:
751                 toggle_keyword(tb, FLG_REALM1);
752                 add_keyword(tb, FLG_SPELLBOOKS);
753                 break;
754         case EC_OK_REALM2:
755                 toggle_keyword(tb, FLG_REALM2);
756                 add_keyword(tb, FLG_SPELLBOOKS);
757                 break;
758         case EC_OK_FIRST:
759                 toggle_keyword(tb, FLG_FIRST);
760                 add_keyword(tb, FLG_SPELLBOOKS);
761                 break;
762         case EC_OK_SECOND:
763                 toggle_keyword(tb, FLG_SECOND);
764                 add_keyword(tb, FLG_SPELLBOOKS);
765                 break;
766         case EC_OK_THIRD:
767                 toggle_keyword(tb, FLG_THIRD);
768                 add_keyword(tb, FLG_SPELLBOOKS);
769                 break;
770         case EC_OK_FOURTH:
771                 toggle_keyword(tb, FLG_FOURTH);
772                 add_keyword(tb, FLG_SPELLBOOKS);
773                 break;
774         }
775
776         tb->old_com_id = com_id;
777         return APE_QUIT;
778 }