3 /* Purpose: Object Auto-picker/Destroyer */
6 * Copyright (c) 2002 Mogami
8 * This software may be copied and distributed for educational, research, and
9 * not for profit purposes provided that this copyright and statement are
10 * included in all such copies.
16 #define MAX_LINELEN 1024
22 #define FLG_COLLECTING 1
23 #define FLG_UNIDENTIFIED 2
24 #define FLG_IDENTIFIED 3
25 #define FLG_STAR_IDENTIFIED 4
27 #define FLG_MORE_THAN 6
29 #define FLG_MORE_BONUS 8
30 #define FLG_MORE_BONUS2 9
31 #define FLG_WORTHLESS 10
32 #define FLG_ARTIFACT 11
34 #define FLG_NAMELESS 13
35 #define FLG_UNAWARE 14
39 #define FLG_UNREADABLE 18
48 #define FLG_WEAPONS 31
50 #define FLG_MISSILES 33
51 #define FLG_DEVICES 34
54 #define FLG_SPELLBOOKS 37
56 #define FLG_SHIELDS 39
59 #define FLG_AMULETS 42
65 #define FLG_FAVORITE 48
67 #define FLG_NOUN_BEGIN FLG_ITEMS
68 #define FLG_NOUN_END FLG_FAVORITE
72 #define KEY_ALL "¤¹¤Ù¤Æ¤Î"
76 * MEGA HACK -- MPW¤Î¥Ð¥°½ü¤±¡£
77 * pre-processÃæ¤Ë¡Ö¼ý¡×¤Î»ú¤Î2¥Ð¥¤¥ÈÌܤ¬¾¡¼ê¤Ë¾Ã¤¨¤Æ¤·¤Þ¤¦¡£
79 #define KEY_COLLECTING "\x8e\xfb½¸Ãæ¤Î"
81 #define KEY_COLLECTING "¼ý½¸Ãæ¤Î"
84 #define KEY_UNIDENTIFIED "̤´ÕÄê¤Î"
85 #define KEY_IDENTIFIED "´ÕÄêºÑ¤ß¤Î"
86 #define KEY_STAR_IDENTIFIED "*´ÕÄê*ºÑ¤ß¤Î"
87 #define KEY_BOOSTED "¥À¥¤¥¹Ìܤΰ㤦"
88 #define KEY_MORE_THAN "¥À¥¤¥¹ÌÜ"
89 #define KEY_DICE "°Ê¾å¤Î"
90 #define KEY_MORE_BONUS "½¤ÀµÃÍ"
91 #define KEY_MORE_BONUS2 "°Ê¾å¤Î"
92 #define KEY_WORTHLESS "̵²ÁÃͤÎ"
93 #define KEY_ARTIFACT "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È"
94 #define KEY_EGO "¥¨¥´"
95 #define KEY_NAMELESS "̵ÌäÎ"
96 #define KEY_UNAWARE "̤ȽÌÀ¤Î"
97 #define KEY_WANTED "¾Þ¶â¼ó¤Î"
98 #define KEY_UNIQUE "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î"
99 #define KEY_HUMAN "¿Í´Ö¤Î"
100 #define KEY_UNREADABLE "Æɤá¤Ê¤¤"
101 #define KEY_REALM1 "Âè°ìÎΰè¤Î"
102 #define KEY_REALM2 "ÂèÆóÎΰè¤Î"
103 #define KEY_FIRST "1ºýÌܤÎ"
104 #define KEY_SECOND "2ºýÌܤÎ"
105 #define KEY_THIRD "3ºýÌܤÎ"
106 #define KEY_FOURTH "4ºýÌܤÎ"
107 #define KEY_ITEMS "¥¢¥¤¥Æ¥à"
108 #define KEY_WEAPONS "Éð´ï"
109 #define KEY_ARMORS "Ëɶñ"
110 #define KEY_MISSILES "Ìð"
111 #define KEY_DEVICES "ËâË¡¥¢¥¤¥Æ¥à"
112 #define KEY_LIGHTS "¸÷¸»"
113 #define KEY_JUNKS "¤¬¤é¤¯¤¿"
114 #define KEY_SPELLBOOKS "ËâË¡½ñ"
115 #define KEY_HAFTED "Æß´ï"
116 #define KEY_SHIELDS "½â"
117 #define KEY_BOWS "µÝ"
118 #define KEY_RINGS "»ØÎØ"
119 #define KEY_AMULETS "¥¢¥ß¥å¥ì¥Ã¥È"
120 #define KEY_SUITS "³»"
121 #define KEY_CLOAKS "¥¯¥í¡¼¥¯"
122 #define KEY_HELMS "³õ"
123 #define KEY_GLOVES "äƼê"
124 #define KEY_BOOTS "·¤"
125 #define KEY_FAVORITE "ÆÀ°ÕÉð´ï"
129 #define KEY_ALL "all"
130 #define KEY_COLLECTING "collecting"
131 #define KEY_UNIDENTIFIED "unidentified"
132 #define KEY_IDENTIFIED "identified"
133 #define KEY_STAR_IDENTIFIED "*identified*"
134 #define KEY_BOOSTED "dice boosted"
135 #define KEY_MORE_THAN "more than"
136 #define KEY_DICE " dice"
137 #define KEY_MORE_BONUS "more bonus than"
138 #define KEY_MORE_BONUS2 ""
139 #define KEY_WORTHLESS "worthless"
140 #define KEY_ARTIFACT "artifact"
141 #define KEY_EGO "ego"
142 #define KEY_NAMELESS "nameless"
143 #define KEY_UNAWARE "unaware"
144 #define KEY_WANTED "wanted"
145 #define KEY_UNIQUE "unique monster's"
146 #define KEY_HUMAN "human"
147 #define KEY_UNREADABLE "unreadable"
148 #define KEY_REALM1 "first realm's"
149 #define KEY_REALM2 "second realm's"
150 #define KEY_FIRST "first"
151 #define KEY_SECOND "second"
152 #define KEY_THIRD "third"
153 #define KEY_FOURTH "fourth"
154 #define KEY_ITEMS "items"
155 #define KEY_WEAPONS "weapons"
156 #define KEY_ARMORS "armors"
157 #define KEY_MISSILES "missiles"
158 #define KEY_DEVICES "magical devices"
159 #define KEY_LIGHTS "lights"
160 #define KEY_JUNKS "junks"
161 #define KEY_SPELLBOOKS "spellbooks"
162 #define KEY_HAFTED "hafted weapons"
163 #define KEY_SHIELDS "shields"
164 #define KEY_BOWS "bows"
165 #define KEY_RINGS "rings"
166 #define KEY_AMULETS "amulets"
167 #define KEY_SUITS "suits"
168 #define KEY_CLOAKS "cloaks"
169 #define KEY_HELMS "helms"
170 #define KEY_GLOVES "gloves"
171 #define KEY_BOOTS "boots"
172 #define KEY_FAVORITE "favorite weapons"
176 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
177 ? (ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
178 #define MATCH_KEY2(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
179 ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
182 #define ADD_KEY(KEY) strcat(ptr, KEY)
184 #define ADD_KEY(KEY) (strcat(ptr, KEY), strcat(ptr, " "))
186 #define ADD_KEY2(KEY) strcat(ptr, KEY)
188 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
189 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
190 #define ADD_FLG_NOUN(FLG) (ADD_FLG(FLG), prev_flg = FLG)
191 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
194 static char kanji_colon[] = "¡§";
199 * A function to create new entry
201 bool autopick_new_entry(autopick_type *entry, cptr str)
206 char buf[MAX_LINELEN];
207 cptr prev_ptr, ptr, old_ptr;
210 if (str[1] == ':') switch (str[0])
213 case 'A': case 'P': case 'C':
217 entry->flag[0] = entry->flag[1] = 0L;
220 act = DO_AUTOPICK | DO_DISPLAY;
223 if ((act & DO_AUTOPICK) && *str == '!')
226 act |= DO_AUTODESTROY;
229 else if ((act & DO_AUTOPICK) && *str == '~')
232 act |= DONT_AUTOPICK;
235 else if ((act & DO_AUTOPICK) && *str == ';')
238 act |= DO_QUERY_AUTOPICK;
241 else if ((act & DO_DISPLAY) && *str == '(')
250 /* don't mind upper or lower case */
252 for (i = 0; *str; i++)
263 /* Auto-inscription? */
271 if (isupper(c)) c = tolower(c);
278 /* Skip empty line */
279 if (*buf == 0) return FALSE;
282 ptr = prev_ptr = buf;
285 while (old_ptr != ptr)
287 /* Save current location */
290 if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
291 if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
292 if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
293 if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
294 if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
295 if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
297 /*** Weapons whose dd*ds is more than nn ***/
298 if (MATCH_KEY2(KEY_MORE_THAN))
303 /* Drop leading spaces */
304 while (' ' == *ptr) ptr++;
307 while ('0' <= *ptr && *ptr <= '9')
309 entry->dice = 10 * entry->dice + (*ptr - '0');
316 (void)MATCH_KEY(KEY_DICE);
317 ADD_FLG(FLG_MORE_THAN);
323 /*** Items whose magical bonus is more than n ***/
324 if (MATCH_KEY2(KEY_MORE_BONUS))
329 /* Drop leading spaces */
330 while (' ' == *ptr) ptr++;
333 while ('0' <= *ptr && *ptr <= '9')
335 entry->bonus = 10 * entry->bonus + (*ptr - '0');
342 (void)MATCH_KEY(KEY_MORE_BONUS2);
343 ADD_FLG(FLG_MORE_BONUS);
349 if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
350 if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
351 if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
352 if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
353 if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
354 if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
355 if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
356 if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
357 if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
358 if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
359 if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
360 if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
361 if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
362 if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
365 /* Not yet found any noun */
368 if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
370 if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
371 else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
372 else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
373 else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
374 else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
375 else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
376 else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
377 else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
378 else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
379 else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
380 else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
381 else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
382 else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
383 else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
384 else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
385 else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
386 else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
387 else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
388 else if (MATCH_KEY2(KEY_FAVORITE)) ADD_FLG_NOUN(FLG_FAVORITE);
390 /* Last 'keyword' must be at the correct location */
394 else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
397 else if (*ptr == '\0')
399 /* There was no noun */
402 /* Add extra word "items" */
403 ADD_FLG_NOUN(FLG_ITEMS);
410 /* A noun type keyword didn't end correctly */
411 entry->flag[prev_flg/32] &= ~(1L<< (prev_flg%32));
416 /* Save this auto-picker entry line */
417 entry->name = string_make(ptr);
419 entry->insc = string_make(insc);
426 * A function to delete entry
428 void autopick_free_entry(autopick_type *entry)
430 string_free(entry->name);
431 string_free(entry->insc);
436 * Initialize auto-picker preference
438 void init_autopicker(void)
440 static const char easy_autopick_inscription[] = "(:=g";
444 /* Clear old entries */
445 for( i = 0; i < max_autopick; i++)
446 autopick_free_entry(&autopick_list[i]);
450 /* There is always one entry "=g" */
451 autopick_new_entry(&entry, easy_autopick_inscription);
452 autopick_list[max_autopick++] = entry;
458 * Process line for auto picker/destroyer.
460 errr process_pickpref_file_line(char *buf)
465 if (max_autopick == MAX_AUTOPICK)
468 /* Nuke illegal char */
469 for(i = 0; buf[i]; i++)
478 if (isspace(buf[i]) && buf[i] != ' ')
483 if (!autopick_new_entry(&entry, buf)) return 0;
485 /* Already has the same entry? */
486 for(i = 0; i < max_autopick; i++)
487 if(!strcmp(entry.name, autopick_list[i].name)
488 && entry.flag[0] == autopick_list[i].flag[0]
489 && entry.flag[1] == autopick_list[i].flag[1]
490 && entry.dice == autopick_list[i].dice
491 && entry.bonus == autopick_list[i].bonus) return 0;
493 autopick_list[max_autopick++] = entry;
499 * Reconstruct preference line from entry
501 cptr autopick_line_from_entry(autopick_type *entry)
503 char buf[MAX_LINELEN];
505 bool sepa_flag = TRUE;
508 if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
509 if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
510 if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
511 if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
515 if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
516 if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
517 if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
518 if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
519 if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
520 if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
521 if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
523 if (IS_FLG(FLG_MORE_THAN))
525 ADD_KEY(KEY_MORE_THAN);
526 strcat(ptr, format("%d", entry->dice));
530 if (IS_FLG(FLG_MORE_BONUS))
532 ADD_KEY(KEY_MORE_BONUS);
533 strcat(ptr, format("%d", entry->bonus));
534 ADD_KEY(KEY_MORE_BONUS2);
537 if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
538 if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
539 if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
540 if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
541 if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
542 if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
543 if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
544 if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
545 if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
546 if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
547 if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
548 if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
549 if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
551 if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
553 if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
554 else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
555 else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
556 else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
557 else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
558 else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
559 else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
560 else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
561 else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
562 else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
563 else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
564 else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
565 else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
566 else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
567 else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
568 else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
569 else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
570 else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
571 else if (IS_FLG(FLG_FAVORITE)) ADD_KEY2(KEY_FAVORITE);
573 /* You don't need sepalator after adjective */
574 /* 'artifact' is not true adjective */
575 else if (!IS_FLG(FLG_ARTIFACT))
578 if (entry->name && entry->name[0])
582 if (sepa_flag) strcat(buf, ":");
585 while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
588 if (iskanji(entry->name[j]))
589 buf[i++] = entry->name[j++];
591 buf[i++] = entry->name[j++];
602 while (entry->insc[j] && i < MAX_LINELEN - 2)
605 if (iskanji(entry->insc[j]))
606 buf[i++] = entry->insc[j++];
608 buf[i++] = entry->insc[j++];
613 return string_make(buf);
618 * Reconstruct preference line from entry and kill entry
620 static cptr autopick_line_from_entry_kill(autopick_type *entry)
622 cptr ptr = autopick_line_from_entry(entry);
624 /* Free memory for original entry */
625 autopick_free_entry(entry);
634 static bool is_favorite(object_type *o_ptr, bool others_ok)
636 /* Only weapons match */
639 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
640 case TV_SWORD: case TV_DIGGING:
642 default: return FALSE;
645 /* Favorite weapons are varied depend on the class */
646 switch (p_ptr->pclass)
650 u32b flgs[TR_FLAG_SIZE];
651 object_flags_known(o_ptr, flgs);
653 if (!have_flag(flgs, TR_BLESSED) &&
654 !(o_ptr->tval == TV_HAFTED))
660 case CLASS_FORCETRAINER:
662 if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval]))
666 case CLASS_BEASTMASTER:
669 u32b flgs[TR_FLAG_SIZE];
670 object_flags_known(o_ptr, flgs);
672 /* Is it known to be suitable to using while riding? */
673 if (!(have_flag(flgs, TR_RIDING)))
681 if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
686 /* Non-special class */
687 if (others_ok) return TRUE;
695 * A function for Auto-picker/destroyer
696 * Examine whether the object matches to the entry
698 static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
701 cptr ptr = entry->name;
703 /*** Unidentified ***/
704 if (IS_FLG(FLG_UNIDENTIFIED)
705 && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
709 if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
712 /*** *Identified* ***/
713 if (IS_FLG(FLG_STAR_IDENTIFIED) &&
714 (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
717 /*** Dice boosted (weapon of slaying) ***/
718 if (IS_FLG(FLG_BOOSTED))
720 object_kind *k_ptr = &k_info[o_ptr->k_idx];
722 switch( o_ptr->tval )
728 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
737 /*** Weapons which dd*ds is more than nn ***/
738 if (IS_FLG(FLG_MORE_THAN))
740 if (o_ptr->dd * o_ptr->ds < entry->dice)
744 /*** Weapons whic dd*ds is more than nn ***/
745 if (IS_FLG(FLG_MORE_BONUS))
747 if (!object_known_p(o_ptr)) return FALSE;
751 if (o_ptr->pval < entry->bonus) return FALSE;
755 if (o_ptr->to_h < entry->bonus &&
756 o_ptr->to_d < entry->bonus &&
757 o_ptr->to_a < entry->bonus &&
758 o_ptr->pval < entry->bonus)
763 /*** Worthless items ***/
764 if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
767 /*** Artifact object ***/
768 if (IS_FLG(FLG_ARTIFACT))
770 if (!object_known_p(o_ptr) || (!o_ptr->name1 && !o_ptr->art_name))
777 if (!object_known_p(o_ptr) || !o_ptr->name2)
782 if (IS_FLG(FLG_NAMELESS))
787 case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
788 case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD:
789 case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
790 case TV_SHIELD: case TV_CLOAK:
791 case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
792 case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
793 if ((!object_known_p(o_ptr) || o_ptr->inscription
794 || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
803 /*** Unaware items ***/
804 if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
807 /*** Wanted monster's corpse/skeletons ***/
808 if (IS_FLG(FLG_WANTED) &&
809 (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
812 /*** Unique monster's corpse/skeletons/statues ***/
813 if (IS_FLG(FLG_UNIQUE) &&
814 ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
815 !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
818 /*** Human corpse/skeletons (for Daemon magic) ***/
819 if (IS_FLG(FLG_HUMAN) &&
820 (o_ptr->tval != TV_CORPSE ||
821 !strchr("pht", r_info[o_ptr->pval].d_char)))
824 /*** Unreadable spellbooks ***/
825 if (IS_FLG(FLG_UNREADABLE) &&
826 (o_ptr->tval < TV_LIFE_BOOK ||
827 check_book_realm(o_ptr->tval, o_ptr->sval)))
830 /*** First realm spellbooks ***/
831 if (IS_FLG(FLG_REALM1) &&
832 (REALM1_BOOK != o_ptr->tval ||
833 p_ptr->pclass == CLASS_SORCERER ||
834 p_ptr->pclass == CLASS_RED_MAGE))
837 /*** Second realm spellbooks ***/
838 if (IS_FLG(FLG_REALM2) &&
839 (REALM2_BOOK != o_ptr->tval ||
840 p_ptr->pclass == CLASS_SORCERER ||
841 p_ptr->pclass == CLASS_RED_MAGE))
844 /*** First rank spellbooks ***/
845 if (IS_FLG(FLG_FIRST) &&
846 (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
849 /*** Second rank spellbooks ***/
850 if (IS_FLG(FLG_SECOND) &&
851 (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
854 /*** Third rank spellbooks ***/
855 if (IS_FLG(FLG_THIRD) &&
856 (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
859 /*** Fourth rank spellbooks ***/
860 if (IS_FLG(FLG_FOURTH) &&
861 (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
865 if (IS_FLG(FLG_WEAPONS))
869 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
870 case TV_SWORD: case TV_DIGGING:
872 default: return FALSE;
875 else if (IS_FLG(FLG_ARMORS))
879 case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
880 case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
881 case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
883 default: return FALSE;
886 else if (IS_FLG(FLG_MISSILES))
890 case TV_SHOT: case TV_BOLT: case TV_ARROW:
892 default: return FALSE;
895 else if (IS_FLG(FLG_DEVICES))
899 case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
901 default: return FALSE;
904 else if (IS_FLG(FLG_LIGHTS))
906 if (!(o_ptr->tval == TV_LITE))
909 else if (IS_FLG(FLG_JUNKS))
913 case TV_SKELETON: case TV_BOTTLE:
914 case TV_JUNK: case TV_STATUE:
916 default: return FALSE;
919 else if (IS_FLG(FLG_SPELLBOOKS))
921 if (!(o_ptr->tval >= TV_LIFE_BOOK))
924 else if (IS_FLG(FLG_HAFTED))
926 if (!(o_ptr->tval == TV_HAFTED))
929 else if (IS_FLG(FLG_SHIELDS))
931 if (!(o_ptr->tval == TV_SHIELD))
934 else if (IS_FLG(FLG_BOWS))
936 if (!(o_ptr->tval == TV_BOW))
939 else if (IS_FLG(FLG_RINGS))
941 if (!(o_ptr->tval == TV_RING))
944 else if (IS_FLG(FLG_AMULETS))
946 if (!(o_ptr->tval == TV_AMULET))
949 else if (IS_FLG(FLG_SUITS))
951 if (!(o_ptr->tval == TV_DRAG_ARMOR ||
952 o_ptr->tval == TV_HARD_ARMOR ||
953 o_ptr->tval == TV_SOFT_ARMOR))
956 else if (IS_FLG(FLG_CLOAKS))
958 if (!(o_ptr->tval == TV_CLOAK))
961 else if (IS_FLG(FLG_HELMS))
963 if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
966 else if (IS_FLG(FLG_GLOVES))
968 if (!(o_ptr->tval == TV_GLOVES))
971 else if (IS_FLG(FLG_BOOTS))
973 if (!(o_ptr->tval == TV_BOOTS))
976 else if (IS_FLG(FLG_FAVORITE))
978 if (!is_favorite(o_ptr, TRUE))
982 /* Keyword don't match */
986 if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
991 if (!strstr_j(o_name, ptr)) return FALSE;
993 if (!strstr(o_name, ptr)) return FALSE;
997 /* TRUE when it need not to be 'collecting' */
998 if (!IS_FLG(FLG_COLLECTING)) return TRUE;
1000 /* Check if there is a same item */
1001 for (j = 0; j < INVEN_PACK; j++)
1004 * 'Collecting' means the item must be absorbed
1005 * into an inventory slot.
1006 * But an item can not be absorbed into itself!
1008 if ((&inventory[j] != o_ptr) &&
1009 object_similar(&inventory[j], o_ptr))
1013 /* Not collecting */
1019 * A function for Auto-picker/destroyer
1020 * Examine whether the object matches to the list of keywords or not.
1022 int is_autopick(object_type *o_ptr)
1025 char o_name[MAX_NLEN];
1027 if (o_ptr->tval == TV_GOLD) return -1;
1029 object_desc(o_name, o_ptr, FALSE, 3);
1031 /* Force to be lower case string */
1032 for (i = 0; o_name[i]; i++)
1035 if (iskanji(o_name[i]))
1039 if (isupper(o_name[i]))
1040 o_name[i] = tolower(o_name[i]);
1043 for (i=0; i < max_autopick; i++)
1045 autopick_type *entry = &autopick_list[i];
1047 if (is_autopick_aux(o_ptr, entry, o_name)) return i;
1050 /* No matching entry */
1058 void auto_inscribe_item(int item, int idx)
1062 /* Get the item (in the pack) */
1063 if (item >= 0) o_ptr = &inventory[item];
1065 /* Get the item (on the floor) */
1066 else o_ptr = &o_list[0 - item];
1068 /* Auto-inscription or Re-inscribe for resistances {%} */
1069 if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
1072 if (!o_ptr->inscription)
1073 o_ptr->inscription = quark_add(autopick_list[idx].insc);
1075 if (item > INVEN_PACK)
1077 /* Redraw inscription */
1078 p_ptr->window |= (PW_EQUIP);
1080 /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
1081 p_ptr->update |= (PU_BONUS);
1085 /* Redraw inscription */
1086 p_ptr->window |= (PW_INVEN);
1092 * Automatically destroy items in this grid.
1094 static bool is_opt_confirm_destroy(object_type *o_ptr)
1096 if (!destroy_items) return FALSE;
1098 /* Known to be worthless? */
1100 if (object_value(o_ptr) > 0) return FALSE;
1103 if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_DRAG_ARMOR)) return FALSE;
1106 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
1110 if (o_ptr->tval == TV_CORPSE
1111 && object_is_shoukinkubi(o_ptr)) return FALSE;
1115 if (o_ptr->tval == TV_CORPSE) return FALSE;
1118 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
1122 if (p_ptr->prace == RACE_DEMON)
1124 if (o_ptr->tval == TV_CORPSE &&
1125 o_ptr->sval == SV_CORPSE &&
1126 strchr("pht", r_info[o_ptr->pval].d_char))
1130 if (p_ptr->pclass == CLASS_ARCHER)
1132 if (o_ptr->tval == TV_SKELETON ||
1133 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
1136 else if (p_ptr->pclass == CLASS_NINJA)
1138 if (o_ptr->tval == TV_LITE &&
1139 o_ptr->name2 == EGO_LITE_DARKNESS)
1142 else if (p_ptr->pclass == CLASS_BEASTMASTER ||
1143 p_ptr->pclass == CLASS_CAVALRY)
1145 if (o_ptr->tval == TV_WAND &&
1146 o_ptr->sval == SV_WAND_HEAL_MONSTER)
1151 if (o_ptr->tval == TV_GOLD) return FALSE;
1158 * Automatically destroy an item if it is to be destroyed
1160 static object_type autopick_last_destroyed_object;
1162 bool auto_destroy_item(int item, int autopick_idx)
1164 bool destroy = FALSE;
1167 /* Don't destroy equipped items */
1168 if (item > INVEN_PACK) return FALSE;
1170 /* Get the item (in the pack) */
1171 if (item >= 0) o_ptr = &inventory[item];
1173 /* Get the item (on the floor) */
1174 else o_ptr = &o_list[0 - item];
1176 /* Easy-Auto-Destroyer */
1177 if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
1179 /* Protected by auto-picker */
1180 if (autopick_idx >= 0 &&
1181 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1186 /* Auto-picker/destroyer */
1187 if (autopick_idx >= 0 &&
1188 (autopick_list[autopick_idx].action & DO_AUTODESTROY))
1192 /* Not to be destroyed */
1193 if (!destroy) return FALSE;
1195 /* Now decided to destroy */
1200 if (!can_player_destroy_object(o_ptr))
1202 char o_name[MAX_NLEN];
1204 /* Describe the object (with {terrible/special}) */
1205 object_desc(o_name, o_ptr, TRUE, 3);
1209 msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
1211 msg_format("You cannot auto-destroy %s.", o_name);
1218 /* Record name of destroyed item */
1219 COPY(&autopick_last_destroyed_object, o_ptr, object_type);
1222 o_ptr->marked |= OM_AUTODESTROY;
1223 p_ptr->notice |= PN_AUTODESTROY;
1230 * Auto-destroy marked item
1232 static void delayed_auto_destroy_aux(int item)
1236 /* Get the item (in the pack) */
1237 if (item >= 0) o_ptr = &inventory[item];
1239 /* Get the item (on the floor) */
1240 else o_ptr = &o_list[0 - item];
1242 if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
1244 char o_name[MAX_NLEN];
1246 /* Describe the object (with {terrible/special}) */
1247 object_desc(o_name, o_ptr, TRUE, 3);
1249 /* Eliminate the item (from the pack) */
1252 inven_item_increase(item, -(o_ptr->number));
1253 inven_item_optimize(item);
1256 /* Eliminate the item (from the floor) */
1259 delete_object_idx(0 - item);
1262 /* Print a message */
1264 msg_format("%s¤ò¼«Æ°Ç˲õ¤·¤Þ¤¹¡£", o_name);
1266 msg_format("Auto-destroying %s.", o_name);
1273 * Auto-destroy marked item in inventry and on floor
1275 void delayed_auto_destroy(void)
1280 * Scan inventry in reverse order to prevent
1281 * skipping after inven_item_optimize()
1283 for (item = INVEN_TOTAL - 1; item >= 0 ; item--)
1284 delayed_auto_destroy_aux(item);
1286 /* Scan the pile of objects */
1287 item = cave[py][px].o_idx;
1290 int next = o_list[item].next_o_idx;
1291 delayed_auto_destroy_aux(-item);
1298 * Automatically pickup/destroy items in this grid.
1300 void auto_pickup_items(cave_type *c_ptr)
1302 s16b this_o_idx, next_o_idx = 0;
1304 /* Scan the pile of objects */
1305 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1309 /* Acquire object */
1310 object_type *o_ptr = &o_list[this_o_idx];
1312 /* Acquire next object */
1313 next_o_idx = o_ptr->next_o_idx;
1315 idx = is_autopick(o_ptr);
1317 /* Item index for floor -1,-2,-3,... */
1318 auto_inscribe_item((-this_o_idx), idx);
1321 (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)))
1325 if (!inven_carry_okay(o_ptr))
1327 char o_name[MAX_NLEN];
1329 /* Describe the object */
1330 object_desc(o_name, o_ptr, TRUE, 3);
1334 msg_format("¥¶¥Ã¥¯¤Ë¤Ï%s¤òÆþ¤ì¤ë·ä´Ö¤¬¤Ê¤¤¡£", o_name);
1336 msg_format("You have no room for %s.", o_name);
1338 /* Hack - remember that the item has given a message here. */
1339 o_ptr->marked |= OM_NOMSG;
1343 else if (autopick_list[idx].action & DO_QUERY_AUTOPICK)
1345 char out_val[MAX_NLEN+20];
1346 char o_name[MAX_NLEN];
1348 if (o_ptr->marked & OM_NO_QUERY)
1350 /* Already answered as 'No' */
1354 /* Describe the object */
1355 object_desc(o_name, o_ptr, TRUE, 3);
1358 sprintf(out_val, "%s¤ò½¦¤¤¤Þ¤¹¤«? ", o_name);
1360 sprintf(out_val, "Pick up %s? ", o_name);
1363 if (!get_check(out_val))
1365 /* Hack - remember that the item has given a message here. */
1366 o_ptr->marked |= (OM_NOMSG | OM_NO_QUERY);
1371 py_pickup_aux(this_o_idx);
1378 * When always_pickup is 'yes', we disable
1379 * auto-destroyer from autopick function, and do only
1380 * easy-auto-destroyer.
1384 if (auto_destroy_item((-this_o_idx), idx))
1391 /******** Auto-picker/destroyer editor **********/
1393 #define MAX_YANK MAX_LINELEN
1396 * Struct for yank buffer
1398 typedef struct chain_str {
1399 struct chain_str *next;
1405 * Data struct for text editor
1411 int old_wid, old_hgt;
1413 int old_upper, old_left;
1416 object_type *search_o_ptr;
1418 cptr last_destroyed;
1419 chain_str_type *yank;
1430 * Describe which kind of object is Auto-picked/destroyed
1432 static void describe_autopick(char *buff, autopick_type *entry)
1434 cptr str = entry->name;
1435 byte act = entry->action;
1436 cptr insc = entry->insc;
1442 cptr before_str[100], body_str;
1445 body_str = "¥¢¥¤¥Æ¥à";
1447 /*** Collecting items ***/
1448 /*** Which can be absorbed into a slot as a bundle ***/
1449 if (IS_FLG(FLG_COLLECTING))
1450 before_str[before_n++] = "¼ý½¸Ãæ¤Ç´û¤Ë»ý¤Ã¤Æ¤¤¤ë¥¹¥í¥Ã¥È¤Ë¤Þ¤È¤á¤é¤ì¤ë";
1452 /*** Unidentified ***/
1453 if (IS_FLG(FLG_UNIDENTIFIED))
1454 before_str[before_n++] = "̤´ÕÄê¤Î";
1456 /*** Identified ***/
1457 if (IS_FLG(FLG_IDENTIFIED))
1458 before_str[before_n++] = "´ÕÄêºÑ¤ß¤Î";
1460 /*** *Identified* ***/
1461 if (IS_FLG(FLG_STAR_IDENTIFIED))
1462 before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
1464 /*** Dice boosted (weapon of slaying) ***/
1465 if (IS_FLG(FLG_BOOSTED))
1467 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤¬Ä̾ï¤è¤êÂ礤¤";
1471 /*** Weapons whose dd*ds is more than nn ***/
1472 if (IS_FLG(FLG_MORE_THAN))
1474 static char more_than_desc_str[] = "___";
1475 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
1478 sprintf(more_than_desc_str,"%d", entry->dice);
1479 before_str[before_n++] = more_than_desc_str;
1480 before_str[before_n++] = "°Ê¾å¤Î";
1483 /*** Items whose magical bonus is more than nn ***/
1484 if (IS_FLG(FLG_MORE_BONUS))
1486 static char more_bonus_desc_str[] = "___";
1487 before_str[before_n++] = "½¤ÀµÃͤ¬(+";
1489 sprintf(more_bonus_desc_str,"%d", entry->bonus);
1490 before_str[before_n++] = more_bonus_desc_str;
1491 before_str[before_n++] = ")°Ê¾å¤Î";
1494 /*** Worthless items ***/
1495 if (IS_FLG(FLG_WORTHLESS))
1496 before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
1499 if (IS_FLG(FLG_ARTIFACT))
1501 before_str[before_n++] = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Î";
1506 if (IS_FLG(FLG_EGO))
1508 before_str[before_n++] = "¥¨¥´¥¢¥¤¥Æ¥à¤Î";
1513 if (IS_FLG(FLG_NAMELESS))
1515 before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
1519 /*** Unaware items ***/
1520 if (IS_FLG(FLG_UNAWARE))
1521 before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
1523 /*** Wanted monster's corpse/skeletons ***/
1524 if (IS_FLG(FLG_WANTED))
1526 before_str[before_n++] = "¥Ï¥ó¥¿¡¼»ö̳½ê¤Ç¾Þ¶â¼ó¤È¤µ¤ì¤Æ¤¤¤ë";
1527 body_str = "»àÂΤä¹ü";
1530 /*** Human corpse/skeletons (for Daemon magic) ***/
1531 if (IS_FLG(FLG_HUMAN))
1533 before_str[before_n++] = "°ËâËâË¡¤Ç»È¤¦¤¿¤á¤Î¿Í´Ö¤ä¥Ò¥å¡¼¥Þ¥Î¥¤¥É¤Î";
1534 body_str = "»àÂΤä¹ü";
1537 /*** Unique monster's corpse/skeletons/statues ***/
1538 if (IS_FLG(FLG_UNIQUE))
1540 before_str[before_n++] = "¥æ¥Ë¡¼¥¯¥â¥ó¥¹¥¿¡¼¤Î";
1541 body_str = "»àÂΤä¹ü";
1544 /*** Unreadable spellbooks ***/
1545 if (IS_FLG(FLG_UNREADABLE))
1547 before_str[before_n++] = "¤¢¤Ê¤¿¤¬Æɤá¤Ê¤¤Îΰè¤Î";
1548 body_str = "ËâË¡½ñ";
1551 /*** First realm spellbooks ***/
1552 if (IS_FLG(FLG_REALM1))
1554 before_str[before_n++] = "Âè°ìÎΰè¤Î";
1555 body_str = "ËâË¡½ñ";
1558 /*** Second realm spellbooks ***/
1559 if (IS_FLG(FLG_REALM2))
1561 before_str[before_n++] = "ÂèÆóÎΰè¤Î";
1562 body_str = "ËâË¡½ñ";
1565 /*** First rank spellbooks ***/
1566 if (IS_FLG(FLG_FIRST))
1568 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î1ºýÌܤÎ";
1569 body_str = "ËâË¡½ñ";
1572 /*** Second rank spellbooks ***/
1573 if (IS_FLG(FLG_SECOND))
1575 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î2ºýÌܤÎ";
1576 body_str = "ËâË¡½ñ";
1579 /*** Third rank spellbooks ***/
1580 if (IS_FLG(FLG_THIRD))
1582 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î3ºýÌܤÎ";
1583 body_str = "ËâË¡½ñ";
1586 /*** Fourth rank spellbooks ***/
1587 if (IS_FLG(FLG_FOURTH))
1589 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î4ºýÌܤÎ";
1590 body_str = "ËâË¡½ñ";
1594 if (IS_FLG(FLG_ITEMS))
1595 ; /* Nothing to do */
1596 else if (IS_FLG(FLG_WEAPONS))
1598 else if (IS_FLG(FLG_ARMORS))
1600 else if (IS_FLG(FLG_MISSILES))
1601 body_str = "ÃƤäÌð¤ä¥¯¥í¥¹¥Ü¥¦¤ÎÌð";
1602 else if (IS_FLG(FLG_DEVICES))
1603 body_str = "´¬Êª¤äËâË¡ËÀ¤ä¾ó¤ä¥í¥Ã¥É";
1604 else if (IS_FLG(FLG_LIGHTS))
1605 body_str = "¸÷¸»ÍѤΥ¢¥¤¥Æ¥à";
1606 else if (IS_FLG(FLG_JUNKS))
1607 body_str = "Àޤ줿ËÀÅù¤Î¥¬¥é¥¯¥¿";
1608 else if (IS_FLG(FLG_SPELLBOOKS))
1609 body_str = "ËâË¡½ñ";
1610 else if (IS_FLG(FLG_HAFTED))
1612 else if (IS_FLG(FLG_SHIELDS))
1614 else if (IS_FLG(FLG_BOWS))
1615 body_str = "¥¹¥ê¥ó¥°¤äµÝ¤ä¥¯¥í¥¹¥Ü¥¦";
1616 else if (IS_FLG(FLG_RINGS))
1618 else if (IS_FLG(FLG_AMULETS))
1619 body_str = "¥¢¥ß¥å¥ì¥Ã¥È";
1620 else if (IS_FLG(FLG_SUITS))
1622 else if (IS_FLG(FLG_CLOAKS))
1623 body_str = "¥¯¥í¡¼¥¯";
1624 else if (IS_FLG(FLG_HELMS))
1625 body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
1626 else if (IS_FLG(FLG_GLOVES))
1628 else if (IS_FLG(FLG_BOOTS))
1629 body_str = "¥Ö¡¼¥Ä";
1630 else if (IS_FLG(FLG_FAVORITE))
1631 body_str = "ÆÀ°ÕÉð´ï";
1635 strcat(buff, "Á´¤Æ¤Î");
1636 else for (i = 0; i < before_n && before_str[i]; i++)
1637 strcat(buff, before_str[i]);
1639 strcat(buff, body_str);
1649 strcat(buff, "¤Ç¡¢Ì¾Á°¤¬¡Ö");
1650 strncat(buff, str, 80);
1652 strcat(buff, "¡×¤Ç»Ï¤Þ¤ë¤â¤Î");
1654 strcat(buff, "¡×¤ò´Þ¤à¤â¤Î");
1659 strncat(buff, format("¤Ë¡Ö%s¡×", insc), 80);
1661 if (strstr(insc, "%%all"))
1662 strcat(buff, "(%%all¤ÏÁ´Ç½ÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1663 else if (strstr(insc, "%all"))
1664 strcat(buff, "(%all¤ÏÁ´Ç½ÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1665 else if (strstr(insc, "%%"))
1666 strcat(buff, "(%%¤ÏÄɲÃǽÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1667 else if (strstr(insc, "%"))
1668 strcat(buff, "(%¤ÏÄɲÃǽÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1670 strcat(buff, "¤È¹ï¤ó¤Ç");
1675 if (act & DONT_AUTOPICK)
1676 strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
1677 else if (act & DO_AUTODESTROY)
1678 strcat(buff, "Ç˲õ¤¹¤ë¡£");
1679 else if (act & DO_QUERY_AUTOPICK)
1680 strcat(buff, "³Îǧ¤Î¸å¤Ë½¦¤¦¡£");
1682 strcat(buff, "½¦¤¦¡£");
1684 if (act & DO_DISPLAY)
1686 if (act & DONT_AUTOPICK)
1687 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'N'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1688 else if (act & DO_AUTODESTROY)
1689 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'K'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1691 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'M'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1694 strcat(buff, "Á´ÂΥޥåפˤÏɽ¼¨¤·¤Ê¤¤");
1698 cptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
1699 int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
1703 /*** Collecting items ***/
1704 /*** Which can be absorbed into a slot as a bundle ***/
1705 if (IS_FLG(FLG_COLLECTING))
1706 which_str[which_n++] = "can be absorbed into an existing inventory slot";
1708 /*** Unidentified ***/
1709 if (IS_FLG(FLG_UNIDENTIFIED))
1710 before_str[before_n++] = "unidentified";
1712 /*** Identified ***/
1713 if (IS_FLG(FLG_IDENTIFIED))
1714 before_str[before_n++] = "identified";
1716 /*** *Identified* ***/
1717 if (IS_FLG(FLG_STAR_IDENTIFIED))
1718 before_str[before_n++] = "fully identified";
1720 /*** Worthless items ***/
1721 if (IS_FLG(FLG_WORTHLESS))
1723 before_str[before_n++] = "worthless";
1724 which_str[which_n++] = "can not be sold at stores";
1728 if (IS_FLG(FLG_ARTIFACT))
1730 before_str[before_n++] = "artifact";
1734 if (IS_FLG(FLG_EGO))
1736 before_str[before_n++] = "ego";
1740 if (IS_FLG(FLG_NAMELESS))
1742 body_str = "equipment";
1743 which_str[which_n++] = "is neither ego-item nor artifact";
1746 /*** Unaware items ***/
1747 if (IS_FLG(FLG_UNAWARE))
1749 before_str[before_n++] = "unidentified";
1750 whose_str[whose_n++] = "basic abilities are not known";
1753 /*** Dice boosted (weapon of slaying) ***/
1754 if (IS_FLG(FLG_BOOSTED))
1756 body_str = "weapons";
1757 whose_str[whose_n++] = "damage dice is bigger than normal";
1760 /*** Weapons whose dd*ds is more than nn ***/
1761 if (IS_FLG(FLG_MORE_THAN))
1763 static char more_than_desc_str[] =
1764 "maximum damage from dice is bigger than __";
1765 body_str = "weapons";
1767 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
1769 whose_str[whose_n++] = more_than_desc_str;
1772 /*** Items whose magical bonus is more than nn ***/
1773 if (IS_FLG(FLG_MORE_BONUS))
1775 static char more_bonus_desc_str[] =
1776 "magical bonus is bigger than (+__)";
1778 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
1779 "%d)", entry->bonus);
1780 whose_str[whose_n++] = more_bonus_desc_str;
1783 /*** Wanted monster's corpse/skeletons ***/
1784 if (IS_FLG(FLG_WANTED))
1786 body_str = "corpse or skeletons";
1787 which_str[which_n++] = "is wanted at the Hunter's Office";
1790 /*** Human corpse/skeletons (for Daemon magic) ***/
1791 if (IS_FLG(FLG_HUMAN))
1793 before_str[before_n++] = "humanoid";
1794 body_str = "corpse or skeletons";
1795 which_str[which_n++] = "can be used for Daemon magic";
1798 /*** Unique monster's corpse/skeletons/statues ***/
1799 if (IS_FLG(FLG_UNIQUE))
1801 before_str[before_n++] = "unique monster's";
1802 body_str = "corpse or skeletons";
1805 /*** Unreadable spellbooks ***/
1806 if (IS_FLG(FLG_UNREADABLE))
1808 body_str = "spellbooks";
1809 after_str[after_n++] = "of different realms from yours";
1812 /*** First realm spellbooks ***/
1813 if (IS_FLG(FLG_REALM1))
1815 body_str = "spellbooks";
1816 after_str[after_n++] = "of your first realm";
1819 /*** Second realm spellbooks ***/
1820 if (IS_FLG(FLG_REALM2))
1822 body_str = "spellbooks";
1823 after_str[after_n++] = "of your second realm";
1826 /*** First rank spellbooks ***/
1827 if (IS_FLG(FLG_FIRST))
1829 before_str[before_n++] = "first one of four";
1830 body_str = "spellbooks";
1833 /*** Second rank spellbooks ***/
1834 if (IS_FLG(FLG_SECOND))
1836 before_str[before_n++] = "second one of four";
1837 body_str = "spellbooks";
1840 /*** Third rank spellbooks ***/
1841 if (IS_FLG(FLG_THIRD))
1843 before_str[before_n++] = "third one of four";
1844 body_str = "spellbooks";
1847 /*** Fourth rank spellbooks ***/
1848 if (IS_FLG(FLG_FOURTH))
1850 before_str[before_n++] = "fourth one of four";
1851 body_str = "spellbooks";
1855 if (IS_FLG(FLG_ITEMS))
1856 ; /* Nothing to do */
1857 else if (IS_FLG(FLG_WEAPONS))
1858 body_str = "weapons";
1859 else if (IS_FLG(FLG_ARMORS))
1860 body_str = "armors";
1861 else if (IS_FLG(FLG_MISSILES))
1862 body_str = "shots, arrows or crossbow bolts";
1863 else if (IS_FLG(FLG_DEVICES))
1864 body_str = "scrolls, wands, staves or rods";
1865 else if (IS_FLG(FLG_LIGHTS))
1866 body_str = "light sources";
1867 else if (IS_FLG(FLG_JUNKS))
1868 body_str = "junk such as broken sticks";
1869 else if (IS_FLG(FLG_SPELLBOOKS))
1870 body_str = "spellbooks";
1871 else if (IS_FLG(FLG_HAFTED))
1872 body_str = "hafted weapons";
1873 else if (IS_FLG(FLG_SHIELDS))
1874 body_str = "shields";
1875 else if (IS_FLG(FLG_BOWS))
1876 body_str = "slings, bows or crossbows";
1877 else if (IS_FLG(FLG_RINGS))
1879 else if (IS_FLG(FLG_AMULETS))
1880 body_str = "amulets";
1881 else if (IS_FLG(FLG_SUITS))
1882 body_str = "body armors";
1883 else if (IS_FLG(FLG_CLOAKS))
1884 body_str = "cloaks";
1885 else if (IS_FLG(FLG_HELMS))
1886 body_str = "helms or crowns";
1887 else if (IS_FLG(FLG_GLOVES))
1888 body_str = "gloves";
1889 else if (IS_FLG(FLG_BOOTS))
1891 else if (IS_FLG(FLG_FAVORITE))
1892 body_str = "favorite weapons";
1894 /* Prepare a string for item name */
1901 whose_str[whose_n++] = "name is beginning with \"";
1904 which_str[which_n++] = "have \"";
1908 /* Describe action flag */
1909 if (act & DONT_AUTOPICK)
1910 strcpy(buff, "Leave on floor ");
1911 else if (act & DO_AUTODESTROY)
1912 strcpy(buff, "Destroy ");
1913 else if (act & DO_QUERY_AUTOPICK)
1914 strcpy(buff, "Ask to pick up ");
1916 strcpy(buff, "Pickup ");
1918 /* Auto-insctiption */
1921 strncat(buff, format("and inscribe \"%s\"", insc), 80);
1923 if (strstr(insc, "%all"))
1924 strcat(buff, ", replacing %all with code string representing all abilities,");
1925 else if (strstr(insc, "%"))
1926 strcat(buff, ", replacing % with code string representing extra random abilities,");
1928 strcat(buff, " on ");
1933 strcat(buff, "all ");
1934 else for (i = 0; i < before_n && before_str[i]; i++)
1936 strcat(buff, before_str[i]);
1941 strcat(buff, body_str);
1944 for (i = 0; i < after_n && after_str[i]; i++)
1947 strcat(buff, after_str[i]);
1951 for (i = 0; i < whose_n && whose_str[i]; i++)
1954 strcat(buff, " whose ");
1956 strcat(buff, ", and ");
1958 strcat(buff, whose_str[i]);
1961 /* Item name ; whose name is beginning with "str" */
1968 /* whose ..., and which .... */
1969 if (whose_n && which_n)
1970 strcat(buff, ", and ");
1973 for (i = 0; i < which_n && which_str[i]; i++)
1976 strcat(buff, " which ");
1978 strcat(buff, ", and ");
1980 strcat(buff, which_str[i]);
1983 /* Item name ; which have "str" as part of its name */
1986 strncat(buff, str, 80);
1987 strcat(buff, "\" as part of its name");
1991 /* Describe whether it will be displayed on the full map or not */
1992 if (act & DO_DISPLAY)
1994 if (act & DONT_AUTOPICK)
1995 strcat(buff, " Display these items when you press the N key in the full 'M'ap.");
1996 else if (act & DO_AUTODESTROY)
1997 strcat(buff, " Display these items when you press the K key in the full 'M'ap.");
1999 strcat(buff, " Display these items when you press the M key in the full 'M'ap.");
2002 strcat(buff, " Not displayed in the full map.");
2008 #define MAX_LINES 3000
2011 * Read whole lines of a file to memory
2013 static cptr *read_text_lines(cptr filename, bool user)
2015 cptr *lines_list = NULL;
2023 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2027 path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
2031 fff = my_fopen(buf, "r");
2035 /* Allocate list of pointers */
2036 C_MAKE(lines_list, MAX_LINES, cptr);
2039 while (0 == my_fgets(fff, buf, sizeof(buf)))
2041 lines_list[lines++] = string_make(buf);
2042 if (lines >= MAX_LINES - 1) break;
2045 lines_list[0] = string_make("");
2050 if (!fff) return NULL;
2055 #define PT_DEFAULT 0
2056 #define PT_WITH_PNAME 1
2058 static cptr *read_pickpref_text_lines(int *filename_mode_p)
2064 sprintf(buf, "picktype-%s.prf", player_name);
2066 sprintf(buf, "pickpref-%s.prf", player_name);
2068 lines_list = read_text_lines(buf, TRUE);
2073 lines_list = read_text_lines("picktype.prf", TRUE);
2075 lines_list = read_text_lines("pickpref.prf", TRUE);
2077 *filename_mode_p = PT_DEFAULT;
2083 lines_list = read_text_lines("picktype.prf", FALSE);
2085 lines_list = read_text_lines("pickpref.prf", FALSE);
2087 *filename_mode_p = PT_WITH_PNAME;
2092 /* Allocate list of pointers */
2093 C_MAKE(lines_list, MAX_LINES, cptr);
2094 lines_list[0] = string_make("");
2095 *filename_mode_p = PT_WITH_PNAME;
2102 * Write whole lines of memory to a file.
2104 static bool write_text_lines(cptr filename, cptr *lines_list)
2111 /* Build the filename */
2112 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2115 fff = my_fopen(buf, "w");
2118 for (lines = 0; lines_list[lines]; lines++)
2119 my_fputs(fff, lines_list[lines], 1024);
2124 if (!fff) return FALSE;
2130 * Free memory of lines_list.
2132 static void free_text_lines(cptr *lines_list)
2136 for (lines = 0; lines_list[lines]; lines++)
2137 string_free(lines_list[lines]);
2139 /* free list of pointers */
2140 C_FREE((char **)lines_list, MAX_LINES, char *);
2145 * Delete or insert string
2147 static void toggle_keyword(text_body_type *tb, int flg)
2149 autopick_type an_entry, *entry = &an_entry;
2151 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
2154 string_free(tb->lines_list[tb->cy]);
2156 /* Remove all noun flag */
2157 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2160 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2169 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
2172 tb->dirty_line = tb->cy;
2177 * Delete or insert string
2179 static void add_keyword(text_body_type *tb, int flg)
2181 autopick_type an_entry, *entry = &an_entry;
2183 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
2186 /* There is the flag already */
2189 /* Free memory for the entry */
2190 autopick_free_entry(entry);
2195 string_free(tb->lines_list[tb->cy]);
2197 /* Remove all noun flag */
2198 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2201 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2207 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
2210 tb->dirty_line = tb->cy;
2215 * Insert return code and split the line
2217 static bool insert_return_code(cptr *lines_list, int cx, int cy)
2219 char buf[MAX_LINELEN];
2222 for (k = 0; lines_list[k]; k++)
2223 /* count number of lines */ ;
2225 if (k >= MAX_LINES - 2) return FALSE;
2228 /* Move down lines */
2230 lines_list[k+1] = lines_list[k];
2232 /* Split current line */
2233 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2236 if (iskanji(lines_list[cy][i]))
2237 buf[j++] = lines_list[cy][i++];
2239 buf[j++] = lines_list[cy][i];
2242 lines_list[cy+1] = string_make(&lines_list[cy][i]);
2243 string_free(lines_list[cy]);
2244 lines_list[cy] = string_make(buf);
2250 * Get auto-picker entry from o_ptr.
2252 void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
2254 char o_name[MAX_NLEN];
2255 object_desc(o_name, o_ptr, FALSE, 0);
2257 entry->name = string_make(o_name);
2258 entry->insc = string_make(quark_str(o_ptr->inscription));
2259 entry->action = DO_AUTOPICK | DO_DISPLAY;
2260 entry->flag[0] = entry->flag[1] = 0L;
2263 if (!object_aware_p(o_ptr))
2264 ADD_FLG(FLG_UNAWARE);
2265 if (object_value(o_ptr) <= 0)
2266 ADD_FLG(FLG_WORTHLESS);
2268 if (object_known_p(o_ptr))
2272 else if (o_ptr->name1 || o_ptr->art_name)
2273 ADD_FLG(FLG_ARTIFACT);
2279 case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING:
2280 k_ptr = &k_info[o_ptr->k_idx];
2281 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
2282 ADD_FLG(FLG_BOOSTED);
2285 if (o_ptr->tval == TV_CORPSE && object_is_shoukinkubi(o_ptr))
2287 REM_FLG(FLG_WORTHLESS);
2288 ADD_FLG(FLG_WANTED);
2291 if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
2292 && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
2294 REM_FLG(FLG_WORTHLESS);
2295 ADD_FLG(FLG_UNIQUE);
2298 if (o_ptr->tval == TV_CORPSE && strchr("pht", r_info[o_ptr->pval].d_char))
2300 REM_FLG(FLG_WORTHLESS);
2304 if (o_ptr->tval >= TV_LIFE_BOOK &&
2305 !check_book_realm(o_ptr->tval, o_ptr->sval))
2306 ADD_FLG(FLG_UNREADABLE);
2308 if (REALM1_BOOK == o_ptr->tval &&
2309 p_ptr->pclass != CLASS_SORCERER &&
2310 p_ptr->pclass != CLASS_RED_MAGE)
2311 ADD_FLG(FLG_REALM1);
2313 if (REALM2_BOOK == o_ptr->tval &&
2314 p_ptr->pclass != CLASS_SORCERER &&
2315 p_ptr->pclass != CLASS_RED_MAGE)
2316 ADD_FLG(FLG_REALM2);
2318 if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
2320 if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
2321 ADD_FLG(FLG_SECOND);
2322 if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
2324 if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
2325 ADD_FLG(FLG_FOURTH);
2327 if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
2328 || o_ptr->tval == TV_ARROW)
2329 ADD_FLG(FLG_MISSILES);
2330 else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
2331 || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
2332 ADD_FLG(FLG_DEVICES);
2333 else if (o_ptr->tval == TV_LITE)
2334 ADD_FLG(FLG_LIGHTS);
2335 else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
2336 || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
2338 else if (o_ptr->tval >= TV_LIFE_BOOK)
2339 ADD_FLG(FLG_SPELLBOOKS);
2340 else if (is_favorite(o_ptr, FALSE))
2341 ADD_FLG(FLG_FAVORITE);
2342 else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
2343 || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)
2344 ADD_FLG(FLG_WEAPONS);
2345 else if (o_ptr->tval == TV_SHIELD)
2346 ADD_FLG(FLG_SHIELDS);
2347 else if (o_ptr->tval == TV_BOW)
2349 else if (o_ptr->tval == TV_RING)
2351 else if (o_ptr->tval == TV_AMULET)
2352 ADD_FLG(FLG_AMULETS);
2353 else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
2354 o_ptr->tval == TV_SOFT_ARMOR)
2356 else if (o_ptr->tval == TV_CLOAK)
2357 ADD_FLG(FLG_CLOAKS);
2358 else if (o_ptr->tval == TV_HELM)
2360 else if (o_ptr->tval == TV_GLOVES)
2361 ADD_FLG(FLG_GLOVES);
2362 else if (o_ptr->tval == TV_BOOTS)
2370 * Choose an item and get auto-picker entry from it.
2372 static object_type *choose_object(cptr q, cptr s)
2376 if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return NULL;
2378 /* Get the item (in the pack) */
2379 if (item >= 0) return &inventory[item];
2381 /* Get the item (on the floor) */
2382 else return &o_list[0 - item];
2387 * Choose an item and get auto-picker entry from it.
2389 static bool entry_from_choosed_object(autopick_type *entry)
2396 q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
2397 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2399 q = "Enter which item? ";
2400 s = "You have nothing to enter.";
2402 o_ptr = choose_object(q, s);
2403 if (!o_ptr) return FALSE;
2405 autopick_entry_from_object(entry, o_ptr);
2411 * Choose an item for search
2413 static byte get_object_for_search(object_type **o_handle, cptr *search_strp)
2415 char buf[MAX_NLEN+20];
2421 q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
2422 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2424 q = "Enter which item? ";
2425 s = "You have nothing to enter.";
2427 o_ptr = choose_object(q, s);
2428 if (!o_ptr) return 0;
2432 string_free(*search_strp);
2433 object_desc(buf, *o_handle, FALSE, 3);
2434 *search_strp = string_make(format("<%s>", buf));
2440 * Prepare for search by destroyed object
2442 static byte get_destroyed_object_for_search(object_type **o_handle, cptr *search_strp)
2444 char buf[MAX_NLEN+20];
2446 if (!autopick_last_destroyed_object.k_idx) return 0;
2448 *o_handle = &autopick_last_destroyed_object;
2450 string_free(*search_strp);
2451 object_desc(buf, *o_handle, FALSE, 3);
2452 *search_strp = string_make(format("<%s>", buf));
2458 * Choose an item or string for search
2460 static byte get_string_for_search(object_type **o_handle, cptr *search_strp)
2463 char buf[MAX_NLEN+20];
2466 int k_flag[MAX_NLEN+20];
2467 char prompt[] = "¸¡º÷(^I:»ý¤Áʪ ^L:Ç˲õ¤µ¤ì¤¿Êª): ";
2469 char prompt[] = "Search key(^I:inven ^L:destroyed): ";
2471 int col = sizeof(prompt) - 1;
2473 if (*search_strp) strcpy(buf, *search_strp);
2476 /* Display prompt */
2479 /* Display the default answer */
2480 Term_erase(col, 0, 255);
2481 Term_putstr(col, 0, -1, TERM_YELLOW, buf);
2490 Term_gotoxy(col + pos, 0);
2495 /* HACK -- ignore macro defined on ASCII keys */
2496 if (strlen(inkey_macro_trigger_string) == 1)
2497 i = inkey_macro_trigger_string[0];
2500 /* Analyze the key */
2513 if (!pos && *o_handle) return (back ? -1 : 1);
2514 string_free(*search_strp);
2515 *search_strp = string_make(buf);
2517 return (back ? -1 : 1);
2521 return get_object_for_search(o_handle, search_strp);
2524 /* Prepare string for destroyed object if there is one. */
2525 if (get_destroyed_object_for_search(o_handle, search_strp))
2535 if (k_flag[pos]) pos--;
2550 if (pos + 1 < MAX_NLEN)
2558 else if (pos < MAX_NLEN && isprint(i))
2565 if (pos < MAX_NLEN && isprint(i)) buf[pos++] = i;
2574 /* Update the entry */
2575 Term_erase(col, 0, 255);
2576 Term_putstr(col, 0, -1, TERM_WHITE, buf);
2584 * Search next line matches for o_ptr
2586 static bool search_for_object(cptr *lines_list, object_type *o_ptr, int *cxp, int *cyp, bool forward)
2589 autopick_type an_entry, *entry = &an_entry;
2590 char o_name[MAX_NLEN];
2592 object_desc(o_name, o_ptr, FALSE, 3);
2594 /* Force to be lower case string */
2595 for (i = 0; o_name[i]; i++)
2598 if (iskanji(o_name[i]))
2602 if (isupper(o_name[i]))
2603 o_name[i] = tolower(o_name[i]);
2612 if (!lines_list[++i]) break;
2619 if (!autopick_new_entry(entry, lines_list[i])) continue;
2621 if (is_autopick_aux(o_ptr, entry, o_name))
2634 * Search next line matches to the string
2636 static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *cyp, bool forward)
2646 if (!lines_list[++i]) break;
2653 pos = strstr_j(lines_list[i], search_str);
2655 pos = strstr(lines_list[i], search_str);
2659 *cxp = (int)(pos - lines_list[i]);
2685 #define EC_PGDOWN 12
2687 #define EC_BOTTOM 14
2692 #define EC_KILL_LINE 19
2693 #define EC_DELETE_CHAR 20
2694 #define EC_BACKSPACE 21
2695 #define EC_SEARCH_STR 22
2696 #define EC_SEARCH_FORW 23
2697 #define EC_SEARCH_BACK 24
2698 #define EC_SEARCH_OBJ 25
2699 #define EC_SEARCH_DESTROYED 26
2700 #define EC_INSERT_OBJECT 27
2701 #define EC_INSERT_DESTROYED 28
2702 #define EC_INSERT_BLOCK 29
2703 #define EC_INSERT_MACRO 30
2704 #define EC_INSERT_KEYMAP 31
2705 #define EC_CL_AUTOPICK 32
2706 #define EC_CL_DESTROY 33
2707 #define EC_CL_LEAVE 34
2708 #define EC_CL_QUERY 35
2709 #define EC_CL_NO_DISP 36
2710 #define EC_IK_UNAWARE 37
2711 #define EC_IK_UNIDENTIFIED 38
2712 #define EC_IK_IDENTIFIED 39
2713 #define EC_IK_STAR_IDENTIFIED 40
2714 #define EC_KK_WEAPONS 41
2715 #define EC_KK_FAVORITE 42
2716 #define EC_KK_ARMORS 43
2717 #define EC_KK_MISSILES 44
2718 #define EC_KK_DEVICES 45
2719 #define EC_KK_LIGHTS 46
2720 #define EC_KK_JUNKS 47
2721 #define EC_KK_SPELLBOOKS 48
2722 #define EC_KK_SHIELDS 49
2723 #define EC_KK_BOWS 50
2724 #define EC_KK_RINGS 51
2725 #define EC_KK_AMULETS 52
2726 #define EC_KK_SUITS 53
2727 #define EC_KK_CLOAKS 54
2728 #define EC_KK_HELMS 55
2729 #define EC_KK_GLOVES 56
2730 #define EC_KK_BOOTS 57
2731 #define EC_OK_COLLECTING 58
2732 #define EC_OK_BOOSTED 59
2733 #define EC_OK_MORE_THAN 60
2734 #define EC_OK_MORE_BONUS 61
2735 #define EC_OK_WORTHLESS 62
2736 #define EC_OK_ARTIFACT 63
2737 #define EC_OK_EGO 64
2738 #define EC_OK_NAMELESS 65
2739 #define EC_OK_WANTED 66
2740 #define EC_OK_UNIQUE 67
2741 #define EC_OK_HUMAN 68
2742 #define EC_OK_UNREADABLE 69
2743 #define EC_OK_REALM1 70
2744 #define EC_OK_REALM2 71
2745 #define EC_OK_FIRST 72
2746 #define EC_OK_SECOND 73
2747 #define EC_OK_THIRD 74
2748 #define EC_OK_FOURTH 75
2755 } command_menu_type;
2758 command_menu_type menu_data[] =
2760 {0, KTRL('q'), EC_QUIT},
2761 {0, KTRL('z'), EC_REVERT},
2765 {1, KTRL('b'), EC_LEFT},
2766 {1, KTRL('n'), EC_DOWN},
2767 {1, KTRL('p'), EC_UP},
2768 {1, KTRL('f'), EC_RIGHT},
2769 {1, KTRL('a'), EC_BOL},
2770 {1, KTRL('e'), EC_EOL},
2771 {1, KTRL('o'), EC_PGUP},
2772 {1, KTRL('l'), EC_PGDOWN},
2773 {1, KTRL('y'), EC_TOP},
2774 {1, KTRL('u'), EC_BOTTOM},
2777 {1, KTRL('x'), EC_CUT},
2778 {1, KTRL('c'), EC_COPY},
2779 {1, KTRL('v'), EC_PASTE},
2780 {1, KTRL('g'), EC_BLOCK},
2781 {1, KTRL('k'), EC_KILL_LINE},
2782 {1, KTRL('d'), EC_DELETE_CHAR},
2783 {1, KTRL('h'), EC_BACKSPACE},
2784 {1, KTRL('j'), EC_RETURN},
2785 {1, KTRL('m'), EC_RETURN},
2788 {1, KTRL('s'), EC_SEARCH_STR},
2789 {1, -1, EC_SEARCH_FORW},
2790 {1, KTRL('r'), EC_SEARCH_BACK},
2791 {1, -1, EC_SEARCH_OBJ},
2792 {1, -1, EC_SEARCH_DESTROYED},
2795 {1, KTRL('i'), EC_INSERT_OBJECT},
2796 {1, -1, EC_INSERT_DESTROYED},
2797 {1, -1, EC_INSERT_BLOCK},
2798 {1, -1, EC_INSERT_MACRO},
2799 {1, -1, EC_INSERT_KEYMAP},
2802 {1, -1, EC_CL_AUTOPICK},
2803 {1, -1, EC_CL_DESTROY},
2804 {1, -1, EC_CL_LEAVE},
2805 {1, -1, EC_CL_QUERY},
2806 {1, -1, EC_CL_NO_DISP},
2809 {1, -1, EC_IK_UNAWARE},
2810 {1, -1, EC_IK_UNIDENTIFIED},
2811 {1, -1, EC_IK_IDENTIFIED},
2812 {1, -1, EC_IK_STAR_IDENTIFIED},
2815 {1, -1, EC_KK_WEAPONS},
2816 {1, -1, EC_KK_FAVORITE},
2817 {1, -1, EC_KK_ARMORS},
2818 {1, -1, EC_KK_MISSILES},
2819 {1, -1, EC_KK_DEVICES},
2820 {1, -1, EC_KK_LIGHTS},
2821 {1, -1, EC_KK_JUNKS},
2822 {1, -1, EC_KK_SPELLBOOKS},
2823 {1, -1, EC_KK_SHIELDS},
2824 {1, -1, EC_KK_BOWS},
2825 {1, -1, EC_KK_RINGS},
2826 {1, -1, EC_KK_AMULETS},
2827 {1, -1, EC_KK_SUITS},
2828 {1, -1, EC_KK_CLOAKS},
2829 {1, -1, EC_KK_HELMS},
2830 {1, -1, EC_KK_GLOVES},
2831 {1, -1, EC_KK_BOOTS},
2834 {1, -1, EC_OK_COLLECTING},
2835 {1, -1, EC_OK_BOOSTED},
2836 {1, -1, EC_OK_MORE_THAN},
2837 {1, -1, EC_OK_MORE_BONUS},
2838 {1, -1, EC_OK_WORTHLESS},
2839 {1, -1, EC_OK_ARTIFACT},
2841 {1, -1, EC_OK_NAMELESS},
2842 {1, -1, EC_OK_WANTED},
2843 {1, -1, EC_OK_UNIQUE},
2844 {1, -1, EC_OK_HUMAN},
2845 {1, -1, EC_OK_UNREADABLE},
2846 {1, -1, EC_OK_REALM1},
2847 {1, -1, EC_OK_REALM2},
2848 {1, -1, EC_OK_FIRST},
2849 {1, -1, EC_OK_SECOND},
2850 {1, -1, EC_OK_THIRD},
2851 {1, -1, EC_OK_FOURTH},
2891 "¥¢¥¤¥Æ¥à¤òÁªÂò¤·¤Æ¸¡º÷",
2892 "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Ç¸¡º÷",
2895 "ÁªÂò¤·¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ",
2896 "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ",
2897 "¾ò·ïʬ´ô¥Ö¥í¥Ã¥¯¤ÎÎã¤òÁÞÆþ",
2899 "¥¡¼¥Þ¥Ã¥×ÄêµÁ¤òÁÞÆþ",
2901 "¼«Æ°¥³¥Þ¥ó¥É»ØÄêʸ»ú",
2905 "¡Ö;¡× (³Îǧ¤·¤Æ½¦¤¦)",
2906 "¡Ö(¡× (¥Þ¥Ã¥×¥³¥Þ¥ó¥É¤Çɽ¼¨¤·¤Ê¤¤)",
2908 "¼±Ê̾õÂÖ¥¡¼¥ï¡¼¥É",
2914 "¥¡¼¥ï¡¼¥É (̾»ì)",
2933 "¥¡¼¥ï¡¼¥É (·ÁÍÆ»ì)",
2935 "¥À¥¤¥¹Ìܤΰ㤦 (Éð´ï)",
2936 "¥À¥¤¥¹ÌÜ # °Ê¾å¤Î (Éð´ï)",
2943 "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î",
2945 "Æɤá¤Ê¤¤ (ËâË¡½ñ)",
2946 "Âè°ìÎΰè¤Î (ËâË¡½ñ)",
2947 "ÂèÆóÎΰè¤Î (ËâË¡½ñ)",
2956 "Revert all changes",
2964 "Beggining of line",
2976 "Kill rest of line",
2986 "Search by inventory object",
2987 "Search by destroyed object",
2990 "Insert name of choosen object",
2991 "Insert name of destroyed object",
2992 "Insert conditional block",
2993 "Insert a macro definition",
2994 "Insert a keymap definition",
2998 "'!' (Auto destroy)",
2999 "'~' (Leave it on the floor)",
3000 "';' (Query to pick up)",
3001 "'(' (No display on the large map)",
3028 "Keywords (adjective)",
3030 "dice boosted (weapons)",
3031 "more than # dice (weapons)",
3032 "more bonus than #",
3036 "nameless (equipments)",
3040 "unreadable (spellbooks)",
3041 "realm1 (spellbooks)",
3042 "realm2 (spellbooks)",
3043 "first (spellbooks)",
3044 "second (spellbooks)",
3045 "third (spellbooks)",
3046 "fourth (spellbooks)",
3052 * Find a command by 'key'.
3054 static int get_com_id(char key)
3058 for (i = 0; menu_name[i]; i++)
3060 if (menu_data[i].key == key)
3062 return menu_data[i].com_id;
3071 * Display the menu, and get a command
3073 static int do_command_menu(int level, int start)
3078 int col0 = 5 + level*4;
3079 int row0 = 1 + level*2;
3081 int menu_id_list[26];
3083 char linestr[MAX_LINELEN];
3085 /* Get max length */
3087 for (i = start; menu_data[i].level >= level; i++)
3091 /* Ignore lower level sub menus */
3092 if (menu_data[i].level > level) continue;
3094 len = strlen(menu_name[i]);
3095 if (len > max_len) max_len = len;
3097 menu_id_list[menu_key] = i;
3101 while (menu_key < 26)
3103 menu_id_list[menu_key] = -1;
3107 /* Extra space for displaying menu key and command key */
3108 max_menu_wid = max_len + 3 + 3;
3110 /* Prepare box line */
3112 strcat(linestr, "+");
3113 for (i = 0; i < max_menu_wid + 2; i++)
3115 strcat(linestr, "-");
3117 strcat(linestr, "+");
3127 int row1 = row0 + 1;
3130 Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
3132 /* Draw menu items */
3134 for (i = start; menu_data[i].level >= level; i++)
3136 char com_key_str[3];
3139 /* Ignore lower level sub menus */
3140 if (menu_data[i].level > level) continue;
3142 if (menu_data[i].com_id == -1)
3145 strcpy(com_key_str, "¢§");
3147 strcpy(com_key_str, ">");
3150 else if (menu_data[i].key != -1)
3152 com_key_str[0] = '^';
3153 com_key_str[1] = menu_data[i].key + '@';
3154 com_key_str[2] = '\0';
3158 com_key_str[0] = '\0';
3161 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_name[i], com_key_str);
3163 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
3168 /* Draw bottom line */
3169 Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
3171 /* The menu was shown */
3174 prt(format("(a-%c) ¥³¥Þ¥ó¥É:", menu_key + 'a' - 1), 0, 0);
3177 if (key == ESCAPE) return 0;
3179 if ('a' <= key && key <= 'z')
3181 menu_id = menu_id_list[key - 'a'];
3185 com_id = menu_data[menu_id].com_id;
3189 com_id = do_command_menu(level + 1, menu_id + 1);
3190 if (com_id) return com_id;
3202 com_id = get_com_id(key);
3203 if (com_id) return com_id;
3210 static chain_str_type *new_chain_str(cptr str)
3212 chain_str_type *chain;
3214 size_t len = strlen(str);
3216 chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
3218 strcpy(chain->s, str);
3225 static void kill_yank_chain(text_body_type *tb)
3227 chain_str_type *chain = tb->yank;
3232 chain_str_type *next = chain->next;
3233 size_t len = strlen(chain->s);
3235 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
3242 static void add_str_to_yank(text_body_type *tb, cptr str)
3244 chain_str_type *chain;
3246 tb->yank_eol = FALSE;
3248 if (NULL == tb->yank)
3250 tb->yank = new_chain_str(str);
3260 chain->next = new_chain_str(str);
3265 chain = chain->next;
3271 * Dirty flag for text editor
3273 #define DIRTY_ALL 0x01
3274 #define DIRTY_MODE 0x04
3275 #define DIRTY_SCREEN 0x08
3276 #define DIRTY_NOT_FOUND 0x10
3277 #define DIRTY_NO_SEARCH 0x20
3280 #define DESCRIPT_HGT 3
3285 static void draw_text_editor(text_body_type *tb)
3288 int by1 = -1, bx1 = -1, by2 = -1, bx2 = -1;
3291 Term_get_size(&tb->wid, &tb->hgt);
3294 * Top line (-1), description line (-3), separator (-1)
3297 tb->hgt -= 2 + DESCRIPT_HGT;
3300 /* Don't let cursor at second byte of kanji */
3301 for (i = 0; tb->lines_list[tb->cy][i]; i++)
3302 if (iskanji(tb->lines_list[tb->cy][i]))
3313 /* Scroll if necessary */
3314 if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
3315 tb->upper = tb->cy - (tb->hgt)/2;
3318 if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
3319 tb->left = tb->cx - (tb->wid)*2/3;
3323 /* Redraw whole window after resize */
3324 if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
3325 tb->dirty_flags |= DIRTY_SCREEN;
3327 /* Redraw all text after scroll */
3328 else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
3329 tb->dirty_flags |= DIRTY_ALL;
3332 if (tb->dirty_flags & DIRTY_SCREEN)
3334 tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
3340 /* Redraw mode line */
3341 if (tb->dirty_flags & DIRTY_MODE)
3343 char buf[MAX_LINELEN];
3345 int sepa_length = tb->wid;
3348 for (i = 0; i < sepa_length; i++)
3352 Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
3357 tb->dirty_flags |= DIRTY_ALL;
3359 if (tb->my < tb->cy ||
3360 (tb->my == tb->cy && tb->mx < tb->cx))
3376 /* Dump up to tb->hgt lines of messages */
3377 for (i = 0; i < tb->hgt; i++)
3382 int y = tb->upper+i;
3384 /* clean or dirty? */
3385 if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
3388 msg = tb->lines_list[y];
3391 /* Apply horizontal scroll */
3392 for (j = 0; *msg; msg++, j++)
3394 if (j == tb->left) break;
3410 Term_erase(0, i + 1, tb->wid);
3414 /* Dump the messages, bottom to top */
3415 Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_WHITE, msg);
3420 int x0 = leftcol + tb->left;
3425 if (by1 <= y && y < by2) sx1 = strlen(msg);
3426 if (y == by1) sx0 = bx1;
3427 if (y == by2) sx1 = bx2;
3429 Term_gotoxy(leftcol, i + 1);
3430 if (x0 < sx0) Term_addstr(sx0 - x0, TERM_WHITE, msg);
3431 if (x0 < sx1) Term_addstr(sx1 - sx0, TERM_YELLOW, msg + (sx0 - x0));
3432 Term_addstr(-1, TERM_WHITE, msg + (sx1 - x0));
3436 for (; i < tb->hgt; i++)
3439 Term_erase(0, i + 1, tb->wid);
3442 /* Display information when updated */
3443 if (tb->old_cy != tb->cy || (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || tb->dirty_line == tb->cy)
3445 autopick_type an_entry, *entry = &an_entry;
3447 /* Clear information line */
3448 for (i = 0; i < DESCRIPT_HGT; i++)
3451 Term_erase(0, tb->hgt + 2 + i, tb->wid);
3454 /* Display information */
3455 if (tb->dirty_flags & DIRTY_NOT_FOUND)
3458 prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3460 prt(format("Pattern not found: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3463 else if (tb->dirty_flags & DIRTY_NO_SEARCH)
3466 prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", tb->hgt + 1 + 1, 0);
3468 prt("No pattern to search. (Press '/' to search.)", tb->hgt +1 + 1, 0);
3471 else if (tb->lines_list[tb->cy][0] == '#')
3474 prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3476 prt("This line is a comment.", tb->hgt +1 + 1, 0);
3479 else if (tb->lines_list[tb->cy][1] == ':')
3481 switch(tb->lines_list[tb->cy][0])
3485 prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3487 prt("This line is a Conditional Expression.", tb->hgt +1 + 1, 0);
3492 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3494 prt("This line defines a Macro action.", tb->hgt +1 + 1, 0);
3499 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3501 prt("This line defines a Macro trigger key.", tb->hgt +1 + 1, 0);
3506 prt("¤³¤Î¹Ô¤Ï¥¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3508 prt("This line defines a Keymap.", tb->hgt +1 + 1, 0);
3514 /* Get description of an autopicker preference line */
3515 else if (autopick_new_entry(entry, tb->lines_list[tb->cy]))
3517 char buf[MAX_LINELEN];
3518 char temp[MAX_LINELEN];
3521 describe_autopick(buf, entry);
3523 roff_to_buf(buf, 81, temp, sizeof(temp));
3525 for (i = 0; i < 3; i++)
3531 prt(t, tb->hgt +1 + 1 + i, 0);
3535 autopick_free_entry(entry);
3542 * Kill segment of a line
3544 static void kill_line_segment(text_body_type *tb, int y, int x0, int x1)
3546 char buf[MAX_LINELEN];
3547 cptr s = tb->lines_list[y];
3552 if (x0 == x1) return;
3554 /* Kill whole line? */
3555 if (x0 == 0 && s[x1] == '\0')
3559 string_free(tb->lines_list[y]);
3561 /* Shift lines up */
3562 for (i = y; tb->lines_list[i+1]; i++)
3563 tb->lines_list[i] = tb->lines_list[i+1];
3564 tb->lines_list[i] = NULL;
3569 /* Before the segment */
3570 for (x = 0; x < x0; x++)
3573 /* After the segment */
3574 for (x = x1; s[x]; x++)
3580 string_free(tb->lines_list[y]);
3581 tb->lines_list[y] = string_make(buf);
3586 * Kill text in the block selection
3588 static bool kill_text_in_selection(text_body_type *tb, bool force)
3590 int by1, bx1, by2, bx2;
3593 if (!force && tb->mark == -1)
3595 /* Don't kill auto selection block (by paste) */
3599 tb->dirty_flags |= DIRTY_ALL;
3604 /* Correct cursor location */
3605 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
3606 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
3608 if (tb->my < tb->cy ||
3609 (tb->my == tb->cy && tb->mx < tb->cx))
3624 /* Kill lines in reverse order */
3625 for (y = by2; y >= by1; y--)
3628 int x1 = strlen(tb->lines_list[y]);
3630 if (y == by1) x0 = bx1;
3631 if (y == by2) x1 = bx2;
3633 kill_line_segment(tb, y, x0, x1);
3636 /* Correct cursor position */
3640 /* Disable selection */
3644 tb->dirty_flags |= DIRTY_ALL;
3651 * Get a trigger key and insert ASCII string for the trigger
3653 static bool insert_macro_line(cptr *lines_list, int cy)
3662 /* Do not process macros */
3668 /* Read the pattern */
3674 /* Do not process macros */
3677 /* Do not wait for keys */
3680 /* Attempt to read a key */
3690 /* Convert the trigger */
3691 ascii_to_text(tmp, buf);
3694 if(!tmp[0]) return FALSE;
3696 /* Insert preference string */
3697 insert_return_code(lines_list, 0, cy);
3698 string_free(lines_list[cy]);
3699 lines_list[cy] = string_make(format("P:%s", tmp));
3701 /* Acquire action */
3702 i = macro_find_exact(buf);
3706 /* Nothing defined */
3711 /* Analyze the current action */
3712 ascii_to_text(tmp, macro__act[i]);
3715 /* Insert blank action preference line */
3716 insert_return_code(lines_list, 0, cy);
3717 string_free(lines_list[cy]);
3718 lines_list[cy] = string_make(format("A:%s", tmp));
3725 * Get a command key and insert ASCII string for the key
3727 static bool insert_keymap_line(cptr *lines_list, int cy)
3735 if (rogue_like_commands)
3737 mode = KEYMAP_MODE_ROGUE;
3743 mode = KEYMAP_MODE_ORIG;
3756 /* Convert the trigger */
3757 ascii_to_text(tmp, buf);
3760 if(!tmp[0]) return FALSE;
3762 /* Insert preference string */
3763 insert_return_code(lines_list, 0, cy);
3764 string_free(lines_list[cy]);
3765 lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
3767 /* Look up the keymap */
3768 act = keymap_act[mode][(byte)(buf[0])];
3770 /* Insert blank action preference line */
3771 insert_return_code(lines_list, 0, cy);
3772 string_free(lines_list[cy]);
3773 lines_list[cy] = string_make(format("A:%s", act));
3780 * Execute a single editor command
3782 static bool do_editor_command(text_body_type *tb, int com_id)
3790 /* Revert to original */
3792 if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
3794 if (!get_check("Discard all changes and revert to original file. Are you sure? "))
3798 free_text_lines(tb->lines_list);
3799 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
3800 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE;
3801 tb->cx = tb->cy = 0;
3805 /* Peruse the main help file */
3807 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
3809 (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
3812 tb->dirty_flags |= DIRTY_SCREEN;
3817 /* Split a line or insert end of line */
3820 * If there is a selection, kill it, and replace it
3823 if (tb->mark) kill_text_in_selection(tb, FALSE);
3825 insert_return_code(tb->lines_list, tb->cx, tb->cy);
3830 tb->dirty_flags |= DIRTY_ALL;
3840 len = strlen(tb->lines_list[tb->cy]);
3841 if (len < tb->cx) tb->cx = len;
3843 else if (tb->cy > 0)
3846 tb->cx = strlen(tb->lines_list[tb->cy]);
3852 if (tb->lines_list[tb->cy + 1]) tb->cy++;
3857 if (tb->cy > 0) tb->cy--;
3866 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
3869 len = strlen(tb->lines_list[tb->cy]);
3872 if (tb->lines_list[tb->cy + 1])
3884 /* Beginning of line */
3890 tb->cx = strlen(tb->lines_list[tb->cy]);
3894 while (0 < tb->cy && tb->upper <= tb->cy)
3896 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
3902 while (tb->cy < tb->upper + tb->hgt && tb->lines_list[tb->cy + 1])
3912 while (tb->lines_list[tb->cy + 1])
3918 /* Need block selection */
3919 if (!tb->mark) break;
3921 /* Copy the text first */
3922 do_editor_command(tb, EC_COPY);
3925 kill_text_in_selection(tb, TRUE);
3932 int by1, bx1, by2, bx2;
3935 /* Need block selection */
3936 if (!tb->mark) break;
3938 /* Correct cursor location */
3939 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
3940 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
3942 if (tb->my < tb->cy ||
3943 (tb->my == tb->cy && tb->mx < tb->cx))
3958 /* Kill old yank buffer */
3959 kill_yank_chain(tb);
3961 /* Copy string to yank buffer */
3962 for (y = by1; y <= by2; y++)
3965 char buf[MAX_LINELEN];
3968 int x1 = strlen(tb->lines_list[y]);
3970 if (y == by1) x0 = bx1;
3971 if (y == by2) x1 = bx2;
3973 for (i = 0; i < x1 - x0; i++)
3975 buf[i] = tb->lines_list[y][x0 + i];
3979 add_str_to_yank(tb, buf);
3982 /* Disable selection */
3986 tb->dirty_flags |= DIRTY_ALL;
3992 /* Paste killed text */
3994 chain_str_type *chain = tb->yank;
3996 /* Correct cursor location */
3997 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
3998 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4001 * If there is a selection, kill text, and
4002 * replace it with the yank text.
4004 if (tb->mark) kill_text_in_selection(tb, FALSE);
4006 /* Auto select pasted text */
4014 cptr yank_str = chain->s;
4016 char buf[MAX_LINELEN];
4018 char rest[MAX_LINELEN], *rest_ptr = rest;
4020 /* Save preceding string */
4021 for(i = 0; i < tb->cx; i++)
4022 buf[i] = tb->lines_list[tb->cy][i];
4024 strcpy(rest, &(tb->lines_list[tb->cy][i]));
4026 /* Paste yank buffer */
4027 while (*yank_str && i < MAX_LINELEN-1)
4029 buf[i++] = *yank_str++;
4035 chain = chain->next;
4037 if (chain || tb->yank_eol)
4039 /* There is an end of line between chain nodes */
4041 insert_return_code(tb->lines_list, tb->cx, tb->cy);
4043 /* Replace this line with new one */
4044 string_free(tb->lines_list[tb->cy]);
4045 tb->lines_list[tb->cy] = string_make(buf);
4047 /* Move to next line */
4054 /* Final line doesn't have end of line */
4056 tb->cx = strlen(buf);
4058 /* Rest of original line */
4059 while (*rest_ptr && i < MAX_LINELEN-1)
4061 buf[i++] = *rest_ptr++;
4067 /* Replace this line with new one */
4068 string_free(tb->lines_list[tb->cy]);
4069 tb->lines_list[tb->cy] = string_make(buf);
4076 tb->dirty_flags |= DIRTY_ALL;
4083 /* Disable the selection */
4087 tb->dirty_flags |= DIRTY_ALL;
4093 /* Repeating this command swaps cursor position */
4094 if (com_id == tb->old_com_id)
4106 tb->dirty_flags |= DIRTY_ALL;
4110 /* Mark the point 1 */
4119 /* Kill rest of line */
4122 char buf[MAX_LINELEN];
4125 /* If there is a selection, kill it */
4128 if (kill_text_in_selection(tb, FALSE)) break;
4131 /* Correct cursor location */
4132 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4133 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4135 /* Save preceding string */
4136 for (i = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4139 if (iskanji(tb->lines_list[tb->cy][i]))
4141 buf[i] = tb->lines_list[tb->cy][i];
4145 buf[i] = tb->lines_list[tb->cy][i];
4148 line = string_make(buf);
4150 /* Append only if this command is repeated. */
4151 if (tb->old_com_id != com_id)
4153 kill_yank_chain(tb);
4157 /* Really deleted some text */
4158 if (strlen(tb->lines_list[tb->cy] + i))
4160 /* Add deleted string to yank buffer */
4161 add_str_to_yank(tb, tb->lines_list[tb->cy] + i);
4163 /* Replace current line with 'preceding string' */
4164 string_free(tb->lines_list[tb->cy]);
4165 tb->lines_list[tb->cy] = line;
4168 tb->dirty_line = tb->cy;
4170 /* Leave end of line character */
4174 /* Delete the end of line character only */
4175 if (tb->yank_eol) add_str_to_yank(tb, "");
4176 else tb->yank_eol = TRUE;
4178 do_editor_command(tb, EC_DELETE_CHAR);
4182 case EC_DELETE_CHAR:
4183 /* DELETE == go forward + BACK SPACE */
4185 /* If there is a selection, kill it */
4188 if (kill_text_in_selection(tb, FALSE)) break;
4192 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4196 do_editor_command(tb, EC_BACKSPACE);
4204 char buf[MAX_LINELEN];
4206 /* If there is a selection, kill it */
4209 if (kill_text_in_selection(tb, FALSE)) break;
4212 len = strlen(tb->lines_list[tb->cy]);
4215 if (tb->lines_list[tb->cy + 1])
4229 /* delete a return code and union two lines */
4230 if (tb->cy == 0) break;
4231 tb->cx = strlen(tb->lines_list[tb->cy-1]);
4232 strcpy(buf, tb->lines_list[tb->cy-1]);
4233 strcat(buf, tb->lines_list[tb->cy]);
4234 string_free(tb->lines_list[tb->cy-1]);
4235 string_free(tb->lines_list[tb->cy]);
4236 tb->lines_list[tb->cy-1] = string_make(buf);
4237 for (i = tb->cy; tb->lines_list[i+1]; i++)
4238 tb->lines_list[i] = tb->lines_list[i+1];
4239 tb->lines_list[i] = NULL;
4243 tb->dirty_flags |= DIRTY_ALL;
4247 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4251 if (iskanji(tb->lines_list[tb->cy][i]))
4252 buf[j++] = tb->lines_list[tb->cy][i++];
4254 buf[j++] = tb->lines_list[tb->cy][i];
4261 for (; tb->lines_list[tb->cy][i]; i++)
4262 buf[j++] = tb->lines_list[tb->cy][i];
4264 string_free(tb->lines_list[tb->cy]);
4265 tb->lines_list[tb->cy] = string_make(buf);
4268 tb->dirty_line = tb->cy;
4276 /* Become dirty because of item/equip menu */
4277 tb->dirty_flags |= DIRTY_SCREEN;
4279 search_dir = get_string_for_search(&tb->search_o_ptr, &tb->search_str);
4281 if (!search_dir) break;
4283 if (search_dir == 1) do_editor_command(tb, EC_SEARCH_FORW);
4284 else do_editor_command(tb, EC_SEARCH_BACK);
4288 case EC_SEARCH_FORW:
4289 if (tb->search_o_ptr)
4291 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4293 else if (tb->search_str)
4295 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4299 tb->dirty_flags |= DIRTY_NO_SEARCH;
4303 case EC_SEARCH_BACK:
4304 if (tb->search_o_ptr)
4306 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4308 else if (tb->search_str)
4310 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4314 tb->dirty_flags |= DIRTY_NO_SEARCH;
4319 /* Become dirty because of item/equip menu */
4320 tb->dirty_flags |= DIRTY_SCREEN;
4322 if (!get_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4324 do_editor_command(tb, EC_SEARCH_FORW);
4327 case EC_SEARCH_DESTROYED:
4328 if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4330 do_editor_command(tb, EC_SEARCH_FORW);
4333 case EC_INSERT_OBJECT:
4335 /* Insert choosen item name */
4337 autopick_type an_entry, *entry = &an_entry;
4339 if (!entry_from_choosed_object(entry))
4341 /* Now dirty because of item/equip menu */
4342 tb->dirty_flags |= DIRTY_SCREEN;
4346 insert_return_code(tb->lines_list, 0, tb->cy);
4347 string_free(tb->lines_list[tb->cy]);
4348 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4351 /* Now dirty because of item/equip menu */
4352 tb->dirty_flags |= DIRTY_SCREEN;
4357 case EC_INSERT_DESTROYED:
4358 /* Insert a name of last destroyed item */
4359 if (tb->last_destroyed)
4361 insert_return_code(tb->lines_list, 0, tb->cy);
4362 string_free(tb->lines_list[tb->cy]);
4363 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
4367 tb->dirty_flags |= DIRTY_ALL;
4371 case EC_INSERT_BLOCK:
4373 /* Insert a conditinal expression line */
4376 /* Conditional Expression for Class and Race */
4377 sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]",
4379 rp_ptr->E_title, cp_ptr->E_title
4381 rp_ptr->title, cp_ptr->title
4385 insert_return_code(tb->lines_list, 0, tb->cy);
4386 string_free(tb->lines_list[tb->cy]);
4387 tb->lines_list[tb->cy] = string_make(classrace);
4389 insert_return_code(tb->lines_list, 0, tb->cy);
4390 string_free(tb->lines_list[tb->cy]);
4391 tb->lines_list[tb->cy] = string_make("?:1");
4395 tb->dirty_flags |= DIRTY_ALL;
4399 case EC_INSERT_MACRO:
4400 /* Draw_everythig (delete menu) */
4401 draw_text_editor(tb);
4404 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4408 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥¡¼>: ");
4410 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<Trigger key>: ");
4412 if (insert_macro_line(tb->lines_list, tb->cy))
4414 /* Prepare to input action */
4418 tb->dirty_flags |= DIRTY_ALL;
4419 tb->dirty_flags |= DIRTY_MODE;
4424 case EC_INSERT_KEYMAP:
4425 /* Draw_everythig (delete menu) */
4426 draw_text_editor(tb);
4429 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4433 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
4435 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<Keypress>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
4438 if (insert_keymap_line(tb->lines_list, tb->cy))
4440 /* Prepare to input action */
4444 tb->dirty_flags |= DIRTY_ALL;
4445 tb->dirty_flags |= DIRTY_MODE;
4449 case EC_CL_AUTOPICK:
4451 autopick_type an_entry, *entry = &an_entry;
4453 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
4457 string_free(tb->lines_list[tb->cy]);
4459 if (entry->action & (DO_AUTODESTROY | DONT_AUTOPICK | DO_QUERY_AUTOPICK))
4460 if (tb->cx > 0) tb->cx--;
4462 entry->action &= ~DO_AUTODESTROY;
4463 entry->action &= ~DONT_AUTOPICK;
4464 entry->action &= ~DO_QUERY_AUTOPICK;
4465 entry->action |= DO_AUTOPICK;
4467 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4470 tb->dirty_line = tb->cy;
4476 autopick_type an_entry, *entry = &an_entry;
4478 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
4482 string_free(tb->lines_list[tb->cy]);
4484 entry->action &= ~DONT_AUTOPICK;
4485 entry->action &= ~DO_QUERY_AUTOPICK;
4486 if (!(entry->action & DO_AUTODESTROY))
4488 entry->action &= ~DO_AUTOPICK;
4489 entry->action |= DO_AUTODESTROY;
4494 entry->action &= ~DO_AUTODESTROY;
4495 entry->action |= DO_AUTOPICK;
4496 if (tb->cx > 0) tb->cx--;
4499 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4502 tb->dirty_line = tb->cy;
4509 autopick_type an_entry, *entry = &an_entry;
4511 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
4515 string_free(tb->lines_list[tb->cy]);
4517 entry->action &= ~DO_AUTODESTROY;
4518 entry->action &= ~DO_QUERY_AUTOPICK;
4519 if (!(entry->action & DONT_AUTOPICK))
4521 entry->action &= ~DO_AUTOPICK;
4522 entry->action |= DONT_AUTOPICK;
4527 entry->action &= ~DONT_AUTOPICK;
4528 entry->action |= DO_AUTOPICK;
4529 if (tb->cx > 0) tb->cx--;
4532 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4535 tb->dirty_line = tb->cy;
4541 autopick_type an_entry, *entry = &an_entry;
4543 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
4547 string_free(tb->lines_list[tb->cy]);
4549 entry->action &= ~DO_AUTODESTROY;
4550 entry->action &= ~DONT_AUTOPICK;
4551 if (!(entry->action & DO_QUERY_AUTOPICK))
4553 entry->action &= ~DO_AUTOPICK;
4554 entry->action |= DO_QUERY_AUTOPICK;
4559 entry->action &= ~DO_QUERY_AUTOPICK;
4560 entry->action |= DO_AUTOPICK;
4561 if (tb->cx > 0) tb->cx--;
4564 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4567 tb->dirty_line = tb->cy;
4573 /* Toggle display on the 'M'ap */
4575 autopick_type an_entry, *entry = &an_entry;
4577 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
4579 string_free(tb->lines_list[tb->cy]);
4581 if (entry->action & DO_DISPLAY)
4583 entry->action &= ~DO_DISPLAY;
4588 entry->action |= DO_DISPLAY;
4589 if (tb->cx > 0) tb->cx--;
4592 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4595 tb->dirty_line = tb->cy;
4599 case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
4600 case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
4601 case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
4602 case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
4603 case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
4604 case EC_KK_FAVORITE: toggle_keyword(tb, FLG_FAVORITE); break;
4605 case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
4606 case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
4607 case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
4608 case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
4609 case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
4610 case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
4611 case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
4612 case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
4613 case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
4614 case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
4615 case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
4616 case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
4617 case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
4618 case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
4619 case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
4620 case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
4621 case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
4622 case EC_OK_MORE_THAN: toggle_keyword(tb, FLG_MORE_THAN); break;
4623 case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
4624 case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
4625 case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
4626 case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
4627 case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
4628 case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
4629 case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
4630 case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
4631 case EC_OK_UNREADABLE:
4632 toggle_keyword(tb, FLG_UNREADABLE);
4633 add_keyword(tb, FLG_SPELLBOOKS);
4636 toggle_keyword(tb, FLG_REALM1);
4637 add_keyword(tb, FLG_SPELLBOOKS);
4640 toggle_keyword(tb, FLG_REALM2);
4641 add_keyword(tb, FLG_SPELLBOOKS);
4644 toggle_keyword(tb, FLG_FIRST);
4645 add_keyword(tb, FLG_SPELLBOOKS);
4648 toggle_keyword(tb, FLG_SECOND);
4649 add_keyword(tb, FLG_SPELLBOOKS);
4652 toggle_keyword(tb, FLG_THIRD);
4653 add_keyword(tb, FLG_SPELLBOOKS);
4656 toggle_keyword(tb, FLG_FOURTH);
4657 add_keyword(tb, FLG_SPELLBOOKS);
4661 /* Save old command */
4662 tb->old_com_id = com_id;
4669 * Insert single letter at cursor position.
4671 static void insert_single_letter(text_body_type *tb, int key)
4674 char buf[MAX_LINELEN];
4676 /* Save preceding string */
4677 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4678 buf[j++] = tb->lines_list[tb->cy][i];
4680 /* Add a character */
4688 if (j+2 < MAX_LINELEN)
4700 if (j+1 < MAX_LINELEN)
4706 for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
4707 buf[j++] = tb->lines_list[tb->cy][i];
4710 /* Replace current line with new line */
4711 string_free(tb->lines_list[tb->cy]);
4712 tb->lines_list[tb->cy] = string_make(buf);
4714 /* Move to correct collumn */
4715 len = strlen(tb->lines_list[tb->cy]);
4716 if (len < tb->cx) tb->cx = len;
4719 tb->dirty_line = tb->cy;
4723 * In-game editor of Object Auto-picker/Destoryer
4725 void do_cmd_edit_autopick(void)
4727 text_body_type text_body, *tb = &text_body;
4729 autopick_type an_entry, *entry = &an_entry;
4730 char buf[MAX_LINELEN];
4735 static s32b old_autosave_turn = 0L;
4738 tb->cx = tb->cy = tb->upper = tb->left = 0;
4740 tb->mx = tb->my = 0;
4741 tb->old_cy = tb->old_upper = tb->old_left = -1;
4742 tb->old_wid = tb->old_hgt = -1;
4746 tb->search_o_ptr = NULL;
4747 tb->search_str = NULL;
4748 tb->last_destroyed = NULL;
4749 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE;
4750 tb->dirty_line = -1;
4751 tb->filename_mode = PT_WITH_PNAME;
4754 if (turn > old_autosave_turn + 100L)
4756 do_cmd_save_game(TRUE);
4757 old_autosave_turn = turn;
4760 /* HACK -- Reset start_time to stop counting playtime while edit */
4763 /* Free old entries */
4766 /* Command Description of the 'Last Destroyed Item' */
4767 if (autopick_last_destroyed_object.k_idx)
4769 autopick_entry_from_object(entry, &autopick_last_destroyed_object);
4770 tb->last_destroyed = autopick_line_from_entry_kill(entry);
4773 /* Read or initialize whole text */
4774 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
4776 /* Reset cursor position if needed */
4777 for (i = 0; i < tb->cy; i++)
4779 if (!tb->lines_list[i])
4781 tb->cy = tb->cx = 0;
4786 /* Save the screen */
4789 /* Process requests until done */
4794 /* Draw_everythig */
4795 draw_text_editor(tb);
4797 /* Display header line */
4799 prt("(^Q:½ªÎ», ESC:¥á¥Ë¥å¡¼, ¤½¤Î¾:ÆþÎÏ)", 0, 0);
4801 prt("(^Q:quit, ESC:menu, Other:input text)", 0, 0);
4805 /* Display current position */
4806 prt (format("(%d, %d)", tb->cx, tb->cy), 0, 60);
4810 /* Display current position and mark position */
4811 prt (format("(%d-%d, %d-%d)", tb->mx, tb->cx, tb->my, tb->cy), 0, 60);
4815 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
4818 tb->dirty_flags = 0;
4819 tb->dirty_line = -1;
4821 /* Save old key and location */
4822 tb->old_cy = tb->cy;
4823 tb->old_upper = tb->upper;
4824 tb->old_left = tb->left;
4825 tb->old_wid = tb->wid;
4826 tb->old_hgt = tb->hgt;
4832 if (key == 0x7F) key = KTRL('d');
4834 /* HACK -- ignore macro defined on ASCII keys */
4835 if (strlen(inkey_macro_trigger_string) == 1)
4837 /* Get original key */
4838 key = inkey_macro_trigger_string[0];
4844 com_id = do_command_menu(0, 0);
4847 tb->dirty_flags |= DIRTY_SCREEN;
4850 /* Cursor key macroes to direction command */
4851 else if (strlen(inkey_macro_trigger_string) > 1)
4869 /* Mega Hack!!! Start selection with shift + cursor keys */
4874 /* Get ascii form */
4875 ascii_to_text(buf, inkey_macro_trigger_string);
4877 if (strstr(buf, "shift-Down"))
4879 else if (strstr(buf, "shift-Left"))
4881 else if (strstr(buf, "shift-Right"))
4883 else if (strstr(buf, "shift-Up"))
4888 /* Kill further macro expansion */
4891 /* Start selection */
4898 /* Need to redraw text */
4899 if (com_id == EC_UP || com_id == EC_DOWN)
4902 tb->dirty_flags |= DIRTY_ALL;
4914 /* Insert a character */
4915 else if (!iscntrl(key & 0xff))
4918 * If there is a selection, kill text, and
4919 * replace it with a single letter.
4921 if (tb->mark) kill_text_in_selection(tb, FALSE);
4923 insert_single_letter(tb, key);
4929 /* Other commands */
4932 com_id = get_com_id(key);
4935 if (com_id) quit = do_editor_command(tb, com_id);
4938 /* Restore the screen */
4941 switch (tb->filename_mode)
4945 strcpy(buf, "picktype.prf");
4947 strcpy(buf, "pickpref.prf");
4953 sprintf(buf, "picktype-%s.prf", player_name);
4955 sprintf(buf, "pickpref-%s.prf", player_name);
4960 write_text_lines(buf, tb->lines_list);
4961 free_text_lines(tb->lines_list);
4963 string_free(tb->last_destroyed);
4965 /* Destroy string chain */
4966 kill_yank_chain(tb);
4968 /* Reload autopick pref */
4969 process_pickpref_file(buf);
4971 /* HACK -- reset start_time so that playtime is not increase while edit */
4972 start_time = time(NULL);