OSDN Git Service

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