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);
277 /* Skip comment line */
278 if (*buf == 0 && insc) return FALSE;
280 ptr = prev_ptr = buf;
283 while (old_ptr != ptr)
285 /* Save current location */
288 if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
289 if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
290 if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
291 if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
292 if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
293 if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
295 /*** Weapons whose dd*ds is more than nn ***/
296 if (MATCH_KEY2(KEY_MORE_THAN))
301 /* Drop leading spaces */
302 while (' ' == *ptr) ptr++;
305 while ('0' <= *ptr && *ptr <= '9')
307 entry->dice = 10 * entry->dice + (*ptr - '0');
314 (void)MATCH_KEY(KEY_DICE);
315 ADD_FLG(FLG_MORE_THAN);
321 /*** Items whose magical bonus is more than n ***/
322 if (MATCH_KEY2(KEY_MORE_BONUS))
327 /* Drop leading spaces */
328 while (' ' == *ptr) ptr++;
331 while ('0' <= *ptr && *ptr <= '9')
333 entry->bonus = 10 * entry->bonus + (*ptr - '0');
340 (void)MATCH_KEY(KEY_MORE_BONUS2);
341 ADD_FLG(FLG_MORE_BONUS);
347 if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
348 if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
349 if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
350 if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
351 if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
352 if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
353 if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
354 if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
355 if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
356 if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
357 if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
358 if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
359 if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
360 if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
363 /* Not yet found any noun */
366 if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
368 if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
369 else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
370 else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
371 else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
372 else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
373 else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
374 else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
375 else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
376 else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
377 else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
378 else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
379 else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
380 else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
381 else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
382 else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
383 else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
384 else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
385 else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
386 else if (MATCH_KEY2(KEY_FAVORITE)) ADD_FLG_NOUN(FLG_FAVORITE);
388 /* Last 'keyword' must be at the correct location */
392 else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
395 else if (*ptr == '\0')
397 /* There was no noun */
400 /* Add extra word "items" */
401 ADD_FLG_NOUN(FLG_ITEMS);
408 /* A noun type keyword didn't end correctly */
409 entry->flag[prev_flg/32] &= ~(1L<< (prev_flg%32));
414 /* Save this auto-picker entry line */
415 entry->name = string_make(ptr);
417 entry->insc = string_make(insc);
424 * A function to delete entry
426 void autopick_free_entry(autopick_type *entry)
428 string_free(entry->name);
429 string_free(entry->insc);
434 * Initialize auto-picker preference
436 void init_autopicker(void)
438 static const char easy_autopick_inscription[] = "(:=g";
442 /* Clear old entries */
443 for( i = 0; i < max_autopick; i++)
444 autopick_free_entry(&autopick_list[i]);
448 /* There is always one entry "=g" */
449 autopick_new_entry(&entry, easy_autopick_inscription);
450 autopick_list[max_autopick++] = entry;
456 * Process line for auto picker/destroyer.
458 errr process_pickpref_file_line(char *buf)
463 if (max_autopick == MAX_AUTOPICK)
466 /* Nuke illegal char */
467 for(i = 0; buf[i]; i++)
476 if (isspace(buf[i]) && buf[i] != ' ')
481 if (!autopick_new_entry(&entry, buf)) return 0;
483 /* Already has the same entry? */
484 for(i = 0; i < max_autopick; i++)
485 if(!strcmp(entry.name, autopick_list[i].name)
486 && entry.flag[0] == autopick_list[i].flag[0]
487 && entry.flag[1] == autopick_list[i].flag[1]
488 && entry.dice == autopick_list[i].dice
489 && entry.bonus == autopick_list[i].bonus) return 0;
491 autopick_list[max_autopick++] = entry;
497 * Reconstruct preference line from entry
499 cptr autopick_line_from_entry(autopick_type *entry)
501 char buf[MAX_LINELEN];
503 bool sepa_flag = TRUE;
506 if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
507 if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
508 if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
509 if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
513 if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
514 if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
515 if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
516 if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
517 if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
518 if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
519 if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
521 if (IS_FLG(FLG_MORE_THAN))
523 ADD_KEY(KEY_MORE_THAN);
524 strcat(ptr, format("%d", entry->dice));
528 if (IS_FLG(FLG_MORE_BONUS))
530 ADD_KEY(KEY_MORE_BONUS);
531 strcat(ptr, format("%d", entry->bonus));
532 ADD_KEY(KEY_MORE_BONUS2);
535 if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
536 if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
537 if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
538 if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
539 if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
540 if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
541 if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
542 if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
543 if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
544 if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
545 if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
546 if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
547 if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
549 if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
551 if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
552 else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
553 else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
554 else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
555 else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
556 else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
557 else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
558 else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
559 else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
560 else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
561 else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
562 else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
563 else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
564 else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
565 else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
566 else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
567 else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
568 else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
569 else if (IS_FLG(FLG_FAVORITE)) ADD_KEY2(KEY_FAVORITE);
571 /* You don't need sepalator after adjective */
572 /* 'artifact' is not true adjective */
573 else if (!IS_FLG(FLG_ARTIFACT))
576 if (entry->name && entry->name[0])
580 if (sepa_flag) strcat(buf, ":");
583 while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
586 if (iskanji(entry->name[j]))
587 buf[i++] = entry->name[j++];
589 buf[i++] = entry->name[j++];
600 while (entry->insc[j] && i < MAX_LINELEN - 2)
603 if (iskanji(entry->insc[j]))
604 buf[i++] = entry->insc[j++];
606 buf[i++] = entry->insc[j++];
611 return string_make(buf);
616 * Reconstruct preference line from entry and kill entry
618 static cptr autopick_line_from_entry_kill(autopick_type *entry)
620 cptr ptr = autopick_line_from_entry(entry);
622 /* Free memory for original entry */
623 autopick_free_entry(entry);
632 static bool is_favorite(object_type *o_ptr, bool others_ok)
634 /* Only weapons match */
637 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
638 case TV_SWORD: case TV_DIGGING:
640 default: return FALSE;
643 /* Favorite weapons are varied depend on the class */
644 switch (p_ptr->pclass)
648 u32b flgs[TR_FLAG_SIZE];
649 object_flags_known(o_ptr, flgs);
651 if (!have_flag(flgs, TR_BLESSED) &&
652 !(o_ptr->tval == TV_HAFTED))
658 case CLASS_FORCETRAINER:
660 if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval]))
664 case CLASS_BEASTMASTER:
667 u32b flgs[TR_FLAG_SIZE];
668 object_flags_known(o_ptr, flgs);
670 /* Is it known to be suitable to using while riding? */
671 if (!(have_flag(flgs, TR_RIDING)))
679 if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
684 /* Non-special class */
685 if (others_ok) return TRUE;
693 * A function for Auto-picker/destroyer
694 * Examine whether the object matches to the entry
696 static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
699 cptr ptr = entry->name;
701 /*** Unidentified ***/
702 if (IS_FLG(FLG_UNIDENTIFIED)
703 && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
707 if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
710 /*** *Identified* ***/
711 if (IS_FLG(FLG_STAR_IDENTIFIED) &&
712 (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
715 /*** Dice boosted (weapon of slaying) ***/
716 if (IS_FLG(FLG_BOOSTED))
718 object_kind *k_ptr = &k_info[o_ptr->k_idx];
720 switch( o_ptr->tval )
726 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
735 /*** Weapons which dd*ds is more than nn ***/
736 if (IS_FLG(FLG_MORE_THAN))
738 if (o_ptr->dd * o_ptr->ds < entry->dice)
742 /*** Weapons whic dd*ds is more than nn ***/
743 if (IS_FLG(FLG_MORE_BONUS))
745 if (!object_known_p(o_ptr)) return FALSE;
749 if (o_ptr->pval < entry->bonus) return FALSE;
753 if (o_ptr->to_h < entry->bonus &&
754 o_ptr->to_d < entry->bonus &&
755 o_ptr->to_a < entry->bonus &&
756 o_ptr->pval < entry->bonus)
761 /*** Worthless items ***/
762 if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
765 /*** Artifact object ***/
766 if (IS_FLG(FLG_ARTIFACT))
768 if (!object_known_p(o_ptr) || (!o_ptr->name1 && !o_ptr->art_name))
775 if (!object_known_p(o_ptr) || !o_ptr->name2)
780 if (IS_FLG(FLG_NAMELESS))
785 case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
786 case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD:
787 case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
788 case TV_SHIELD: case TV_CLOAK:
789 case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
790 case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
791 if ((!object_known_p(o_ptr) || o_ptr->inscription
792 || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
801 /*** Unaware items ***/
802 if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
805 /*** Wanted monster's corpse/skeletons ***/
806 if (IS_FLG(FLG_WANTED) &&
807 (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
810 /*** Unique monster's corpse/skeletons/statues ***/
811 if (IS_FLG(FLG_UNIQUE) &&
812 ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
813 !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
816 /*** Human corpse/skeletons (for Daemon magic) ***/
817 if (IS_FLG(FLG_HUMAN) &&
818 (o_ptr->tval != TV_CORPSE ||
819 !strchr("pht", r_info[o_ptr->pval].d_char)))
822 /*** Unreadable spellbooks ***/
823 if (IS_FLG(FLG_UNREADABLE) &&
824 (o_ptr->tval < TV_LIFE_BOOK ||
825 check_book_realm(o_ptr->tval, o_ptr->sval)))
828 /*** First realm spellbooks ***/
829 if (IS_FLG(FLG_REALM1) &&
830 (REALM1_BOOK != o_ptr->tval ||
831 p_ptr->pclass == CLASS_SORCERER ||
832 p_ptr->pclass == CLASS_RED_MAGE))
835 /*** Second realm spellbooks ***/
836 if (IS_FLG(FLG_REALM2) &&
837 (REALM2_BOOK != o_ptr->tval ||
838 p_ptr->pclass == CLASS_SORCERER ||
839 p_ptr->pclass == CLASS_RED_MAGE))
842 /*** First rank spellbooks ***/
843 if (IS_FLG(FLG_FIRST) &&
844 (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
847 /*** Second rank spellbooks ***/
848 if (IS_FLG(FLG_SECOND) &&
849 (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
852 /*** Third rank spellbooks ***/
853 if (IS_FLG(FLG_THIRD) &&
854 (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
857 /*** Fourth rank spellbooks ***/
858 if (IS_FLG(FLG_FOURTH) &&
859 (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
863 if (IS_FLG(FLG_WEAPONS))
867 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
868 case TV_SWORD: case TV_DIGGING:
870 default: return FALSE;
873 else if (IS_FLG(FLG_ARMORS))
877 case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
878 case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
879 case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
881 default: return FALSE;
884 else if (IS_FLG(FLG_MISSILES))
888 case TV_SHOT: case TV_BOLT: case TV_ARROW:
890 default: return FALSE;
893 else if (IS_FLG(FLG_DEVICES))
897 case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
899 default: return FALSE;
902 else if (IS_FLG(FLG_LIGHTS))
904 if (!(o_ptr->tval == TV_LITE))
907 else if (IS_FLG(FLG_JUNKS))
911 case TV_SKELETON: case TV_BOTTLE:
912 case TV_JUNK: case TV_STATUE:
914 default: return FALSE;
917 else if (IS_FLG(FLG_SPELLBOOKS))
919 if (!(o_ptr->tval >= TV_LIFE_BOOK))
922 else if (IS_FLG(FLG_HAFTED))
924 if (!(o_ptr->tval == TV_HAFTED))
927 else if (IS_FLG(FLG_SHIELDS))
929 if (!(o_ptr->tval == TV_SHIELD))
932 else if (IS_FLG(FLG_BOWS))
934 if (!(o_ptr->tval == TV_BOW))
937 else if (IS_FLG(FLG_RINGS))
939 if (!(o_ptr->tval == TV_RING))
942 else if (IS_FLG(FLG_AMULETS))
944 if (!(o_ptr->tval == TV_AMULET))
947 else if (IS_FLG(FLG_SUITS))
949 if (!(o_ptr->tval == TV_DRAG_ARMOR ||
950 o_ptr->tval == TV_HARD_ARMOR ||
951 o_ptr->tval == TV_SOFT_ARMOR))
954 else if (IS_FLG(FLG_CLOAKS))
956 if (!(o_ptr->tval == TV_CLOAK))
959 else if (IS_FLG(FLG_HELMS))
961 if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
964 else if (IS_FLG(FLG_GLOVES))
966 if (!(o_ptr->tval == TV_GLOVES))
969 else if (IS_FLG(FLG_BOOTS))
971 if (!(o_ptr->tval == TV_BOOTS))
974 else if (IS_FLG(FLG_FAVORITE))
976 if (!is_favorite(o_ptr, TRUE))
980 /* Keyword don't match */
984 if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
989 if (!strstr_j(o_name, ptr)) return FALSE;
991 if (!strstr(o_name, ptr)) return FALSE;
995 /* TRUE when it need not to be 'collecting' */
996 if (!IS_FLG(FLG_COLLECTING)) return TRUE;
998 /* Check if there is a same item */
999 for (j = 0; j < INVEN_PACK; j++)
1002 * 'Collecting' means the item must be absorbed
1003 * into an inventory slot.
1004 * But an item can not be absorbed into itself!
1006 if ((&inventory[j] != o_ptr) &&
1007 object_similar(&inventory[j], o_ptr))
1011 /* Not collecting */
1017 * A function for Auto-picker/destroyer
1018 * Examine whether the object matches to the list of keywords or not.
1020 int is_autopick(object_type *o_ptr)
1023 char o_name[MAX_NLEN];
1025 if (o_ptr->tval == TV_GOLD) return -1;
1027 object_desc(o_name, o_ptr, FALSE, 3);
1029 /* Force to be lower case string */
1030 for (i = 0; o_name[i]; i++)
1033 if (iskanji(o_name[i]))
1037 if (isupper(o_name[i]))
1038 o_name[i] = tolower(o_name[i]);
1041 for (i=0; i < max_autopick; i++)
1043 autopick_type *entry = &autopick_list[i];
1045 if (is_autopick_aux(o_ptr, entry, o_name)) return i;
1048 /* No matching entry */
1056 void auto_inscribe_item(int item, int idx)
1060 /* Get the item (in the pack) */
1061 if (item >= 0) o_ptr = &inventory[item];
1063 /* Get the item (on the floor) */
1064 else o_ptr = &o_list[0 - item];
1066 /* Auto-inscription or Re-inscribe for resistances {%} */
1067 if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
1070 if (!o_ptr->inscription)
1071 o_ptr->inscription = quark_add(autopick_list[idx].insc);
1073 if (item > INVEN_PACK)
1075 /* Redraw inscription */
1076 p_ptr->window |= (PW_EQUIP);
1078 /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
1079 p_ptr->update |= (PU_BONUS);
1083 /* Redraw inscription */
1084 p_ptr->window |= (PW_INVEN);
1090 * Automatically destroy items in this grid.
1092 static bool is_opt_confirm_destroy(object_type *o_ptr)
1094 if (!destroy_items) return FALSE;
1096 /* Known to be worthless? */
1098 if (object_value(o_ptr) > 0) return FALSE;
1101 if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_DRAG_ARMOR)) return FALSE;
1104 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
1108 if (o_ptr->tval == TV_CORPSE
1109 && object_is_shoukinkubi(o_ptr)) return FALSE;
1113 if (o_ptr->tval == TV_CORPSE) return FALSE;
1116 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
1120 if (p_ptr->prace == RACE_DEMON)
1122 if (o_ptr->tval == TV_CORPSE &&
1123 o_ptr->sval == SV_CORPSE &&
1124 strchr("pht", r_info[o_ptr->pval].d_char))
1128 if (p_ptr->pclass == CLASS_ARCHER)
1130 if (o_ptr->tval == TV_SKELETON ||
1131 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
1134 else if (p_ptr->pclass == CLASS_NINJA)
1136 if (o_ptr->tval == TV_LITE &&
1137 o_ptr->name2 == EGO_LITE_DARKNESS)
1140 else if (p_ptr->pclass == CLASS_BEASTMASTER ||
1141 p_ptr->pclass == CLASS_CAVALRY)
1143 if (o_ptr->tval == TV_WAND &&
1144 o_ptr->sval == SV_WAND_HEAL_MONSTER)
1149 if (o_ptr->tval == TV_GOLD) return FALSE;
1156 * Automatically destroy an item if it is to be destroyed
1158 static object_type autopick_last_destroyed_object;
1160 bool auto_destroy_item(int item, int autopick_idx)
1162 bool destroy = FALSE;
1165 /* Don't destroy equipped items */
1166 if (item > INVEN_PACK) return FALSE;
1168 /* Get the item (in the pack) */
1169 if (item >= 0) o_ptr = &inventory[item];
1171 /* Get the item (on the floor) */
1172 else o_ptr = &o_list[0 - item];
1174 /* Easy-Auto-Destroyer */
1175 if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
1177 /* Protected by auto-picker */
1178 if (autopick_idx >= 0 &&
1179 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1184 /* Auto-picker/destroyer */
1185 if (autopick_idx >= 0 &&
1186 (autopick_list[autopick_idx].action & DO_AUTODESTROY))
1190 /* Not to be destroyed */
1191 if (!destroy) return FALSE;
1193 /* Now decided to destroy */
1198 if (!can_player_destroy_object(o_ptr))
1200 char o_name[MAX_NLEN];
1202 /* Describe the object (with {terrible/special}) */
1203 object_desc(o_name, o_ptr, TRUE, 3);
1207 msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
1209 msg_format("You cannot auto-destroy %s.", o_name);
1216 /* Record name of destroyed item */
1217 COPY(&autopick_last_destroyed_object, o_ptr, object_type);
1220 o_ptr->marked |= OM_AUTODESTROY;
1221 p_ptr->notice |= PN_AUTODESTROY;
1228 * Auto-destroy marked item
1230 static void delayed_auto_destroy_aux(int item)
1234 /* Get the item (in the pack) */
1235 if (item >= 0) o_ptr = &inventory[item];
1237 /* Get the item (on the floor) */
1238 else o_ptr = &o_list[0 - item];
1240 if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
1242 char o_name[MAX_NLEN];
1244 /* Describe the object (with {terrible/special}) */
1245 object_desc(o_name, o_ptr, TRUE, 3);
1247 /* Eliminate the item (from the pack) */
1250 inven_item_increase(item, -(o_ptr->number));
1251 inven_item_optimize(item);
1254 /* Eliminate the item (from the floor) */
1257 delete_object_idx(0 - item);
1260 /* Print a message */
1262 msg_format("%s¤ò¼«Æ°Ç˲õ¤·¤Þ¤¹¡£", o_name);
1264 msg_format("Auto-destroying %s.", o_name);
1271 * Auto-destroy marked item in inventry and on floor
1273 void delayed_auto_destroy(void)
1278 * Scan inventry in reverse order to prevent
1279 * skipping after inven_item_optimize()
1281 for (item = INVEN_TOTAL - 1; item >= 0 ; item--)
1282 delayed_auto_destroy_aux(item);
1284 /* Scan the pile of objects */
1285 item = cave[py][px].o_idx;
1288 int next = o_list[item].next_o_idx;
1289 delayed_auto_destroy_aux(-item);
1296 * Automatically pickup/destroy items in this grid.
1298 void auto_pickup_items(cave_type *c_ptr)
1300 s16b this_o_idx, next_o_idx = 0;
1302 /* Scan the pile of objects */
1303 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1307 /* Acquire object */
1308 object_type *o_ptr = &o_list[this_o_idx];
1310 /* Acquire next object */
1311 next_o_idx = o_ptr->next_o_idx;
1313 idx = is_autopick(o_ptr);
1315 /* Item index for floor -1,-2,-3,... */
1316 auto_inscribe_item((-this_o_idx), idx);
1319 (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)))
1323 if (!inven_carry_okay(o_ptr))
1325 char o_name[MAX_NLEN];
1327 /* Describe the object */
1328 object_desc(o_name, o_ptr, TRUE, 3);
1332 msg_format("¥¶¥Ã¥¯¤Ë¤Ï%s¤òÆþ¤ì¤ë·ä´Ö¤¬¤Ê¤¤¡£", o_name);
1334 msg_format("You have no room for %s.", o_name);
1336 /* Hack - remember that the item has given a message here. */
1337 o_ptr->marked |= OM_NOMSG;
1341 else if (autopick_list[idx].action & DO_QUERY_AUTOPICK)
1343 char out_val[MAX_NLEN+20];
1344 char o_name[MAX_NLEN];
1346 if (o_ptr->marked & OM_NO_QUERY)
1348 /* Already answered as 'No' */
1352 /* Describe the object */
1353 object_desc(o_name, o_ptr, TRUE, 3);
1356 sprintf(out_val, "%s¤ò½¦¤¤¤Þ¤¹¤«? ", o_name);
1358 sprintf(out_val, "Pick up %s? ", o_name);
1361 if (!get_check(out_val))
1363 /* Hack - remember that the item has given a message here. */
1364 o_ptr->marked |= (OM_NOMSG | OM_NO_QUERY);
1369 py_pickup_aux(this_o_idx);
1376 * When always_pickup is 'yes', we disable
1377 * auto-destroyer from autopick function, and do only
1378 * easy-auto-destroyer.
1382 if (auto_destroy_item((-this_o_idx), idx))
1389 /******** Auto-picker/destroyer editor **********/
1391 #define MAX_YANK MAX_LINELEN
1394 * Struct for yank buffer
1396 typedef struct chain_str {
1397 struct chain_str *next;
1403 * Data struct for text editor
1409 int old_wid, old_hgt;
1411 int old_upper, old_left;
1414 object_type *search_o_ptr;
1416 cptr last_destroyed;
1417 chain_str_type *yank;
1428 * Dirty flag for text editor
1430 #define DIRTY_ALL 0x01
1431 #define DIRTY_MODE 0x04
1432 #define DIRTY_SCREEN 0x08
1433 #define DIRTY_NOT_FOUND 0x10
1434 #define DIRTY_NO_SEARCH 0x20
1438 * Describe which kind of object is Auto-picked/destroyed
1440 static void describe_autopick(char *buff, autopick_type *entry)
1442 cptr str = entry->name;
1443 byte act = entry->action;
1444 cptr insc = entry->insc;
1450 cptr before_str[100], body_str;
1453 body_str = "¥¢¥¤¥Æ¥à";
1455 /*** Collecting items ***/
1456 /*** Which can be absorbed into a slot as a bundle ***/
1457 if (IS_FLG(FLG_COLLECTING))
1458 before_str[before_n++] = "¼ý½¸Ãæ¤Ç´û¤Ë»ý¤Ã¤Æ¤¤¤ë¥¹¥í¥Ã¥È¤Ë¤Þ¤È¤á¤é¤ì¤ë";
1460 /*** Unidentified ***/
1461 if (IS_FLG(FLG_UNIDENTIFIED))
1462 before_str[before_n++] = "̤´ÕÄê¤Î";
1464 /*** Identified ***/
1465 if (IS_FLG(FLG_IDENTIFIED))
1466 before_str[before_n++] = "´ÕÄêºÑ¤ß¤Î";
1468 /*** *Identified* ***/
1469 if (IS_FLG(FLG_STAR_IDENTIFIED))
1470 before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
1472 /*** Dice boosted (weapon of slaying) ***/
1473 if (IS_FLG(FLG_BOOSTED))
1475 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤¬Ä̾ï¤è¤êÂ礤¤";
1479 /*** Weapons whose dd*ds is more than nn ***/
1480 if (IS_FLG(FLG_MORE_THAN))
1482 static char more_than_desc_str[] = "___";
1483 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
1486 sprintf(more_than_desc_str,"%d", entry->dice);
1487 before_str[before_n++] = more_than_desc_str;
1488 before_str[before_n++] = "°Ê¾å¤Î";
1491 /*** Items whose magical bonus is more than nn ***/
1492 if (IS_FLG(FLG_MORE_BONUS))
1494 static char more_bonus_desc_str[] = "___";
1495 before_str[before_n++] = "½¤ÀµÃͤ¬(+";
1497 sprintf(more_bonus_desc_str,"%d", entry->bonus);
1498 before_str[before_n++] = more_bonus_desc_str;
1499 before_str[before_n++] = ")°Ê¾å¤Î";
1502 /*** Worthless items ***/
1503 if (IS_FLG(FLG_WORTHLESS))
1504 before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
1507 if (IS_FLG(FLG_ARTIFACT))
1509 before_str[before_n++] = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Î";
1514 if (IS_FLG(FLG_EGO))
1516 before_str[before_n++] = "¥¨¥´¥¢¥¤¥Æ¥à¤Î";
1521 if (IS_FLG(FLG_NAMELESS))
1523 before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
1527 /*** Unaware items ***/
1528 if (IS_FLG(FLG_UNAWARE))
1529 before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
1531 /*** Wanted monster's corpse/skeletons ***/
1532 if (IS_FLG(FLG_WANTED))
1534 before_str[before_n++] = "¥Ï¥ó¥¿¡¼»ö̳½ê¤Ç¾Þ¶â¼ó¤È¤µ¤ì¤Æ¤¤¤ë";
1535 body_str = "»àÂΤä¹ü";
1538 /*** Human corpse/skeletons (for Daemon magic) ***/
1539 if (IS_FLG(FLG_HUMAN))
1541 before_str[before_n++] = "°ËâËâË¡¤Ç»È¤¦¤¿¤á¤Î¿Í´Ö¤ä¥Ò¥å¡¼¥Þ¥Î¥¤¥É¤Î";
1542 body_str = "»àÂΤä¹ü";
1545 /*** Unique monster's corpse/skeletons/statues ***/
1546 if (IS_FLG(FLG_UNIQUE))
1548 before_str[before_n++] = "¥æ¥Ë¡¼¥¯¥â¥ó¥¹¥¿¡¼¤Î";
1549 body_str = "»àÂΤä¹ü";
1552 /*** Unreadable spellbooks ***/
1553 if (IS_FLG(FLG_UNREADABLE))
1555 before_str[before_n++] = "¤¢¤Ê¤¿¤¬Æɤá¤Ê¤¤Îΰè¤Î";
1556 body_str = "ËâË¡½ñ";
1559 /*** First realm spellbooks ***/
1560 if (IS_FLG(FLG_REALM1))
1562 before_str[before_n++] = "Âè°ìÎΰè¤Î";
1563 body_str = "ËâË¡½ñ";
1566 /*** Second realm spellbooks ***/
1567 if (IS_FLG(FLG_REALM2))
1569 before_str[before_n++] = "ÂèÆóÎΰè¤Î";
1570 body_str = "ËâË¡½ñ";
1573 /*** First rank spellbooks ***/
1574 if (IS_FLG(FLG_FIRST))
1576 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î1ºýÌܤÎ";
1577 body_str = "ËâË¡½ñ";
1580 /*** Second rank spellbooks ***/
1581 if (IS_FLG(FLG_SECOND))
1583 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î2ºýÌܤÎ";
1584 body_str = "ËâË¡½ñ";
1587 /*** Third rank spellbooks ***/
1588 if (IS_FLG(FLG_THIRD))
1590 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î3ºýÌܤÎ";
1591 body_str = "ËâË¡½ñ";
1594 /*** Fourth rank spellbooks ***/
1595 if (IS_FLG(FLG_FOURTH))
1597 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î4ºýÌܤÎ";
1598 body_str = "ËâË¡½ñ";
1602 if (IS_FLG(FLG_ITEMS))
1603 ; /* Nothing to do */
1604 else if (IS_FLG(FLG_WEAPONS))
1606 else if (IS_FLG(FLG_ARMORS))
1608 else if (IS_FLG(FLG_MISSILES))
1609 body_str = "ÃƤäÌð¤ä¥¯¥í¥¹¥Ü¥¦¤ÎÌð";
1610 else if (IS_FLG(FLG_DEVICES))
1611 body_str = "´¬Êª¤äËâË¡ËÀ¤ä¾ó¤ä¥í¥Ã¥É";
1612 else if (IS_FLG(FLG_LIGHTS))
1613 body_str = "¸÷¸»ÍѤΥ¢¥¤¥Æ¥à";
1614 else if (IS_FLG(FLG_JUNKS))
1615 body_str = "Àޤ줿ËÀÅù¤Î¥¬¥é¥¯¥¿";
1616 else if (IS_FLG(FLG_SPELLBOOKS))
1617 body_str = "ËâË¡½ñ";
1618 else if (IS_FLG(FLG_HAFTED))
1620 else if (IS_FLG(FLG_SHIELDS))
1622 else if (IS_FLG(FLG_BOWS))
1623 body_str = "¥¹¥ê¥ó¥°¤äµÝ¤ä¥¯¥í¥¹¥Ü¥¦";
1624 else if (IS_FLG(FLG_RINGS))
1626 else if (IS_FLG(FLG_AMULETS))
1627 body_str = "¥¢¥ß¥å¥ì¥Ã¥È";
1628 else if (IS_FLG(FLG_SUITS))
1630 else if (IS_FLG(FLG_CLOAKS))
1631 body_str = "¥¯¥í¡¼¥¯";
1632 else if (IS_FLG(FLG_HELMS))
1633 body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
1634 else if (IS_FLG(FLG_GLOVES))
1636 else if (IS_FLG(FLG_BOOTS))
1637 body_str = "¥Ö¡¼¥Ä";
1638 else if (IS_FLG(FLG_FAVORITE))
1639 body_str = "ÆÀ°ÕÉð´ï";
1643 strcat(buff, "Á´¤Æ¤Î");
1644 else for (i = 0; i < before_n && before_str[i]; i++)
1645 strcat(buff, before_str[i]);
1647 strcat(buff, body_str);
1657 strcat(buff, "¤Ç¡¢Ì¾Á°¤¬¡Ö");
1658 strncat(buff, str, 80);
1660 strcat(buff, "¡×¤Ç»Ï¤Þ¤ë¤â¤Î");
1662 strcat(buff, "¡×¤ò´Þ¤à¤â¤Î");
1667 strncat(buff, format("¤Ë¡Ö%s¡×", insc), 80);
1669 if (strstr(insc, "%%all"))
1670 strcat(buff, "(%%all¤ÏÁ´Ç½ÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1671 else if (strstr(insc, "%all"))
1672 strcat(buff, "(%all¤ÏÁ´Ç½ÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1673 else if (strstr(insc, "%%"))
1674 strcat(buff, "(%%¤ÏÄɲÃǽÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1675 else if (strstr(insc, "%"))
1676 strcat(buff, "(%¤ÏÄɲÃǽÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1678 strcat(buff, "¤È¹ï¤ó¤Ç");
1683 if (act & DONT_AUTOPICK)
1684 strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
1685 else if (act & DO_AUTODESTROY)
1686 strcat(buff, "Ç˲õ¤¹¤ë¡£");
1687 else if (act & DO_QUERY_AUTOPICK)
1688 strcat(buff, "³Îǧ¤Î¸å¤Ë½¦¤¦¡£");
1690 strcat(buff, "½¦¤¦¡£");
1692 if (act & DO_DISPLAY)
1694 if (act & DONT_AUTOPICK)
1695 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'N'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1696 else if (act & DO_AUTODESTROY)
1697 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'K'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1699 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'M'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1702 strcat(buff, "Á´ÂΥޥåפˤÏɽ¼¨¤·¤Ê¤¤");
1706 cptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
1707 int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
1711 /*** Collecting items ***/
1712 /*** Which can be absorbed into a slot as a bundle ***/
1713 if (IS_FLG(FLG_COLLECTING))
1714 which_str[which_n++] = "can be absorbed into an existing inventory slot";
1716 /*** Unidentified ***/
1717 if (IS_FLG(FLG_UNIDENTIFIED))
1718 before_str[before_n++] = "unidentified";
1720 /*** Identified ***/
1721 if (IS_FLG(FLG_IDENTIFIED))
1722 before_str[before_n++] = "identified";
1724 /*** *Identified* ***/
1725 if (IS_FLG(FLG_STAR_IDENTIFIED))
1726 before_str[before_n++] = "fully identified";
1728 /*** Worthless items ***/
1729 if (IS_FLG(FLG_WORTHLESS))
1731 before_str[before_n++] = "worthless";
1732 which_str[which_n++] = "can not be sold at stores";
1736 if (IS_FLG(FLG_ARTIFACT))
1738 before_str[before_n++] = "artifact";
1742 if (IS_FLG(FLG_EGO))
1744 before_str[before_n++] = "ego";
1748 if (IS_FLG(FLG_NAMELESS))
1750 body_str = "equipment";
1751 which_str[which_n++] = "is neither ego-item nor artifact";
1754 /*** Unaware items ***/
1755 if (IS_FLG(FLG_UNAWARE))
1757 before_str[before_n++] = "unidentified";
1758 whose_str[whose_n++] = "basic abilities are not known";
1761 /*** Dice boosted (weapon of slaying) ***/
1762 if (IS_FLG(FLG_BOOSTED))
1764 body_str = "weapons";
1765 whose_str[whose_n++] = "damage dice is bigger than normal";
1768 /*** Weapons whose dd*ds is more than nn ***/
1769 if (IS_FLG(FLG_MORE_THAN))
1771 static char more_than_desc_str[] =
1772 "maximum damage from dice is bigger than __";
1773 body_str = "weapons";
1775 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
1777 whose_str[whose_n++] = more_than_desc_str;
1780 /*** Items whose magical bonus is more than nn ***/
1781 if (IS_FLG(FLG_MORE_BONUS))
1783 static char more_bonus_desc_str[] =
1784 "magical bonus is bigger than (+__)";
1786 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
1787 "%d)", entry->bonus);
1788 whose_str[whose_n++] = more_bonus_desc_str;
1791 /*** Wanted monster's corpse/skeletons ***/
1792 if (IS_FLG(FLG_WANTED))
1794 body_str = "corpse or skeletons";
1795 which_str[which_n++] = "is wanted at the Hunter's Office";
1798 /*** Human corpse/skeletons (for Daemon magic) ***/
1799 if (IS_FLG(FLG_HUMAN))
1801 before_str[before_n++] = "humanoid";
1802 body_str = "corpse or skeletons";
1803 which_str[which_n++] = "can be used for Daemon magic";
1806 /*** Unique monster's corpse/skeletons/statues ***/
1807 if (IS_FLG(FLG_UNIQUE))
1809 before_str[before_n++] = "unique monster's";
1810 body_str = "corpse or skeletons";
1813 /*** Unreadable spellbooks ***/
1814 if (IS_FLG(FLG_UNREADABLE))
1816 body_str = "spellbooks";
1817 after_str[after_n++] = "of different realms from yours";
1820 /*** First realm spellbooks ***/
1821 if (IS_FLG(FLG_REALM1))
1823 body_str = "spellbooks";
1824 after_str[after_n++] = "of your first realm";
1827 /*** Second realm spellbooks ***/
1828 if (IS_FLG(FLG_REALM2))
1830 body_str = "spellbooks";
1831 after_str[after_n++] = "of your second realm";
1834 /*** First rank spellbooks ***/
1835 if (IS_FLG(FLG_FIRST))
1837 before_str[before_n++] = "first one of four";
1838 body_str = "spellbooks";
1841 /*** Second rank spellbooks ***/
1842 if (IS_FLG(FLG_SECOND))
1844 before_str[before_n++] = "second one of four";
1845 body_str = "spellbooks";
1848 /*** Third rank spellbooks ***/
1849 if (IS_FLG(FLG_THIRD))
1851 before_str[before_n++] = "third one of four";
1852 body_str = "spellbooks";
1855 /*** Fourth rank spellbooks ***/
1856 if (IS_FLG(FLG_FOURTH))
1858 before_str[before_n++] = "fourth one of four";
1859 body_str = "spellbooks";
1863 if (IS_FLG(FLG_ITEMS))
1864 ; /* Nothing to do */
1865 else if (IS_FLG(FLG_WEAPONS))
1866 body_str = "weapons";
1867 else if (IS_FLG(FLG_ARMORS))
1868 body_str = "armors";
1869 else if (IS_FLG(FLG_MISSILES))
1870 body_str = "shots, arrows or crossbow bolts";
1871 else if (IS_FLG(FLG_DEVICES))
1872 body_str = "scrolls, wands, staves or rods";
1873 else if (IS_FLG(FLG_LIGHTS))
1874 body_str = "light sources";
1875 else if (IS_FLG(FLG_JUNKS))
1876 body_str = "junk such as broken sticks";
1877 else if (IS_FLG(FLG_SPELLBOOKS))
1878 body_str = "spellbooks";
1879 else if (IS_FLG(FLG_HAFTED))
1880 body_str = "hafted weapons";
1881 else if (IS_FLG(FLG_SHIELDS))
1882 body_str = "shields";
1883 else if (IS_FLG(FLG_BOWS))
1884 body_str = "slings, bows or crossbows";
1885 else if (IS_FLG(FLG_RINGS))
1887 else if (IS_FLG(FLG_AMULETS))
1888 body_str = "amulets";
1889 else if (IS_FLG(FLG_SUITS))
1890 body_str = "body armors";
1891 else if (IS_FLG(FLG_CLOAKS))
1892 body_str = "cloaks";
1893 else if (IS_FLG(FLG_HELMS))
1894 body_str = "helms or crowns";
1895 else if (IS_FLG(FLG_GLOVES))
1896 body_str = "gloves";
1897 else if (IS_FLG(FLG_BOOTS))
1899 else if (IS_FLG(FLG_FAVORITE))
1900 body_str = "favorite weapons";
1902 /* Prepare a string for item name */
1909 whose_str[whose_n++] = "name is beginning with \"";
1912 which_str[which_n++] = "have \"";
1916 /* Describe action flag */
1917 if (act & DONT_AUTOPICK)
1918 strcpy(buff, "Leave on floor ");
1919 else if (act & DO_AUTODESTROY)
1920 strcpy(buff, "Destroy ");
1921 else if (act & DO_QUERY_AUTOPICK)
1922 strcpy(buff, "Ask to pick up ");
1924 strcpy(buff, "Pickup ");
1926 /* Auto-insctiption */
1929 strncat(buff, format("and inscribe \"%s\"", insc), 80);
1931 if (strstr(insc, "%all"))
1932 strcat(buff, ", replacing %all with code string representing all abilities,");
1933 else if (strstr(insc, "%"))
1934 strcat(buff, ", replacing % with code string representing extra random abilities,");
1936 strcat(buff, " on ");
1941 strcat(buff, "all ");
1942 else for (i = 0; i < before_n && before_str[i]; i++)
1944 strcat(buff, before_str[i]);
1949 strcat(buff, body_str);
1952 for (i = 0; i < after_n && after_str[i]; i++)
1955 strcat(buff, after_str[i]);
1959 for (i = 0; i < whose_n && whose_str[i]; i++)
1962 strcat(buff, " whose ");
1964 strcat(buff, ", and ");
1966 strcat(buff, whose_str[i]);
1969 /* Item name ; whose name is beginning with "str" */
1976 /* whose ..., and which .... */
1977 if (whose_n && which_n)
1978 strcat(buff, ", and ");
1981 for (i = 0; i < which_n && which_str[i]; i++)
1984 strcat(buff, " which ");
1986 strcat(buff, ", and ");
1988 strcat(buff, which_str[i]);
1991 /* Item name ; which have "str" as part of its name */
1994 strncat(buff, str, 80);
1995 strcat(buff, "\" as part of its name");
1999 /* Describe whether it will be displayed on the full map or not */
2000 if (act & DO_DISPLAY)
2002 if (act & DONT_AUTOPICK)
2003 strcat(buff, " Display these items when you press the N key in the full 'M'ap.");
2004 else if (act & DO_AUTODESTROY)
2005 strcat(buff, " Display these items when you press the K key in the full 'M'ap.");
2007 strcat(buff, " Display these items when you press the M key in the full 'M'ap.");
2010 strcat(buff, " Not displayed in the full map.");
2016 #define MAX_LINES 3000
2019 * Read whole lines of a file to memory
2021 static cptr *read_text_lines(cptr filename, bool user)
2023 cptr *lines_list = NULL;
2031 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2035 path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
2039 fff = my_fopen(buf, "r");
2043 /* Allocate list of pointers */
2044 C_MAKE(lines_list, MAX_LINES, cptr);
2047 while (0 == my_fgets(fff, buf, sizeof(buf)))
2049 lines_list[lines++] = string_make(buf);
2050 if (lines >= MAX_LINES - 1) break;
2053 lines_list[0] = string_make("");
2058 if (!fff) return NULL;
2063 #define PT_DEFAULT 0
2064 #define PT_WITH_PNAME 1
2066 static cptr *read_pickpref_text_lines(int *filename_mode_p)
2072 sprintf(buf, "picktype-%s.prf", player_name);
2074 sprintf(buf, "pickpref-%s.prf", player_name);
2076 lines_list = read_text_lines(buf, TRUE);
2081 lines_list = read_text_lines("picktype.prf", TRUE);
2083 lines_list = read_text_lines("pickpref.prf", TRUE);
2085 *filename_mode_p = PT_DEFAULT;
2091 lines_list = read_text_lines("picktype.prf", FALSE);
2093 lines_list = read_text_lines("pickpref.prf", FALSE);
2095 *filename_mode_p = PT_WITH_PNAME;
2100 /* Allocate list of pointers */
2101 C_MAKE(lines_list, MAX_LINES, cptr);
2102 lines_list[0] = string_make("");
2103 *filename_mode_p = PT_WITH_PNAME;
2110 * Write whole lines of memory to a file.
2112 static bool write_text_lines(cptr filename, cptr *lines_list)
2119 /* Build the filename */
2120 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2123 fff = my_fopen(buf, "w");
2126 for (lines = 0; lines_list[lines]; lines++)
2127 my_fputs(fff, lines_list[lines], 1024);
2132 if (!fff) return FALSE;
2138 * Free memory of lines_list.
2140 static void free_text_lines(cptr *lines_list)
2144 for (lines = 0; lines_list[lines]; lines++)
2145 string_free(lines_list[lines]);
2147 /* free list of pointers */
2148 C_FREE((char **)lines_list, MAX_LINES, char *);
2153 * Delete or insert string
2155 static void toggle_keyword(text_body_type *tb, int flg)
2157 int by1, by2, bx1, bx2, y;
2161 /* Select this line */
2162 if (!tb->mark) tb->my = tb->cy;
2164 if (tb->my < tb->cy)
2179 /* String on these lines are not really selected */
2180 if (tb->lines_list[by1][bx1] == '\0' && by1 < tb->cy) by1++;
2181 if (bx2 == 0 && tb->cy < by2) by2--;
2184 /* Set/Reset flag of each line */
2185 for (y = by1; y <= by2; y++)
2187 autopick_type an_entry, *entry = &an_entry;
2189 if (!autopick_new_entry(entry, tb->lines_list[y]))
2192 string_free(tb->lines_list[y]);
2196 /* Add? or Remove? */
2197 if (!IS_FLG(flg)) add = TRUE;
2200 /* No more change */
2204 /* Remove all noun flag */
2205 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2208 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2212 if (add) ADD_FLG(flg);
2215 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
2218 tb->dirty_flags = DIRTY_ALL;
2224 * Change command letter
2226 static void toggle_command_letter(text_body_type *tb, byte flg)
2228 autopick_type an_entry, *entry = &an_entry;
2229 int by1, by2, bx1, bx2, y;
2233 /* Select this line */
2234 if (!tb->mark) tb->my = tb->cy;
2236 if (tb->my < tb->cy)
2251 /* String on these lines are not really selected */
2252 if (tb->lines_list[by1][bx1] == '\0' && by1 < tb->cy) by1++;
2253 if (bx2 == 0 && tb->cy < by2) by2--;
2256 /* Set/Reset flag of each line */
2257 for (y = by1; y <= by2; y++)
2261 if (!autopick_new_entry(entry, tb->lines_list[y])) continue;
2263 string_free(tb->lines_list[y]);
2267 /* Add? or Remove? */
2268 if (!(entry->action & flg)) add = TRUE;
2271 /* No more change */
2275 /* Count number of letter (by negative number) */
2276 if (entry->action & DONT_AUTOPICK) wid--;
2277 else if (entry->action & DO_AUTODESTROY) wid--;
2278 else if (entry->action & DO_QUERY_AUTOPICK) wid--;
2279 if (!(entry->action & DO_DISPLAY)) wid--;
2281 /* Set/Reset the flag */
2282 if (flg != DO_DISPLAY)
2284 entry->action &= ~(DO_AUTOPICK | DONT_AUTOPICK | DO_AUTODESTROY | DO_QUERY_AUTOPICK);
2285 if (add) entry->action |= flg;
2286 else entry->action |= DO_AUTOPICK;
2290 entry->action &= ~(DO_DISPLAY);
2291 if (add) entry->action |= flg;
2294 /* Correct cursor location */
2297 if (entry->action & DONT_AUTOPICK) wid++;
2298 else if (entry->action & DO_AUTODESTROY) wid++;
2299 else if (entry->action & DO_QUERY_AUTOPICK) wid++;
2300 if (!(entry->action & DO_DISPLAY)) wid++;
2302 if (wid > 0) tb->cx++;
2303 if (wid < 0 && tb->cx > 0) tb->cx--;
2306 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
2309 tb->dirty_flags |= DIRTY_ALL;
2314 * Delete or insert string
2316 static void add_keyword(text_body_type *tb, int flg)
2318 autopick_type an_entry, *entry = &an_entry;
2320 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
2323 /* There is the flag already */
2326 /* Free memory for the entry */
2327 autopick_free_entry(entry);
2332 string_free(tb->lines_list[tb->cy]);
2334 /* Remove all noun flag */
2335 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2338 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2344 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
2347 tb->dirty_line = tb->cy;
2352 * Insert return code and split the line
2354 static bool insert_return_code(cptr *lines_list, int cx, int cy)
2356 char buf[MAX_LINELEN];
2359 for (k = 0; lines_list[k]; k++)
2360 /* count number of lines */ ;
2362 if (k >= MAX_LINES - 2) return FALSE;
2365 /* Move down lines */
2367 lines_list[k+1] = lines_list[k];
2369 /* Split current line */
2370 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2373 if (iskanji(lines_list[cy][i]))
2374 buf[j++] = lines_list[cy][i++];
2376 buf[j++] = lines_list[cy][i];
2379 lines_list[cy+1] = string_make(&lines_list[cy][i]);
2380 string_free(lines_list[cy]);
2381 lines_list[cy] = string_make(buf);
2387 * Get auto-picker entry from o_ptr.
2389 void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
2391 char o_name[MAX_NLEN];
2392 object_desc(o_name, o_ptr, FALSE, 0);
2394 entry->name = string_make(o_name);
2395 entry->insc = string_make(quark_str(o_ptr->inscription));
2396 entry->action = DO_AUTOPICK | DO_DISPLAY;
2397 entry->flag[0] = entry->flag[1] = 0L;
2400 if (!object_aware_p(o_ptr))
2401 ADD_FLG(FLG_UNAWARE);
2402 if (object_value(o_ptr) <= 0)
2403 ADD_FLG(FLG_WORTHLESS);
2405 if (object_known_p(o_ptr))
2409 else if (o_ptr->name1 || o_ptr->art_name)
2410 ADD_FLG(FLG_ARTIFACT);
2416 case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING:
2417 k_ptr = &k_info[o_ptr->k_idx];
2418 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
2419 ADD_FLG(FLG_BOOSTED);
2422 if (o_ptr->tval == TV_CORPSE && object_is_shoukinkubi(o_ptr))
2424 REM_FLG(FLG_WORTHLESS);
2425 ADD_FLG(FLG_WANTED);
2428 if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
2429 && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
2431 REM_FLG(FLG_WORTHLESS);
2432 ADD_FLG(FLG_UNIQUE);
2435 if (o_ptr->tval == TV_CORPSE && strchr("pht", r_info[o_ptr->pval].d_char))
2437 REM_FLG(FLG_WORTHLESS);
2441 if (o_ptr->tval >= TV_LIFE_BOOK &&
2442 !check_book_realm(o_ptr->tval, o_ptr->sval))
2443 ADD_FLG(FLG_UNREADABLE);
2445 if (REALM1_BOOK == o_ptr->tval &&
2446 p_ptr->pclass != CLASS_SORCERER &&
2447 p_ptr->pclass != CLASS_RED_MAGE)
2448 ADD_FLG(FLG_REALM1);
2450 if (REALM2_BOOK == o_ptr->tval &&
2451 p_ptr->pclass != CLASS_SORCERER &&
2452 p_ptr->pclass != CLASS_RED_MAGE)
2453 ADD_FLG(FLG_REALM2);
2455 if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
2457 if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
2458 ADD_FLG(FLG_SECOND);
2459 if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
2461 if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
2462 ADD_FLG(FLG_FOURTH);
2464 if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
2465 || o_ptr->tval == TV_ARROW)
2466 ADD_FLG(FLG_MISSILES);
2467 else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
2468 || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
2469 ADD_FLG(FLG_DEVICES);
2470 else if (o_ptr->tval == TV_LITE)
2471 ADD_FLG(FLG_LIGHTS);
2472 else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
2473 || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
2475 else if (o_ptr->tval >= TV_LIFE_BOOK)
2476 ADD_FLG(FLG_SPELLBOOKS);
2477 else if (is_favorite(o_ptr, FALSE))
2478 ADD_FLG(FLG_FAVORITE);
2479 else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
2480 || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)
2481 ADD_FLG(FLG_WEAPONS);
2482 else if (o_ptr->tval == TV_SHIELD)
2483 ADD_FLG(FLG_SHIELDS);
2484 else if (o_ptr->tval == TV_BOW)
2486 else if (o_ptr->tval == TV_RING)
2488 else if (o_ptr->tval == TV_AMULET)
2489 ADD_FLG(FLG_AMULETS);
2490 else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
2491 o_ptr->tval == TV_SOFT_ARMOR)
2493 else if (o_ptr->tval == TV_CLOAK)
2494 ADD_FLG(FLG_CLOAKS);
2495 else if (o_ptr->tval == TV_HELM)
2497 else if (o_ptr->tval == TV_GLOVES)
2498 ADD_FLG(FLG_GLOVES);
2499 else if (o_ptr->tval == TV_BOOTS)
2507 * Choose an item and get auto-picker entry from it.
2509 static object_type *choose_object(cptr q, cptr s)
2513 if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return NULL;
2515 /* Get the item (in the pack) */
2516 if (item >= 0) return &inventory[item];
2518 /* Get the item (on the floor) */
2519 else return &o_list[0 - item];
2524 * Choose an item and get auto-picker entry from it.
2526 static bool entry_from_choosed_object(autopick_type *entry)
2533 q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
2534 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2536 q = "Enter which item? ";
2537 s = "You have nothing to enter.";
2539 o_ptr = choose_object(q, s);
2540 if (!o_ptr) return FALSE;
2542 autopick_entry_from_object(entry, o_ptr);
2548 * Choose an item for search
2550 static byte get_object_for_search(object_type **o_handle, cptr *search_strp)
2552 char buf[MAX_NLEN+20];
2558 q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
2559 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2561 q = "Enter which item? ";
2562 s = "You have nothing to enter.";
2564 o_ptr = choose_object(q, s);
2565 if (!o_ptr) return 0;
2569 string_free(*search_strp);
2570 object_desc(buf, *o_handle, FALSE, 3);
2571 *search_strp = string_make(format("<%s>", buf));
2577 * Prepare for search by destroyed object
2579 static byte get_destroyed_object_for_search(object_type **o_handle, cptr *search_strp)
2581 char buf[MAX_NLEN+20];
2583 if (!autopick_last_destroyed_object.k_idx) return 0;
2585 *o_handle = &autopick_last_destroyed_object;
2587 string_free(*search_strp);
2588 object_desc(buf, *o_handle, FALSE, 3);
2589 *search_strp = string_make(format("<%s>", buf));
2595 * Choose an item or string for search
2597 static byte get_string_for_search(object_type **o_handle, cptr *search_strp)
2600 char buf[MAX_NLEN+20];
2603 int k_flag[MAX_NLEN+20];
2604 char prompt[] = "¸¡º÷(^I:»ý¤Áʪ ^L:Ç˲õ¤µ¤ì¤¿Êª): ";
2606 char prompt[] = "Search key(^I:inven ^L:destroyed): ";
2608 int col = sizeof(prompt) - 1;
2610 if (*search_strp) strcpy(buf, *search_strp);
2613 /* Display prompt */
2616 /* Display the default answer */
2617 Term_erase(col, 0, 255);
2618 Term_putstr(col, 0, -1, TERM_YELLOW, buf);
2627 Term_gotoxy(col + pos, 0);
2632 /* HACK -- ignore macro defined on ASCII keys */
2633 if (strlen(inkey_macro_trigger_string) == 1)
2634 i = inkey_macro_trigger_string[0];
2637 /* Analyze the key */
2650 if (!pos && *o_handle) return (back ? -1 : 1);
2651 string_free(*search_strp);
2652 *search_strp = string_make(buf);
2654 return (back ? -1 : 1);
2658 return get_object_for_search(o_handle, search_strp);
2661 /* Prepare string for destroyed object if there is one. */
2662 if (get_destroyed_object_for_search(o_handle, search_strp))
2672 if (k_flag[pos]) pos--;
2687 if (pos + 1 < MAX_NLEN)
2695 else if (pos < MAX_NLEN && isprint(i))
2702 if (pos < MAX_NLEN && isprint(i)) buf[pos++] = i;
2711 /* Update the entry */
2712 Term_erase(col, 0, 255);
2713 Term_putstr(col, 0, -1, TERM_WHITE, buf);
2721 * Search next line matches for o_ptr
2723 static bool search_for_object(cptr *lines_list, object_type *o_ptr, int *cxp, int *cyp, bool forward)
2726 autopick_type an_entry, *entry = &an_entry;
2727 char o_name[MAX_NLEN];
2729 object_desc(o_name, o_ptr, FALSE, 3);
2731 /* Force to be lower case string */
2732 for (i = 0; o_name[i]; i++)
2735 if (iskanji(o_name[i]))
2739 if (isupper(o_name[i]))
2740 o_name[i] = tolower(o_name[i]);
2749 if (!lines_list[++i]) break;
2756 if (!autopick_new_entry(entry, lines_list[i])) continue;
2758 if (is_autopick_aux(o_ptr, entry, o_name))
2771 * Search next line matches to the string
2773 static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *cyp, bool forward)
2783 if (!lines_list[++i]) break;
2790 pos = strstr_j(lines_list[i], search_str);
2792 pos = strstr(lines_list[i], search_str);
2796 *cxp = (int)(pos - lines_list[i]);
2822 #define EC_PGDOWN 12
2824 #define EC_BOTTOM 14
2829 #define EC_KILL_LINE 19
2830 #define EC_DELETE_CHAR 20
2831 #define EC_BACKSPACE 21
2832 #define EC_SEARCH_STR 22
2833 #define EC_SEARCH_FORW 23
2834 #define EC_SEARCH_BACK 24
2835 #define EC_SEARCH_OBJ 25
2836 #define EC_SEARCH_DESTROYED 26
2837 #define EC_INSERT_OBJECT 27
2838 #define EC_INSERT_DESTROYED 28
2839 #define EC_INSERT_BLOCK 29
2840 #define EC_INSERT_MACRO 30
2841 #define EC_INSERT_KEYMAP 31
2842 #define EC_CL_AUTOPICK 32
2843 #define EC_CL_DESTROY 33
2844 #define EC_CL_LEAVE 34
2845 #define EC_CL_QUERY 35
2846 #define EC_CL_NO_DISP 36
2847 #define EC_IK_UNAWARE 37
2848 #define EC_IK_UNIDENTIFIED 38
2849 #define EC_IK_IDENTIFIED 39
2850 #define EC_IK_STAR_IDENTIFIED 40
2851 #define EC_KK_WEAPONS 41
2852 #define EC_KK_FAVORITE 42
2853 #define EC_KK_ARMORS 43
2854 #define EC_KK_MISSILES 44
2855 #define EC_KK_DEVICES 45
2856 #define EC_KK_LIGHTS 46
2857 #define EC_KK_JUNKS 47
2858 #define EC_KK_SPELLBOOKS 48
2859 #define EC_KK_SHIELDS 49
2860 #define EC_KK_BOWS 50
2861 #define EC_KK_RINGS 51
2862 #define EC_KK_AMULETS 52
2863 #define EC_KK_SUITS 53
2864 #define EC_KK_CLOAKS 54
2865 #define EC_KK_HELMS 55
2866 #define EC_KK_GLOVES 56
2867 #define EC_KK_BOOTS 57
2868 #define EC_OK_COLLECTING 58
2869 #define EC_OK_BOOSTED 59
2870 #define EC_OK_MORE_THAN 60
2871 #define EC_OK_MORE_BONUS 61
2872 #define EC_OK_WORTHLESS 62
2873 #define EC_OK_ARTIFACT 63
2874 #define EC_OK_EGO 64
2875 #define EC_OK_NAMELESS 65
2876 #define EC_OK_WANTED 66
2877 #define EC_OK_UNIQUE 67
2878 #define EC_OK_HUMAN 68
2879 #define EC_OK_UNREADABLE 69
2880 #define EC_OK_REALM1 70
2881 #define EC_OK_REALM2 71
2882 #define EC_OK_FIRST 72
2883 #define EC_OK_SECOND 73
2884 #define EC_OK_THIRD 74
2885 #define EC_OK_FOURTH 75
2892 } command_menu_type;
2895 command_menu_type menu_data[] =
2897 {0, KTRL('q'), EC_QUIT},
2898 {0, KTRL('z'), EC_REVERT},
2902 {1, KTRL('b'), EC_LEFT},
2903 {1, KTRL('n'), EC_DOWN},
2904 {1, KTRL('p'), EC_UP},
2905 {1, KTRL('f'), EC_RIGHT},
2906 {1, KTRL('a'), EC_BOL},
2907 {1, KTRL('e'), EC_EOL},
2908 {1, KTRL('o'), EC_PGUP},
2909 {1, KTRL('l'), EC_PGDOWN},
2910 {1, KTRL('y'), EC_TOP},
2911 {1, KTRL('u'), EC_BOTTOM},
2914 {1, KTRL('x'), EC_CUT},
2915 {1, KTRL('c'), EC_COPY},
2916 {1, KTRL('v'), EC_PASTE},
2917 {1, KTRL('g'), EC_BLOCK},
2918 {1, KTRL('k'), EC_KILL_LINE},
2919 {1, KTRL('d'), EC_DELETE_CHAR},
2920 {1, KTRL('h'), EC_BACKSPACE},
2921 {1, KTRL('j'), EC_RETURN},
2922 {1, KTRL('m'), EC_RETURN},
2925 {1, KTRL('s'), EC_SEARCH_STR},
2926 {1, -1, EC_SEARCH_FORW},
2927 {1, KTRL('r'), EC_SEARCH_BACK},
2928 {1, -1, EC_SEARCH_OBJ},
2929 {1, -1, EC_SEARCH_DESTROYED},
2932 {1, KTRL('i'), EC_INSERT_OBJECT},
2933 {1, -1, EC_INSERT_DESTROYED},
2934 {1, -1, EC_INSERT_BLOCK},
2935 {1, -1, EC_INSERT_MACRO},
2936 {1, -1, EC_INSERT_KEYMAP},
2939 {1, -1, EC_CL_AUTOPICK},
2940 {1, -1, EC_CL_DESTROY},
2941 {1, -1, EC_CL_LEAVE},
2942 {1, -1, EC_CL_QUERY},
2943 {1, -1, EC_CL_NO_DISP},
2946 {1, -1, EC_IK_UNAWARE},
2947 {1, -1, EC_IK_UNIDENTIFIED},
2948 {1, -1, EC_IK_IDENTIFIED},
2949 {1, -1, EC_IK_STAR_IDENTIFIED},
2952 {1, -1, EC_KK_WEAPONS},
2953 {1, -1, EC_KK_FAVORITE},
2954 {1, -1, EC_KK_ARMORS},
2955 {1, -1, EC_KK_MISSILES},
2956 {1, -1, EC_KK_DEVICES},
2957 {1, -1, EC_KK_LIGHTS},
2958 {1, -1, EC_KK_JUNKS},
2959 {1, -1, EC_KK_SPELLBOOKS},
2960 {1, -1, EC_KK_SHIELDS},
2961 {1, -1, EC_KK_BOWS},
2962 {1, -1, EC_KK_RINGS},
2963 {1, -1, EC_KK_AMULETS},
2964 {1, -1, EC_KK_SUITS},
2965 {1, -1, EC_KK_CLOAKS},
2966 {1, -1, EC_KK_HELMS},
2967 {1, -1, EC_KK_GLOVES},
2968 {1, -1, EC_KK_BOOTS},
2971 {1, -1, EC_OK_COLLECTING},
2972 {1, -1, EC_OK_BOOSTED},
2973 {1, -1, EC_OK_MORE_THAN},
2974 {1, -1, EC_OK_MORE_BONUS},
2975 {1, -1, EC_OK_WORTHLESS},
2976 {1, -1, EC_OK_ARTIFACT},
2978 {1, -1, EC_OK_NAMELESS},
2979 {1, -1, EC_OK_WANTED},
2980 {1, -1, EC_OK_UNIQUE},
2981 {1, -1, EC_OK_HUMAN},
2982 {1, -1, EC_OK_UNREADABLE},
2983 {1, -1, EC_OK_REALM1},
2984 {1, -1, EC_OK_REALM2},
2985 {1, -1, EC_OK_FIRST},
2986 {1, -1, EC_OK_SECOND},
2987 {1, -1, EC_OK_THIRD},
2988 {1, -1, EC_OK_FOURTH},
3028 "¥¢¥¤¥Æ¥à¤òÁªÂò¤·¤Æ¸¡º÷",
3029 "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Ç¸¡º÷",
3032 "ÁªÂò¤·¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ",
3033 "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ",
3034 "¾ò·ïʬ´ô¥Ö¥í¥Ã¥¯¤ÎÎã¤òÁÞÆþ",
3036 "¥¡¼¥Þ¥Ã¥×ÄêµÁ¤òÁÞÆþ",
3038 "½¦¤¤/Ç˲õ/ÊüÃÖ¤ÎÁªÂò",
3042 "¡Ö;¡× (³Îǧ¤·¤Æ½¦¤¦)",
3043 "¡Ö(¡× (¥Þ¥Ã¥×¥³¥Þ¥ó¥É¤Çɽ¼¨¤·¤Ê¤¤)",
3045 "¼±Ê̾õÂÖ¥¡¼¥ï¡¼¥É",
3051 "¥¡¼¥ï¡¼¥É (̾»ì)",
3070 "¥¡¼¥ï¡¼¥É (·ÁÍÆ»ì)",
3072 "¥À¥¤¥¹Ìܤΰ㤦 (Éð´ï)",
3073 "¥À¥¤¥¹ÌÜ # °Ê¾å¤Î (Éð´ï)",
3080 "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î",
3082 "Æɤá¤Ê¤¤ (ËâË¡½ñ)",
3083 "Âè°ìÎΰè¤Î (ËâË¡½ñ)",
3084 "ÂèÆóÎΰè¤Î (ËâË¡½ñ)",
3093 "Revert all changes",
3101 "Beggining of line",
3113 "Kill rest of line",
3123 "Search by inventory object",
3124 "Search by destroyed object",
3127 "Insert name of choosen object",
3128 "Insert name of destroyed object",
3129 "Insert conditional block",
3130 "Insert a macro definition",
3131 "Insert a keymap definition",
3135 "'!' (Auto destroy)",
3136 "'~' (Leave it on the floor)",
3137 "';' (Query to pick up)",
3138 "'(' (No display on the large map)",
3165 "Keywords (adjective)",
3167 "dice boosted (weapons)",
3168 "more than # dice (weapons)",
3169 "more bonus than #",
3173 "nameless (equipments)",
3177 "unreadable (spellbooks)",
3178 "realm1 (spellbooks)",
3179 "realm2 (spellbooks)",
3180 "first (spellbooks)",
3181 "second (spellbooks)",
3182 "third (spellbooks)",
3183 "fourth (spellbooks)",
3189 * Find a command by 'key'.
3191 static int get_com_id(char key)
3195 for (i = 0; menu_name[i]; i++)
3197 if (menu_data[i].key == key)
3199 return menu_data[i].com_id;
3208 * Display the menu, and get a command
3210 static int do_command_menu(int level, int start)
3215 int col0 = 5 + level*4;
3216 int row0 = 1 + level*2;
3218 int menu_id_list[26];
3220 char linestr[MAX_LINELEN];
3222 /* Get max length */
3224 for (i = start; menu_data[i].level >= level; i++)
3228 /* Ignore lower level sub menus */
3229 if (menu_data[i].level > level) continue;
3231 len = strlen(menu_name[i]);
3232 if (len > max_len) max_len = len;
3234 menu_id_list[menu_key] = i;
3238 while (menu_key < 26)
3240 menu_id_list[menu_key] = -1;
3244 /* Extra space for displaying menu key and command key */
3245 max_menu_wid = max_len + 3 + 3;
3247 /* Prepare box line */
3249 strcat(linestr, "+");
3250 for (i = 0; i < max_menu_wid + 2; i++)
3252 strcat(linestr, "-");
3254 strcat(linestr, "+");
3264 int row1 = row0 + 1;
3267 Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
3269 /* Draw menu items */
3271 for (i = start; menu_data[i].level >= level; i++)
3273 char com_key_str[3];
3276 /* Ignore lower level sub menus */
3277 if (menu_data[i].level > level) continue;
3279 if (menu_data[i].com_id == -1)
3282 strcpy(com_key_str, "¢§");
3284 strcpy(com_key_str, ">");
3287 else if (menu_data[i].key != -1)
3289 com_key_str[0] = '^';
3290 com_key_str[1] = menu_data[i].key + '@';
3291 com_key_str[2] = '\0';
3295 com_key_str[0] = '\0';
3298 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_name[i], com_key_str);
3300 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
3305 /* Draw bottom line */
3306 Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
3308 /* The menu was shown */
3311 prt(format("(a-%c) ¥³¥Þ¥ó¥É:", menu_key + 'a' - 1), 0, 0);
3314 if (key == ESCAPE) return 0;
3316 if ('a' <= key && key <= 'z')
3318 menu_id = menu_id_list[key - 'a'];
3322 com_id = menu_data[menu_id].com_id;
3326 com_id = do_command_menu(level + 1, menu_id + 1);
3327 if (com_id) return com_id;
3339 com_id = get_com_id(key);
3340 if (com_id) return com_id;
3347 static chain_str_type *new_chain_str(cptr str)
3349 chain_str_type *chain;
3351 size_t len = strlen(str);
3353 chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
3355 strcpy(chain->s, str);
3362 static void kill_yank_chain(text_body_type *tb)
3364 chain_str_type *chain = tb->yank;
3369 chain_str_type *next = chain->next;
3370 size_t len = strlen(chain->s);
3372 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
3379 static void add_str_to_yank(text_body_type *tb, cptr str)
3381 chain_str_type *chain;
3383 tb->yank_eol = FALSE;
3385 if (NULL == tb->yank)
3387 tb->yank = new_chain_str(str);
3397 chain->next = new_chain_str(str);
3402 chain = chain->next;
3407 #define DESCRIPT_HGT 3
3412 static void draw_text_editor(text_body_type *tb)
3415 int by1 = -1, bx1 = -1, by2 = -1, bx2 = -1;
3418 Term_get_size(&tb->wid, &tb->hgt);
3421 * Top line (-1), description line (-3), separator (-1)
3424 tb->hgt -= 2 + DESCRIPT_HGT;
3427 /* Don't let cursor at second byte of kanji */
3428 for (i = 0; tb->lines_list[tb->cy][i]; i++)
3429 if (iskanji(tb->lines_list[tb->cy][i]))
3440 /* Scroll if necessary */
3441 if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
3442 tb->upper = tb->cy - (tb->hgt)/2;
3445 if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
3446 tb->left = tb->cx - (tb->wid)*2/3;
3450 /* Redraw whole window after resize */
3451 if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
3452 tb->dirty_flags |= DIRTY_SCREEN;
3454 /* Redraw all text after scroll */
3455 else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
3456 tb->dirty_flags |= DIRTY_ALL;
3459 if (tb->dirty_flags & DIRTY_SCREEN)
3461 tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
3467 /* Redraw mode line */
3468 if (tb->dirty_flags & DIRTY_MODE)
3470 char buf[MAX_LINELEN];
3472 int sepa_length = tb->wid;
3475 for (i = 0; i < sepa_length; i++)
3479 Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
3484 /* Correct cursor location */
3485 int tmp_cx = MIN(tb->cx, (int)strlen(tb->lines_list[tb->cy]));
3487 tb->dirty_flags |= DIRTY_ALL;
3489 if (tb->my < tb->cy ||
3490 (tb->my == tb->cy && tb->mx < tmp_cx))
3506 /* Dump up to tb->hgt lines of messages */
3507 for (i = 0; i < tb->hgt; i++)
3512 int y = tb->upper+i;
3514 /* clean or dirty? */
3515 if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
3518 msg = tb->lines_list[y];
3521 /* Apply horizontal scroll */
3522 for (j = 0; *msg; msg++, j++)
3524 if (j == tb->left) break;
3540 Term_erase(0, i + 1, tb->wid);
3544 /* Dump the messages, bottom to top */
3545 Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_WHITE, msg);
3550 int x0 = leftcol + tb->left;
3555 if (by1 <= y && y < by2) sx1 = strlen(msg);
3556 if (y == by1) sx0 = bx1;
3557 if (y == by2) sx1 = bx2;
3559 Term_gotoxy(leftcol, i + 1);
3560 if (x0 < sx0) Term_addstr(sx0 - x0, TERM_WHITE, msg);
3561 if (x0 < sx1) Term_addstr(sx1 - sx0, TERM_YELLOW, msg + (sx0 - x0));
3562 Term_addstr(-1, TERM_WHITE, msg + (sx1 - x0));
3566 for (; i < tb->hgt; i++)
3569 Term_erase(0, i + 1, tb->wid);
3572 /* Display information when updated */
3573 if (tb->old_cy != tb->cy || (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || tb->dirty_line == tb->cy)
3575 autopick_type an_entry, *entry = &an_entry;
3577 /* Clear information line */
3578 for (i = 0; i < DESCRIPT_HGT; i++)
3581 Term_erase(0, tb->hgt + 2 + i, tb->wid);
3584 /* Display information */
3585 if (tb->dirty_flags & DIRTY_NOT_FOUND)
3588 prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3590 prt(format("Pattern not found: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3593 else if (tb->dirty_flags & DIRTY_NO_SEARCH)
3596 prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", tb->hgt + 1 + 1, 0);
3598 prt("No pattern to search. (Press '/' to search.)", tb->hgt +1 + 1, 0);
3601 else if (tb->lines_list[tb->cy][0] == '#')
3604 prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3606 prt("This line is a comment.", tb->hgt +1 + 1, 0);
3609 else if (tb->lines_list[tb->cy][1] == ':')
3611 switch(tb->lines_list[tb->cy][0])
3615 prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3617 prt("This line is a Conditional Expression.", tb->hgt +1 + 1, 0);
3622 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3624 prt("This line defines a Macro action.", tb->hgt +1 + 1, 0);
3629 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3631 prt("This line defines a Macro trigger key.", tb->hgt +1 + 1, 0);
3636 prt("¤³¤Î¹Ô¤Ï¥¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3638 prt("This line defines a Keymap.", tb->hgt +1 + 1, 0);
3644 /* Get description of an autopicker preference line */
3645 else if (autopick_new_entry(entry, tb->lines_list[tb->cy]))
3647 char buf[MAX_LINELEN];
3648 char temp[MAX_LINELEN];
3651 describe_autopick(buf, entry);
3653 roff_to_buf(buf, 81, temp, sizeof(temp));
3655 for (i = 0; i < 3; i++)
3661 prt(t, tb->hgt +1 + 1 + i, 0);
3665 autopick_free_entry(entry);
3672 * Kill segment of a line
3674 static void kill_line_segment(text_body_type *tb, int y, int x0, int x1)
3676 char buf[MAX_LINELEN];
3677 cptr s = tb->lines_list[y];
3682 if (x0 == x1) return;
3684 /* Kill whole line? */
3685 if (x0 == 0 && s[x1] == '\0')
3689 string_free(tb->lines_list[y]);
3691 /* Shift lines up */
3692 for (i = y; tb->lines_list[i+1]; i++)
3693 tb->lines_list[i] = tb->lines_list[i+1];
3694 tb->lines_list[i] = NULL;
3699 /* Before the segment */
3700 for (x = 0; x < x0; x++)
3703 /* After the segment */
3704 for (x = x1; s[x]; x++)
3710 string_free(tb->lines_list[y]);
3711 tb->lines_list[y] = string_make(buf);
3716 * Kill text in the block selection
3718 static bool kill_text_in_selection(text_body_type *tb, bool force)
3720 int by1, bx1, by2, bx2;
3723 if (!force && tb->mark == -1)
3725 /* Don't kill auto selection block (by paste) */
3729 tb->dirty_flags |= DIRTY_ALL;
3734 /* Correct cursor location */
3735 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
3736 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
3738 if (tb->my < tb->cy ||
3739 (tb->my == tb->cy && tb->mx < tb->cx))
3754 /* Kill lines in reverse order */
3755 for (y = by2; y >= by1; y--)
3758 int x1 = strlen(tb->lines_list[y]);
3760 if (y == by1) x0 = bx1;
3761 if (y == by2) x1 = bx2;
3763 kill_line_segment(tb, y, x0, x1);
3766 /* Correct cursor position */
3770 /* Disable selection */
3774 tb->dirty_flags |= DIRTY_ALL;
3781 * Get a trigger key and insert ASCII string for the trigger
3783 static bool insert_macro_line(cptr *lines_list, int cy)
3792 /* Do not process macros */
3798 /* Read the pattern */
3804 /* Do not process macros */
3807 /* Do not wait for keys */
3810 /* Attempt to read a key */
3820 /* Convert the trigger */
3821 ascii_to_text(tmp, buf);
3824 if(!tmp[0]) return FALSE;
3826 /* Insert preference string */
3827 insert_return_code(lines_list, 0, cy);
3828 string_free(lines_list[cy]);
3829 lines_list[cy] = string_make(format("P:%s", tmp));
3831 /* Acquire action */
3832 i = macro_find_exact(buf);
3836 /* Nothing defined */
3841 /* Analyze the current action */
3842 ascii_to_text(tmp, macro__act[i]);
3845 /* Insert blank action preference line */
3846 insert_return_code(lines_list, 0, cy);
3847 string_free(lines_list[cy]);
3848 lines_list[cy] = string_make(format("A:%s", tmp));
3855 * Get a command key and insert ASCII string for the key
3857 static bool insert_keymap_line(cptr *lines_list, int cy)
3865 if (rogue_like_commands)
3867 mode = KEYMAP_MODE_ROGUE;
3873 mode = KEYMAP_MODE_ORIG;
3886 /* Convert the trigger */
3887 ascii_to_text(tmp, buf);
3890 if(!tmp[0]) return FALSE;
3892 /* Insert preference string */
3893 insert_return_code(lines_list, 0, cy);
3894 string_free(lines_list[cy]);
3895 lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
3897 /* Look up the keymap */
3898 act = keymap_act[mode][(byte)(buf[0])];
3900 /* Insert blank action preference line */
3901 insert_return_code(lines_list, 0, cy);
3902 string_free(lines_list[cy]);
3903 lines_list[cy] = string_make(format("A:%s", act));
3910 * Execute a single editor command
3912 static bool do_editor_command(text_body_type *tb, int com_id)
3920 /* Revert to original */
3922 if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© ")) break;
3924 if (!get_check("Discard all changes and revert to original file. Are you sure? ")) break;
3927 free_text_lines(tb->lines_list);
3928 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
3929 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE;
3930 tb->cx = tb->cy = 0;
3935 /* Peruse the main help file */
3937 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
3939 (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
3942 tb->dirty_flags |= DIRTY_SCREEN;
3947 /* Split a line or insert end of line */
3950 * If there is a selection, kill it, and replace it
3953 if (tb->mark) kill_text_in_selection(tb, FALSE);
3955 insert_return_code(tb->lines_list, tb->cx, tb->cy);
3960 tb->dirty_flags |= DIRTY_ALL;
3970 len = strlen(tb->lines_list[tb->cy]);
3971 if (len < tb->cx) tb->cx = len;
3973 else if (tb->cy > 0)
3976 tb->cx = strlen(tb->lines_list[tb->cy]);
3982 if (tb->lines_list[tb->cy + 1]) tb->cy++;
3987 if (tb->cy > 0) tb->cy--;
3996 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
3999 len = strlen(tb->lines_list[tb->cy]);
4002 if (tb->lines_list[tb->cy + 1])
4014 /* Beginning of line */
4020 tb->cx = strlen(tb->lines_list[tb->cy]);
4024 while (0 < tb->cy && tb->upper <= tb->cy)
4026 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
4032 while (tb->cy < tb->upper + tb->hgt && tb->lines_list[tb->cy + 1])
4042 while (tb->lines_list[tb->cy + 1])
4048 /* Need block selection */
4049 if (!tb->mark) break;
4051 /* Copy the text first */
4052 do_editor_command(tb, EC_COPY);
4055 kill_text_in_selection(tb, TRUE);
4062 int by1, bx1, by2, bx2;
4065 /* Need block selection */
4066 if (!tb->mark) break;
4068 /* Correct cursor location */
4069 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4070 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4072 if (tb->my < tb->cy ||
4073 (tb->my == tb->cy && tb->mx < tb->cx))
4088 /* Kill old yank buffer */
4089 kill_yank_chain(tb);
4091 /* Copy string to yank buffer */
4092 for (y = by1; y <= by2; y++)
4095 char buf[MAX_LINELEN];
4098 int x1 = strlen(tb->lines_list[y]);
4100 if (y == by1) x0 = bx1;
4101 if (y == by2) x1 = bx2;
4103 for (i = 0; i < x1 - x0; i++)
4105 buf[i] = tb->lines_list[y][x0 + i];
4109 add_str_to_yank(tb, buf);
4112 /* Disable selection */
4116 tb->dirty_flags |= DIRTY_ALL;
4122 /* Paste killed text */
4124 chain_str_type *chain = tb->yank;
4126 /* Nothing to do? */
4129 /* Correct cursor location */
4130 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4131 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4134 * If there is a selection, kill text, and
4135 * replace it with the yank text.
4137 if (tb->mark) kill_text_in_selection(tb, FALSE);
4139 /* Auto select pasted text */
4147 cptr yank_str = chain->s;
4149 char buf[MAX_LINELEN];
4151 char rest[MAX_LINELEN], *rest_ptr = rest;
4153 /* Save preceding string */
4154 for(i = 0; i < tb->cx; i++)
4155 buf[i] = tb->lines_list[tb->cy][i];
4157 strcpy(rest, &(tb->lines_list[tb->cy][i]));
4159 /* Paste yank buffer */
4160 while (*yank_str && i < MAX_LINELEN-1)
4162 buf[i++] = *yank_str++;
4168 chain = chain->next;
4170 if (chain || tb->yank_eol)
4172 /* There is an end of line between chain nodes */
4174 insert_return_code(tb->lines_list, tb->cx, tb->cy);
4176 /* Replace this line with new one */
4177 string_free(tb->lines_list[tb->cy]);
4178 tb->lines_list[tb->cy] = string_make(buf);
4180 /* Move to next line */
4187 /* Final line doesn't have end of line */
4189 tb->cx = strlen(buf);
4191 /* Rest of original line */
4192 while (*rest_ptr && i < MAX_LINELEN-1)
4194 buf[i++] = *rest_ptr++;
4200 /* Replace this line with new one */
4201 string_free(tb->lines_list[tb->cy]);
4202 tb->lines_list[tb->cy] = string_make(buf);
4209 tb->dirty_flags |= DIRTY_ALL;
4216 /* Disable the selection */
4220 tb->dirty_flags |= DIRTY_ALL;
4226 /* Repeating this command swaps cursor position */
4227 if (com_id == tb->old_com_id)
4239 tb->dirty_flags |= DIRTY_ALL;
4243 /* Mark the point 1 */
4252 /* Kill rest of line */
4255 char buf[MAX_LINELEN];
4258 /* If there is a selection, kill it */
4261 if (kill_text_in_selection(tb, FALSE)) break;
4264 /* Correct cursor location */
4265 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4266 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4268 /* Save preceding string */
4269 for (i = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4272 if (iskanji(tb->lines_list[tb->cy][i]))
4274 buf[i] = tb->lines_list[tb->cy][i];
4278 buf[i] = tb->lines_list[tb->cy][i];
4281 line = string_make(buf);
4283 /* Append only if this command is repeated. */
4284 if (tb->old_com_id != com_id)
4286 kill_yank_chain(tb);
4290 /* Really deleted some text */
4291 if (strlen(tb->lines_list[tb->cy] + i))
4293 /* Add deleted string to yank buffer */
4294 add_str_to_yank(tb, tb->lines_list[tb->cy] + i);
4296 /* Replace current line with 'preceding string' */
4297 string_free(tb->lines_list[tb->cy]);
4298 tb->lines_list[tb->cy] = line;
4301 tb->dirty_line = tb->cy;
4303 /* Leave end of line character */
4307 /* Delete the end of line character only */
4308 if (tb->yank_eol) add_str_to_yank(tb, "");
4309 else tb->yank_eol = TRUE;
4311 do_editor_command(tb, EC_DELETE_CHAR);
4315 case EC_DELETE_CHAR:
4316 /* DELETE == go forward + BACK SPACE */
4318 /* If there is a selection, kill it */
4321 if (kill_text_in_selection(tb, FALSE)) break;
4325 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4329 do_editor_command(tb, EC_BACKSPACE);
4337 char buf[MAX_LINELEN];
4339 /* If there is a selection, kill it */
4342 if (kill_text_in_selection(tb, FALSE)) break;
4345 len = strlen(tb->lines_list[tb->cy]);
4348 if (tb->lines_list[tb->cy + 1])
4362 /* delete a return code and union two lines */
4363 if (tb->cy == 0) break;
4364 tb->cx = strlen(tb->lines_list[tb->cy-1]);
4365 strcpy(buf, tb->lines_list[tb->cy-1]);
4366 strcat(buf, tb->lines_list[tb->cy]);
4367 string_free(tb->lines_list[tb->cy-1]);
4368 string_free(tb->lines_list[tb->cy]);
4369 tb->lines_list[tb->cy-1] = string_make(buf);
4370 for (i = tb->cy; tb->lines_list[i+1]; i++)
4371 tb->lines_list[i] = tb->lines_list[i+1];
4372 tb->lines_list[i] = NULL;
4376 tb->dirty_flags |= DIRTY_ALL;
4380 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4384 if (iskanji(tb->lines_list[tb->cy][i]))
4385 buf[j++] = tb->lines_list[tb->cy][i++];
4387 buf[j++] = tb->lines_list[tb->cy][i];
4394 for (; tb->lines_list[tb->cy][i]; i++)
4395 buf[j++] = tb->lines_list[tb->cy][i];
4397 string_free(tb->lines_list[tb->cy]);
4398 tb->lines_list[tb->cy] = string_make(buf);
4401 tb->dirty_line = tb->cy;
4409 /* Become dirty because of item/equip menu */
4410 tb->dirty_flags |= DIRTY_SCREEN;
4412 search_dir = get_string_for_search(&tb->search_o_ptr, &tb->search_str);
4414 if (!search_dir) break;
4416 if (search_dir == 1) do_editor_command(tb, EC_SEARCH_FORW);
4417 else do_editor_command(tb, EC_SEARCH_BACK);
4421 case EC_SEARCH_FORW:
4422 if (tb->search_o_ptr)
4424 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4426 else if (tb->search_str)
4428 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4432 tb->dirty_flags |= DIRTY_NO_SEARCH;
4436 case EC_SEARCH_BACK:
4437 if (tb->search_o_ptr)
4439 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4441 else if (tb->search_str)
4443 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4447 tb->dirty_flags |= DIRTY_NO_SEARCH;
4452 /* Become dirty because of item/equip menu */
4453 tb->dirty_flags |= DIRTY_SCREEN;
4455 if (!get_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4457 do_editor_command(tb, EC_SEARCH_FORW);
4460 case EC_SEARCH_DESTROYED:
4461 if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4463 do_editor_command(tb, EC_SEARCH_FORW);
4466 case EC_INSERT_OBJECT:
4468 /* Insert choosen item name */
4470 autopick_type an_entry, *entry = &an_entry;
4472 if (!entry_from_choosed_object(entry))
4474 /* Now dirty because of item/equip menu */
4475 tb->dirty_flags |= DIRTY_SCREEN;
4479 insert_return_code(tb->lines_list, 0, tb->cy);
4480 string_free(tb->lines_list[tb->cy]);
4481 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4484 /* Now dirty because of item/equip menu */
4485 tb->dirty_flags |= DIRTY_SCREEN;
4490 case EC_INSERT_DESTROYED:
4491 /* Insert a name of last destroyed item */
4492 if (tb->last_destroyed)
4494 insert_return_code(tb->lines_list, 0, tb->cy);
4495 string_free(tb->lines_list[tb->cy]);
4496 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
4500 tb->dirty_flags |= DIRTY_ALL;
4504 case EC_INSERT_BLOCK:
4506 /* Insert a conditinal expression line */
4509 /* Conditional Expression for Class and Race */
4510 sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]",
4512 rp_ptr->E_title, cp_ptr->E_title
4514 rp_ptr->title, cp_ptr->title
4518 insert_return_code(tb->lines_list, 0, tb->cy);
4519 string_free(tb->lines_list[tb->cy]);
4520 tb->lines_list[tb->cy] = string_make(classrace);
4522 insert_return_code(tb->lines_list, 0, tb->cy);
4523 string_free(tb->lines_list[tb->cy]);
4524 tb->lines_list[tb->cy] = string_make("?:1");
4528 tb->dirty_flags |= DIRTY_ALL;
4532 case EC_INSERT_MACRO:
4533 /* Draw_everythig (delete menu) */
4534 draw_text_editor(tb);
4537 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4541 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥¡¼>: ");
4543 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<Trigger key>: ");
4545 if (insert_macro_line(tb->lines_list, tb->cy))
4547 /* Prepare to input action */
4551 tb->dirty_flags |= DIRTY_ALL;
4552 tb->dirty_flags |= DIRTY_MODE;
4557 case EC_INSERT_KEYMAP:
4558 /* Draw_everythig (delete menu) */
4559 draw_text_editor(tb);
4562 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4566 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)));
4568 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)));
4571 if (insert_keymap_line(tb->lines_list, tb->cy))
4573 /* Prepare to input action */
4577 tb->dirty_flags |= DIRTY_ALL;
4578 tb->dirty_flags |= DIRTY_MODE;
4582 case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
4583 case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
4584 case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
4585 case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
4586 case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
4588 case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
4589 case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
4590 case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
4591 case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
4592 case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
4593 case EC_KK_FAVORITE: toggle_keyword(tb, FLG_FAVORITE); break;
4594 case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
4595 case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
4596 case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
4597 case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
4598 case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
4599 case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
4600 case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
4601 case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
4602 case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
4603 case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
4604 case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
4605 case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
4606 case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
4607 case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
4608 case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
4609 case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
4610 case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
4611 case EC_OK_MORE_THAN: toggle_keyword(tb, FLG_MORE_THAN); break;
4612 case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
4613 case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
4614 case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
4615 case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
4616 case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
4617 case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
4618 case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
4619 case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
4620 case EC_OK_UNREADABLE:
4621 toggle_keyword(tb, FLG_UNREADABLE);
4622 add_keyword(tb, FLG_SPELLBOOKS);
4625 toggle_keyword(tb, FLG_REALM1);
4626 add_keyword(tb, FLG_SPELLBOOKS);
4629 toggle_keyword(tb, FLG_REALM2);
4630 add_keyword(tb, FLG_SPELLBOOKS);
4633 toggle_keyword(tb, FLG_FIRST);
4634 add_keyword(tb, FLG_SPELLBOOKS);
4637 toggle_keyword(tb, FLG_SECOND);
4638 add_keyword(tb, FLG_SPELLBOOKS);
4641 toggle_keyword(tb, FLG_THIRD);
4642 add_keyword(tb, FLG_SPELLBOOKS);
4645 toggle_keyword(tb, FLG_FOURTH);
4646 add_keyword(tb, FLG_SPELLBOOKS);
4650 /* Save old command */
4651 tb->old_com_id = com_id;
4658 * Insert single letter at cursor position.
4660 static void insert_single_letter(text_body_type *tb, int key)
4663 char buf[MAX_LINELEN];
4665 /* Save preceding string */
4666 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4667 buf[j++] = tb->lines_list[tb->cy][i];
4669 /* Add a character */
4677 if (j+2 < MAX_LINELEN)
4689 if (j+1 < MAX_LINELEN)
4695 for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
4696 buf[j++] = tb->lines_list[tb->cy][i];
4699 /* Replace current line with new line */
4700 string_free(tb->lines_list[tb->cy]);
4701 tb->lines_list[tb->cy] = string_make(buf);
4703 /* Move to correct collumn */
4704 len = strlen(tb->lines_list[tb->cy]);
4705 if (len < tb->cx) tb->cx = len;
4708 tb->dirty_line = tb->cy;
4712 * In-game editor of Object Auto-picker/Destoryer
4714 void do_cmd_edit_autopick(void)
4716 text_body_type text_body, *tb = &text_body;
4718 autopick_type an_entry, *entry = &an_entry;
4719 char buf[MAX_LINELEN];
4724 static s32b old_autosave_turn = 0L;
4727 tb->cx = tb->cy = tb->upper = tb->left = 0;
4729 tb->mx = tb->my = 0;
4730 tb->old_cy = tb->old_upper = tb->old_left = -1;
4731 tb->old_wid = tb->old_hgt = -1;
4735 tb->search_o_ptr = NULL;
4736 tb->search_str = NULL;
4737 tb->last_destroyed = NULL;
4738 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE;
4739 tb->dirty_line = -1;
4740 tb->filename_mode = PT_WITH_PNAME;
4743 if (turn > old_autosave_turn + 100L)
4745 do_cmd_save_game(TRUE);
4746 old_autosave_turn = turn;
4749 /* HACK -- Reset start_time to stop counting playtime while edit */
4752 /* Free old entries */
4755 /* Command Description of the 'Last Destroyed Item' */
4756 if (autopick_last_destroyed_object.k_idx)
4758 autopick_entry_from_object(entry, &autopick_last_destroyed_object);
4759 tb->last_destroyed = autopick_line_from_entry_kill(entry);
4762 /* Read or initialize whole text */
4763 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
4765 /* Reset cursor position if needed */
4766 for (i = 0; i < tb->cy; i++)
4768 if (!tb->lines_list[i])
4770 tb->cy = tb->cx = 0;
4775 /* Save the screen */
4778 /* Process requests until done */
4784 /* Draw_everythig */
4785 draw_text_editor(tb);
4787 /* Display header line */
4789 prt("(^Q:½ªÎ», ESC:¥á¥Ë¥å¡¼, ¤½¤Î¾:ÆþÎÏ)", 0, 0);
4791 prt("(^Q:quit, ESC:menu, Other:input text)", 0, 0);
4795 /* Display current position */
4796 prt (format("(%d,%d)", tb->cx, tb->cy), 0, 60);
4800 /* Display current position and mark position */
4801 prt (format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
4805 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
4808 tb->dirty_flags = 0;
4809 tb->dirty_line = -1;
4811 /* Save old key and location */
4812 tb->old_cy = tb->cy;
4813 tb->old_upper = tb->upper;
4814 tb->old_left = tb->left;
4815 tb->old_wid = tb->wid;
4816 tb->old_hgt = tb->hgt;
4821 /* Count length of macro trigger which induced this key */
4822 trig_len = strlen(inkey_macro_trigger_string);
4824 /* HACK -- ignore macro defined on ASCII keys */
4827 /* Get original key */
4828 key = inkey_macro_trigger_string[0];
4832 if (key == 0x7F) key = KTRL('d');
4835 /* Cursor key macroes to direction command */
4836 if (strlen(inkey_macro_trigger_string) > 1)
4854 /* Mega Hack!!! Start selection with shift + cursor keys */
4859 /* Get ascii form */
4860 ascii_to_text(buf, inkey_macro_trigger_string);
4862 if (strstr(buf, "shift-Down"))
4864 else if (strstr(buf, "shift-Left"))
4866 else if (strstr(buf, "shift-Right"))
4868 else if (strstr(buf, "shift-Up"))
4873 /* Kill further macro expansion */
4876 /* Start selection */
4883 /* Need to redraw text */
4884 if (com_id == EC_UP || com_id == EC_DOWN)
4887 tb->dirty_flags |= DIRTY_ALL;
4900 else if (key == ESCAPE)
4902 com_id = do_command_menu(0, 0);
4905 tb->dirty_flags |= DIRTY_SCREEN;
4908 /* Insert a character */
4909 else if (!iscntrl(key & 0xff))
4912 * If there is a selection, kill text, and
4913 * replace it with a single letter.
4915 if (tb->mark) kill_text_in_selection(tb, FALSE);
4917 insert_single_letter(tb, key);
4923 /* Other commands */
4926 com_id = get_com_id(key);
4929 if (com_id) quit = do_editor_command(tb, com_id);
4932 /* Restore the screen */
4935 switch (tb->filename_mode)
4939 strcpy(buf, "picktype.prf");
4941 strcpy(buf, "pickpref.prf");
4947 sprintf(buf, "picktype-%s.prf", player_name);
4949 sprintf(buf, "pickpref-%s.prf", player_name);
4954 write_text_lines(buf, tb->lines_list);
4955 free_text_lines(tb->lines_list);
4957 string_free(tb->last_destroyed);
4959 /* Destroy string chain */
4960 kill_yank_chain(tb);
4962 /* Reload autopick pref */
4963 process_pickpref_file(buf);
4965 /* HACK -- reset start_time so that playtime is not increase while edit */
4966 start_time = time(NULL);