OSDN Git Service

update year to 2020
[jnethack/source.git] / src / role.c
1 /* NetHack 3.6  role.c  $NHDT-Date: 1547086250 2019/01/10 02:10:50 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 /*** Table of all roles ***/
14 /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
15  * (4-sided for wizards).  But this is not AD&D, and using the AD&D
16  * rule here produces an unplayable character.  Thus I have used a minimum
17  * of an 10-sided hit die for everything.  Another AD&D change: wizards get
18  * a minimum strength of 4 since without one you can't teleport or cast
19  * spells. --KAA
20  *
21  * As the wizard has been updated (wizard patch 5 jun '96) their HD can be
22  * brought closer into line with AD&D. This forces wizards to use magic more
23  * and distance themselves from their attackers. --LSZ
24  *
25  * With the introduction of races, some hit points and energy
26  * has been reallocated for each race.  The values assigned
27  * to the roles has been reduced by the amount allocated to
28  * humans.  --KMH
29  *
30  * God names use a leading underscore to flag goddesses.
31  */
32 const struct Role roles[] = {
33 #if 0 /*JP:T*/
34     { { "Archeologist", 0 },
35       { { "Digger", 0 },
36         { "Field Worker", 0 },
37         { "Investigator", 0 },
38         { "Exhumer", 0 },
39         { "Excavator", 0 },
40         { "Spelunker", 0 },
41         { "Speleologist", 0 },
42         { "Collector", 0 },
43         { "Curator", 0 } },
44       "Quetzalcoatl", "Camaxtli", "Huhetotl", /* Central American */
45 #else
46     { { "\8dl\8cÃ\8aw\8eÒ", 0 },
47       { { "\8dz\88õ", 0 },
48         { "\98J\93­\8eÒ", 0 },
49         { "\92²\8d¸\8eÒ", 0 },
50         { "\94­\8c@\8eÒ", 0 },
51         { "\8c@\8dí\8eÒ", 0 },
52         { "\92T\8c\9f\8eÒ", 0 },
53         { "\93´\8cA\8aw\8eÒ", 0 },
54         { "\94ü\8fp\8eû\8fW\8eÒ", 0 },
55         { "\8aÙ\92·", 0 } },
56       "\83P\83c\83A\83\8b\83J\83g\83\8b", "\83J\83}\83L\83V\83g\83\8a", "\83t\83w\83g\83g\83\8b", /* Central American */
57 #endif
58       "Arc",
59 #if 0 /*JP:T*/
60       "the College of Archeology",
61       "the Tomb of the Toltec Kings",
62 #else
63       "\8dl\8cÃ\8aw\91å\8aw",
64       "\83g\83\8b\83e\83J\89¤\89Æ\82Ì\95æ",
65 #endif
66       PM_ARCHEOLOGIST,
67       NON_PM,
68       NON_PM,
69       PM_LORD_CARNARVON,
70       PM_STUDENT,
71       PM_MINION_OF_HUHETOTL,
72       NON_PM,
73       PM_HUMAN_MUMMY,
74       S_SNAKE,
75       S_MUMMY,
76       ART_ORB_OF_DETECTION,
77       MH_HUMAN | MH_DWARF | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL
78           | ROLE_NEUTRAL,
79       /* Str Int Wis Dex Con Cha */
80       { 7, 10, 10, 7, 7, 7 },
81       { 20, 20, 20, 10, 20, 10 },
82       /* Init   Lower  Higher */
83       { 11, 0, 0, 8, 1, 0 }, /* Hit points */
84       { 1, 0, 0, 1, 0, 1 },
85       14, /* Energy */
86       10,
87       5,
88       0,
89       2,
90       10,
91       A_INT,
92       SPE_MAGIC_MAPPING,
93       -4 },
94 #if 0 /*JP:T*/
95     { { "Barbarian", 0 },
96       { { "Plunderer", "Plunderess" },
97         { "Pillager", 0 },
98         { "Bandit", 0 },
99         { "Brigand", 0 },
100         { "Raider", 0 },
101         { "Reaver", 0 },
102         { "Slayer", 0 },
103         { "Chieftain", "Chieftainess" },
104         { "Conqueror", "Conqueress" } },
105       "Mitra", "Crom", "Set", /* Hyborian */
106 #else
107     { { "\96ì\94Ø\90l", 0 },
108       { { "\93\90\91¯", 0 },
109         { "\97ª\92D\8eÒ", 0 },
110         { "\88«\8a¿", 0 },
111         { "\8eR\91¯", 0 },
112         { "\90N\97ª\8eÒ", 0 },
113         { "\8b­\93\90", 0 },
114         { "\8eE\9dC\8eÒ", 0 },
115         { "\8eñ\97Ì", 0 },
116         { "\90ª\95\9e\8eÒ", 0 } },
117       "\83~\83g\83\89", "\83N\83\8d\83\80", "\83Z\83g", /* Hyborian */
118 #endif
119       "Bar",
120 #if 0 /*JP:T*/
121       "the Camp of the Duali Tribe",
122       "the Duali Oasis",
123 #else
124       "\83f\83\85\83A\83\8a\91°\82Ì\83L\83\83\83\93\83v",
125       "\83f\83\85\83A\83\8a\91°\82Ì\83I\83A\83V\83X",
126 #endif
127       PM_BARBARIAN,
128       NON_PM,
129       NON_PM,
130       PM_PELIAS,
131       PM_CHIEFTAIN,
132       PM_THOTH_AMON,
133       PM_OGRE,
134       PM_TROLL,
135       S_OGRE,
136       S_TROLL,
137       ART_HEART_OF_AHRIMAN,
138       MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL
139           | ROLE_CHAOTIC,
140       /* Str Int Wis Dex Con Cha */
141       { 16, 7, 7, 15, 16, 6 },
142       { 30, 6, 7, 20, 30, 7 },
143       /* Init   Lower  Higher */
144       { 14, 0, 0, 10, 2, 0 }, /* Hit points */
145       { 1, 0, 0, 1, 0, 1 },
146       10, /* Energy */
147       10,
148       14,
149       0,
150       0,
151       8,
152       A_INT,
153       SPE_HASTE_SELF,
154       -4 },
155 #if 0 /*JP:T*/
156     { { "Caveman", "Cavewoman" },
157       { { "Troglodyte", 0 },
158         { "Aborigine", 0 },
159         { "Wanderer", 0 },
160         { "Vagrant", 0 },
161         { "Wayfarer", 0 },
162         { "Roamer", 0 },
163         { "Nomad", 0 },
164         { "Rover", 0 },
165         { "Pioneer", 0 } },
166       "Anu", "_Ishtar", "Anshar", /* Babylonian */
167 #else
168     { { "\93´\8cA\90l", 0 },
169       { { "\8c\8a\8b\8f\90l", 0 },
170         { "\8c´\8fZ\96¯", 0 },
171         { "\95ú\98Q\8eÒ", 0 },
172         { "\95\82\98Q\8eÒ", 0 },
173         { "\97·\8ds\8eÒ", 0 },
174         { "\95ú\97V\8eÒ", 0 },
175         { "\97V\96q\96¯", 0 },
176         { "\97¬\98Q\8eÒ", 0 },
177         { "\90æ\8bì\8eÒ", 0 } },
178       "\83A\83k", "_\83C\83V\83\85\83^\83\8b", "\83A\83\93\83V\83\83\83\8b", /* Babylonian */
179 #endif
180       "Cav",
181 #if 0 /*JP:T*/
182       "the Caves of the Ancestors",
183       "the Dragon's Lair",
184 #else
185       "\91¾\8cÃ\82Ì\93´\8cA",
186       "\97³\82Ì\89B\82ê\89Æ",
187 #endif
188       PM_CAVEMAN,
189       PM_CAVEWOMAN,
190       PM_LITTLE_DOG,
191       PM_SHAMAN_KARNOV,
192       PM_NEANDERTHAL,
193       PM_CHROMATIC_DRAGON,
194       PM_BUGBEAR,
195       PM_HILL_GIANT,
196       S_HUMANOID,
197       S_GIANT,
198       ART_SCEPTRE_OF_MIGHT,
199       MH_HUMAN | MH_DWARF | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL
200           | ROLE_NEUTRAL,
201       /* Str Int Wis Dex Con Cha */
202       { 10, 7, 7, 7, 8, 6 },
203       { 30, 6, 7, 20, 30, 7 },
204       /* Init   Lower  Higher */
205       { 14, 0, 0, 8, 2, 0 }, /* Hit points */
206       { 1, 0, 0, 1, 0, 1 },
207       10, /* Energy */
208       0,
209       12,
210       0,
211       1,
212       8,
213       A_INT,
214       SPE_DIG,
215       -4 },
216 #if 0 /*JP:T*/
217     { { "Healer", 0 },
218       { { "Rhizotomist", 0 },
219         { "Empiric", 0 },
220         { "Embalmer", 0 },
221         { "Dresser", 0 },
222         { "Medicus ossium", "Medica ossium" },
223         { "Herbalist", 0 },
224         { "Magister", "Magistra" },
225         { "Physician", 0 },
226         { "Chirurgeon", 0 } },
227       "_Athena", "Hermes", "Poseidon", /* Greek */
228 #else
229     { { "\96ò\8et", 0 },
230       { { "\8c©\8fK\82¢", 0 },
231         { "\88ã\8et\8c©\8fK\82¢", 0 },
232         { "\8aÅ\8cì\8et", "\8aÅ\8cì\95w" },
233         { "\88ã\8et\8f\95\8eè", 0 },
234         { "\96ò\95¨\8eå\94C", 0 },
235         { "\8a¿\95û\88ã", 0 },
236         { "\88ã\8et\8eå\94C", 0 },
237         { "\93à\89È\88ã", 0 },
238         { "\8aO\89È\88ã", 0 } },
239       "_\83A\83e\83i", "\83w\83\8b\83\81\83X", "\83|\83Z\83C\83h\83\93", /* Greek */
240 #endif
241       "Hea",
242 #if 0 /*JP:T*/
243       "the Temple of Epidaurus",
244       "the Temple of Coeus",
245 #else
246       "\83G\83s\83_\83E\83\8d\83X\8e\9b\89@",
247       "\83R\83C\83I\83X\8e\9b\89@",
248 #endif
249       PM_HEALER,
250       NON_PM,
251       NON_PM,
252       PM_HIPPOCRATES,
253       PM_ATTENDANT,
254       PM_CYCLOPS,
255       PM_GIANT_RAT,
256       PM_SNAKE,
257       S_RODENT,
258       S_YETI,
259       ART_STAFF_OF_AESCULAPIUS,
260       MH_HUMAN | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
261       /* Str Int Wis Dex Con Cha */
262       { 7, 7, 13, 7, 11, 16 },
263       { 15, 20, 20, 15, 25, 5 },
264       /* Init   Lower  Higher */
265       { 11, 0, 0, 8, 1, 0 }, /* Hit points */
266       { 1, 4, 0, 1, 0, 2 },
267       20, /* Energy */
268       10,
269       3,
270       -3,
271       2,
272       10,
273       A_WIS,
274       SPE_CURE_SICKNESS,
275       -4 },
276 #if 0 /*JP:T*/
277     { { "Knight", 0 },
278       { { "Gallant", 0 },
279         { "Esquire", 0 },
280         { "Bachelor", 0 },
281         { "Sergeant", 0 },
282         { "Knight", 0 },
283         { "Banneret", 0 },
284         { "Chevalier", "Chevaliere" },
285         { "Seignieur", "Dame" },
286         { "Paladin", 0 } },
287       "Lugh", "_Brigit", "Manannan Mac Lir", /* Celtic */
288 #else
289     { { "\8bR\8em", 0 },
290       { { "\8c©\8fK\82¢", 0 },
291         { "\95à\95º", 0 },
292         { "\90í\8em", 0 },
293         { "\8bR\95º", 0 },
294         { "\8fd\90í\8em", 0 },
295         { "\8bR\8em", 0 },
296         { "\8fd\8bR\8em", 0 },
297         { "\8cM\8bR\8em", 0 },
298         { "\90¹\8bR\8em", 0 } },
299       "\83\8b\81[\83t", "_\83u\83\8a\83W\83b\83g", "\83}\83i\83\93\83i\83\93\81E\83}\83N\83\8a\81[\83\8b", /* Celtic */
300 #endif
301       "Kni",
302 #if 0 /*JP:T*/
303       "Camelot Castle",
304       "the Isle of Glass",
305 #else
306       "\83L\83\83\83\81\83\8d\83b\83g\8fé",
307       "\83K\83\89\83X\82Ì\93\87",
308 #endif
309       PM_KNIGHT,
310       NON_PM,
311       PM_PONY,
312       PM_KING_ARTHUR,
313       PM_PAGE,
314       PM_IXOTH,
315       PM_QUASIT,
316       PM_OCHRE_JELLY,
317       S_IMP,
318       S_JELLY,
319       ART_MAGIC_MIRROR_OF_MERLIN,
320       MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
321       /* Str Int Wis Dex Con Cha */
322       { 13, 7, 14, 8, 10, 17 },
323       { 30, 15, 15, 10, 20, 10 },
324       /* Init   Lower  Higher */
325       { 14, 0, 0, 8, 2, 0 }, /* Hit points */
326       { 1, 4, 0, 1, 0, 2 },
327       10, /* Energy */
328       10,
329       8,
330       -2,
331       0,
332       9,
333       A_WIS,
334       SPE_TURN_UNDEAD,
335       -4 },
336 #if 0 /*JP:T*/
337     { { "Monk", 0 },
338       { { "Candidate", 0 },
339         { "Novice", 0 },
340         { "Initiate", 0 },
341         { "Student of Stones", 0 },
342         { "Student of Waters", 0 },
343         { "Student of Metals", 0 },
344         { "Student of Winds", 0 },
345         { "Student of Fire", 0 },
346         { "Master", 0 } },
347       "Shan Lai Ching", "Chih Sung-tzu", "Huan Ti", /* Chinese */
348 #else
349     { { "\95\90\93¬\89Æ", 0 },
350       { { "\93ü\96å\8aó\96]\8eÒ", 0 },
351         { "\8f\89\90S\8eÒ", 0 },
352         { "\93ü\96å\8eÒ\93`", 0 },
353         { "\93y\82Ì\8fK\82¢\8eè", 0 },
354         { "\90\85\82Ì\8fK\82¢\8eè", 0 },
355         { "\8bà\82Ì\8fK\82¢\8eè", 0 },
356         { "\96Ø\82Ì\8fK\82¢\8eè", 0 },
357         { "\89Î\82Ì\8fK\82¢\8eè", 0 },
358         { "\96Æ\8b\96\8aF\93`", 0 } },
359       "\8eR\97\8b\90¸", "\90Ô\8f¼\8eq", "\89©\92é", /* Chinese */
360 #endif
361       "Mon",
362 #if 0 /*JP:T*/
363       "the Monastery of Chan-Sune",
364       "the Monastery of the Earth-Lord",
365 #else
366       "\83`\83\83\83\93\81E\83X\81[\8fC\93¹\89@",
367       "\92n\89¤\82Ì\8fC\93¹\89@",
368 #endif
369       PM_MONK,
370       NON_PM,
371       NON_PM,
372       PM_GRAND_MASTER,
373       PM_ABBOT,
374       PM_MASTER_KAEN,
375       PM_EARTH_ELEMENTAL,
376       PM_XORN,
377       S_ELEMENTAL,
378       S_XORN,
379       ART_EYES_OF_THE_OVERWORLD,
380       MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
381           | ROLE_CHAOTIC,
382       /* Str Int Wis Dex Con Cha */
383       { 10, 7, 8, 8, 7, 7 },
384       { 25, 10, 20, 20, 15, 10 },
385       /* Init   Lower  Higher */
386       { 12, 0, 0, 8, 1, 0 }, /* Hit points */
387       { 2, 2, 0, 2, 0, 2 },
388       10, /* Energy */
389       10,
390       8,
391       -2,
392       2,
393       20,
394       A_WIS,
395       SPE_RESTORE_ABILITY,
396       -4 },
397 #if 0 /*JP:T*/
398     { { "Priest", "Priestess" },
399       { { "Aspirant", 0 },
400         { "Acolyte", 0 },
401         { "Adept", 0 },
402         { "Priest", "Priestess" },
403         { "Curate", 0 },
404         { "Canon", "Canoness" },
405         { "Lama", 0 },
406         { "Patriarch", "Matriarch" },
407         { "High Priest", "High Priestess" } },
408       0, 0, 0, /* deities from a randomly chosen other role will be used */
409 #else
410     { { "\91m\97µ", "\93ò\91m" },
411       { { "\8fC\93¹\8eÒ", "\8fC\93¹\8f\97" },
412         { "\8e\98\8eÒ", 0 },
413         { "\8e\98\8dÕ", 0 },
414         { "\91m\97µ", "\93ò\91m" },
415         { "\8f\95\94C\8ei\8dÕ", 0 },
416         { "\90¹\8eÒ", "\90¹\8f\97" },
417         { "\8ei\8b³", 0 },
418         { "\91å\8ei\8b³", 0 },
419         { "\91å\91m\8fã", 0 } },
420       0, 0, 0, /* deities from a randomly chosen other role will be used */
421 #endif
422       "Pri",
423 #if 0 /*JP:T*/
424       "the Great Temple",
425       "the Temple of Nalzok",
426 #else
427       "\88Ì\91å\82È\82é\8e\9b\89@",
428       "\83i\83\8b\83]\83N\8e\9b\89@",
429 #endif
430       PM_PRIEST,
431       PM_PRIESTESS,
432       NON_PM,
433       PM_ARCH_PRIEST,
434       PM_ACOLYTE,
435       PM_NALZOK,
436       PM_HUMAN_ZOMBIE,
437       PM_WRAITH,
438       S_ZOMBIE,
439       S_WRAITH,
440       ART_MITRE_OF_HOLINESS,
441       MH_HUMAN | MH_ELF | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
442           | ROLE_CHAOTIC,
443       /* Str Int Wis Dex Con Cha */
444       { 7, 7, 10, 7, 7, 7 },
445       { 15, 10, 30, 15, 20, 10 },
446       /* Init   Lower  Higher */
447       { 12, 0, 0, 8, 1, 0 }, /* Hit points */
448       { 4, 3, 0, 2, 0, 2 },
449       10, /* Energy */
450       0,
451       3,
452       -2,
453       2,
454       10,
455       A_WIS,
456       SPE_REMOVE_CURSE,
457       -4 },
458     /* Note:  Rogue precedes Ranger so that use of `-R' on the command line
459        retains its traditional meaning. */
460 #if 0 /*JP:T*/
461     { { "Rogue", 0 },
462       { { "Footpad", 0 },
463         { "Cutpurse", 0 },
464         { "Rogue", 0 },
465         { "Pilferer", 0 },
466         { "Robber", 0 },
467         { "Burglar", 0 },
468         { "Filcher", 0 },
469         { "Magsman", "Magswoman" },
470         { "Thief", 0 } },
471       "Issek", "Mog", "Kos", /* Nehwon */
472 #else
473     { { "\93\90\91¯", 0 },
474       { { "\92Ç\82¢\82Í\82¬", 0 },
475         { "\82Ð\82Á\82½\82­\82è", 0 },
476         { "\83X\83\8a", 0 },
477         { "\82²\82ë\82Â\82«", 0 },
478         { "\82±\82»\82Ç\82ë", 0 },
479         { "\8bó\91\83", 0 },
480         { "\93D\96_", 0 },
481         { "\8b­\93\90", 0 },
482         { "\91å\93D\96_", 0 } },
483       "\83C\83Z\83b\83N", "\83\82\83O", "\83R\83X", /* Nehwon */
484 #endif
485       "Rog",
486 #if 0 /*JP:T*/
487       "the Thieves' Guild Hall",
488       "the Assassins' Guild Hall",
489 #else
490       "\93\90\91¯\83M\83\8b\83h",
491       "\88Ã\8eE\8eÒ\83M\83\8b\83h",
492 #endif
493       PM_ROGUE,
494       NON_PM,
495       NON_PM,
496       PM_MASTER_OF_THIEVES,
497       PM_THUG,
498       PM_MASTER_ASSASSIN,
499       PM_LEPRECHAUN,
500       PM_GUARDIAN_NAGA,
501       S_NYMPH,
502       S_NAGA,
503       ART_MASTER_KEY_OF_THIEVERY,
504       MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
505       /* Str Int Wis Dex Con Cha */
506       { 7, 7, 7, 10, 7, 6 },
507       { 20, 10, 10, 30, 20, 10 },
508       /* Init   Lower  Higher */
509       { 10, 0, 0, 8, 1, 0 }, /* Hit points */
510       { 1, 0, 0, 1, 0, 1 },
511       11, /* Energy */
512       10,
513       8,
514       0,
515       1,
516       9,
517       A_INT,
518       SPE_DETECT_TREASURE,
519       -4 },
520 #if 0 /*JP:T*/
521     { { "Ranger", 0 },
522       {
523 #if 0 /* OBSOLETE */
524         {"Edhel",   "Elleth"},
525         {"Edhel",   "Elleth"},         /* elf-maid */
526         {"Ohtar",   "Ohtie"},          /* warrior */
527         {"Kano",    "Kanie"},          /* commander (Q.) ['a] educated guess,
528                                           until further research- SAC */
529         {"Arandur"," Aranduriel"}, /* king's servant, minister (Q.) - guess */
530         {"Hir",         "Hiril"},      /* lord, lady (S.) ['ir] */
531         {"Aredhel",     "Arwen"},      /* noble elf, maiden (S.) */
532         {"Ernil",       "Elentariel"}, /* prince (S.), elf-maiden (Q.) */
533         {"Elentar",     "Elentari"},   /* Star-king, -queen (Q.) */
534         "Solonor Thelandira", "Aerdrie Faenya", "Lolth", /* Elven */
535 #endif
536         { "Tenderfoot", 0 },
537         { "Lookout", 0 },
538         { "Trailblazer", 0 },
539         { "Reconnoiterer", "Reconnoiteress" },
540         { "Scout", 0 },
541         { "Arbalester", 0 }, /* One skilled at crossbows */
542         { "Archer", 0 },
543         { "Sharpshooter", 0 },
544         { "Marksman", "Markswoman" } },
545       "Mercury", "_Venus", "Mars", /* Roman/planets */
546 #else
547     { { "\83\8c\83\93\83W\83\83\81[", 0 },
548       { { "\90V\95Ä", 0 },
549         { "\8c©\92£\82è", 0 },
550         { "\90æ\93±", 0 },
551         { "\92ã\8e@", 0 },
552         { "\90Ë\8có", 0 },
553         { "\8b|\95º", 0 }, /* One skilled at crossbows */
554         { "\92\86\8b\89\8b|\95º", 0 },
555         { "\8fã\8b\89\8b|\95º", 0 },
556         { "\8fã\8b\89\8b|\95º", 0 } },
557       "\83}\81[\83L\83\85\83\8a\81[", "_\83r\81[\83i\83X", "\83}\81[\83Y", /* Roman/planets */
558 #endif
559       "Ran",
560 #if 0 /*JP:T*/
561       "Orion's camp",
562       "the cave of the wumpus",
563 #else
564       "\83I\83\8a\83I\83\93\82Ì\83L\83\83\83\93\83v",
565       "\83\8f\83\93\83p\83X\82Ì\93´\8cA",
566 #endif
567       PM_RANGER,
568       NON_PM,
569       PM_LITTLE_DOG /* Orion & canis major */,
570       PM_ORION,
571       PM_HUNTER,
572       PM_SCORPIUS,
573       PM_FOREST_CENTAUR,
574       PM_SCORPION,
575       S_CENTAUR,
576       S_SPIDER,
577       ART_LONGBOW_OF_DIANA,
578       MH_HUMAN | MH_ELF | MH_GNOME | MH_ORC | ROLE_MALE | ROLE_FEMALE
579           | ROLE_NEUTRAL | ROLE_CHAOTIC,
580       /* Str Int Wis Dex Con Cha */
581       { 13, 13, 13, 9, 13, 7 },
582       { 30, 10, 10, 20, 20, 10 },
583       /* Init   Lower  Higher */
584       { 13, 0, 0, 6, 1, 0 }, /* Hit points */
585       { 1, 0, 0, 1, 0, 1 },
586       12, /* Energy */
587       10,
588       9,
589       2,
590       1,
591       10,
592       A_INT,
593       SPE_INVISIBILITY,
594       -4 },
595 #if 0 /*JP:T*/
596     { { "Samurai", 0 },
597       { { "Hatamoto", 0 },       /* Banner Knight */
598         { "Ronin", 0 },          /* no allegiance */
599         { "Ninja", "Kunoichi" }, /* secret society */
600         { "Joshu", 0 },          /* heads a castle */
601         { "Ryoshu", 0 },         /* has a territory */
602         { "Kokushu", 0 },        /* heads a province */
603         { "Daimyo", 0 },         /* a samurai lord */
604         { "Kuge", 0 },           /* Noble of the Court */
605         { "Shogun", 0 } },       /* supreme commander, warlord */
606       "_Amaterasu Omikami", "Raijin", "Susanowo", /* Japanese */
607 #else
608     { { "\8e\98", 0 },
609       { { "\8aø\96{", 0 },       /* Banner Knight */
610         { "\98Q\90l", 0 },          /* no allegiance */
611         { "\94E\8eÒ", "\82­\83m\88ê" }, /* secret society */
612         { "\8fé\8eå", 0 },          /* heads a castle */
613         { "\97Ì\8eå", 0 },         /* has a territory */
614         { "\97Ì\8eå", 0 },        /* heads a province */
615         { "\91å\96¼", "\8d\98\8c³" },         /* a samurai lord */
616         { "\8cö\89Æ", 0 },           /* Noble of the Court */
617         { "\8cö\89Æ", "\91å\89\9c" } },       /* supreme commander, warlord */
618       "_\93V\8fÆ\91å\90_", "\97\8b\90_", "\90{\8d²\94V\92j", /* Japanese */
619 #endif
620       "Sam",
621 #if 0 /*JP:T*/
622       "the Castle of the Taro Clan",
623       "the Shogun's Castle",
624 #else
625       "\91¾\98Y\88ê\91°\82Ì\8fé",
626       "\8f«\8cR\82Ì\8fé",
627 #endif
628       PM_SAMURAI,
629       NON_PM,
630       PM_LITTLE_DOG,
631       PM_LORD_SATO,
632       PM_ROSHI,
633       PM_ASHIKAGA_TAKAUJI,
634       PM_WOLF,
635       PM_STALKER,
636       S_DOG,
637       S_ELEMENTAL,
638       ART_TSURUGI_OF_MURAMASA,
639       MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
640       /* Str Int Wis Dex Con Cha */
641       { 10, 8, 7, 10, 17, 6 },
642       { 30, 10, 8, 30, 14, 8 },
643       /* Init   Lower  Higher */
644       { 13, 0, 0, 8, 1, 0 }, /* Hit points */
645       { 1, 0, 0, 1, 0, 1 },
646       11, /* Energy */
647       10,
648       10,
649       0,
650       0,
651       8,
652       A_INT,
653       SPE_CLAIRVOYANCE,
654       -4 },
655 #if 0 /*JP:T*/
656     { { "Tourist", 0 },
657       { { "Rambler", 0 },
658         { "Sightseer", 0 },
659         { "Excursionist", 0 },
660         { "Peregrinator", "Peregrinatrix" },
661         { "Traveler", 0 },
662         { "Journeyer", 0 },
663         { "Voyager", 0 },
664         { "Explorer", 0 },
665         { "Adventurer", 0 } },
666       "Blind Io", "_The Lady", "Offler", /* Discworld */
667 #else
668     { { "\8aÏ\8cõ\8bq", 0 },
669       { { "\83v\81[\91¾\98Y", "\83v\81[\8eq" },
670         { "\8aÏ\8cõ\8bq", 0 },
671         { "\8eü\97V\97·\8ds\8eÒ", 0 },
672         { "\95Õ\97ð\8eÒ", 0 },
673         { "\97·\8ds\8eÒ", 0 },
674         { "\97·\90l", 0 },
675         { "\8dq\8aC\8eÒ", 0 },
676         { "\92T\8c\9f\89Æ", 0 },
677         { "\96`\8c¯\8eÒ", 0 } },
678       "\96Ó\96Ú\82Ì\83C\83I", "_\81\83\8f\97\90_\81\84", "\83I\83t\83\89\81[", /* Discworld */
679 #endif
680       "Tou",
681 #if 0 /*JP:T*/
682       "Ankh-Morpork",
683       "the Thieves' Guild Hall",
684 #else
685       "\83A\83\93\83N\83\82\83\8b\83|\81[\83N",
686       "\93\90\91¯\83M\83\8b\83h",
687 #endif
688       PM_TOURIST,
689       NON_PM,
690       NON_PM,
691       PM_TWOFLOWER,
692       PM_GUIDE,
693       PM_MASTER_OF_THIEVES,
694       PM_GIANT_SPIDER,
695       PM_FOREST_CENTAUR,
696       S_SPIDER,
697       S_CENTAUR,
698       ART_YENDORIAN_EXPRESS_CARD,
699       MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
700       /* Str Int Wis Dex Con Cha */
701       { 7, 10, 6, 7, 7, 10 },
702       { 15, 10, 10, 15, 30, 20 },
703       /* Init   Lower  Higher */
704       { 8, 0, 0, 8, 0, 0 }, /* Hit points */
705       { 1, 0, 0, 1, 0, 1 },
706       14, /* Energy */
707       0,
708       5,
709       1,
710       2,
711       10,
712       A_INT,
713       SPE_CHARM_MONSTER,
714       -4 },
715 #if 0 /*JP:T*/
716     { { "Valkyrie", 0 },
717       { { "Stripling", 0 },
718         { "Skirmisher", 0 },
719         { "Fighter", 0 },
720         { "Man-at-arms", "Woman-at-arms" },
721         { "Warrior", 0 },
722         { "Swashbuckler", 0 },
723         { "Hero", "Heroine" },
724         { "Champion", 0 },
725         { "Lord", "Lady" } },
726       "Tyr", "Odin", "Loki", /* Norse */
727 #else
728     { { "\83\8f\83\8b\83L\83\85\81[\83\8c", 0 },
729       { { "\8c©\8fK\82¢", 0 },
730         { "\95à\95º", 0 },
731         { "\90í\8em", 0 },
732         { "\8bR\95º", 0 },
733         { "\90í\93¬\95º", 0 },
734         { "\8dU\8c\82\95º", 0 },
735         { "\89p\97Y", 0 },
736         { "\90æ\93±\8eÒ", 0 },
737         { "\83\8d\81[\83h", "\83\8c\83f\83B" } },
738       "\83`\83\85\81[\83\8b", "\83I\81[\83f\83B\83\93", "\83\8d\83L", /* Norse */
739 #endif
740       "Val",
741 #if 0 /*JP:T*/
742       "the Shrine of Destiny",
743       "the cave of Surtur",
744 #else
745       "\89^\96½\82Ì\90¹\93°",
746       "\83X\83\8b\83g\82Ì\93´\8cA",
747 #endif
748       PM_VALKYRIE,
749       NON_PM,
750       NON_PM /*PM_WINTER_WOLF_CUB*/,
751       PM_NORN,
752       PM_WARRIOR,
753       PM_LORD_SURTUR,
754       PM_FIRE_ANT,
755       PM_FIRE_GIANT,
756       S_ANT,
757       S_GIANT,
758       ART_ORB_OF_FATE,
759       MH_HUMAN | MH_DWARF | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL,
760       /* Str Int Wis Dex Con Cha */
761       { 10, 7, 7, 7, 10, 7 },
762       { 30, 6, 7, 20, 30, 7 },
763       /* Init   Lower  Higher */
764       { 14, 0, 0, 8, 2, 0 }, /* Hit points */
765       { 1, 0, 0, 1, 0, 1 },
766       10, /* Energy */
767       0,
768       10,
769       -2,
770       0,
771       9,
772       A_WIS,
773       SPE_CONE_OF_COLD,
774       -4 },
775 #if 0 /*JP:T*/
776     { { "Wizard", 0 },
777       { { "Evoker", 0 },
778         { "Conjurer", 0 },
779         { "Thaumaturge", 0 },
780         { "Magician", 0 },
781         { "Enchanter", "Enchantress" },
782         { "Sorcerer", "Sorceress" },
783         { "Necromancer", 0 },
784         { "Wizard", 0 },
785         { "Mage", 0 } },
786       "Ptah", "Thoth", "Anhur", /* Egyptian */
787 #else
788     { { "\96\82\96@\8eg\82¢", 0 },
789       { { "\8eè\95i\8et", 0 },
790         { "\8aï\8fp\8et", 0 },
791         { "\90è\82¢\8et", 0 },
792         { "\97ì\8a´\8et", 0 },
793         { "\8f¢\8a«\8et", 0 },
794         { "\97d\8fp\8et", 0 },
795         { "\96\82\8fp\8et", 0 },
796         { "\96\82\96@\8eg\82¢", 0 },
797         { "\91å\96\82\96@\8eg\82¢", 0 } },
798       "\83v\83^\83n", "\83g\81[\83g", "\83A\83\93\83t\83\8b", /* Egyptian */
799 #endif
800       "Wiz",
801 #if 0 /*JP:T*/
802       "the Lonely Tower",
803       "the Tower of Darkness",
804 #else
805       "\8cÇ\8d\82\82Ì\93\83",
806       "\88Ã\8d\95\82Ì\93\83",
807 #endif
808       PM_WIZARD,
809       NON_PM,
810       PM_KITTEN,
811       PM_NEFERET_THE_GREEN,
812       PM_APPRENTICE,
813       PM_DARK_ONE,
814       PM_VAMPIRE_BAT,
815       PM_XORN,
816       S_BAT,
817       S_WRAITH,
818       ART_EYE_OF_THE_AETHIOPICA,
819       MH_HUMAN | MH_ELF | MH_GNOME | MH_ORC | ROLE_MALE | ROLE_FEMALE
820           | ROLE_NEUTRAL | ROLE_CHAOTIC,
821       /* Str Int Wis Dex Con Cha */
822       { 7, 10, 7, 7, 7, 7 },
823       { 10, 30, 10, 20, 20, 10 },
824       /* Init   Lower  Higher */
825       { 10, 0, 0, 8, 1, 0 }, /* Hit points */
826       { 4, 3, 0, 2, 0, 3 },
827       12, /* Energy */
828       0,
829       1,
830       0,
831       3,
832       10,
833       A_INT,
834       SPE_MAGIC_MISSILE,
835       -4 },
836     /* Array terminator */
837     { { 0, 0 } }
838 };
839
840 /* The player's role, created at runtime from initial
841  * choices.  This may be munged in role_init().
842  */
843 struct Role urole = {
844     { "Undefined", 0 },
845     { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
846       { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
847     "L", "N", "C",
848     "Xxx", "home", "locate",
849     NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM,
850     0, 0, 0, 0,
851     /* Str Int Wis Dex Con Cha */
852     { 7, 7, 7, 7, 7, 7 },
853     { 20, 15, 15, 20, 20, 10 },
854     /* Init   Lower  Higher */
855     { 10, 0, 0, 8, 1, 0 }, /* Hit points */
856     { 2, 0, 0, 2, 0, 3 },
857     14, /* Energy */
858      0,
859     10,
860      0,
861      0,
862      4,
863     A_INT,
864      0,
865     -3
866 };
867
868 /* Table of all races */
869 const struct Race races[] = {
870     {
871 #if 0 /*JP:T*/
872         "human",
873         "human",
874         "humanity",
875 #else
876         "\90l\8aÔ",
877         "\90l\8aÔ\82Ì",
878         "\90l\8aÔ",
879 #endif
880         "Hum",
881 #if 0 /*JP:T*/
882         { "man", "woman" },
883 #else
884         { "\92j", "\8f\97" },
885 #endif
886         PM_HUMAN,
887         NON_PM,
888         PM_HUMAN_MUMMY,
889         PM_HUMAN_ZOMBIE,
890         MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
891             | ROLE_CHAOTIC,
892         MH_HUMAN,
893         0,
894         MH_GNOME | MH_ORC,
895         /*    Str     Int Wis Dex Con Cha */
896         { 3, 3, 3, 3, 3, 3 },
897         { STR18(100), 18, 18, 18, 18, 18 },
898         /* Init   Lower  Higher */
899         { 2, 0, 0, 2, 1, 0 }, /* Hit points */
900         { 1, 0, 2, 0, 2, 0 }  /* Energy */
901     },
902     {
903 #if 0 /*JP:T*/
904         "elf",
905         "elven",
906         "elvenkind",
907 #else
908         "\83G\83\8b\83t",
909         "\83G\83\8b\83t\82Ì",
910         "\83G\83\8b\83t",
911 #endif
912         "Elf",
913         { 0, 0 },
914         PM_ELF,
915         NON_PM,
916         PM_ELF_MUMMY,
917         PM_ELF_ZOMBIE,
918         MH_ELF | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
919         MH_ELF,
920         MH_ELF,
921         MH_ORC,
922         /*  Str    Int Wis Dex Con Cha */
923         { 3, 3, 3, 3, 3, 3 },
924         { 18, 20, 20, 18, 16, 18 },
925         /* Init   Lower  Higher */
926         { 1, 0, 0, 1, 1, 0 }, /* Hit points */
927         { 2, 0, 3, 0, 3, 0 }  /* Energy */
928     },
929     {
930 #if 0 /*JP:T*/
931         "dwarf",
932         "dwarven",
933         "dwarvenkind",
934 #else
935         "\83h\83\8f\81[\83t",
936         "\83h\83\8f\81[\83t\82Ì",
937         "\83h\83\8f\81[\83t",
938 #endif
939         "Dwa",
940         { 0, 0 },
941         PM_DWARF,
942         NON_PM,
943         PM_DWARF_MUMMY,
944         PM_DWARF_ZOMBIE,
945         MH_DWARF | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
946         MH_DWARF,
947         MH_DWARF | MH_GNOME,
948         MH_ORC,
949         /*    Str     Int Wis Dex Con Cha */
950         { 3, 3, 3, 3, 3, 3 },
951         { STR18(100), 16, 16, 20, 20, 16 },
952         /* Init   Lower  Higher */
953         { 4, 0, 0, 3, 2, 0 }, /* Hit points */
954         { 0, 0, 0, 0, 0, 0 }  /* Energy */
955     },
956     {
957 #if 0 /*JP:T*/
958         "gnome",
959         "gnomish",
960         "gnomehood",
961 #else
962         "\83m\81[\83\80",
963         "\83m\81[\83\80\82Ì",
964         "\83m\81[\83\80",
965 #endif
966         "Gno",
967         { 0, 0 },
968         PM_GNOME,
969         NON_PM,
970         PM_GNOME_MUMMY,
971         PM_GNOME_ZOMBIE,
972         MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
973         MH_GNOME,
974         MH_DWARF | MH_GNOME,
975         MH_HUMAN,
976         /*  Str    Int Wis Dex Con Cha */
977         { 3, 3, 3, 3, 3, 3 },
978         { STR18(50), 19, 18, 18, 18, 18 },
979         /* Init   Lower  Higher */
980         { 1, 0, 0, 1, 0, 0 }, /* Hit points */
981         { 2, 0, 2, 0, 2, 0 }  /* Energy */
982     },
983     {
984 #if 0 /*JP:T*/
985         "orc",
986         "orcish",
987         "orcdom",
988 #else
989         "\83I\81[\83N",
990         "\83I\81[\83N\82Ì",
991         "\83I\81[\83N",
992 #endif
993         "Orc",
994         { 0, 0 },
995         PM_ORC,
996         NON_PM,
997         PM_ORC_MUMMY,
998         PM_ORC_ZOMBIE,
999         MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
1000         MH_ORC,
1001         0,
1002         MH_HUMAN | MH_ELF | MH_DWARF,
1003         /*  Str    Int Wis Dex Con Cha */
1004         { 3, 3, 3, 3, 3, 3 },
1005         { STR18(50), 16, 16, 18, 18, 16 },
1006         /* Init   Lower  Higher */
1007         { 1, 0, 0, 1, 0, 0 }, /* Hit points */
1008         { 1, 0, 1, 0, 1, 0 }  /* Energy */
1009     },
1010     /* Array terminator */
1011     { 0, 0, 0, 0 }
1012 };
1013
1014 /* The player's race, created at runtime from initial
1015  * choices.  This may be munged in role_init().
1016  */
1017 struct Race urace = {
1018     "something",
1019     "undefined",
1020     "something",
1021     "Xxx",
1022     { 0, 0 },
1023     NON_PM,
1024     NON_PM,
1025     NON_PM,
1026     NON_PM,
1027     0,
1028     0,
1029     0,
1030     0,
1031     /*    Str     Int Wis Dex Con Cha */
1032     { 3, 3, 3, 3, 3, 3 },
1033     { STR18(100), 18, 18, 18, 18, 18 },
1034     /* Init   Lower  Higher */
1035     { 2, 0, 0, 2, 1, 0 }, /* Hit points */
1036     { 1, 0, 2, 0, 2, 0 }  /* Energy */
1037 };
1038
1039 /* Table of all genders */
1040 /*JP:
1041 - steed.c kick_steed() He[] \82É\92l\82ª\83R\83s\81[\82³\82ê\82é\82Ì\82Å\92·\82³\82ð\95Ï\82¦\82½\82Æ\82«\82É\82Í
1042   \8aY\93\96\95\94\82à\97v\8fC\90³\81B
1043 */
1044 const struct Gender genders[] = {
1045 #if 0 /*JP:T*/
1046     { "male", "he", "him", "his", "Mal", ROLE_MALE },
1047     { "female", "she", "her", "her", "Fem", ROLE_FEMALE },
1048     { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER }
1049 #else
1050     { "\92j\90«", "\94Þ", "\94Þ", "\94Þ\82Ì", "Mal", ROLE_MALE },
1051     { "\8f\97\90«", "\94Þ\8f\97", "\94Þ\8f\97", "\94Þ\8f\97\82Ì", "Fem", ROLE_FEMALE },
1052     { "\92\86\90«", "\82»\82ê", "\82»\82ê", "\82»\82Ì", "Ntr", ROLE_NEUTER }
1053 #endif
1054 };
1055
1056 /* Table of all alignments */
1057 const struct Align aligns[] = {
1058 #if 0 /*JP:T*/
1059     { "law", "lawful", "Law", ROLE_LAWFUL, A_LAWFUL },
1060     { "balance", "neutral", "Neu", ROLE_NEUTRAL, A_NEUTRAL },
1061     { "chaos", "chaotic", "Cha", ROLE_CHAOTIC, A_CHAOTIC },
1062     { "evil", "unaligned", "Una", 0, A_NONE }
1063 #else
1064     { "\92\81\8f\98", "\92\81\8f\98\82Ì", "Law", ROLE_LAWFUL, A_LAWFUL },
1065     { "\92\86\97§", "\92\86\97§\82Ì", "Neu", ROLE_NEUTRAL, A_NEUTRAL },
1066     { "\8d¬\93×", "\8d¬\93×\82Ì", "Cha", ROLE_CHAOTIC, A_CHAOTIC },
1067     { "\96³\90S", "\96³\90S\82Ì", "Una", 0, A_NONE }
1068 #endif
1069 };
1070
1071 /* Filters */
1072 static struct {
1073     boolean roles[SIZE(roles)];
1074     short mask;
1075 } rfilter;
1076
1077 STATIC_DCL int NDECL(randrole_filtered);
1078 STATIC_DCL char *FDECL(promptsep, (char *, int));
1079 STATIC_DCL int FDECL(role_gendercount, (int));
1080 STATIC_DCL int FDECL(race_alignmentcount, (int));
1081
1082 /* used by str2XXX() */
1083 /*JP
1084 static char NEARDATA randomstr[] = "random";
1085 */
1086 static char NEARDATA randomstr[] = "\83\89\83\93\83_\83\80";
1087
1088 boolean
1089 validrole(rolenum)
1090 int rolenum;
1091 {
1092     return (boolean) (rolenum >= 0 && rolenum < SIZE(roles) - 1);
1093 }
1094
1095 int
1096 randrole(for_display)
1097 boolean for_display;
1098 {
1099     int res = SIZE(roles) - 1;
1100
1101     if (for_display)
1102         res = rn2_on_display_rng(res);
1103     else
1104         res = rn2(res);
1105     return res;
1106 }
1107
1108 STATIC_OVL int
1109 randrole_filtered()
1110 {
1111     int i, n = 0, set[SIZE(roles)];
1112
1113     /* this doesn't rule out impossible combinations but attempts to
1114        honor all the filter masks */
1115     for (i = 0; i < SIZE(roles); ++i)
1116         if (ok_role(i, ROLE_NONE, ROLE_NONE, ROLE_NONE)
1117             && ok_race(i, ROLE_RANDOM, ROLE_NONE, ROLE_NONE)
1118             && ok_gend(i, ROLE_NONE, ROLE_RANDOM, ROLE_NONE)
1119             && ok_align(i, ROLE_NONE, ROLE_NONE, ROLE_RANDOM))
1120             set[n++] = i;
1121     return n ? set[rn2(n)] : randrole(FALSE);
1122 }
1123
1124 int
1125 str2role(str)
1126 const char *str;
1127 {
1128     int i, len;
1129
1130     /* Is str valid? */
1131     if (!str || !str[0])
1132         return ROLE_NONE;
1133
1134     /* Match as much of str as is provided */
1135     len = strlen(str);
1136     for (i = 0; roles[i].name.m; i++) {
1137         /* Does it match the male name? */
1138         if (!strncmpi(str, roles[i].name.m, len))
1139             return i;
1140         /* Or the female name? */
1141         if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len))
1142             return i;
1143         /* Or the filecode? */
1144         if (!strcmpi(str, roles[i].filecode))
1145             return i;
1146     }
1147
1148     if ((len == 1 && (*str == '*' || *str == '@'))
1149         || !strncmpi(str, randomstr, len))
1150         return ROLE_RANDOM;
1151
1152     /* Couldn't find anything appropriate */
1153     return ROLE_NONE;
1154 }
1155
1156 boolean
1157 validrace(rolenum, racenum)
1158 int rolenum, racenum;
1159 {
1160     /* Assumes validrole */
1161     return (boolean) (racenum >= 0 && racenum < SIZE(races) - 1
1162                       && (roles[rolenum].allow & races[racenum].allow
1163                           & ROLE_RACEMASK));
1164 }
1165
1166 int
1167 randrace(rolenum)
1168 int rolenum;
1169 {
1170     int i, n = 0;
1171
1172     /* Count the number of valid races */
1173     for (i = 0; races[i].noun; i++)
1174         if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK)
1175             n++;
1176
1177     /* Pick a random race */
1178     /* Use a factor of 100 in case of bad random number generators */
1179     if (n)
1180         n = rn2(n * 100) / 100;
1181     for (i = 0; races[i].noun; i++)
1182         if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) {
1183             if (n)
1184                 n--;
1185             else
1186                 return i;
1187         }
1188
1189     /* This role has no permitted races? */
1190     return rn2(SIZE(races) - 1);
1191 }
1192
1193 int
1194 str2race(str)
1195 const char *str;
1196 {
1197     int i, len;
1198
1199     /* Is str valid? */
1200     if (!str || !str[0])
1201         return ROLE_NONE;
1202
1203     /* Match as much of str as is provided */
1204     len = strlen(str);
1205     for (i = 0; races[i].noun; i++) {
1206         /* Does it match the noun? */
1207         if (!strncmpi(str, races[i].noun, len))
1208             return i;
1209         /* Or the filecode? */
1210         if (!strcmpi(str, races[i].filecode))
1211             return i;
1212     }
1213
1214     if ((len == 1 && (*str == '*' || *str == '@'))
1215         || !strncmpi(str, randomstr, len))
1216         return ROLE_RANDOM;
1217
1218     /* Couldn't find anything appropriate */
1219     return ROLE_NONE;
1220 }
1221
1222 boolean
1223 validgend(rolenum, racenum, gendnum)
1224 int rolenum, racenum, gendnum;
1225 {
1226     /* Assumes validrole and validrace */
1227     return (boolean) (gendnum >= 0 && gendnum < ROLE_GENDERS
1228                       && (roles[rolenum].allow & races[racenum].allow
1229                           & genders[gendnum].allow & ROLE_GENDMASK));
1230 }
1231
1232 int
1233 randgend(rolenum, racenum)
1234 int rolenum, racenum;
1235 {
1236     int i, n = 0;
1237
1238     /* Count the number of valid genders */
1239     for (i = 0; i < ROLE_GENDERS; i++)
1240         if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1241             & ROLE_GENDMASK)
1242             n++;
1243
1244     /* Pick a random gender */
1245     if (n)
1246         n = rn2(n);
1247     for (i = 0; i < ROLE_GENDERS; i++)
1248         if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1249             & ROLE_GENDMASK) {
1250             if (n)
1251                 n--;
1252             else
1253                 return i;
1254         }
1255
1256     /* This role/race has no permitted genders? */
1257     return rn2(ROLE_GENDERS);
1258 }
1259
1260 int
1261 str2gend(str)
1262 const char *str;
1263 {
1264     int i, len;
1265
1266     /* Is str valid? */
1267     if (!str || !str[0])
1268         return ROLE_NONE;
1269
1270     /* Match as much of str as is provided */
1271     len = strlen(str);
1272     for (i = 0; i < ROLE_GENDERS; i++) {
1273         /* Does it match the adjective? */
1274         if (!strncmpi(str, genders[i].adj, len))
1275             return i;
1276         /* Or the filecode? */
1277         if (!strcmpi(str, genders[i].filecode))
1278             return i;
1279     }
1280     if ((len == 1 && (*str == '*' || *str == '@'))
1281         || !strncmpi(str, randomstr, len))
1282         return ROLE_RANDOM;
1283
1284     /* Couldn't find anything appropriate */
1285     return ROLE_NONE;
1286 }
1287
1288 boolean
1289 validalign(rolenum, racenum, alignnum)
1290 int rolenum, racenum, alignnum;
1291 {
1292     /* Assumes validrole and validrace */
1293     return (boolean) (alignnum >= 0 && alignnum < ROLE_ALIGNS
1294                       && (roles[rolenum].allow & races[racenum].allow
1295                           & aligns[alignnum].allow & ROLE_ALIGNMASK));
1296 }
1297
1298 int
1299 randalign(rolenum, racenum)
1300 int rolenum, racenum;
1301 {
1302     int i, n = 0;
1303
1304     /* Count the number of valid alignments */
1305     for (i = 0; i < ROLE_ALIGNS; i++)
1306         if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1307             & ROLE_ALIGNMASK)
1308             n++;
1309
1310     /* Pick a random alignment */
1311     if (n)
1312         n = rn2(n);
1313     for (i = 0; i < ROLE_ALIGNS; i++)
1314         if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1315             & ROLE_ALIGNMASK) {
1316             if (n)
1317                 n--;
1318             else
1319                 return i;
1320         }
1321
1322     /* This role/race has no permitted alignments? */
1323     return rn2(ROLE_ALIGNS);
1324 }
1325
1326 int
1327 str2align(str)
1328 const char *str;
1329 {
1330     int i, len;
1331
1332     /* Is str valid? */
1333     if (!str || !str[0])
1334         return ROLE_NONE;
1335
1336     /* Match as much of str as is provided */
1337     len = strlen(str);
1338     for (i = 0; i < ROLE_ALIGNS; i++) {
1339         /* Does it match the adjective? */
1340         if (!strncmpi(str, aligns[i].adj, len))
1341             return i;
1342         /* Or the filecode? */
1343         if (!strcmpi(str, aligns[i].filecode))
1344             return i;
1345     }
1346     if ((len == 1 && (*str == '*' || *str == '@'))
1347         || !strncmpi(str, randomstr, len))
1348         return ROLE_RANDOM;
1349
1350     /* Couldn't find anything appropriate */
1351     return ROLE_NONE;
1352 }
1353
1354 /* is rolenum compatible with any racenum/gendnum/alignnum constraints? */
1355 boolean
1356 ok_role(rolenum, racenum, gendnum, alignnum)
1357 int rolenum, racenum, gendnum, alignnum;
1358 {
1359     int i;
1360     short allow;
1361
1362     if (rolenum >= 0 && rolenum < SIZE(roles) - 1) {
1363         if (rfilter.roles[rolenum])
1364             return FALSE;
1365         allow = roles[rolenum].allow;
1366         if (racenum >= 0 && racenum < SIZE(races) - 1
1367             && !(allow & races[racenum].allow & ROLE_RACEMASK))
1368             return FALSE;
1369         if (gendnum >= 0 && gendnum < ROLE_GENDERS
1370             && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1371             return FALSE;
1372         if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1373             && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1374             return FALSE;
1375         return TRUE;
1376     } else {
1377         /* random; check whether any selection is possible */
1378         for (i = 0; i < SIZE(roles) - 1; i++) {
1379             if (rfilter.roles[i])
1380                 continue;
1381             allow = roles[i].allow;
1382             if (racenum >= 0 && racenum < SIZE(races) - 1
1383                 && !(allow & races[racenum].allow & ROLE_RACEMASK))
1384                 continue;
1385             if (gendnum >= 0 && gendnum < ROLE_GENDERS
1386                 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1387                 continue;
1388             if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1389                 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1390                 continue;
1391             return TRUE;
1392         }
1393         return FALSE;
1394     }
1395 }
1396
1397 /* pick a random role subject to any racenum/gendnum/alignnum constraints */
1398 /* If pickhow == PICK_RIGID a role is returned only if there is  */
1399 /* a single possibility */
1400 int
1401 pick_role(racenum, gendnum, alignnum, pickhow)
1402 int racenum, gendnum, alignnum, pickhow;
1403 {
1404     int i;
1405     int roles_ok = 0, set[SIZE(roles)];
1406
1407     for (i = 0; i < SIZE(roles) - 1; i++) {
1408         if (ok_role(i, racenum, gendnum, alignnum)
1409             && ok_race(i, (racenum >= 0) ? racenum : ROLE_RANDOM,
1410                        gendnum, alignnum)
1411             && ok_gend(i, racenum,
1412                        (gendnum >= 0) ? gendnum : ROLE_RANDOM, alignnum)
1413             && ok_race(i, racenum,
1414                        gendnum, (alignnum >= 0) ? alignnum : ROLE_RANDOM))
1415             set[roles_ok++] = i;
1416     }
1417     if (roles_ok == 0 || (roles_ok > 1 && pickhow == PICK_RIGID))
1418         return ROLE_NONE;
1419     return set[rn2(roles_ok)];
1420 }
1421
1422 /* is racenum compatible with any rolenum/gendnum/alignnum constraints? */
1423 boolean
1424 ok_race(rolenum, racenum, gendnum, alignnum)
1425 int rolenum, racenum, gendnum, alignnum;
1426 {
1427     int i;
1428     short allow;
1429
1430     if (racenum >= 0 && racenum < SIZE(races) - 1) {
1431         if (rfilter.mask & races[racenum].selfmask)
1432             return FALSE;
1433         allow = races[racenum].allow;
1434         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1435             && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1436             return FALSE;
1437         if (gendnum >= 0 && gendnum < ROLE_GENDERS
1438             && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1439             return FALSE;
1440         if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1441             && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1442             return FALSE;
1443         return TRUE;
1444     } else {
1445         /* random; check whether any selection is possible */
1446         for (i = 0; i < SIZE(races) - 1; i++) {
1447             if (rfilter.mask & races[i].selfmask)
1448                 continue;
1449             allow = races[i].allow;
1450             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1451                 && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1452                 continue;
1453             if (gendnum >= 0 && gendnum < ROLE_GENDERS
1454                 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1455                 continue;
1456             if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1457                 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1458                 continue;
1459             return TRUE;
1460         }
1461         return FALSE;
1462     }
1463 }
1464
1465 /* Pick a random race subject to any rolenum/gendnum/alignnum constraints.
1466    If pickhow == PICK_RIGID a race is returned only if there is
1467    a single possibility. */
1468 int
1469 pick_race(rolenum, gendnum, alignnum, pickhow)
1470 int rolenum, gendnum, alignnum, pickhow;
1471 {
1472     int i;
1473     int races_ok = 0;
1474
1475     for (i = 0; i < SIZE(races) - 1; i++) {
1476         if (ok_race(rolenum, i, gendnum, alignnum))
1477             races_ok++;
1478     }
1479     if (races_ok == 0 || (races_ok > 1 && pickhow == PICK_RIGID))
1480         return ROLE_NONE;
1481     races_ok = rn2(races_ok);
1482     for (i = 0; i < SIZE(races) - 1; i++) {
1483         if (ok_race(rolenum, i, gendnum, alignnum)) {
1484             if (races_ok == 0)
1485                 return i;
1486             else
1487                 races_ok--;
1488         }
1489     }
1490     return ROLE_NONE;
1491 }
1492
1493 /* is gendnum compatible with any rolenum/racenum/alignnum constraints? */
1494 /* gender and alignment are not comparable (and also not constrainable) */
1495 boolean
1496 ok_gend(rolenum, racenum, gendnum, alignnum)
1497 int rolenum, racenum, gendnum;
1498 int alignnum UNUSED;
1499 {
1500     int i;
1501     short allow;
1502
1503     if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
1504         if (rfilter.mask & genders[gendnum].allow)
1505             return FALSE;
1506         allow = genders[gendnum].allow;
1507         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1508             && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1509             return FALSE;
1510         if (racenum >= 0 && racenum < SIZE(races) - 1
1511             && !(allow & races[racenum].allow & ROLE_GENDMASK))
1512             return FALSE;
1513         return TRUE;
1514     } else {
1515         /* random; check whether any selection is possible */
1516         for (i = 0; i < ROLE_GENDERS; i++) {
1517             if (rfilter.mask & genders[i].allow)
1518                 continue;
1519             allow = genders[i].allow;
1520             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1521                 && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1522                 continue;
1523             if (racenum >= 0 && racenum < SIZE(races) - 1
1524                 && !(allow & races[racenum].allow & ROLE_GENDMASK))
1525                 continue;
1526             return TRUE;
1527         }
1528         return FALSE;
1529     }
1530 }
1531
1532 /* pick a random gender subject to any rolenum/racenum/alignnum constraints */
1533 /* gender and alignment are not comparable (and also not constrainable) */
1534 /* If pickhow == PICK_RIGID a gender is returned only if there is  */
1535 /* a single possibility */
1536 int
1537 pick_gend(rolenum, racenum, alignnum, pickhow)
1538 int rolenum, racenum, alignnum, pickhow;
1539 {
1540     int i;
1541     int gends_ok = 0;
1542
1543     for (i = 0; i < ROLE_GENDERS; i++) {
1544         if (ok_gend(rolenum, racenum, i, alignnum))
1545             gends_ok++;
1546     }
1547     if (gends_ok == 0 || (gends_ok > 1 && pickhow == PICK_RIGID))
1548         return ROLE_NONE;
1549     gends_ok = rn2(gends_ok);
1550     for (i = 0; i < ROLE_GENDERS; i++) {
1551         if (ok_gend(rolenum, racenum, i, alignnum)) {
1552             if (gends_ok == 0)
1553                 return i;
1554             else
1555                 gends_ok--;
1556         }
1557     }
1558     return ROLE_NONE;
1559 }
1560
1561 /* is alignnum compatible with any rolenum/racenum/gendnum constraints? */
1562 /* alignment and gender are not comparable (and also not constrainable) */
1563 boolean
1564 ok_align(rolenum, racenum, gendnum, alignnum)
1565 int rolenum, racenum;
1566 int gendnum UNUSED;
1567 int alignnum;
1568 {
1569     int i;
1570     short allow;
1571
1572     if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
1573         if (rfilter.mask & aligns[alignnum].allow)
1574             return FALSE;
1575         allow = aligns[alignnum].allow;
1576         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1577             && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1578             return FALSE;
1579         if (racenum >= 0 && racenum < SIZE(races) - 1
1580             && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1581             return FALSE;
1582         return TRUE;
1583     } else {
1584         /* random; check whether any selection is possible */
1585         for (i = 0; i < ROLE_ALIGNS; i++) {
1586             if (rfilter.mask & aligns[i].allow)
1587                 return FALSE;
1588             allow = aligns[i].allow;
1589             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1590                 && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1591                 continue;
1592             if (racenum >= 0 && racenum < SIZE(races) - 1
1593                 && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1594                 continue;
1595             return TRUE;
1596         }
1597         return FALSE;
1598     }
1599 }
1600
1601 /* Pick a random alignment subject to any rolenum/racenum/gendnum constraints;
1602    alignment and gender are not comparable (and also not constrainable).
1603    If pickhow == PICK_RIGID an alignment is returned only if there is
1604    a single possibility. */
1605 int
1606 pick_align(rolenum, racenum, gendnum, pickhow)
1607 int rolenum, racenum, gendnum, pickhow;
1608 {
1609     int i;
1610     int aligns_ok = 0;
1611
1612     for (i = 0; i < ROLE_ALIGNS; i++) {
1613         if (ok_align(rolenum, racenum, gendnum, i))
1614             aligns_ok++;
1615     }
1616     if (aligns_ok == 0 || (aligns_ok > 1 && pickhow == PICK_RIGID))
1617         return ROLE_NONE;
1618     aligns_ok = rn2(aligns_ok);
1619     for (i = 0; i < ROLE_ALIGNS; i++) {
1620         if (ok_align(rolenum, racenum, gendnum, i)) {
1621             if (aligns_ok == 0)
1622                 return i;
1623             else
1624                 aligns_ok--;
1625         }
1626     }
1627     return ROLE_NONE;
1628 }
1629
1630 void
1631 rigid_role_checks()
1632 {
1633     int tmp;
1634
1635     /* Some roles are limited to a single race, alignment, or gender and
1636      * calling this routine prior to XXX_player_selection() will help
1637      * prevent an extraneous prompt that actually doesn't allow
1638      * you to choose anything further. Note the use of PICK_RIGID which
1639      * causes the pick_XX() routine to return a value only if there is one
1640      * single possible selection, otherwise it returns ROLE_NONE.
1641      *
1642      */
1643     if (flags.initrole == ROLE_RANDOM) {
1644         /* If the role was explicitly specified as ROLE_RANDOM
1645          * via -uXXXX-@ or OPTIONS=role:random then choose the role
1646          * in here to narrow down later choices.
1647          */
1648         flags.initrole = pick_role(flags.initrace, flags.initgend,
1649                                    flags.initalign, PICK_RANDOM);
1650         if (flags.initrole < 0)
1651             flags.initrole = randrole_filtered();
1652     }
1653     if (flags.initrace == ROLE_RANDOM
1654         && (tmp = pick_race(flags.initrole, flags.initgend,
1655                             flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1656         flags.initrace = tmp;
1657     if (flags.initalign == ROLE_RANDOM
1658         && (tmp = pick_align(flags.initrole, flags.initrace,
1659                              flags.initgend, PICK_RANDOM)) != ROLE_NONE)
1660         flags.initalign = tmp;
1661     if (flags.initgend == ROLE_RANDOM
1662         && (tmp = pick_gend(flags.initrole, flags.initrace,
1663                             flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1664         flags.initgend = tmp;
1665
1666     if (flags.initrole != ROLE_NONE) {
1667         if (flags.initrace == ROLE_NONE)
1668             flags.initrace = pick_race(flags.initrole, flags.initgend,
1669                                        flags.initalign, PICK_RIGID);
1670         if (flags.initalign == ROLE_NONE)
1671             flags.initalign = pick_align(flags.initrole, flags.initrace,
1672                                          flags.initgend, PICK_RIGID);
1673         if (flags.initgend == ROLE_NONE)
1674             flags.initgend = pick_gend(flags.initrole, flags.initrace,
1675                                        flags.initalign, PICK_RIGID);
1676     }
1677 }
1678
1679 boolean
1680 setrolefilter(bufp)
1681 const char *bufp;
1682 {
1683     int i;
1684     boolean reslt = TRUE;
1685
1686     if ((i = str2role(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1687         rfilter.roles[i] = TRUE;
1688     else if ((i = str2race(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1689         rfilter.mask |= races[i].selfmask;
1690     else if ((i = str2gend(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1691         rfilter.mask |= genders[i].allow;
1692     else if ((i = str2align(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1693         rfilter.mask |= aligns[i].allow;
1694     else
1695         reslt = FALSE;
1696     return reslt;
1697 }
1698
1699 boolean
1700 gotrolefilter()
1701 {
1702     int i;
1703
1704     if (rfilter.mask)
1705         return TRUE;
1706     for (i = 0; i < SIZE(roles); ++i)
1707         if (rfilter.roles[i])
1708             return TRUE;
1709     return FALSE;
1710 }
1711
1712 void
1713 clearrolefilter()
1714 {
1715     int i;
1716
1717     for (i = 0; i < SIZE(roles); ++i)
1718         rfilter.roles[i] = FALSE;
1719     rfilter.mask = 0;
1720 }
1721
1722 #define BP_ALIGN 0
1723 #define BP_GEND 1
1724 #define BP_RACE 2
1725 #define BP_ROLE 3
1726 #define NUM_BP 4
1727
1728 STATIC_VAR char pa[NUM_BP], post_attribs;
1729
1730 STATIC_OVL char *
1731 promptsep(buf, num_post_attribs)
1732 char *buf;
1733 int num_post_attribs;
1734 {
1735 #if 0 /*JP*/
1736     const char *conjuct = "and ";
1737
1738     if (num_post_attribs > 1 && post_attribs < num_post_attribs
1739         && post_attribs > 1)
1740         Strcat(buf, ",");
1741     Strcat(buf, " ");
1742     --post_attribs;
1743     if (!post_attribs && num_post_attribs > 1)
1744         Strcat(buf, conjuct);
1745 #else
1746     /*JP: \93ú\96{\8cê\82Å\82Í "A, B, and C" \82Æ\82¢\82¤\8f\88\97\9d\82Í\95s\97v */
1747     if(num_post_attribs > post_attribs){
1748         Strcat(buf, "\81C");
1749     }
1750     --post_attribs;
1751 #endif
1752     return buf;
1753 }
1754
1755 STATIC_OVL int
1756 role_gendercount(rolenum)
1757 int rolenum;
1758 {
1759     int gendcount = 0;
1760
1761     if (validrole(rolenum)) {
1762         if (roles[rolenum].allow & ROLE_MALE)
1763             ++gendcount;
1764         if (roles[rolenum].allow & ROLE_FEMALE)
1765             ++gendcount;
1766         if (roles[rolenum].allow & ROLE_NEUTER)
1767             ++gendcount;
1768     }
1769     return gendcount;
1770 }
1771
1772 STATIC_OVL int
1773 race_alignmentcount(racenum)
1774 int racenum;
1775 {
1776     int aligncount = 0;
1777
1778     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1779         if (races[racenum].allow & ROLE_CHAOTIC)
1780             ++aligncount;
1781         if (races[racenum].allow & ROLE_LAWFUL)
1782             ++aligncount;
1783         if (races[racenum].allow & ROLE_NEUTRAL)
1784             ++aligncount;
1785     }
1786     return aligncount;
1787 }
1788
1789 char *
1790 root_plselection_prompt(suppliedbuf, buflen, rolenum, racenum, gendnum,
1791                         alignnum)
1792 char *suppliedbuf;
1793 int buflen, rolenum, racenum, gendnum, alignnum;
1794 {
1795     int k, gendercount = 0, aligncount = 0;
1796     char buf[BUFSZ];
1797 /*JP
1798     static char err_ret[] = " character's";
1799 */
1800     static char err_ret[] = "\83L\83\83\83\89\83N\83^\81[\82Ì";
1801 #if 0 /*JP*/
1802     boolean donefirst = FALSE;
1803 #endif
1804
1805     if (!suppliedbuf || buflen < 1)
1806         return err_ret;
1807
1808     /* initialize these static variables each time this is called */
1809     post_attribs = 0;
1810     for (k = 0; k < NUM_BP; ++k)
1811         pa[k] = 0;
1812     buf[0] = '\0';
1813     *suppliedbuf = '\0';
1814
1815     /* How many alignments are allowed for the desired race? */
1816     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1817         aligncount = race_alignmentcount(racenum);
1818
1819     if (alignnum != ROLE_NONE && alignnum != ROLE_RANDOM
1820         && ok_align(rolenum, racenum, gendnum, alignnum)) {
1821         /* if race specified, and multiple choice of alignments for it */
1822         if ((racenum >= 0) && (aligncount > 1)) {
1823 #if 0 /*JP*/
1824             if (donefirst)
1825                 Strcat(buf, " ");
1826 #endif
1827             Strcat(buf, aligns[alignnum].adj);
1828 #if 0 /*JP*/
1829             donefirst = TRUE;
1830 #endif
1831         } else {
1832 #if 0 /*JP*/
1833             if (donefirst)
1834                 Strcat(buf, " ");
1835 #endif
1836             Strcat(buf, aligns[alignnum].adj);
1837 #if 0 /*JP*/
1838             donefirst = TRUE;
1839 #endif
1840         }
1841     } else {
1842         /* in case we got here by failing the ok_align() test */
1843         if (alignnum != ROLE_RANDOM)
1844             alignnum = ROLE_NONE;
1845         /* if alignment not specified, but race is specified
1846            and only one choice of alignment for that race then
1847            don't include it in the later list */
1848         if ((((racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1849               && ok_race(rolenum, racenum, gendnum, alignnum))
1850              && (aligncount > 1))
1851             || (racenum == ROLE_NONE || racenum == ROLE_RANDOM)) {
1852             pa[BP_ALIGN] = 1;
1853             post_attribs++;
1854         }
1855     }
1856     /* <your lawful> */
1857
1858     /* How many genders are allowed for the desired role? */
1859     if (validrole(rolenum))
1860         gendercount = role_gendercount(rolenum);
1861
1862     if (gendnum != ROLE_NONE && gendnum != ROLE_RANDOM) {
1863         if (validrole(rolenum)) {
1864             /* if role specified, and multiple choice of genders for it,
1865                and name of role itself does not distinguish gender */
1866             if ((rolenum != ROLE_NONE) && (gendercount > 1)
1867                 && !roles[rolenum].name.f) {
1868 #if 0 /*JP*/
1869                 if (donefirst)
1870                     Strcat(buf, " ");
1871 #endif
1872                 Strcat(buf, genders[gendnum].adj);
1873 #if 0 /*JP*/
1874                 donefirst = TRUE;
1875 #endif
1876             }
1877         } else {
1878 #if 0 /*JP*/
1879             if (donefirst)
1880                 Strcat(buf, " ");
1881 #endif
1882             Strcat(buf, genders[gendnum].adj);
1883 #if 0 /*JP*/
1884             donefirst = TRUE;
1885 #endif
1886         }
1887     } else {
1888         /* if gender not specified, but role is specified
1889                 and only one choice of gender then
1890                 don't include it in the later list */
1891         if ((validrole(rolenum) && (gendercount > 1))
1892             || !validrole(rolenum)) {
1893             pa[BP_GEND] = 1;
1894             post_attribs++;
1895         }
1896     }
1897     /* <your lawful female> */
1898
1899     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1900         if (validrole(rolenum)
1901             && ok_race(rolenum, racenum, gendnum, alignnum)) {
1902 #if 0 /*JP*/
1903             if (donefirst)
1904                 Strcat(buf, " ");
1905 #endif
1906             Strcat(buf, (rolenum == ROLE_NONE) ? races[racenum].noun
1907                                                : races[racenum].adj);
1908 #if 0 /*JP*/
1909             donefirst = TRUE;
1910 #endif
1911         } else if (!validrole(rolenum)) {
1912 #if 0 /*JP*/
1913             if (donefirst)
1914                 Strcat(buf, " ");
1915 #endif
1916             Strcat(buf, races[racenum].noun);
1917 #if 0 /*JP*/
1918             donefirst = TRUE;
1919 #endif
1920         } else {
1921             pa[BP_RACE] = 1;
1922             post_attribs++;
1923         }
1924     } else {
1925         pa[BP_RACE] = 1;
1926         post_attribs++;
1927     }
1928     /* <your lawful female gnomish> || <your lawful female gnome> */
1929
1930     if (validrole(rolenum)) {
1931 #if 0 /*JP*/
1932         if (donefirst)
1933             Strcat(buf, " ");
1934 #endif
1935         if (gendnum != ROLE_NONE) {
1936             if (gendnum == 1 && roles[rolenum].name.f)
1937                 Strcat(buf, roles[rolenum].name.f);
1938             else
1939                 Strcat(buf, roles[rolenum].name.m);
1940         } else {
1941             if (roles[rolenum].name.f) {
1942                 Strcat(buf, roles[rolenum].name.m);
1943                 Strcat(buf, "/");
1944                 Strcat(buf, roles[rolenum].name.f);
1945             } else
1946                 Strcat(buf, roles[rolenum].name.m);
1947         }
1948 #if 0 /*JP*/
1949         donefirst = TRUE;
1950 #endif
1951     } else if (rolenum == ROLE_NONE) {
1952         pa[BP_ROLE] = 1;
1953         post_attribs++;
1954     }
1955
1956     if ((racenum == ROLE_NONE || racenum == ROLE_RANDOM)
1957         && !validrole(rolenum)) {
1958 #if 0 /*JP*/
1959         if (donefirst)
1960             Strcat(buf, " ");
1961 #endif
1962 /*JP
1963         Strcat(buf, "character");
1964 */
1965         Strcat(buf, "\83L\83\83\83\89\83N\83^\81[");
1966 #if 0 /*JP*/
1967         donefirst = TRUE;
1968 #endif
1969     }
1970     /* <your lawful female gnomish cavewoman> || <your lawful female gnome>
1971      *    || <your lawful female character>
1972      */
1973     if (buflen > (int) (strlen(buf) + 1)) {
1974         Strcpy(suppliedbuf, buf);
1975         return suppliedbuf;
1976     } else
1977         return err_ret;
1978 }
1979
1980 char *
1981 build_plselection_prompt(buf, buflen, rolenum, racenum, gendnum, alignnum)
1982 char *buf;
1983 int buflen, rolenum, racenum, gendnum, alignnum;
1984 {
1985 /*JP
1986     const char *defprompt = "Shall I pick a character for you? [ynaq] ";
1987 */
1988     const char *defprompt = "\93K\93\96\82É\83L\83\83\83\89\83N\83^\81[\82ð\91I\82ñ\82Å\82æ\82¢\82Å\82·\82©\81H[ynaq] ";
1989     int num_post_attribs = 0;
1990 #if 0 /*JP*/
1991     char tmpbuf[BUFSZ], *p;
1992 #else
1993     char tmpbuf[BUFSZ];
1994 #endif
1995
1996     if (buflen < QBUFSZ)
1997         return (char *) defprompt;
1998
1999 #if 0 /*JP*/
2000     Strcpy(tmpbuf, "Shall I pick ");
2001     if (racenum != ROLE_NONE || validrole(rolenum))
2002         Strcat(tmpbuf, "your ");
2003     else
2004         Strcat(tmpbuf, "a ");
2005 #else
2006     Strcpy(tmpbuf, "");
2007 #endif
2008     /* <your> */
2009
2010     (void) root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf),
2011                                    rolenum, racenum, gendnum, alignnum);
2012 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
2013     /* "Shall I pick a character's role, race, gender, and alignment for you?"
2014        plus " [ynaq] (y)" is a little too long for a conventional 80 columns;
2015        also, "pick a character's <anything>" sounds a bit stilted */
2016     strsubst(tmpbuf, "pick a character", "pick character");
2017 #endif
2018 #if 0 /*JP*/
2019     Sprintf(buf, "%s", s_suffix(tmpbuf));
2020 #else
2021     Sprintf(buf, "%s\82Ì", tmpbuf);
2022 #endif
2023 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\95s\97v*/
2024     /* don't bother splitting caveman/cavewoman or priest/priestess
2025        in order to apply possessive suffix to both halves, but do
2026        change "priest/priestess'" to "priest/priestess's" */
2027     if ((p = strstri(buf, "priest/priestess'")) != 0
2028         && p[sizeof "priest/priestess'" - sizeof ""] == '\0')
2029         strkitten(buf, 's');
2030 #endif
2031
2032     /* buf should now be:
2033      *    <your lawful female gnomish cavewoman's>
2034      * || <your lawful female gnome's>
2035      * || <your lawful female character's>
2036      *
2037      * Now append the post attributes to it
2038      */
2039     num_post_attribs = post_attribs;
2040     if (!num_post_attribs) {
2041         /* some constraints might have been mutually exclusive, in which case
2042            some prompting that would have been omitted is needed after all */
2043         if (flags.initrole == ROLE_NONE && !pa[BP_ROLE])
2044             pa[BP_ROLE] = ++post_attribs;
2045         if (flags.initrace == ROLE_NONE && !pa[BP_RACE])
2046             pa[BP_RACE] = ++post_attribs;
2047         if (flags.initalign == ROLE_NONE && !pa[BP_ALIGN])
2048             pa[BP_ALIGN] = ++post_attribs;
2049         if (flags.initgend == ROLE_NONE && !pa[BP_GEND])
2050             pa[BP_GEND] = ++post_attribs;
2051         num_post_attribs = post_attribs;
2052     }
2053     if (num_post_attribs) {
2054         if (pa[BP_RACE]) {
2055             (void) promptsep(eos(buf), num_post_attribs);
2056 /*JP
2057             Strcat(buf, "race");
2058 */
2059             Strcat(buf, "\8eí\91°");
2060         }
2061         if (pa[BP_ROLE]) {
2062             (void) promptsep(eos(buf), num_post_attribs);
2063 /*JP
2064             Strcat(buf, "role");
2065 */
2066             Strcat(buf, "\90E\8bÆ");
2067         }
2068         if (pa[BP_GEND]) {
2069             (void) promptsep(eos(buf), num_post_attribs);
2070 /*JP
2071             Strcat(buf, "gender");
2072 */
2073             Strcat(buf, "\90«\95Ê");
2074         }
2075         if (pa[BP_ALIGN]) {
2076             (void) promptsep(eos(buf), num_post_attribs);
2077 /*JP
2078             Strcat(buf, "alignment");
2079 */
2080             Strcat(buf, "\91®\90«");
2081         }
2082     }
2083 /*JP
2084     Strcat(buf, " for you? [ynaq] ");
2085 */
2086     Strcat(buf, "\82ð\93K\93\96\82É\91I\82ñ\82Å\82æ\82ë\82µ\82¢\82Å\82·\82©\81H[ynq] ");
2087     return buf;
2088 }
2089
2090 #undef BP_ALIGN
2091 #undef BP_GEND
2092 #undef BP_RACE
2093 #undef BP_ROLE
2094 #undef NUM_BP
2095
2096 void
2097 plnamesuffix()
2098 {
2099     char *sptr, *eptr;
2100     int i;
2101
2102     /* some generic user names will be ignored in favor of prompting */
2103     if (sysopt.genericusers) {
2104         if (*sysopt.genericusers == '*') {
2105             *plname = '\0';
2106         } else {
2107             i = (int) strlen(plname);
2108             if ((sptr = strstri(sysopt.genericusers, plname)) != 0
2109                 && (sptr == sysopt.genericusers || sptr[-1] == ' ')
2110                 && (sptr[i] == ' ' || sptr[i] == '\0'))
2111                 *plname = '\0'; /* call askname() */
2112         }
2113     }
2114
2115     do {
2116         if (!*plname)
2117             askname(); /* fill plname[] if necessary, or set defer_plname */
2118
2119         /* Look for tokens delimited by '-' */
2120         if ((eptr = index(plname, '-')) != (char *) 0)
2121             *eptr++ = '\0';
2122         while (eptr) {
2123             /* Isolate the next token */
2124             sptr = eptr;
2125             if ((eptr = index(sptr, '-')) != (char *) 0)
2126                 *eptr++ = '\0';
2127
2128             /* Try to match it to something */
2129             if ((i = str2role(sptr)) != ROLE_NONE)
2130                 flags.initrole = i;
2131             else if ((i = str2race(sptr)) != ROLE_NONE)
2132                 flags.initrace = i;
2133             else if ((i = str2gend(sptr)) != ROLE_NONE)
2134                 flags.initgend = i;
2135             else if ((i = str2align(sptr)) != ROLE_NONE)
2136                 flags.initalign = i;
2137         }
2138     } while (!*plname && !iflags.defer_plname);
2139
2140     /* commas in the plname confuse the record file, convert to spaces */
2141     for (sptr = plname; *sptr; sptr++) {
2142         if (*sptr == ',')
2143             *sptr = ' ';
2144     }
2145 }
2146
2147 /* show current settings for name, role, race, gender, and alignment
2148    in the specified window */
2149 void
2150 role_selection_prolog(which, where)
2151 int which;
2152 winid where;
2153 {
2154 /*JP
2155     static const char NEARDATA choosing[] = " choosing now",
2156 */
2157     static const char NEARDATA choosing[] = " \8c»\8dÝ\91I\91ð\92\86",
2158 /*JP
2159                                not_yet[] = " not yet specified",
2160 */
2161                                not_yet[] = " \96¢\91I\91ð",
2162 /*JP
2163                                rand_choice[] = " random";
2164 */
2165                                rand_choice[] = " \83\89\83\93\83_\83\80";
2166     char buf[BUFSZ];
2167     int r, c, g, a, allowmask;
2168
2169     r = flags.initrole;
2170     c = flags.initrace;
2171     g = flags.initgend;
2172     a = flags.initalign;
2173     if (r >= 0) {
2174         allowmask = roles[r].allow;
2175         if ((allowmask & ROLE_RACEMASK) == MH_HUMAN)
2176             c = 0; /* races[human] */
2177         else if (c >= 0 && !(allowmask & ROLE_RACEMASK & races[c].allow))
2178             c = ROLE_RANDOM;
2179         if ((allowmask & ROLE_GENDMASK) == ROLE_MALE)
2180             g = 0; /* role forces male (hypothetical) */
2181         else if ((allowmask & ROLE_GENDMASK) == ROLE_FEMALE)
2182             g = 1; /* role forces female (valkyrie) */
2183         if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2184             a = 0; /* aligns[lawful] */
2185         else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2186             a = 1; /* aligns[neutral] */
2187         else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2188             a = 2; /* alings[chaotic] */
2189     }
2190     if (c >= 0) {
2191         allowmask = races[c].allow;
2192         if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2193             a = 0; /* aligns[lawful] */
2194         else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2195             a = 1; /* aligns[neutral] */
2196         else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2197             a = 2; /* alings[chaotic] */
2198         /* [c never forces gender] */
2199     }
2200     /* [g and a don't constrain anything sufficiently
2201        to narrow something done to a single choice] */
2202
2203 /*JP
2204     Sprintf(buf, "%12s ", "name:");
2205 */
2206     Sprintf(buf, "%12s ", "\96¼\91O:");
2207     Strcat(buf, (which == RS_NAME) ? choosing : !*plname ? not_yet : plname);
2208     putstr(where, 0, buf);
2209 /*JP
2210     Sprintf(buf, "%12s ", "role:");
2211 */
2212     Sprintf(buf, "%12s ", "\90E\8bÆ:");
2213     Strcat(buf, (which == RS_ROLE) ? choosing : (r == ROLE_NONE)
2214                                                     ? not_yet
2215                                                     : (r == ROLE_RANDOM)
2216                                                           ? rand_choice
2217                                                           : roles[r].name.m);
2218     if (r >= 0 && roles[r].name.f) {
2219         /* distinct female name [caveman/cavewoman, priest/priestess] */
2220         if (g == 1)
2221             /* female specified; replace male role name with female one */
2222             Sprintf(index(buf, ':'), ": %s", roles[r].name.f);
2223         else if (g < 0)
2224             /* gender unspecified; append slash and female role name */
2225             Sprintf(eos(buf), "/%s", roles[r].name.f);
2226     }
2227     putstr(where, 0, buf);
2228 /*JP
2229     Sprintf(buf, "%12s ", "race:");
2230 */
2231     Sprintf(buf, "%12s ", "\8eí\91°:");
2232     Strcat(buf, (which == RS_RACE) ? choosing : (c == ROLE_NONE)
2233                                                     ? not_yet
2234                                                     : (c == ROLE_RANDOM)
2235                                                           ? rand_choice
2236                                                           : races[c].noun);
2237     putstr(where, 0, buf);
2238 /*JP
2239     Sprintf(buf, "%12s ", "gender:");
2240 */
2241     Sprintf(buf, "%12s ", "\90«\95Ê:");
2242     Strcat(buf, (which == RS_GENDER) ? choosing : (g == ROLE_NONE)
2243                                                       ? not_yet
2244                                                       : (g == ROLE_RANDOM)
2245                                                             ? rand_choice
2246                                                             : genders[g].adj);
2247     putstr(where, 0, buf);
2248 /*JP
2249     Sprintf(buf, "%12s ", "alignment:");
2250 */
2251     Sprintf(buf, "%12s ", "\91®\90«:");
2252 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\96¼\8e\8c\82ª\8e©\91R*/
2253     Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
2254                                                        ? not_yet
2255                                                        : (a == ROLE_RANDOM)
2256                                                              ? rand_choice
2257                                                              : aligns[a].adj);
2258 #else
2259     Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
2260                                                        ? not_yet
2261                                                        : (a == ROLE_RANDOM)
2262                                                              ? rand_choice
2263                                                              : aligns[a].noun);
2264 #endif
2265     putstr(where, 0, buf);
2266 }
2267
2268 /* add a "pick alignment first"-type entry to the specified menu */
2269 void
2270 role_menu_extra(which, where, preselect)
2271 int which;
2272 winid where;
2273 boolean preselect;
2274 {
2275     static NEARDATA const char RS_menu_let[] = {
2276         '=',  /* name */
2277         '?',  /* role */
2278         '/',  /* race */
2279         '\"', /* gender */
2280         '[',  /* alignment */
2281     };
2282     anything any;
2283     char buf[BUFSZ];
2284     const char *what = 0, *constrainer = 0, *forcedvalue = 0;
2285     int f = 0, r, c, g, a, i, allowmask;
2286
2287     r = flags.initrole;
2288     c = flags.initrace;
2289     switch (which) {
2290     case RS_NAME:
2291 /*JP
2292         what = "name";
2293 */
2294         what = "\96¼\91O";
2295         break;
2296     case RS_ROLE:
2297 /*JP
2298         what = "role";
2299 */
2300         what = "\90E\8bÆ";
2301         f = r;
2302         for (i = 0; i < SIZE(roles); ++i)
2303             if (i != f && !rfilter.roles[i])
2304                 break;
2305         if (i == SIZE(roles)) {
2306 /*JP
2307             constrainer = "filter";
2308 */
2309             constrainer = "\8di\82è\8d\9e\82Ý";
2310 /*JP
2311             forcedvalue = "role";
2312 */
2313             forcedvalue = "\90E\8bÆ";
2314         }
2315         break;
2316     case RS_RACE:
2317 /*JP
2318         what = "race";
2319 */
2320         what = "\8eí\91°";
2321         f = flags.initrace;
2322         c = ROLE_NONE; /* override player's setting */
2323         if (r >= 0) {
2324             allowmask = roles[r].allow & ROLE_RACEMASK;
2325             if (allowmask == MH_HUMAN)
2326                 c = 0; /* races[human] */
2327             if (c >= 0) {
2328 /*JP
2329                 constrainer = "role";
2330 */
2331                 constrainer = "\90E\8bÆ";
2332                 forcedvalue = races[c].noun;
2333             } else if (f >= 0
2334                        && (allowmask & ~rfilter.mask) == races[f].selfmask) {
2335                 /* if there is only one race choice available due to user
2336                    options disallowing others, race menu entry is disabled */
2337 /*JP
2338                 constrainer = "filter";
2339 */
2340                 constrainer = "\8di\82è\8d\9e\82Ý";
2341 /*JP
2342                 forcedvalue = "race";
2343 */
2344                 forcedvalue = "\8eí\91°";
2345             }
2346         }
2347         break;
2348     case RS_GENDER:
2349 /*JP
2350         what = "gender";
2351 */
2352         what = "\90«\95Ê";
2353         f = flags.initgend;
2354         g = ROLE_NONE;
2355         if (r >= 0) {
2356             allowmask = roles[r].allow & ROLE_GENDMASK;
2357             if (allowmask == ROLE_MALE)
2358                 g = 0; /* genders[male] */
2359             else if (allowmask == ROLE_FEMALE)
2360                 g = 1; /* genders[female] */
2361             if (g >= 0) {
2362 /*JP
2363                 constrainer = "role";
2364 */
2365                 constrainer = "\90E\8bÆ";
2366                 forcedvalue = genders[g].adj;
2367             } else if (f >= 0
2368                        && (allowmask & ~rfilter.mask) == genders[f].allow) {
2369                 /* if there is only one gender choice available due to user
2370                    options disallowing other, gender menu entry is disabled */
2371 /*JP
2372                 constrainer = "filter";
2373 */
2374                 constrainer = "\8di\82è\8d\9e\82Ý";
2375 /*JP
2376                 forcedvalue = "gender";
2377 */
2378                 forcedvalue = "\90«\95Ê";
2379             }
2380         }
2381         break;
2382     case RS_ALGNMNT:
2383 /*JP
2384         what = "alignment";
2385 */
2386         what = "\91®\90«";
2387         f = flags.initalign;
2388         a = ROLE_NONE;
2389         if (r >= 0) {
2390             allowmask = roles[r].allow & ROLE_ALIGNMASK;
2391             if (allowmask == AM_LAWFUL)
2392                 a = 0; /* aligns[lawful] */
2393             else if (allowmask == AM_NEUTRAL)
2394                 a = 1; /* aligns[neutral] */
2395             else if (allowmask == AM_CHAOTIC)
2396                 a = 2; /* aligns[chaotic] */
2397             if (a >= 0)
2398 /*JP
2399                 constrainer = "role";
2400 */
2401                 constrainer = "\90E\8bÆ";
2402         }
2403         if (c >= 0 && !constrainer) {
2404             allowmask = races[c].allow & ROLE_ALIGNMASK;
2405             if (allowmask == AM_LAWFUL)
2406                 a = 0; /* aligns[lawful] */
2407             else if (allowmask == AM_NEUTRAL)
2408                 a = 1; /* aligns[neutral] */
2409             else if (allowmask == AM_CHAOTIC)
2410                 a = 2; /* aligns[chaotic] */
2411             if (a >= 0)
2412 /*JP
2413                 constrainer = "race";
2414 */
2415                 constrainer = "\8eí\91°";
2416         }
2417         if (f >= 0 && !constrainer
2418             && (ROLE_ALIGNMASK & ~rfilter.mask) == aligns[f].allow) {
2419             /* if there is only one alignment choice available due to user
2420                options disallowing others, algn menu entry is disabled */
2421 /*JP
2422             constrainer = "filter";
2423 */
2424             constrainer = "\8di\82è\8d\9e\82Ý";
2425 /*JP
2426             forcedvalue = "alignment";
2427 */
2428             forcedvalue = "\91®\90«";
2429         }
2430         if (a >= 0)
2431 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\96¼\8e\8c\82ª\8e©\91R*/
2432             forcedvalue = aligns[a].adj;
2433 #else
2434             forcedvalue = aligns[a].noun;
2435 #endif
2436         break;
2437     }
2438
2439     any = zeroany; /* zero out all bits */
2440     if (constrainer) {
2441         any.a_int = 0;
2442         /* use four spaces of padding to fake a grayed out menu choice */
2443 /*JP
2444         Sprintf(buf, "%4s%s forces %s", "", constrainer, forcedvalue);
2445 */
2446         Sprintf(buf, "%4s\82±\82Ì%s\82Å\82Í%s\82Ì\82Ý", "", constrainer, forcedvalue);
2447         add_menu(where, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
2448                  MENU_UNSELECTED);
2449     } else if (what) {
2450         any.a_int = RS_menu_arg(which);
2451 /*JP
2452         Sprintf(buf, "Pick%s %s first", (f >= 0) ? " another" : "", what);
2453 */
2454         Sprintf(buf, "%s%s\82ð\90æ\82É\91I\82Ô", (f >= 0) ? "\91¼\82Ì" : "", what);
2455         add_menu(where, NO_GLYPH, &any, RS_menu_let[which], 0, ATR_NONE, buf,
2456                  MENU_UNSELECTED);
2457     } else if (which == RS_filter) {
2458         any.a_int = RS_menu_arg(RS_filter);
2459 #if 0 /*JP:T*/
2460         add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2461                  "Reset role/race/&c filtering", MENU_UNSELECTED);
2462 #else
2463         add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2464                  "\90E\8bÆ/\8eí\91°\82È\82Ç\82Ì\8di\82è\8d\9e\82Ý\82ð\89ð\8f\9c\82·\82é", MENU_UNSELECTED);
2465 #endif
2466     } else if (which == ROLE_RANDOM) {
2467         any.a_int = ROLE_RANDOM;
2468 #if 0 /*JP:T*/
2469         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
2470                  preselect ? MENU_SELECTED : MENU_UNSELECTED);
2471 #else
2472         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "\83\89\83\93\83_\83\80",
2473                  MENU_UNSELECTED);
2474 #endif
2475     } else if (which == ROLE_NONE) {
2476         any.a_int = ROLE_NONE;
2477 #if 0 /*JP:T*/
2478         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
2479                  preselect ? MENU_SELECTED : MENU_UNSELECTED);
2480 #else
2481         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "\94²\82¯\82é",
2482                  MENU_UNSELECTED);
2483 #endif
2484     } else {
2485         impossible("role_menu_extra: bad arg (%d)", which);
2486     }
2487 }
2488
2489 /*
2490  *      Special setup modifications here:
2491  *
2492  *      Unfortunately, this is going to have to be done
2493  *      on each newgame or restore, because you lose the permonst mods
2494  *      across a save/restore.  :-)
2495  *
2496  *      1 - The Rogue Leader is the Tourist Nemesis.
2497  *      2 - Priests start with a random alignment - convert the leader and
2498  *          guardians here.
2499  *      3 - Priests also get their of deities from a randomly chosen role.
2500  *      4 - [obsolete] Elves can have one of two different leaders,
2501  *          but can't work it out here because it requires hacking the
2502  *          level file data (see sp_lev.c).
2503  *
2504  * This code also replaces quest_init().
2505  */
2506 void
2507 role_init()
2508 {
2509     int alignmnt;
2510     struct permonst *pm;
2511
2512     /* Strip the role letter out of the player name.
2513      * This is included for backwards compatibility.
2514      */
2515     plnamesuffix();
2516
2517     /* Check for a valid role.  Try flags.initrole first. */
2518     if (!validrole(flags.initrole)) {
2519         /* Try the player letter second */
2520         if ((flags.initrole = str2role(pl_character)) < 0)
2521             /* None specified; pick a random role */
2522             flags.initrole = randrole_filtered();
2523     }
2524
2525     /* We now have a valid role index.  Copy the role name back. */
2526     /* This should become OBSOLETE */
2527     Strcpy(pl_character, roles[flags.initrole].name.m);
2528     pl_character[PL_CSIZ - 1] = '\0';
2529
2530     /* Check for a valid race */
2531     if (!validrace(flags.initrole, flags.initrace))
2532         flags.initrace = randrace(flags.initrole);
2533
2534     /* Check for a valid gender.  If new game, check both initgend
2535      * and female.  On restore, assume flags.female is correct. */
2536     if (flags.pantheon == -1) { /* new game */
2537         if (!validgend(flags.initrole, flags.initrace, flags.female))
2538             flags.female = !flags.female;
2539     }
2540     if (!validgend(flags.initrole, flags.initrace, flags.initgend))
2541         /* Note that there is no way to check for an unspecified gender. */
2542         flags.initgend = flags.female;
2543
2544     /* Check for a valid alignment */
2545     if (!validalign(flags.initrole, flags.initrace, flags.initalign))
2546         /* Pick a random alignment */
2547         flags.initalign = randalign(flags.initrole, flags.initrace);
2548     alignmnt = aligns[flags.initalign].value;
2549
2550     /* Initialize urole and urace */
2551     urole = roles[flags.initrole];
2552     urace = races[flags.initrace];
2553
2554     /* Fix up the quest leader */
2555     if (urole.ldrnum != NON_PM) {
2556         pm = &mons[urole.ldrnum];
2557         pm->msound = MS_LEADER;
2558         pm->mflags2 |= (M2_PEACEFUL);
2559         pm->mflags3 |= M3_CLOSE;
2560         pm->maligntyp = alignmnt * 3;
2561         /* if gender is random, we choose it now instead of waiting
2562            until the leader monster is created */
2563         quest_status.ldrgend =
2564             is_neuter(pm) ? 2 : is_female(pm) ? 1 : is_male(pm)
2565                                                         ? 0
2566                                                         : (rn2(100) < 50);
2567     }
2568
2569     /* Fix up the quest guardians */
2570     if (urole.guardnum != NON_PM) {
2571         pm = &mons[urole.guardnum];
2572         pm->mflags2 |= (M2_PEACEFUL);
2573         pm->maligntyp = alignmnt * 3;
2574     }
2575
2576     /* Fix up the quest nemesis */
2577     if (urole.neminum != NON_PM) {
2578         pm = &mons[urole.neminum];
2579         pm->msound = MS_NEMESIS;
2580         pm->mflags2 &= ~(M2_PEACEFUL);
2581         pm->mflags2 |= (M2_NASTY | M2_STALK | M2_HOSTILE);
2582         pm->mflags3 &= ~(M3_CLOSE);
2583         pm->mflags3 |= M3_WANTSARTI | M3_WAITFORU;
2584         /* if gender is random, we choose it now instead of waiting
2585            until the nemesis monster is created */
2586         quest_status.nemgend = is_neuter(pm) ? 2 : is_female(pm) ? 1
2587                                    : is_male(pm) ? 0 : (rn2(100) < 50);
2588     }
2589
2590     /* Fix up the god names */
2591     if (flags.pantheon == -1) {             /* new game */
2592         flags.pantheon = flags.initrole;    /* use own gods */
2593         while (!roles[flags.pantheon].lgod) /* unless they're missing */
2594             flags.pantheon = randrole(FALSE);
2595     }
2596     if (!urole.lgod) {
2597         urole.lgod = roles[flags.pantheon].lgod;
2598         urole.ngod = roles[flags.pantheon].ngod;
2599         urole.cgod = roles[flags.pantheon].cgod;
2600     }
2601     /* 0 or 1; no gods are neuter, nor is gender randomized */
2602 /*JP
2603     quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess");
2604 */
2605     quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "\8f\97\90_");
2606
2607 #if 0
2608 /*
2609  * Disable this fixup so that mons[] can be const.  The only
2610  * place where it actually matters for the hero is in set_uasmon()
2611  * and that can use mons[race] rather than mons[role] for this
2612  * particular property.  Despite the comment, it is checked--where
2613  * needed--via instrinsic 'Infravision' which set_uasmon() manages.
2614  */
2615     /* Fix up infravision */
2616     if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {
2617         /* although an infravision intrinsic is possible, infravision
2618          * is purely a property of the physical race.  This means that we
2619          * must put the infravision flag in the player's current race
2620          * (either that or have separate permonst entries for
2621          * elven/non-elven members of each class).  The side effect is that
2622          * all NPCs of that class will have (probably bogus) infravision,
2623          * but since infravision has no effect for NPCs anyway we can
2624          * ignore this.
2625          */
2626         mons[urole.malenum].mflags3 |= M3_INFRAVISION;
2627         if (urole.femalenum != NON_PM)
2628             mons[urole.femalenum].mflags3 |= M3_INFRAVISION;
2629     }
2630 #endif /*0*/
2631
2632     /* Artifacts are fixed in hack_artifacts() */
2633
2634     /* Success! */
2635     return;
2636 }
2637
2638 const char *
2639 Hello(mtmp)
2640 struct monst *mtmp;
2641 {
2642 #if 0 /*JP*/
2643     switch (Role_switch) {
2644     case PM_KNIGHT:
2645         return "Salutations"; /* Olde English */
2646     case PM_SAMURAI:
2647         return (mtmp && mtmp->data == &mons[PM_SHOPKEEPER])
2648                     ? "Irasshaimase"
2649                     : "Konnichi wa"; /* Japanese */
2650     case PM_TOURIST:
2651         return "Aloha"; /* Hawaiian */
2652     case PM_VALKYRIE:
2653         return
2654 #ifdef MAIL
2655                (mtmp && mtmp->data == &mons[PM_MAIL_DAEMON]) ? "Hallo" :
2656 #endif
2657                "Velkommen"; /* Norse */
2658     default:
2659         return "Hello";
2660     }
2661 #else
2662 /*
2663   \82 \82¢\82³\82Â\82Í\93ú\96{\8cê\82Æ\82µ\82Ä\8e©\91R\82É\82È\82é\82æ\82¤\91å\82«\82­\8ed\97l\82ð\95Ï\8dX
2664 */
2665     static char helo_buf[BUFSZ];
2666
2667     switch (Role_switch) {
2668     case PM_KNIGHT:
2669         Sprintf(helo_buf, "\82æ\82­\82¼\8eQ\82Á\82½%s\82æ", plname);
2670         break;
2671     case PM_SAMURAI:
2672         Sprintf(helo_buf, "\82æ\82­\82¼\8eQ\82ç\82ê\82½%s\82æ", plname);
2673         break;
2674     case PM_TOURIST:
2675         Sprintf(helo_buf, "\83A\83\8d\81[\83n%s", plname);
2676         break;
2677     case PM_VALKYRIE:
2678         Sprintf(helo_buf, "\8d°\82Ì\8eç\8cì\8eÒ%s\82æ", plname);
2679         break;
2680     default:
2681         Sprintf(helo_buf, "\82æ\82¤\82±\82»%s", plname);
2682         break;
2683     }
2684
2685     return helo_buf;
2686 #endif
2687 }
2688
2689 const char *
2690 Goodbye()
2691 {
2692 #if 0 /*JP*/
2693     switch (Role_switch) {
2694     case PM_KNIGHT:
2695         return "Fare thee well"; /* Olde English */
2696     case PM_SAMURAI:
2697         return "Sayonara"; /* Japanese */
2698     case PM_TOURIST:
2699         return "Aloha"; /* Hawaiian */
2700     case PM_VALKYRIE:
2701         return "Farvel"; /* Norse */
2702     default:
2703         return "Goodbye";
2704     }
2705 #else
2706     static char helo_buf[BUFSZ];
2707
2708     switch (Role_switch) {
2709     case PM_KNIGHT:
2710         Sprintf(helo_buf, "\82³\82ç\82Î\8chåi\82È\82é");
2711         break;
2712     case PM_SAMURAI:
2713         Sprintf(helo_buf, "\82³\82ç\82Î\95\90\8em\93¹\82ð\8eu\82·");
2714         break;
2715     case PM_TOURIST:
2716         Sprintf(helo_buf, "\83A\83\8d\81[\83n");
2717         break;
2718     case PM_VALKYRIE:
2719         Sprintf(helo_buf, "\82³\82ç\82Î\8d°\82Ì\8eç\8cì\8eÒ");
2720         break;
2721     default:
2722         Sprintf(helo_buf, "\82³\82æ\82¤\82È\82ç");
2723         break;
2724     }
2725
2726     return helo_buf;
2727 #endif
2728 }
2729
2730 /* role.c */