OSDN Git Service

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