OSDN Git Service

untabify
[jnethack/source.git] / src / role.c
1 /* NetHack 3.6  role.c  $NHDT-Date: 1463561393 2016/05/18 08:49:53 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.38 $ */
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-2018            */
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
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()
1097 {
1098     return rn2(SIZE(roles) - 1);
1099 }
1100
1101 STATIC_OVL int
1102 randrole_filtered()
1103 {
1104     int i, n = 0, set[SIZE(roles)];
1105
1106     /* this doesn't rule out impossible combinations but attempts to
1107        honor all the filter masks */
1108     for (i = 0; i < SIZE(roles); ++i)
1109         if (ok_role(i, ROLE_NONE, ROLE_NONE, ROLE_NONE)
1110             && ok_race(i, ROLE_RANDOM, ROLE_NONE, ROLE_NONE)
1111             && ok_gend(i, ROLE_NONE, ROLE_RANDOM, ROLE_NONE)
1112             && ok_align(i, ROLE_NONE, ROLE_NONE, ROLE_RANDOM))
1113             set[n++] = i;
1114     return n ? set[rn2(n)] : randrole();
1115 }
1116
1117 int
1118 str2role(str)
1119 const char *str;
1120 {
1121     int i, len;
1122
1123     /* Is str valid? */
1124     if (!str || !str[0])
1125         return ROLE_NONE;
1126
1127     /* Match as much of str as is provided */
1128     len = strlen(str);
1129     for (i = 0; roles[i].name.m; i++) {
1130         /* Does it match the male name? */
1131         if (!strncmpi(str, roles[i].name.m, len))
1132             return i;
1133         /* Or the female name? */
1134         if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len))
1135             return i;
1136         /* Or the filecode? */
1137         if (!strcmpi(str, roles[i].filecode))
1138             return i;
1139     }
1140
1141     if ((len == 1 && (*str == '*' || *str == '@'))
1142         || !strncmpi(str, randomstr, len))
1143         return ROLE_RANDOM;
1144
1145     /* Couldn't find anything appropriate */
1146     return ROLE_NONE;
1147 }
1148
1149 boolean
1150 validrace(rolenum, racenum)
1151 int rolenum, racenum;
1152 {
1153     /* Assumes validrole */
1154     return (boolean) (racenum >= 0 && racenum < SIZE(races) - 1
1155                       && (roles[rolenum].allow & races[racenum].allow
1156                           & ROLE_RACEMASK));
1157 }
1158
1159 int
1160 randrace(rolenum)
1161 int rolenum;
1162 {
1163     int i, n = 0;
1164
1165     /* Count the number of valid races */
1166     for (i = 0; races[i].noun; i++)
1167         if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK)
1168             n++;
1169
1170     /* Pick a random race */
1171     /* Use a factor of 100 in case of bad random number generators */
1172     if (n)
1173         n = rn2(n * 100) / 100;
1174     for (i = 0; races[i].noun; i++)
1175         if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) {
1176             if (n)
1177                 n--;
1178             else
1179                 return i;
1180         }
1181
1182     /* This role has no permitted races? */
1183     return rn2(SIZE(races) - 1);
1184 }
1185
1186 int
1187 str2race(str)
1188 const char *str;
1189 {
1190     int i, len;
1191
1192     /* Is str valid? */
1193     if (!str || !str[0])
1194         return ROLE_NONE;
1195
1196     /* Match as much of str as is provided */
1197     len = strlen(str);
1198     for (i = 0; races[i].noun; i++) {
1199         /* Does it match the noun? */
1200         if (!strncmpi(str, races[i].noun, len))
1201             return i;
1202         /* Or the filecode? */
1203         if (!strcmpi(str, races[i].filecode))
1204             return i;
1205     }
1206
1207     if ((len == 1 && (*str == '*' || *str == '@'))
1208         || !strncmpi(str, randomstr, len))
1209         return ROLE_RANDOM;
1210
1211     /* Couldn't find anything appropriate */
1212     return ROLE_NONE;
1213 }
1214
1215 boolean
1216 validgend(rolenum, racenum, gendnum)
1217 int rolenum, racenum, gendnum;
1218 {
1219     /* Assumes validrole and validrace */
1220     return (boolean) (gendnum >= 0 && gendnum < ROLE_GENDERS
1221                       && (roles[rolenum].allow & races[racenum].allow
1222                           & genders[gendnum].allow & ROLE_GENDMASK));
1223 }
1224
1225 int
1226 randgend(rolenum, racenum)
1227 int rolenum, racenum;
1228 {
1229     int i, n = 0;
1230
1231     /* Count the number of valid genders */
1232     for (i = 0; i < ROLE_GENDERS; i++)
1233         if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1234             & ROLE_GENDMASK)
1235             n++;
1236
1237     /* Pick a random gender */
1238     if (n)
1239         n = rn2(n);
1240     for (i = 0; i < ROLE_GENDERS; i++)
1241         if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1242             & ROLE_GENDMASK) {
1243             if (n)
1244                 n--;
1245             else
1246                 return i;
1247         }
1248
1249     /* This role/race has no permitted genders? */
1250     return rn2(ROLE_GENDERS);
1251 }
1252
1253 int
1254 str2gend(str)
1255 const char *str;
1256 {
1257     int i, len;
1258
1259     /* Is str valid? */
1260     if (!str || !str[0])
1261         return ROLE_NONE;
1262
1263     /* Match as much of str as is provided */
1264     len = strlen(str);
1265     for (i = 0; i < ROLE_GENDERS; i++) {
1266         /* Does it match the adjective? */
1267         if (!strncmpi(str, genders[i].adj, len))
1268             return i;
1269         /* Or the filecode? */
1270         if (!strcmpi(str, genders[i].filecode))
1271             return i;
1272     }
1273     if ((len == 1 && (*str == '*' || *str == '@'))
1274         || !strncmpi(str, randomstr, len))
1275         return ROLE_RANDOM;
1276
1277     /* Couldn't find anything appropriate */
1278     return ROLE_NONE;
1279 }
1280
1281 boolean
1282 validalign(rolenum, racenum, alignnum)
1283 int rolenum, racenum, alignnum;
1284 {
1285     /* Assumes validrole and validrace */
1286     return (boolean) (alignnum >= 0 && alignnum < ROLE_ALIGNS
1287                       && (roles[rolenum].allow & races[racenum].allow
1288                           & aligns[alignnum].allow & ROLE_ALIGNMASK));
1289 }
1290
1291 int
1292 randalign(rolenum, racenum)
1293 int rolenum, racenum;
1294 {
1295     int i, n = 0;
1296
1297     /* Count the number of valid alignments */
1298     for (i = 0; i < ROLE_ALIGNS; i++)
1299         if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1300             & ROLE_ALIGNMASK)
1301             n++;
1302
1303     /* Pick a random alignment */
1304     if (n)
1305         n = rn2(n);
1306     for (i = 0; i < ROLE_ALIGNS; i++)
1307         if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1308             & ROLE_ALIGNMASK) {
1309             if (n)
1310                 n--;
1311             else
1312                 return i;
1313         }
1314
1315     /* This role/race has no permitted alignments? */
1316     return rn2(ROLE_ALIGNS);
1317 }
1318
1319 int
1320 str2align(str)
1321 const char *str;
1322 {
1323     int i, len;
1324
1325     /* Is str valid? */
1326     if (!str || !str[0])
1327         return ROLE_NONE;
1328
1329     /* Match as much of str as is provided */
1330     len = strlen(str);
1331     for (i = 0; i < ROLE_ALIGNS; i++) {
1332         /* Does it match the adjective? */
1333         if (!strncmpi(str, aligns[i].adj, len))
1334             return i;
1335         /* Or the filecode? */
1336         if (!strcmpi(str, aligns[i].filecode))
1337             return i;
1338     }
1339     if ((len == 1 && (*str == '*' || *str == '@'))
1340         || !strncmpi(str, randomstr, len))
1341         return ROLE_RANDOM;
1342
1343     /* Couldn't find anything appropriate */
1344     return ROLE_NONE;
1345 }
1346
1347 /* is rolenum compatible with any racenum/gendnum/alignnum constraints? */
1348 boolean
1349 ok_role(rolenum, racenum, gendnum, alignnum)
1350 int rolenum, racenum, gendnum, alignnum;
1351 {
1352     int i;
1353     short allow;
1354
1355     if (rolenum >= 0 && rolenum < SIZE(roles) - 1) {
1356         if (rfilter.roles[rolenum])
1357             return FALSE;
1358         allow = roles[rolenum].allow;
1359         if (racenum >= 0 && racenum < SIZE(races) - 1
1360             && !(allow & races[racenum].allow & ROLE_RACEMASK))
1361             return FALSE;
1362         if (gendnum >= 0 && gendnum < ROLE_GENDERS
1363             && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1364             return FALSE;
1365         if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1366             && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1367             return FALSE;
1368         return TRUE;
1369     } else {
1370         /* random; check whether any selection is possible */
1371         for (i = 0; i < SIZE(roles) - 1; i++) {
1372             if (rfilter.roles[i])
1373                 continue;
1374             allow = roles[i].allow;
1375             if (racenum >= 0 && racenum < SIZE(races) - 1
1376                 && !(allow & races[racenum].allow & ROLE_RACEMASK))
1377                 continue;
1378             if (gendnum >= 0 && gendnum < ROLE_GENDERS
1379                 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1380                 continue;
1381             if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1382                 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1383                 continue;
1384             return TRUE;
1385         }
1386         return FALSE;
1387     }
1388 }
1389
1390 /* pick a random role subject to any racenum/gendnum/alignnum constraints */
1391 /* If pickhow == PICK_RIGID a role is returned only if there is  */
1392 /* a single possibility */
1393 int
1394 pick_role(racenum, gendnum, alignnum, pickhow)
1395 int racenum, gendnum, alignnum, pickhow;
1396 {
1397     int i;
1398     int roles_ok = 0, set[SIZE(roles)];
1399
1400     for (i = 0; i < SIZE(roles) - 1; i++) {
1401         if (ok_role(i, racenum, gendnum, alignnum)
1402             && ok_race(i, (racenum >= 0) ? racenum : ROLE_RANDOM,
1403                        gendnum, alignnum)
1404             && ok_gend(i, racenum,
1405                        (gendnum >= 0) ? gendnum : ROLE_RANDOM, alignnum)
1406             && ok_race(i, racenum,
1407                        gendnum, (alignnum >= 0) ? alignnum : ROLE_RANDOM))
1408             set[roles_ok++] = i;
1409     }
1410     if (roles_ok == 0 || (roles_ok > 1 && pickhow == PICK_RIGID))
1411         return ROLE_NONE;
1412     return set[rn2(roles_ok)];
1413 }
1414
1415 /* is racenum compatible with any rolenum/gendnum/alignnum constraints? */
1416 boolean
1417 ok_race(rolenum, racenum, gendnum, alignnum)
1418 int rolenum, racenum, gendnum, alignnum;
1419 {
1420     int i;
1421     short allow;
1422
1423     if (racenum >= 0 && racenum < SIZE(races) - 1) {
1424         if (rfilter.mask & races[racenum].selfmask)
1425             return FALSE;
1426         allow = races[racenum].allow;
1427         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1428             && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1429             return FALSE;
1430         if (gendnum >= 0 && gendnum < ROLE_GENDERS
1431             && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1432             return FALSE;
1433         if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1434             && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1435             return FALSE;
1436         return TRUE;
1437     } else {
1438         /* random; check whether any selection is possible */
1439         for (i = 0; i < SIZE(races) - 1; i++) {
1440             if (rfilter.mask & races[i].selfmask)
1441                 continue;
1442             allow = races[i].allow;
1443             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1444                 && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1445                 continue;
1446             if (gendnum >= 0 && gendnum < ROLE_GENDERS
1447                 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1448                 continue;
1449             if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1450                 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1451                 continue;
1452             return TRUE;
1453         }
1454         return FALSE;
1455     }
1456 }
1457
1458 /* Pick a random race subject to any rolenum/gendnum/alignnum constraints.
1459    If pickhow == PICK_RIGID a race is returned only if there is
1460    a single possibility. */
1461 int
1462 pick_race(rolenum, gendnum, alignnum, pickhow)
1463 int rolenum, gendnum, alignnum, pickhow;
1464 {
1465     int i;
1466     int races_ok = 0;
1467
1468     for (i = 0; i < SIZE(races) - 1; i++) {
1469         if (ok_race(rolenum, i, gendnum, alignnum))
1470             races_ok++;
1471     }
1472     if (races_ok == 0 || (races_ok > 1 && pickhow == PICK_RIGID))
1473         return ROLE_NONE;
1474     races_ok = rn2(races_ok);
1475     for (i = 0; i < SIZE(races) - 1; i++) {
1476         if (ok_race(rolenum, i, gendnum, alignnum)) {
1477             if (races_ok == 0)
1478                 return i;
1479             else
1480                 races_ok--;
1481         }
1482     }
1483     return ROLE_NONE;
1484 }
1485
1486 /* is gendnum compatible with any rolenum/racenum/alignnum constraints? */
1487 /* gender and alignment are not comparable (and also not constrainable) */
1488 boolean
1489 ok_gend(rolenum, racenum, gendnum, alignnum)
1490 int rolenum, racenum, gendnum;
1491 int alignnum UNUSED;
1492 {
1493     int i;
1494     short allow;
1495
1496     if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
1497         if (rfilter.mask & genders[gendnum].allow)
1498             return FALSE;
1499         allow = genders[gendnum].allow;
1500         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1501             && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1502             return FALSE;
1503         if (racenum >= 0 && racenum < SIZE(races) - 1
1504             && !(allow & races[racenum].allow & ROLE_GENDMASK))
1505             return FALSE;
1506         return TRUE;
1507     } else {
1508         /* random; check whether any selection is possible */
1509         for (i = 0; i < ROLE_GENDERS; i++) {
1510             if (rfilter.mask & genders[i].allow)
1511                 continue;
1512             allow = genders[i].allow;
1513             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1514                 && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1515                 continue;
1516             if (racenum >= 0 && racenum < SIZE(races) - 1
1517                 && !(allow & races[racenum].allow & ROLE_GENDMASK))
1518                 continue;
1519             return TRUE;
1520         }
1521         return FALSE;
1522     }
1523 }
1524
1525 /* pick a random gender subject to any rolenum/racenum/alignnum constraints */
1526 /* gender and alignment are not comparable (and also not constrainable) */
1527 /* If pickhow == PICK_RIGID a gender is returned only if there is  */
1528 /* a single possibility */
1529 int
1530 pick_gend(rolenum, racenum, alignnum, pickhow)
1531 int rolenum, racenum, alignnum, pickhow;
1532 {
1533     int i;
1534     int gends_ok = 0;
1535
1536     for (i = 0; i < ROLE_GENDERS; i++) {
1537         if (ok_gend(rolenum, racenum, i, alignnum))
1538             gends_ok++;
1539     }
1540     if (gends_ok == 0 || (gends_ok > 1 && pickhow == PICK_RIGID))
1541         return ROLE_NONE;
1542     gends_ok = rn2(gends_ok);
1543     for (i = 0; i < ROLE_GENDERS; i++) {
1544         if (ok_gend(rolenum, racenum, i, alignnum)) {
1545             if (gends_ok == 0)
1546                 return i;
1547             else
1548                 gends_ok--;
1549         }
1550     }
1551     return ROLE_NONE;
1552 }
1553
1554 /* is alignnum compatible with any rolenum/racenum/gendnum constraints? */
1555 /* alignment and gender are not comparable (and also not constrainable) */
1556 boolean
1557 ok_align(rolenum, racenum, gendnum, alignnum)
1558 int rolenum, racenum;
1559 int gendnum UNUSED;
1560 int alignnum;
1561 {
1562     int i;
1563     short allow;
1564
1565     if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
1566         if (rfilter.mask & aligns[alignnum].allow)
1567             return FALSE;
1568         allow = aligns[alignnum].allow;
1569         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1570             && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1571             return FALSE;
1572         if (racenum >= 0 && racenum < SIZE(races) - 1
1573             && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1574             return FALSE;
1575         return TRUE;
1576     } else {
1577         /* random; check whether any selection is possible */
1578         for (i = 0; i < ROLE_ALIGNS; i++) {
1579             if (rfilter.mask & aligns[i].allow)
1580                 return FALSE;
1581             allow = aligns[i].allow;
1582             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1583                 && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1584                 continue;
1585             if (racenum >= 0 && racenum < SIZE(races) - 1
1586                 && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1587                 continue;
1588             return TRUE;
1589         }
1590         return FALSE;
1591     }
1592 }
1593
1594 /* Pick a random alignment subject to any rolenum/racenum/gendnum constraints;
1595    alignment and gender are not comparable (and also not constrainable).
1596    If pickhow == PICK_RIGID an alignment is returned only if there is
1597    a single possibility. */
1598 int
1599 pick_align(rolenum, racenum, gendnum, pickhow)
1600 int rolenum, racenum, gendnum, pickhow;
1601 {
1602     int i;
1603     int aligns_ok = 0;
1604
1605     for (i = 0; i < ROLE_ALIGNS; i++) {
1606         if (ok_align(rolenum, racenum, gendnum, i))
1607             aligns_ok++;
1608     }
1609     if (aligns_ok == 0 || (aligns_ok > 1 && pickhow == PICK_RIGID))
1610         return ROLE_NONE;
1611     aligns_ok = rn2(aligns_ok);
1612     for (i = 0; i < ROLE_ALIGNS; i++) {
1613         if (ok_align(rolenum, racenum, gendnum, i)) {
1614             if (aligns_ok == 0)
1615                 return i;
1616             else
1617                 aligns_ok--;
1618         }
1619     }
1620     return ROLE_NONE;
1621 }
1622
1623 void
1624 rigid_role_checks()
1625 {
1626     int tmp;
1627
1628     /* Some roles are limited to a single race, alignment, or gender and
1629      * calling this routine prior to XXX_player_selection() will help
1630      * prevent an extraneous prompt that actually doesn't allow
1631      * you to choose anything further. Note the use of PICK_RIGID which
1632      * causes the pick_XX() routine to return a value only if there is one
1633      * single possible selection, otherwise it returns ROLE_NONE.
1634      *
1635      */
1636     if (flags.initrole == ROLE_RANDOM) {
1637         /* If the role was explicitly specified as ROLE_RANDOM
1638          * via -uXXXX-@ or OPTIONS=role:random then choose the role
1639          * in here to narrow down later choices.
1640          */
1641         flags.initrole = pick_role(flags.initrace, flags.initgend,
1642                                    flags.initalign, PICK_RANDOM);
1643         if (flags.initrole < 0)
1644             flags.initrole = randrole_filtered();
1645     }
1646     if (flags.initrace == ROLE_RANDOM
1647         && (tmp = pick_race(flags.initrole, flags.initgend,
1648                             flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1649         flags.initrace = tmp;
1650     if (flags.initalign == ROLE_RANDOM
1651         && (tmp = pick_align(flags.initrole, flags.initrace,
1652                              flags.initgend, PICK_RANDOM)) != ROLE_NONE)
1653         flags.initalign = tmp;
1654     if (flags.initgend == ROLE_RANDOM
1655         && (tmp = pick_gend(flags.initrole, flags.initrace,
1656                             flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1657         flags.initgend = tmp;
1658
1659     if (flags.initrole != ROLE_NONE) {
1660         if (flags.initrace == ROLE_NONE)
1661             flags.initrace = pick_race(flags.initrole, flags.initgend,
1662                                        flags.initalign, PICK_RIGID);
1663         if (flags.initalign == ROLE_NONE)
1664             flags.initalign = pick_align(flags.initrole, flags.initrace,
1665                                          flags.initgend, PICK_RIGID);
1666         if (flags.initgend == ROLE_NONE)
1667             flags.initgend = pick_gend(flags.initrole, flags.initrace,
1668                                        flags.initalign, PICK_RIGID);
1669     }
1670 }
1671
1672 boolean
1673 setrolefilter(bufp)
1674 const char *bufp;
1675 {
1676     int i;
1677     boolean reslt = TRUE;
1678
1679     if ((i = str2role(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1680         rfilter.roles[i] = TRUE;
1681     else if ((i = str2race(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1682         rfilter.mask |= races[i].selfmask;
1683     else if ((i = str2gend(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1684         rfilter.mask |= genders[i].allow;
1685     else if ((i = str2align(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1686         rfilter.mask |= aligns[i].allow;
1687     else
1688         reslt = FALSE;
1689     return reslt;
1690 }
1691
1692 boolean
1693 gotrolefilter()
1694 {
1695     int i;
1696
1697     if (rfilter.mask)
1698         return TRUE;
1699     for (i = 0; i < SIZE(roles); ++i)
1700         if (rfilter.roles[i])
1701             return TRUE;
1702     return FALSE;
1703 }
1704
1705 void
1706 clearrolefilter()
1707 {
1708     int i;
1709
1710     for (i = 0; i < SIZE(roles); ++i)
1711         rfilter.roles[i] = FALSE;
1712     rfilter.mask = 0;
1713 }
1714
1715 #define BP_ALIGN 0
1716 #define BP_GEND 1
1717 #define BP_RACE 2
1718 #define BP_ROLE 3
1719 #define NUM_BP 4
1720
1721 STATIC_VAR char pa[NUM_BP], post_attribs;
1722
1723 STATIC_OVL char *
1724 promptsep(buf, num_post_attribs)
1725 char *buf;
1726 int num_post_attribs;
1727 {
1728 #if 0 /*JP*/
1729     const char *conjuct = "and ";
1730
1731     if (num_post_attribs > 1 && post_attribs < num_post_attribs
1732         && post_attribs > 1)
1733         Strcat(buf, ",");
1734     Strcat(buf, " ");
1735     --post_attribs;
1736     if (!post_attribs && num_post_attribs > 1)
1737         Strcat(buf, conjuct);
1738 #else
1739     /*JP: \93ú\96{\8cê\82Å\82Í "A, B, and C" \82Æ\82¢\82¤\8f\88\97\9d\82Í\95s\97v */
1740     if(num_post_attribs > post_attribs){
1741         Strcat(buf, "\81C");
1742     }
1743     --post_attribs;
1744 #endif
1745     return buf;
1746 }
1747
1748 STATIC_OVL int
1749 role_gendercount(rolenum)
1750 int rolenum;
1751 {
1752     int gendcount = 0;
1753
1754     if (validrole(rolenum)) {
1755         if (roles[rolenum].allow & ROLE_MALE)
1756             ++gendcount;
1757         if (roles[rolenum].allow & ROLE_FEMALE)
1758             ++gendcount;
1759         if (roles[rolenum].allow & ROLE_NEUTER)
1760             ++gendcount;
1761     }
1762     return gendcount;
1763 }
1764
1765 STATIC_OVL int
1766 race_alignmentcount(racenum)
1767 int racenum;
1768 {
1769     int aligncount = 0;
1770
1771     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1772         if (races[racenum].allow & ROLE_CHAOTIC)
1773             ++aligncount;
1774         if (races[racenum].allow & ROLE_LAWFUL)
1775             ++aligncount;
1776         if (races[racenum].allow & ROLE_NEUTRAL)
1777             ++aligncount;
1778     }
1779     return aligncount;
1780 }
1781
1782 char *
1783 root_plselection_prompt(suppliedbuf, buflen, rolenum, racenum, gendnum,
1784                         alignnum)
1785 char *suppliedbuf;
1786 int buflen, rolenum, racenum, gendnum, alignnum;
1787 {
1788     int k, gendercount = 0, aligncount = 0;
1789     char buf[BUFSZ];
1790 /*JP
1791     static char err_ret[] = " character's";
1792 */
1793     static char err_ret[] = "\83L\83\83\83\89\83N\83^\81[\82Ì";
1794     boolean donefirst = FALSE;
1795
1796     if (!suppliedbuf || buflen < 1)
1797         return err_ret;
1798
1799     /* initialize these static variables each time this is called */
1800     post_attribs = 0;
1801     for (k = 0; k < NUM_BP; ++k)
1802         pa[k] = 0;
1803     buf[0] = '\0';
1804     *suppliedbuf = '\0';
1805
1806     /* How many alignments are allowed for the desired race? */
1807     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1808         aligncount = race_alignmentcount(racenum);
1809
1810     if (alignnum != ROLE_NONE && alignnum != ROLE_RANDOM
1811         && ok_align(rolenum, racenum, gendnum, alignnum)) {
1812         /* if race specified, and multiple choice of alignments for it */
1813         if ((racenum >= 0) && (aligncount > 1)) {
1814 #if 0 /*JP*/
1815             if (donefirst)
1816                 Strcat(buf, " ");
1817 #endif
1818             Strcat(buf, aligns[alignnum].adj);
1819             donefirst = TRUE;
1820         } else {
1821 #if 0 /*JP*/
1822             if (donefirst)
1823                 Strcat(buf, " ");
1824 #endif
1825             Strcat(buf, aligns[alignnum].adj);
1826             donefirst = TRUE;
1827         }
1828     } else {
1829         /* in case we got here by failing the ok_align() test */
1830         if (alignnum != ROLE_RANDOM)
1831             alignnum = ROLE_NONE;
1832         /* if alignment not specified, but race is specified
1833            and only one choice of alignment for that race then
1834            don't include it in the later list */
1835         if ((((racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1836               && ok_race(rolenum, racenum, gendnum, alignnum))
1837              && (aligncount > 1))
1838             || (racenum == ROLE_NONE || racenum == ROLE_RANDOM)) {
1839             pa[BP_ALIGN] = 1;
1840             post_attribs++;
1841         }
1842     }
1843     /* <your lawful> */
1844
1845     /* How many genders are allowed for the desired role? */
1846     if (validrole(rolenum))
1847         gendercount = role_gendercount(rolenum);
1848
1849     if (gendnum != ROLE_NONE && gendnum != ROLE_RANDOM) {
1850         if (validrole(rolenum)) {
1851             /* if role specified, and multiple choice of genders for it,
1852                and name of role itself does not distinguish gender */
1853             if ((rolenum != ROLE_NONE) && (gendercount > 1)
1854                 && !roles[rolenum].name.f) {
1855 #if 0 /*JP*/
1856                 if (donefirst)
1857                     Strcat(buf, " ");
1858 #endif
1859                 Strcat(buf, genders[gendnum].adj);
1860                 donefirst = TRUE;
1861             }
1862         } else {
1863 #if 0 /*JP*/
1864             if (donefirst)
1865                 Strcat(buf, " ");
1866 #endif
1867             Strcat(buf, genders[gendnum].adj);
1868             donefirst = TRUE;
1869         }
1870     } else {
1871         /* if gender not specified, but role is specified
1872                 and only one choice of gender then
1873                 don't include it in the later list */
1874         if ((validrole(rolenum) && (gendercount > 1))
1875             || !validrole(rolenum)) {
1876             pa[BP_GEND] = 1;
1877             post_attribs++;
1878         }
1879     }
1880     /* <your lawful female> */
1881
1882     if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1883         if (validrole(rolenum)
1884             && ok_race(rolenum, racenum, gendnum, alignnum)) {
1885 #if 0 /*JP*/
1886             if (donefirst)
1887                 Strcat(buf, " ");
1888 #endif
1889             Strcat(buf, (rolenum == ROLE_NONE) ? races[racenum].noun
1890                                                : races[racenum].adj);
1891             donefirst = TRUE;
1892         } else if (!validrole(rolenum)) {
1893 #if 0 /*JP*/
1894             if (donefirst)
1895                 Strcat(buf, " ");
1896 #endif
1897             Strcat(buf, races[racenum].noun);
1898             donefirst = TRUE;
1899         } else {
1900             pa[BP_RACE] = 1;
1901             post_attribs++;
1902         }
1903     } else {
1904         pa[BP_RACE] = 1;
1905         post_attribs++;
1906     }
1907     /* <your lawful female gnomish> || <your lawful female gnome> */
1908
1909     if (validrole(rolenum)) {
1910 #if 0 /*JP*/
1911         if (donefirst)
1912             Strcat(buf, " ");
1913 #endif
1914         if (gendnum != ROLE_NONE) {
1915             if (gendnum == 1 && roles[rolenum].name.f)
1916                 Strcat(buf, roles[rolenum].name.f);
1917             else
1918                 Strcat(buf, roles[rolenum].name.m);
1919         } else {
1920             if (roles[rolenum].name.f) {
1921                 Strcat(buf, roles[rolenum].name.m);
1922                 Strcat(buf, "/");
1923                 Strcat(buf, roles[rolenum].name.f);
1924             } else
1925                 Strcat(buf, roles[rolenum].name.m);
1926         }
1927         donefirst = TRUE;
1928     } else if (rolenum == ROLE_NONE) {
1929         pa[BP_ROLE] = 1;
1930         post_attribs++;
1931     }
1932
1933     if ((racenum == ROLE_NONE || racenum == ROLE_RANDOM)
1934         && !validrole(rolenum)) {
1935 #if 0 /*JP*/
1936         if (donefirst)
1937             Strcat(buf, " ");
1938 #endif
1939 /*JP
1940         Strcat(buf, "character");
1941 */
1942         Strcat(buf, "\83L\83\83\83\89\83N\83^\81[");
1943         donefirst = TRUE;
1944     }
1945     /* <your lawful female gnomish cavewoman> || <your lawful female gnome>
1946      *    || <your lawful female character>
1947      */
1948     if (buflen > (int) (strlen(buf) + 1)) {
1949         Strcpy(suppliedbuf, buf);
1950         return suppliedbuf;
1951     } else
1952         return err_ret;
1953 }
1954
1955 char *
1956 build_plselection_prompt(buf, buflen, rolenum, racenum, gendnum, alignnum)
1957 char *buf;
1958 int buflen, rolenum, racenum, gendnum, alignnum;
1959 {
1960 /*JP
1961     const char *defprompt = "Shall I pick a character for you? [ynaq] ";
1962 */
1963     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] ";
1964     int num_post_attribs = 0;
1965 #if 0 /*JP*/
1966     char tmpbuf[BUFSZ], *p;
1967 #else
1968     char tmpbuf[BUFSZ];
1969 #endif
1970
1971     if (buflen < QBUFSZ)
1972         return (char *) defprompt;
1973
1974 #if 0 /*JP*/
1975     Strcpy(tmpbuf, "Shall I pick ");
1976     if (racenum != ROLE_NONE || validrole(rolenum))
1977         Strcat(tmpbuf, "your ");
1978     else {
1979         Strcat(tmpbuf, "a ");
1980     }
1981 #else
1982     Strcpy(tmpbuf, "");
1983 #endif
1984     /* <your> */
1985
1986     (void) root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf),
1987                                    rolenum, racenum, gendnum, alignnum);
1988 #if 0 /*JP*/
1989     Sprintf(buf, "%s", s_suffix(tmpbuf));
1990 #else
1991     Sprintf(buf, "%s\82Ì", tmpbuf);
1992 #endif
1993 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\95s\97v*/
1994     /* don't bother splitting caveman/cavewoman or priest/priestess
1995        in order to apply possessive suffix to both halves, but do
1996        change "priest/priestess'" to "priest/priestess's" */
1997     if ((p = strstri(buf, "priest/priestess'")) != 0
1998         && p[sizeof "priest/priestess'" - sizeof ""] == '\0')
1999         strkitten(buf, 's');
2000 #endif
2001
2002     /* buf should now be:
2003      *    <your lawful female gnomish cavewoman's>
2004      * || <your lawful female gnome's>
2005      * || <your lawful female character's>
2006      *
2007      * Now append the post attributes to it
2008      */
2009     num_post_attribs = post_attribs;
2010     if (!num_post_attribs) {
2011         /* some constraints might have been mutually exclusive, in which case
2012            some prompting that would have been omitted is needed after all */
2013         if (flags.initrole == ROLE_NONE && !pa[BP_ROLE])
2014             pa[BP_ROLE] = ++post_attribs;
2015         if (flags.initrace == ROLE_NONE && !pa[BP_RACE])
2016             pa[BP_RACE] = ++post_attribs;
2017         if (flags.initalign == ROLE_NONE && !pa[BP_ALIGN])
2018             pa[BP_ALIGN] = ++post_attribs;
2019         if (flags.initgend == ROLE_NONE && !pa[BP_GEND])
2020             pa[BP_GEND] = ++post_attribs;
2021         num_post_attribs = post_attribs;
2022     }
2023     if (num_post_attribs) {
2024         if (pa[BP_RACE]) {
2025             (void) promptsep(eos(buf), num_post_attribs);
2026 /*
2027             Strcat(buf, "race");
2028 */
2029             Strcat(buf, "\8eí\91°");
2030         }
2031         if (pa[BP_ROLE]) {
2032             (void) promptsep(eos(buf), num_post_attribs);
2033 /*
2034             Strcat(buf, "role");
2035 */
2036             Strcat(buf, "\90E\8bÆ");
2037         }
2038         if (pa[BP_GEND]) {
2039             (void) promptsep(eos(buf), num_post_attribs);
2040 /*JP
2041             Strcat(buf, "gender");
2042 */
2043             Strcat(buf, "\90«\95Ê");
2044         }
2045         if (pa[BP_ALIGN]) {
2046             (void) promptsep(eos(buf), num_post_attribs);
2047 /*JP
2048             Strcat(buf, "alignment");
2049 */
2050             Strcat(buf, "\91®\90«");
2051         }
2052     }
2053 /*JP
2054     Strcat(buf, " for you? [ynaq] ");
2055 */
2056     Strcat(buf, "\82ð\93K\93\96\82É\91I\82ñ\82Å\82æ\82ë\82µ\82¢\82Å\82·\82©\81H[ynq] ");
2057     return buf;
2058 }
2059
2060 #undef BP_ALIGN
2061 #undef BP_GEND
2062 #undef BP_RACE
2063 #undef BP_ROLE
2064 #undef NUM_BP
2065
2066 void
2067 plnamesuffix()
2068 {
2069     char *sptr, *eptr;
2070     int i;
2071
2072     /* some generic user names will be ignored in favor of prompting */
2073     if (sysopt.genericusers) {
2074         if (*sysopt.genericusers == '*') *plname = '\0';
2075         else {
2076             i = (int)strlen(plname);
2077             if ((sptr = strstri(sysopt.genericusers, plname)) != 0
2078                 && (sptr == sysopt.genericusers || sptr[-1] == ' ')
2079                 && (sptr[i] == ' ' || sptr[i] == '\0'))
2080                 *plname = '\0'; /* call askname() */
2081         }
2082     }
2083
2084     do {
2085         if (!*plname)
2086             askname(); /* fill plname[] if necessary, or set defer_plname */
2087
2088         /* Look for tokens delimited by '-' */
2089         if ((eptr = index(plname, '-')) != (char *) 0)
2090             *eptr++ = '\0';
2091         while (eptr) {
2092             /* Isolate the next token */
2093             sptr = eptr;
2094             if ((eptr = index(sptr, '-')) != (char *) 0)
2095                 *eptr++ = '\0';
2096
2097             /* Try to match it to something */
2098             if ((i = str2role(sptr)) != ROLE_NONE)
2099                 flags.initrole = i;
2100             else if ((i = str2race(sptr)) != ROLE_NONE)
2101                 flags.initrace = i;
2102             else if ((i = str2gend(sptr)) != ROLE_NONE)
2103                 flags.initgend = i;
2104             else if ((i = str2align(sptr)) != ROLE_NONE)
2105                 flags.initalign = i;
2106         }
2107     } while (!*plname && !iflags.defer_plname);
2108
2109     /* commas in the plname confuse the record file, convert to spaces */
2110     for (sptr = plname; *sptr; sptr++) {
2111         if (*sptr == ',')
2112             *sptr = ' ';
2113     }
2114 }
2115
2116 /* show current settings for name, role, race, gender, and alignment
2117    in the specified window */
2118 void
2119 role_selection_prolog(which, where)
2120 int which;
2121 winid where;
2122 {
2123 /*JP
2124     static const char NEARDATA choosing[] = " choosing now",
2125 */
2126     static const char NEARDATA choosing[] = " \8c»\8dÝ\91I\91ð\92\86",
2127 /*JP
2128                                not_yet[] = " not yet specified",
2129 */
2130                                not_yet[] = " \96¢\91I\91ð",
2131 /*JP
2132                                rand_choice[] = " random";
2133 */
2134                                rand_choice[] = " \83\89\83\93\83_\83\80";
2135     char buf[BUFSZ];
2136     int r, c, g, a, allowmask;
2137
2138     r = flags.initrole;
2139     c = flags.initrace;
2140     g = flags.initgend;
2141     a = flags.initalign;
2142     if (r >= 0) {
2143         allowmask = roles[r].allow;
2144         if ((allowmask & ROLE_RACEMASK) == MH_HUMAN)
2145             c = 0; /* races[human] */
2146         else if (c >= 0 && !(allowmask & ROLE_RACEMASK & races[c].allow))
2147             c = ROLE_RANDOM;
2148         if ((allowmask & ROLE_GENDMASK) == ROLE_MALE)
2149             g = 0; /* role forces male (hypothetical) */
2150         else if ((allowmask & ROLE_GENDMASK) == ROLE_FEMALE)
2151             g = 1; /* role forces female (valkyrie) */
2152         if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2153             a = 0; /* aligns[lawful] */
2154         else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2155             a = 1; /* aligns[neutral] */
2156         else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2157             a = 2; /* alings[chaotic] */
2158     }
2159     if (c >= 0) {
2160         allowmask = races[c].allow;
2161         if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2162             a = 0; /* aligns[lawful] */
2163         else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2164             a = 1; /* aligns[neutral] */
2165         else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2166             a = 2; /* alings[chaotic] */
2167         /* [c never forces gender] */
2168     }
2169     /* [g and a don't constrain anything sufficiently
2170        to narrow something done to a single choice] */
2171
2172 /*JP
2173     Sprintf(buf, "%12s ", "name:");
2174 */
2175     Sprintf(buf, "%12s ", "\96¼\91O:");
2176     Strcat(buf, (which == RS_NAME) ? choosing : !*plname ? not_yet : plname);
2177     putstr(where, 0, buf);
2178 /*JP
2179     Sprintf(buf, "%12s ", "role:");
2180 */
2181     Sprintf(buf, "%12s ", "\90E\8bÆ:");
2182     Strcat(buf, (which == RS_ROLE) ? choosing : (r == ROLE_NONE)
2183                                                     ? not_yet
2184                                                     : (r == ROLE_RANDOM)
2185                                                           ? rand_choice
2186                                                           : roles[r].name.m);
2187     if (r >= 0 && roles[r].name.f) {
2188         /* distinct female name [caveman/cavewoman, priest/priestess] */
2189         if (g == 1)
2190             /* female specified; replace male role name with female one */
2191             Sprintf(index(buf, ':'), ": %s", roles[r].name.f);
2192         else if (g < 0)
2193             /* gender unspecified; append slash and female role name */
2194             Sprintf(eos(buf), "/%s", roles[r].name.f);
2195     }
2196     putstr(where, 0, buf);
2197 /*JP
2198     Sprintf(buf, "%12s ", "race:");
2199 */
2200     Sprintf(buf, "%12s ", "\8eí\91°:");
2201     Strcat(buf, (which == RS_RACE) ? choosing : (c == ROLE_NONE)
2202                                                     ? not_yet
2203                                                     : (c == ROLE_RANDOM)
2204                                                           ? rand_choice
2205                                                           : races[c].noun);
2206     putstr(where, 0, buf);
2207 /*JP
2208     Sprintf(buf, "%12s ", "gender:");
2209 */
2210     Sprintf(buf, "%12s ", "\90«\95Ê:");
2211     Strcat(buf, (which == RS_GENDER) ? choosing : (g == ROLE_NONE)
2212                                                       ? not_yet
2213                                                       : (g == ROLE_RANDOM)
2214                                                             ? rand_choice
2215                                                             : genders[g].adj);
2216     putstr(where, 0, buf);
2217 /*JP
2218     Sprintf(buf, "%12s ", "alignment:");
2219 */
2220     Sprintf(buf, "%12s ", "\91®\90«:");
2221     Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
2222                                                        ? not_yet
2223                                                        : (a == ROLE_RANDOM)
2224                                                              ? rand_choice
2225 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\96¼\8e\8c\82ª\8e©\91R*/
2226                                                              : aligns[a].adj);
2227 #else
2228                                                              : aligns[a].noun);
2229 #endif
2230     putstr(where, 0, buf);
2231 }
2232
2233 /* add a "pick alignment first"-type entry to the specified menu */
2234 void
2235 role_menu_extra(which, where, preselect)
2236 int which;
2237 winid where;
2238 boolean preselect;
2239 {
2240     static NEARDATA const char RS_menu_let[] = {
2241         '=',  /* name */
2242         '?',  /* role */
2243         '/',  /* race */
2244         '\"', /* gender */
2245         '[',  /* alignment */
2246     };
2247     anything any;
2248     char buf[BUFSZ];
2249     const char *what = 0, *constrainer = 0, *forcedvalue = 0;
2250     int f = 0, r, c, g, a, i, allowmask;
2251
2252     r = flags.initrole;
2253     c = flags.initrace;
2254     switch (which) {
2255     case RS_NAME:
2256 /*JP
2257         what = "name";
2258 */
2259         what = "\96¼\91O";
2260         break;
2261     case RS_ROLE:
2262 /*JP
2263         what = "role";
2264 */
2265         what = "\90E\8bÆ";
2266         f = r;
2267         for (i = 0; i < SIZE(roles); ++i)
2268             if (i != f && !rfilter.roles[i])
2269                 break;
2270         if (i == SIZE(roles)) {
2271 /*JP
2272             constrainer = "filter";
2273 */
2274             constrainer = "\8di\82è\8d\9e\82Ý";
2275 /*JP
2276             forcedvalue = "role";
2277 */
2278             forcedvalue = "\90E\8bÆ";
2279         }
2280         break;
2281     case RS_RACE:
2282 /*JP
2283         what = "race";
2284 */
2285         what = "\8eí\91°";
2286         f = flags.initrace;
2287         c = ROLE_NONE; /* override player's setting */
2288         if (r >= 0) {
2289             allowmask = roles[r].allow & ROLE_RACEMASK;
2290             if (allowmask == MH_HUMAN)
2291                 c = 0; /* races[human] */
2292             if (c >= 0) {
2293 /*JP
2294                 constrainer = "role";
2295 */
2296                 constrainer = "\90E\8bÆ";
2297                 forcedvalue = races[c].noun;
2298             } else if (f >= 0
2299                        && (allowmask & ~rfilter.mask) == races[f].selfmask) {
2300                 /* if there is only one race choice available due to user
2301                    options disallowing others, race menu entry is disabled */
2302 /*JP
2303                 constrainer = "filter";
2304 */
2305                 constrainer = "\8di\82è\8d\9e\82Ý";
2306 /*JP
2307                 forcedvalue = "race";
2308 */
2309                 forcedvalue = "\8eí\91°";
2310             }
2311         }
2312         break;
2313     case RS_GENDER:
2314 /*JP
2315         what = "gender";
2316 */
2317         what = "\90«\95Ê";
2318         f = flags.initgend;
2319         g = ROLE_NONE;
2320         if (r >= 0) {
2321             allowmask = roles[r].allow & ROLE_GENDMASK;
2322             if (allowmask == ROLE_MALE)
2323                 g = 0; /* genders[male] */
2324             else if (allowmask == ROLE_FEMALE)
2325                 g = 1; /* genders[female] */
2326             if (g >= 0) {
2327 /*JP
2328                 constrainer = "role";
2329 */
2330                 constrainer = "\90E\8bÆ";
2331                 forcedvalue = genders[g].adj;
2332             } else if (f >= 0
2333                        && (allowmask & ~rfilter.mask) == genders[f].allow) {
2334                 /* if there is only one gender choice available due to user
2335                    options disallowing other, gender menu entry is disabled */
2336 /*JP
2337                 constrainer = "filter";
2338 */
2339                 constrainer = "\8di\82è\8d\9e\82Ý";
2340 /*JP
2341                 forcedvalue = "gender";
2342 */
2343                 forcedvalue = "\90«\95Ê";
2344             }
2345         }
2346         break;
2347     case RS_ALGNMNT:
2348 /*JP
2349         what = "alignment";
2350 */
2351         what = "\91®\90«";
2352         f = flags.initalign;
2353         a = ROLE_NONE;
2354         if (r >= 0) {
2355             allowmask = roles[r].allow & ROLE_ALIGNMASK;
2356             if (allowmask == AM_LAWFUL)
2357                 a = 0; /* aligns[lawful] */
2358             else if (allowmask == AM_NEUTRAL)
2359                 a = 1; /* aligns[neutral] */
2360             else if (allowmask == AM_CHAOTIC)
2361                 a = 2; /* aligns[chaotic] */
2362             if (a >= 0)
2363 /*JP
2364                 constrainer = "role";
2365 */
2366                 constrainer = "\90E\8bÆ";
2367         }
2368         if (c >= 0 && !constrainer) {
2369             allowmask = races[c].allow & ROLE_ALIGNMASK;
2370             if (allowmask == AM_LAWFUL)
2371                 a = 0; /* aligns[lawful] */
2372             else if (allowmask == AM_NEUTRAL)
2373                 a = 1; /* aligns[neutral] */
2374             else if (allowmask == AM_CHAOTIC)
2375                 a = 2; /* aligns[chaotic] */
2376             if (a >= 0)
2377 /*JP
2378                 constrainer = "race";
2379 */
2380                 constrainer = "\8eí\91°";
2381         }
2382         if (f >= 0 && !constrainer
2383             && (ROLE_ALIGNMASK & ~rfilter.mask) == aligns[f].allow) {
2384             /* if there is only one alignment choice available due to user
2385                options disallowing others, algn menu entry is disabled */
2386 /*JP
2387             constrainer = "filter";
2388 */
2389             constrainer = "\8di\82è\8d\9e\82Ý";
2390 /*JP
2391             forcedvalue = "alignment";
2392 */
2393             forcedvalue = "\91®\90«";
2394         }
2395         if (a >= 0)
2396 #if 0 /*JP:\93ú\96{\8cê\82Å\82Í\96¼\8e\8c\82ª\8e©\91R*/
2397             forcedvalue = aligns[a].adj;
2398 #else
2399             forcedvalue = aligns[a].noun;
2400 #endif
2401         break;
2402     }
2403
2404     any = zeroany; /* zero out all bits */
2405     if (constrainer) {
2406         any.a_int = 0;
2407         /* use four spaces of padding to fake a grayed out menu choice */
2408 /*JP
2409         Sprintf(buf, "%4s%s forces %s", "", constrainer, forcedvalue);
2410 */
2411         Sprintf(buf, "%4s\82±\82Ì%s\82Å\82Í%s\82Ì\82Ý", "", constrainer, forcedvalue);
2412         add_menu(where, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
2413                  MENU_UNSELECTED);
2414     } else if (what) {
2415         any.a_int = RS_menu_arg(which);
2416 /*JP
2417         Sprintf(buf, "Pick%s %s first", (f >= 0) ? " another" : "", what);
2418 */
2419         Sprintf(buf, "%s%s\82ð\90æ\82É\91I\82Ô", (f >= 0) ? "\91¼\82Ì" : "", what);
2420         add_menu(where, NO_GLYPH, &any, RS_menu_let[which], 0, ATR_NONE, buf,
2421                  MENU_UNSELECTED);
2422     } else if (which == RS_filter) {
2423         any.a_int = RS_menu_arg(RS_filter);
2424 #if 0 /*JP:T*/
2425         add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2426                  "Reset role/race/&c filtering", MENU_UNSELECTED);
2427 #else
2428         add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2429                  "\90E\8bÆ/\8eí\91°\82È\82Ç\82Ì\8di\82è\8d\9e\82Ý\82ð\89ð\8f\9c\82·\82é", MENU_UNSELECTED);
2430 #endif
2431     } else if (which == ROLE_RANDOM) {
2432         any.a_int = ROLE_RANDOM;
2433 #if 0 /*JP:T*/
2434         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
2435                  preselect ? MENU_SELECTED : MENU_UNSELECTED);
2436 #else
2437         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "\83\89\83\93\83_\83\80",
2438                  MENU_UNSELECTED);
2439 #endif
2440     } else if (which == ROLE_NONE) {
2441         any.a_int = ROLE_NONE;
2442 #if 0 /*JP:T*/
2443         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
2444                  preselect ? MENU_SELECTED : MENU_UNSELECTED);
2445 #else
2446         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "\94²\82¯\82é",
2447                  MENU_UNSELECTED);
2448 #endif
2449     } else {
2450         impossible("role_menu_extra: bad arg (%d)", which);
2451     }
2452 }
2453
2454 /*
2455  *      Special setup modifications here:
2456  *
2457  *      Unfortunately, this is going to have to be done
2458  *      on each newgame or restore, because you lose the permonst mods
2459  *      across a save/restore.  :-)
2460  *
2461  *      1 - The Rogue Leader is the Tourist Nemesis.
2462  *      2 - Priests start with a random alignment - convert the leader and
2463  *          guardians here.
2464  *      3 - Priests also get their of deities from a randomly chosen role.
2465  *      4 - [obsolete] Elves can have one of two different leaders,
2466  *          but can't work it out here because it requires hacking the
2467  *          level file data (see sp_lev.c).
2468  *
2469  * This code also replaces quest_init().
2470  */
2471 void
2472 role_init()
2473 {
2474     int alignmnt;
2475     struct permonst *pm;
2476
2477     /* Strip the role letter out of the player name.
2478      * This is included for backwards compatibility.
2479      */
2480     plnamesuffix();
2481
2482     /* Check for a valid role.  Try flags.initrole first. */
2483     if (!validrole(flags.initrole)) {
2484         /* Try the player letter second */
2485         if ((flags.initrole = str2role(pl_character)) < 0)
2486             /* None specified; pick a random role */
2487             flags.initrole = randrole_filtered();
2488     }
2489
2490     /* We now have a valid role index.  Copy the role name back. */
2491     /* This should become OBSOLETE */
2492     Strcpy(pl_character, roles[flags.initrole].name.m);
2493     pl_character[PL_CSIZ - 1] = '\0';
2494
2495     /* Check for a valid race */
2496     if (!validrace(flags.initrole, flags.initrace))
2497         flags.initrace = randrace(flags.initrole);
2498
2499     /* Check for a valid gender.  If new game, check both initgend
2500      * and female.  On restore, assume flags.female is correct. */
2501     if (flags.pantheon == -1) { /* new game */
2502         if (!validgend(flags.initrole, flags.initrace, flags.female))
2503             flags.female = !flags.female;
2504     }
2505     if (!validgend(flags.initrole, flags.initrace, flags.initgend))
2506         /* Note that there is no way to check for an unspecified gender. */
2507         flags.initgend = flags.female;
2508
2509     /* Check for a valid alignment */
2510     if (!validalign(flags.initrole, flags.initrace, flags.initalign))
2511         /* Pick a random alignment */
2512         flags.initalign = randalign(flags.initrole, flags.initrace);
2513     alignmnt = aligns[flags.initalign].value;
2514
2515     /* Initialize urole and urace */
2516     urole = roles[flags.initrole];
2517     urace = races[flags.initrace];
2518
2519     /* Fix up the quest leader */
2520     if (urole.ldrnum != NON_PM) {
2521         pm = &mons[urole.ldrnum];
2522         pm->msound = MS_LEADER;
2523         pm->mflags2 |= (M2_PEACEFUL);
2524         pm->mflags3 |= M3_CLOSE;
2525         pm->maligntyp = alignmnt * 3;
2526         /* if gender is random, we choose it now instead of waiting
2527            until the leader monster is created */
2528         quest_status.ldrgend =
2529             is_neuter(pm) ? 2 : is_female(pm) ? 1 : is_male(pm)
2530                                                         ? 0
2531                                                         : (rn2(100) < 50);
2532     }
2533
2534     /* Fix up the quest guardians */
2535     if (urole.guardnum != NON_PM) {
2536         pm = &mons[urole.guardnum];
2537         pm->mflags2 |= (M2_PEACEFUL);
2538         pm->maligntyp = alignmnt * 3;
2539     }
2540
2541     /* Fix up the quest nemesis */
2542     if (urole.neminum != NON_PM) {
2543         pm = &mons[urole.neminum];
2544         pm->msound = MS_NEMESIS;
2545         pm->mflags2 &= ~(M2_PEACEFUL);
2546         pm->mflags2 |= (M2_NASTY | M2_STALK | M2_HOSTILE);
2547         pm->mflags3 &= ~(M3_CLOSE);
2548         pm->mflags3 |= M3_WANTSARTI | M3_WAITFORU;
2549         /* if gender is random, we choose it now instead of waiting
2550            until the nemesis monster is created */
2551         quest_status.nemgend = is_neuter(pm) ? 2 : is_female(pm) ? 1
2552                                    : is_male(pm) ? 0 : (rn2(100) < 50);
2553     }
2554
2555     /* Fix up the god names */
2556     if (flags.pantheon == -1) {             /* new game */
2557         flags.pantheon = flags.initrole;    /* use own gods */
2558         while (!roles[flags.pantheon].lgod) /* unless they're missing */
2559             flags.pantheon = randrole();
2560     }
2561     if (!urole.lgod) {
2562         urole.lgod = roles[flags.pantheon].lgod;
2563         urole.ngod = roles[flags.pantheon].ngod;
2564         urole.cgod = roles[flags.pantheon].cgod;
2565     }
2566     /* 0 or 1; no gods are neuter, nor is gender randomized */
2567 /*JP
2568     quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess");
2569 */
2570     quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "\8f\97\90_");
2571
2572     /* Fix up infravision */
2573     if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {
2574         /* although an infravision intrinsic is possible, infravision
2575          * is purely a property of the physical race.  This means that we
2576          * must put the infravision flag in the player's current race
2577          * (either that or have separate permonst entries for
2578          * elven/non-elven members of each class).  The side effect is that
2579          * all NPCs of that class will have (probably bogus) infravision,
2580          * but since infravision has no effect for NPCs anyway we can
2581          * ignore this.
2582          */
2583         mons[urole.malenum].mflags3 |= M3_INFRAVISION;
2584         if (urole.femalenum != NON_PM)
2585             mons[urole.femalenum].mflags3 |= M3_INFRAVISION;
2586     }
2587
2588     /* Artifacts are fixed in hack_artifacts() */
2589
2590     /* Success! */
2591     return;
2592 }
2593
2594 const char *
2595 Hello(mtmp)
2596 struct monst *mtmp;
2597 {
2598 #if 0 /*JP*/
2599     switch (Role_switch) {
2600     case PM_KNIGHT:
2601         return "Salutations"; /* Olde English */
2602     case PM_SAMURAI:
2603         return (mtmp && mtmp->data == &mons[PM_SHOPKEEPER])
2604                     ? "Irasshaimase"
2605                     : "Konnichi wa"; /* Japanese */
2606     case PM_TOURIST:
2607         return "Aloha"; /* Hawaiian */
2608     case PM_VALKYRIE:
2609         return
2610 #ifdef MAIL
2611                (mtmp && mtmp->data == &mons[PM_MAIL_DAEMON]) ? "Hallo" :
2612 #endif
2613                "Velkommen"; /* Norse */
2614     default:
2615         return "Hello";
2616     }
2617 #else
2618 /*
2619   \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
2620 */
2621     static char helo_buf[BUFSZ];
2622
2623     switch (Role_switch) {
2624     case PM_KNIGHT:
2625         Sprintf(helo_buf, "\82æ\82­\82¼\8eQ\82Á\82½%s\82æ", plname);
2626         break;
2627     case PM_SAMURAI:
2628         Sprintf(helo_buf, "\82æ\82­\82¼\8eQ\82ç\82ê\82½%s\82æ", plname);
2629         break;
2630     case PM_TOURIST:
2631         Sprintf(helo_buf, "\83A\83\8d\81[\83n%s", plname);
2632         break;
2633     case PM_VALKYRIE:
2634         Sprintf(helo_buf, "\8d°\82Ì\8eç\8cì\8eÒ%s\82æ", plname);
2635         break;
2636     default:
2637         Sprintf(helo_buf, "\82æ\82¤\82±\82»%s", plname);
2638         break;
2639     }
2640
2641     return helo_buf;
2642 #endif
2643 }
2644
2645 const char *
2646 Goodbye()
2647 {
2648 #if 0 /*JP*/
2649     switch (Role_switch) {
2650     case PM_KNIGHT:
2651         return "Fare thee well"; /* Olde English */
2652     case PM_SAMURAI:
2653         return "Sayonara"; /* Japanese */
2654     case PM_TOURIST:
2655         return "Aloha"; /* Hawaiian */
2656     case PM_VALKYRIE:
2657         return "Farvel"; /* Norse */
2658     default:
2659         return "Goodbye";
2660     }
2661 #else
2662     static char helo_buf[BUFSZ];
2663
2664     switch (Role_switch) {
2665     case PM_KNIGHT:
2666         Sprintf(helo_buf, "\82³\82ç\82Î\8chåi\82È\82é");
2667         break;
2668     case PM_SAMURAI:
2669         Sprintf(helo_buf, "\82³\82ç\82Î\95\90\8em\93¹\82ð\8eu\82·");
2670         break;
2671     case PM_TOURIST:
2672         Sprintf(helo_buf, "\83A\83\8d\81[\83n");
2673         break;
2674     case PM_VALKYRIE:
2675         Sprintf(helo_buf, "\82³\82ç\82Î\8d°\82Ì\8eç\8cì\8eÒ");
2676         break;
2677     default:
2678         Sprintf(helo_buf, "\82³\82æ\82¤\82È\82ç");
2679         break;
2680     }
2681
2682     return helo_buf;
2683 #endif
2684 }
2685
2686 /* role.c */