OSDN Git Service

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