1 /*	SCCS Id: @(#)role.c	3.3	2000/05/21	*/
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 
8 /*** Table of all roles ***/
9 /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
10  * (4-sided for wizards).  But this is not AD&D, and using the AD&D
11  * rule here produces an unplayable character.  Thus I have used a minimum
12  * of an 10-sided hit die for everything.  Another AD&D change: wizards get
13  * a minimum strength of 4 since without one you can't teleport or cast
14  * spells. --KAA
15  *
16  * As the wizard has been updated (wizard patch 5 jun '96) their HD can be
17  * brought closer into line with AD&D. This forces wizards to use magic more
18  * and distance themselves from their attackers. --LSZ
19  *
20  * With the introduction of races, some hit points and energy
21  * has been reallocated for each race.  The values assigned
22  * to the roles has been reduced by the amount allocated to
23  * humans.  --KMH
24  *
25  * God names use a leading underscore to flag goddesses.
26  */
27 const struct Role roles[] = {
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 	"Arc", "the College of Archeology", "the Tomb of the Toltec Kings",
40 	PM_ARCHEOLOGIST, NON_PM, NON_PM,
41 	PM_LORD_CARNARVON, PM_STUDENT, PM_MINION_OF_HUHETOTL,
42 	NON_PM, PM_HUMAN_MUMMY, S_SNAKE, S_MUMMY,
43 	ART_ORB_OF_DETECTION,
44 	MH_HUMAN|MH_DWARF|MH_GNOME | ROLE_MALE|ROLE_FEMALE |
45 	  ROLE_LAWFUL|ROLE_NEUTRAL,
46 	/* Str Int Wis Dex Con Cha */
47 	{   7, 10, 10,  7,  7,  7 },
48 	{  20, 20, 20, 10, 20, 10 },
49 	/* Init   Lower  Higher */
50 	{ 11, 0,  0, 8,  1, 0 },	/* Hit points */
51 	{  1, 0,  0, 1,  0, 1 },14,	/* Energy */
52 	10, 5, 0, 2, 10, A_INT, SPE_MAGIC_MAPPING,   -4
53 },
54 {	{"Barbarian", 0}, {
55 	{"Plunderer",   "Plunderess"},
56 	{"Pillager",    0},
57 	{"Bandit",      0},
58 	{"Brigand",     0},
59 	{"Raider",      0},
60 	{"Reaver",      0},
61 	{"Slayer",      0},
62 	{"Chieftain",   "Chieftainess"},
63 	{"Conqueror",   "Conqueress"} },
64 	"Mitra", "Crom", "Set", /* Hyborian */
65 	"Bar", "the Camp of the Duali Tribe", "the Duali Oasis",
66 	PM_BARBARIAN, NON_PM, NON_PM,
67 	PM_PELIAS, PM_CHIEFTAIN, PM_THOTH_AMON,
68 	PM_OGRE, PM_TROLL, S_OGRE, S_TROLL,
69 	ART_HEART_OF_AHRIMAN,
70 	MH_HUMAN|MH_ORC | ROLE_MALE|ROLE_FEMALE |
71 	  ROLE_NEUTRAL|ROLE_CHAOTIC,
72 	/* Str Int Wis Dex Con Cha */
73 	{  16,  7,  7, 15, 16,  6 },
74 	{  30,  6,  7, 20, 30,  7 },
75 	/* Init   Lower  Higher */
76 	{ 14, 0,  0,10,  2, 0 },	/* Hit points */
77 	{  1, 0,  0, 1,  0, 1 },10,	/* Energy */
78 	10, 14, 0, 0,  8, A_INT, SPE_HASTE_SELF,      -4
79 },
80 {	{"Caveman", "Cavewoman"}, {
81 	{"Troglodyte",  0},
82 	{"Aborigine",   0},
83 	{"Wanderer",    0},
84 	{"Vagrant",     0},
85 	{"Wayfarer",    0},
86 	{"Roamer",      0},
87 	{"Nomad",       0},
88 	{"Rover",       0},
89 	{"Pioneer",     0} },
90 	"Anu", "_Ishtar", "Anshar", /* Babylonian */
91 	"Cav", "the Caves of the Ancestors", "the Dragon's Lair",
92 	PM_CAVEMAN, PM_CAVEWOMAN, PM_LITTLE_DOG,
93 	PM_SHAMAN_KARNOV, PM_NEANDERTHAL, PM_CHROMATIC_DRAGON,
94 	PM_BUGBEAR, PM_HILL_GIANT, S_HUMANOID, S_GIANT,
95 	ART_SCEPTRE_OF_MIGHT,
96 	MH_HUMAN|MH_DWARF|MH_GNOME | ROLE_MALE|ROLE_FEMALE |
97 	  ROLE_LAWFUL|ROLE_NEUTRAL,
98 	/* Str Int Wis Dex Con Cha */
99 	{  10,  7,  7,  7,  8,  6 },
100 	{  30,  6,  7, 20, 30,  7 },
101 	/* Init   Lower  Higher */
102 	{ 14, 0,  0, 8,  2, 0 },	/* Hit points */
103 	{  1, 0,  0, 1,  0, 1 },10,	/* Energy */
104 	0, 12, 0, 1,  8, A_INT, SPE_DIG,             -4
105 },
106 {	{"Healer", 0}, {
107 	{"Rhizotomist",    0},
108 	{"Empiric",        0},
109 	{"Embalmer",       0},
110 	{"Dresser",        0},
111 	{"Medici ossium",  0},
112 	{"Herbalist",      0},
113 	{"Magister",       0},
114 	{"Physician",      0},
115 	{"Chirurgeon",     0} },
116 	"_Athena", "Hermes", "Poseidon", /* Greek */
117 	"Hea", "the Temple of Epidaurus", "the Temple of Coeus",
118 	PM_HEALER, NON_PM, NON_PM,
119 	PM_HIPPOCRATES, PM_ATTENDANT, PM_CYCLOPS,
120 	PM_GIANT_RAT, PM_SNAKE, S_RODENT, S_YETI,
121 	ART_STAFF_OF_AESCULAPIUS,
122 	MH_HUMAN|MH_GNOME | ROLE_MALE|ROLE_FEMALE | ROLE_NEUTRAL,
123 	/* Str Int Wis Dex Con Cha */
124 	{   7,  7, 13,  7, 11, 16 },
125 	{  15, 20, 20, 15, 25, 10 },
126 	/* Init   Lower  Higher */
127 	{ 11, 0,  0, 8,  1, 0 },	/* Hit points */
128 	{  1, 4,  0, 1,  0, 2 },20,	/* Energy */
129 	10, 3,-3, 2, 10, A_WIS, SPE_CURE_SICKNESS,   -4
130 },
131 {	{"Knight", 0}, {
132 	{"Gallant",     0},
133 	{"Esquire",     0},
134 	{"Bachelor",    0},
135 	{"Sergeant",    0},
136 	{"Knight",      0},
137 	{"Banneret",    0},
138 	{"Chevalier",   0},
139 	{"Seignieur",   0},
140 	{"Paladin",     0} },
141 	"Lugh", "_Brigit", "Manannan Mac Lir", /* Celtic */
142 	"Kni", "Camelot Castle", "the Isle of Glass",
143 	PM_KNIGHT, NON_PM, PM_PONY,
144 	PM_KING_ARTHUR, PM_PAGE, PM_IXOTH,
145 	PM_QUASIT, PM_OCHRE_JELLY, S_IMP, S_JELLY,
146 	ART_MAGIC_MIRROR_OF_MERLIN,
147 	MH_HUMAN | ROLE_MALE|ROLE_FEMALE | ROLE_LAWFUL,
148 	/* Str Int Wis Dex Con Cha */
149 	{  13,  7, 14,  8, 10, 17 },
150 	{  20, 15, 15, 10, 20, 10 },
151 	/* Init   Lower  Higher */
152 	{ 14, 0,  0, 8,  2, 0 },	/* Hit points */
153 	{  1, 4,  0, 1,  0, 2 },10,	/* Energy */
154 	10, 8,-2, 0,  9, A_WIS, SPE_TURN_UNDEAD,     -4
155 },
156 {	{"Monk", 0}, {
157 	{"Candidate",         0},
158 	{"Novice",            0},
159 	{"Initiate",          0},
160 	{"Student of Stones", 0},
161 	{"Student of Waters", 0},
162 	{"Student of Metals", 0},
163 	{"Student of Winds",  0},
164 	{"Student of Fire",   0},
165 	{"Master",            0} },
166 	"Shan Lai Ching", "Chih Sung-tzu", "Huan Ti", /* Chinese */
167 	"Mon", "the Monastery of Chan-Sune",
168 	  "the Monastery of the Earth-Lord",
169 	PM_MONK, NON_PM, NON_PM,
170 	PM_GRAND_MASTER, PM_ABBOT, PM_MASTER_KAEN,
171 	PM_EARTH_ELEMENTAL, PM_XORN, S_ELEMENTAL, S_XORN,
172 	ART_EYES_OF_THE_OVERWORLD,
173 	MH_HUMAN | ROLE_MALE|ROLE_FEMALE |
174 	  ROLE_LAWFUL|ROLE_NEUTRAL|ROLE_CHAOTIC,
175 	/* Str Int Wis Dex Con Cha */
176 	{  10,  7,  8,  8,  7,  7 },
177 	{  25, 10, 20, 20, 15, 10 },
178 	/* Init   Lower  Higher */
179 	{ 12, 0,  0, 8,  1, 0 },	/* Hit points */
180 	{  2, 2,  0, 2,  0, 2 },10,	/* Energy */
181 	10, 8,-2, 2, 20, A_WIS, SPE_RESTORE_ABILITY, -4
182 },
183 {	{"Priest", "Priestess"}, {
184 	{"Aspirant",    0},
185 	{"Acolyte",     0},
186 	{"Adept",       0},
187 	{"Priest",      "Priestess"},
188 	{"Curate",      0},
189 	{"Canon",       "Canoness"},
190 	{"Lama",        0},
191 	{"Patriarch",   "Matriarch"},
192 	{"High Priest", "High Priestess"} },
193 	0, 0, 0,	/* chosen randomly from among the other roles */
194 	"Pri", "the Great Temple", "the Temple of Nalzok",
195 	PM_PRIEST, PM_PRIESTESS, NON_PM,
196 	PM_ARCH_PRIEST, PM_ACOLYTE, PM_NALZOK,
197 	PM_HUMAN_ZOMBIE, PM_WRAITH, S_ZOMBIE, S_WRAITH,
198 	ART_MITRE_OF_HOLINESS,
199 	MH_HUMAN|MH_ELF | ROLE_MALE|ROLE_FEMALE |
200 	  ROLE_LAWFUL|ROLE_NEUTRAL|ROLE_CHAOTIC,
201 	/* Str Int Wis Dex Con Cha */
202 	{   7,  7, 10,  7,  7,  7 },
203 	{  15, 10, 30, 15, 20, 10 },
204 	/* Init   Lower  Higher */
205 	{ 12, 0,  0, 8,  1, 0 },	/* Hit points */
206 	{  4, 3,  0, 2,  0, 2 },10,	/* Energy */
207 	0, 3,-2, 2, 10, A_WIS, SPE_REMOVE_CURSE,    -4
208 },
209   /* Note:  Rogue precedes Ranger so that use of `-R' on the command line
210      retains its traditional meaning. */
211 {	{"Rogue", 0}, {
212 	{"Footpad",     0},
213 	{"Cutpurse",    0},
214 	{"Rogue",       0},
215 	{"Pilferer",    0},
216 	{"Robber",      0},
217 	{"Burglar",     0},
218 	{"Filcher",     0},
219 	{"Magsman",     "Magswoman"},
220 	{"Thief",       0} },
221 	"Issek", "Mog", "Kos", /* Nehwon */
222 	"Rog", "the Thieves' Guild Hall", "the Assassins' Guild Hall",
223 	PM_ROGUE, NON_PM, NON_PM,
224 	PM_MASTER_OF_THIEVES, PM_THUG, PM_MASTER_ASSASSIN,
225 	PM_LEPRECHAUN, PM_GUARDIAN_NAGA, S_NYMPH, S_NAGA,
226 	ART_MASTER_KEY_OF_THIEVERY,
227 	MH_HUMAN|MH_ORC | ROLE_MALE|ROLE_FEMALE |
228 	  ROLE_CHAOTIC,
229 	/* Str Int Wis Dex Con Cha */
230 	{   7,  7,  7, 10,  7,  6 },
231 	{  20, 10, 10, 30, 20, 10 },
232 	/* Init   Lower  Higher */
233 	{ 10, 0,  0, 8,  1, 0 },	/* Hit points */
234 	{  1, 0,  0, 1,  0, 1 },11,	/* Energy */
235 	10, 8, 0, 1,  9, A_INT, SPE_DETECT_TREASURE, -4
236 },
237 {	{"Ranger", 0}, {
238 #if 0	/* OBSOLETE */
239 	{"Edhel",       "Elleth"},
240 	{"Edhel",       "Elleth"},      /* elf-maid */
241 	{"Ohtar",       "Ohtie"},       /* warrior */
242 	{"Kano",			/* commander (Q.) ['a] */
243 			"Kanie"},	/* educated guess, until further research- SAC */
244 	{"Arandur",			/* king's servant, minister (Q.) - guess */
245 			"Aranduriel"},	/* educated guess */
246 	{"Hir",         "Hiril"},       /* lord, lady (S.) ['ir] */
247 	{"Aredhel",     "Arwen"},       /* noble elf, maiden (S.) */
248 	{"Ernil",       "Elentariel"},  /* prince (S.), elf-maiden (Q.) */
249 	{"Elentar",     "Elentari"},	/* Star-king, -queen (Q.) */
250 	"Solonor Thelandira", "Aerdrie Faenya", "Lolth", /* Elven */
251 #endif
252 	{"Tenderfoot",    0},
253 	{"Lookout",       0},
254 	{"Trailblazer",   0},
255 	{"Reconnoiterer", "Reconnoiteress"},
256 	{"Scout",         0},
257 	{"Arbalester",    0},	/* One skilled at crossbows */
258 	{"Archer",        0},
259 	{"Sharpshooter",  0},
260 	{"Marksman",      "Markswoman"} },
261 	"Mercury", "_Venus", "Mars", /* Roman/planets */
262 	"Ran", "Orion's camp", "the cave of the wumpus",
263 	PM_RANGER, NON_PM, PM_LITTLE_DOG /* Orion & canis major */,
264 	PM_ORION, PM_HUNTER, PM_SCORPIUS,
265 	PM_FOREST_CENTAUR, PM_SCORPION, S_CENTAUR, S_SPIDER,
266 	ART_LONGBOW_OF_DIANA,
267 	MH_HUMAN|MH_ELF|MH_GNOME|MH_ORC | ROLE_MALE|ROLE_FEMALE |
268 	  ROLE_NEUTRAL|ROLE_CHAOTIC,
269 	/* Str Int Wis Dex Con Cha */
270 	{  13, 13, 13,  9, 13,  7 },
271 	{  30, 10, 10, 20, 20, 10 },
272 	/* Init   Lower  Higher */
273 	{ 13, 0,  0, 6,  1, 0 },	/* Hit points */
274 	{  1, 0,  0, 1,  0, 1 },12,	/* Energy */
275 	10, 9, 2, 1, 10, A_INT, SPE_INVISIBILITY,   -4
276 },
277 {	{"Samurai", 0}, {
278 	{"Hatamoto",    0},  /* Banner Knight */
279 	{"Ronin",       0},  /* no allegiance */
280 	{"Ninja",       0},  /* secret society */
281 	{"Joshu",       0},  /* heads a castle */
282 	{"Ryoshu",      0},  /* has a territory */
283 	{"Kokushu",     0},  /* heads a province */
284 	{"Daimyo",      0},  /* a samurai lord */
285 	{"Kuge",        0},  /* Noble of the Court */
286 	{"Shogun",      0} },/* supreme commander, warlord */
287 	"_Amaterasu Omikami", "Raijin", "Susanowo", /* Japanese */
288 	"Sam", "the Castle of the Taro Clan", "the Shogun's Castle",
289 	PM_SAMURAI, NON_PM, PM_LITTLE_DOG,
290 	PM_LORD_SATO, PM_ROSHI, PM_ASHIKAGA_TAKAUJI,
291 	PM_WOLF, PM_STALKER, S_DOG, S_ELEMENTAL,
292 	ART_TSURUGI_OF_MURAMASA,
293 	MH_HUMAN | ROLE_MALE|ROLE_FEMALE | ROLE_LAWFUL,
294 	/* Str Int Wis Dex Con Cha */
295 	{  10,  8,  7, 10, 17,  6 },
296 	{  30, 10, 10, 30, 14, 10 },
297 	/* Init   Lower  Higher */
298 	{ 13, 0,  0, 8,  1, 0 },	/* Hit points */
299 	{  1, 0,  0, 1,  0, 1 },11,	/* Energy */
300 	10, 10, 0, 0,  8, A_INT, SPE_CLAIRVOYANCE,    -4
301 },
302 #ifdef TOURIST
303 {	{"Tourist", 0}, {
304 	{"Rambler",     0},
305 	{"Sightseer",   0},
306 	{"Excursionist",0},
307 	{"Peregrinator","Peregrinatrix"},
308 	{"Traveler",    0},
309 	{"Journeyer",   0},
310 	{"Voyager",     0},
311 	{"Explorer",    0},
312 	{"Adventurer",  0} },
313 	"Blind Io", "_The Lady", "Offler", /* Discworld */
314 	"Tou", "Ankh-Morpork", "the Thieves' Guild Hall",
315 	PM_TOURIST, NON_PM, NON_PM,
316 	PM_TWOFLOWER, PM_GUIDE, PM_MASTER_OF_THIEVES,
317 	PM_GIANT_SPIDER, PM_FOREST_CENTAUR, S_SPIDER, S_CENTAUR,
318 	ART_YENDORIAN_EXPRESS_CARD,
319 	MH_HUMAN | ROLE_MALE|ROLE_FEMALE | ROLE_NEUTRAL,
320 	/* Str Int Wis Dex Con Cha */
321 	{   7, 10,  6,  7,  7, 10 },
322 	{  15, 10, 10, 15, 30, 20 },
323 	/* Init   Lower  Higher */
324 	{  8, 0,  0, 8,  0, 0 },	/* Hit points */
325 	{  1, 0,  0, 1,  0, 1 },14,	/* Energy */
326 	0, 5, 1, 2, 10, A_INT, SPE_CHARM_MONSTER,   -4
327 },
328 #endif
329 {	{"Valkyrie", 0}, {
330 	{"Stripling",   0},
331 	{"Skirmisher",  0},
332 	{"Fighter",     0},
333 	{"Man-at-arms", "Woman-at-arms"},
334 	{"Warrior",     0},
335 	{"Swashbuckler",0},
336 	{"Hero",        "Heroine"},
337 	{"Champion",    0},
338 	{"Lord",        "Lady"} },
339 	"Tyr", "Odin", "Loki", /* Norse */
340 	"Val", "the Shrine of Destiny", "the cave of Surtur",
341 	PM_VALKYRIE, NON_PM, NON_PM /*PM_WINTER_WOLF_CUB*/,
342 	PM_NORN, PM_WARRIOR, PM_LORD_SURTUR,
343 	PM_FIRE_ANT, PM_FIRE_GIANT, S_ANT, S_GIANT,
344 	ART_ORB_OF_FATE,
345 	MH_HUMAN|MH_DWARF | ROLE_FEMALE | ROLE_LAWFUL|ROLE_NEUTRAL,
346 	/* Str Int Wis Dex Con Cha */
347 	{  10,  7,  7,  7, 10,  7 },
348 	{  30,  6,  7, 20, 30,  7 },
349 	/* Init   Lower  Higher */
350 	{ 14, 0,  0, 8,  2, 0 },	/* Hit points */
351 	{  1, 0,  0, 1,  0, 1 },10,	/* Energy */
352 	0, 10,-2, 0,  9, A_WIS, SPE_CONE_OF_COLD,    -4
353 },
354 {	{"Wizard", 0}, {
355 	{"Evoker",      0},
356 	{"Conjurer",    0},
357 	{"Thaumaturge", 0},
358 	{"Magician",    0},
359 	{"Enchanter",   "Enchantress"},
360 	{"Sorcerer",    "Sorceress"},
361 	{"Necromancer", 0},
362 	{"Wizard",      0},
363 	{"Mage",        0} },
364 	"Ptah", "Thoth", "Anhur", /* Egyptian */
365 	"Wiz", "the Tower of the Balance", "the Tower of Darkness",
366 	PM_WIZARD, NON_PM, PM_KITTEN,
367 	PM_WIZARD_OF_BALANCE, PM_APPRENTICE, PM_DARK_ONE,
368 	PM_VAMPIRE_BAT, PM_XORN, S_BAT, S_WRAITH,
369 	ART_EYE_OF_THE_AETHIOPICA,
370 	MH_HUMAN|MH_ELF|MH_GNOME|MH_ORC | ROLE_MALE|ROLE_FEMALE |
371 	  ROLE_NEUTRAL|ROLE_CHAOTIC,
372 	/* Str Int Wis Dex Con Cha */
373 	{   7, 10,  7,  7,  7,  7 },
374 	{  10, 30, 10, 20, 20, 10 },
375 	/* Init   Lower  Higher */
376 	{ 10, 0,  0, 8,  1, 0 },	/* Hit points */
377 	{  4, 3,  0, 2,  0, 3 },12,	/* Energy */
378 	0, 1, 0, 3, 10, A_INT, SPE_MAGIC_MISSILE,   -4
379 },
380 /* Array terminator */
381 {{0, 0}}
382 };
383 
384 
385 /* The player's role, created at runtime from initial
386  * choices.  This may be munged in role_init().
387  */
388 struct Role urole =
389 {	{"Undefined", 0}, { {0, 0}, {0, 0}, {0, 0},
390 	{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} },
391 	"L", "N", "C", "Xxx", "home", "locate",
392 	NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM,
393 	NON_PM, NON_PM, 0, 0, 0, 0,
394 	/* Str Int Wis Dex Con Cha */
395 	{   7,  7,  7,  7,  7,  7 },
396 	{  20, 15, 15, 20, 20, 10 },
397 	/* Init   Lower  Higher */
398 	{ 10, 0,  0, 8,  1, 0 },	/* Hit points */
399 	{  2, 0,  0, 2,  0, 3 },14,	/* Energy */
400 	0, 10, 0, 0,  4, A_INT, 0, -3
401 };
402 
403 
404 
405 /* Table of all races */
406 const struct Race races[] = {
407 {	"human", "human", "humanity", "Hum",
408 	{"man", "woman"},
409 	PM_HUMAN, NON_PM, PM_HUMAN_MUMMY, PM_HUMAN_ZOMBIE,
410 	MH_HUMAN | ROLE_MALE|ROLE_FEMALE |
411 	  ROLE_LAWFUL|ROLE_NEUTRAL|ROLE_CHAOTIC,
412 	MH_HUMAN, 0, MH_GNOME|MH_ORC,
413 	/*    Str     Int Wis Dex Con Cha */
414 	{      3,      3,  3,  3,  3,  3 },
415 	{ STR18(100), 18, 18, 18, 18, 18 },
416 	/* Init   Lower  Higher */
417 	{  2, 0,  0, 2,  1, 0 },	/* Hit points */
418 	{  1, 0,  2, 0,  2, 0 }		/* Energy */
419 },
420 {	"elf", "elven", "elvenkind", "Elf",
421 	{0, 0},
422 	PM_ELF, NON_PM, PM_ELF_MUMMY, PM_ELF_ZOMBIE,
423 	MH_ELF | ROLE_MALE|ROLE_FEMALE | ROLE_CHAOTIC,
424 	MH_ELF, MH_ELF, MH_ORC,
425 	/*  Str    Int Wis Dex Con Cha */
426 	{    3,     3,  3,  3,  3,  3 },
427 	{   18,    20, 20, 18, 16, 18 },
428 	/* Init   Lower  Higher */
429 	{  1, 0,  0, 1,  1, 0 },	/* Hit points */
430 	{  2, 0,  3, 0,  3, 0 }		/* Energy */
431 },
432 {	"dwarf", "dwarven", "dwarvenkind", "Dwa",
433 	{0, 0},
434 	PM_DWARF, NON_PM, PM_DWARF_MUMMY, PM_DWARF_ZOMBIE,
435 	MH_DWARF | ROLE_MALE|ROLE_FEMALE | ROLE_LAWFUL,
436 	MH_DWARF, MH_DWARF|MH_GNOME, MH_ORC,
437 	/*    Str     Int Wis Dex Con Cha */
438 	{      3,      3,  3,  3,  3,  3 },
439 	{ STR18(100), 16, 16, 20, 20, 16 },
440 	/* Init   Lower  Higher */
441 	{  4, 0,  0, 3,  2, 0 },	/* Hit points */
442 	{  0, 0,  0, 0,  0, 0 }		/* Energy */
443 },
444 {	"gnome", "gnomish", "gnomehood", "Gno",
445 	{0, 0},
446 	PM_GNOME, NON_PM, PM_GNOME_MUMMY, PM_GNOME_ZOMBIE,
447 	MH_GNOME | ROLE_MALE|ROLE_FEMALE | ROLE_NEUTRAL,
448 	MH_GNOME, MH_DWARF|MH_GNOME, MH_HUMAN,
449 	/*  Str    Int Wis Dex Con Cha */
450 	{    3,     3,  3,  3,  3,  3 },
451 	{STR18(50),19, 18, 18, 18, 18 },
452 	/* Init   Lower  Higher */
453 	{  1, 0,  0, 1,  0, 0 },	/* Hit points */
454 	{  2, 0,  2, 0,  2, 0 }		/* Energy */
455 },
456 {	"orc", "orcish", "orcdom", "Orc",
457 	{0, 0},
458 	PM_ORC, NON_PM, PM_ORC_MUMMY, PM_ORC_ZOMBIE,
459 	MH_ORC | ROLE_MALE|ROLE_FEMALE | ROLE_CHAOTIC,
460 	MH_ORC, 0, MH_HUMAN|MH_ELF|MH_DWARF,
461 	/*  Str    Int Wis Dex Con Cha */
462 	{   3,      3,  3,  3,  3,  3 },
463 	{STR18(50),16, 16, 18, 18, 16 },
464 	/* Init   Lower  Higher */
465 	{  1, 0,  0, 1,  0, 0 },	/* Hit points */
466 	{  1, 0,  1, 0,  1, 0 }		/* Energy */
467 },
468 /* Array terminator */
469 { 0, 0, 0, 0 }};
470 
471 
472 /* The player's race, created at runtime from initial
473  * choices.  This may be munged in role_init().
474  */
475 struct Race urace =
476 {	"something", "undefined", "something", "Xxx",
477 	{0, 0},
478 	NON_PM, NON_PM, NON_PM, NON_PM,
479 	0, 0, 0, 0,
480 	/*    Str     Int Wis Dex Con Cha */
481 	{      3,      3,  3,  3,  3,  3 },
482 	{ STR18(100), 18, 18, 18, 18, 18 },
483 	/* Init   Lower  Higher */
484 	{  2, 0,  0, 2,  1, 0 },	/* Hit points */
485 	{  1, 0,  2, 0,  2, 0 }		/* Energy */
486 };
487 
488 
489 /* Table of all genders */
490 const struct Gender genders[] = {
491 	{"male",	"he",	"him",	"his",	"Mal",	ROLE_MALE},
492 	{"female",	"she",	"her",	"her",	"Fem",	ROLE_FEMALE},
493 	{"neuter",	"it",	"it",	"its",	"Ntr",	ROLE_NEUTER}
494 };
495 
496 
497 /* Table of all alignments */
498 const struct Align aligns[] = {
499 	{"law",		"lawful",	"Law",	ROLE_LAWFUL,	A_LAWFUL},
500 	{"balance",	"neutral",	"Neu",	ROLE_NEUTRAL,	A_NEUTRAL},
501 	{"chaos",	"chaotic",	"Cha",	ROLE_CHAOTIC,	A_CHAOTIC},
502 	{"evil",	"unaligned",	"Una",	0,		A_NONE}
503 };
504 
505 /* used by str2XXX() */
506 static char NEARDATA randomstr[] = "random";
507 
508 
509 boolean
validrole(rolenum)510 validrole(rolenum)
511 	int rolenum;
512 {
513 	return (rolenum >= 0 && rolenum < SIZE(roles)-1);
514 }
515 
516 
517 int
randrole()518 randrole()
519 {
520 	return (rn2(SIZE(roles)-1));
521 }
522 
523 
524 int
str2role(str)525 str2role(str)
526 	char *str;
527 {
528 	int i, len;
529 
530 	/* Is str valid? */
531 	if (!str || !str[0])
532 	    return ROLE_NONE;
533 
534 	/* Match as much of str as is provided */
535 	len = strlen(str);
536 	for (i = 0; roles[i].name.m; i++) {
537 	    /* Does it match the male name? */
538 	    if (!strncmpi(str, roles[i].name.m, len))
539 		return i;
540 	    /* Or the female name? */
541 	    if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len))
542 		return i;
543 	    /* Or the filecode? */
544 	    if (!strcmpi(str, roles[i].filecode))
545 		return i;
546 	}
547 
548 	if ((len == 1 && (*str == '*' || *str == '@')) ||
549 		!strncmpi(str, randomstr, len))
550 	    return ROLE_RANDOM;
551 
552 	/* Couldn't find anything appropriate */
553 	return ROLE_NONE;
554 }
555 
556 
557 boolean
validrace(rolenum,racenum)558 validrace(rolenum, racenum)
559 	int rolenum, racenum;
560 {
561 	/* Assumes validrole */
562 	return (racenum >= 0 && racenum < SIZE(races)-1 &&
563 		(roles[rolenum].allow & races[racenum].allow & ROLE_RACEMASK));
564 }
565 
566 
567 int
randrace(rolenum)568 randrace(rolenum)
569 	int rolenum;
570 {
571 	int i, n = 0;
572 
573 	/* Count the number of valid races */
574 	for (i = 0; races[i].noun; i++)
575 	    if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK)
576 	    	n++;
577 
578 	/* Pick a random race */
579 	/* Use a factor of 100 in case of bad random number generators */
580 	if (n) n = rn2(n*100)/100;
581 	for (i = 0; races[i].noun; i++)
582 	    if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) {
583 	    	if (n) n--;
584 	    	else return (i);
585 	    }
586 
587 	/* This role has no permitted races? */
588 	return (rn2(SIZE(races)-1));
589 }
590 
591 
592 int
str2race(str)593 str2race(str)
594 	char *str;
595 {
596 	int i, len;
597 
598 	/* Is str valid? */
599 	if (!str || !str[0])
600 	    return ROLE_NONE;
601 
602 	/* Match as much of str as is provided */
603 	len = strlen(str);
604 	for (i = 0; races[i].noun; i++) {
605 	    /* Does it match the noun? */
606 	    if (!strncmpi(str, races[i].noun, len))
607 		return i;
608 	    /* Or the filecode? */
609 	    if (!strcmpi(str, races[i].filecode))
610 		return i;
611 	}
612 
613 	if ((len == 1 && (*str == '*' || *str == '@')) ||
614 		!strncmpi(str, randomstr, len))
615 	    return ROLE_RANDOM;
616 
617 	/* Couldn't find anything appropriate */
618 	return ROLE_NONE;
619 }
620 
621 
622 boolean
validgend(rolenum,racenum,gendnum)623 validgend(rolenum, racenum, gendnum)
624 	int rolenum, racenum, gendnum;
625 {
626 	/* Assumes validrole and validrace */
627 	return (gendnum >= 0 && gendnum < ROLE_GENDERS &&
628 		(roles[rolenum].allow & races[racenum].allow &
629 		 genders[gendnum].allow & ROLE_GENDMASK));
630 }
631 
632 
633 int
randgend(rolenum,racenum)634 randgend(rolenum, racenum)
635 	int rolenum, racenum;
636 {
637 	int i, n = 0;
638 
639 	/* Count the number of valid genders */
640 	for (i = 0; i < ROLE_GENDERS; i++)
641 	    if (roles[rolenum].allow & races[racenum].allow &
642 	    		genders[i].allow & ROLE_GENDMASK)
643 	    	n++;
644 
645 	/* Pick a random gender */
646 	if (n) n = rn2(n);
647 	for (i = 0; i < ROLE_GENDERS; i++)
648 	    if (roles[rolenum].allow & races[racenum].allow &
649 	    		genders[i].allow & ROLE_GENDMASK) {
650 	    	if (n) n--;
651 	    	else return (i);
652 	    }
653 
654 	/* This role/race has no permitted genders? */
655 	return (rn2(ROLE_GENDERS));
656 }
657 
658 
659 int
str2gend(str)660 str2gend(str)
661 	char *str;
662 {
663 	int i, len;
664 
665 	/* Is str valid? */
666 	if (!str || !str[0])
667 	    return ROLE_NONE;
668 
669 	/* Match as much of str as is provided */
670 	len = strlen(str);
671 	for (i = 0; i < ROLE_GENDERS; i++) {
672 	    /* Does it match the adjective? */
673 	    if (!strncmpi(str, genders[i].adj, len))
674 		return i;
675 	    /* Or the filecode? */
676 	    if (!strcmpi(str, genders[i].filecode))
677 		return i;
678 	}
679 	if ((len == 1 && (*str == '*' || *str == '@')) ||
680 		!strncmpi(str, randomstr, len))
681 	    return ROLE_RANDOM;
682 
683 	/* Couldn't find anything appropriate */
684 	return ROLE_NONE;
685 }
686 
687 
688 boolean
validalign(rolenum,racenum,alignnum)689 validalign(rolenum, racenum, alignnum)
690 	int rolenum, racenum, alignnum;
691 {
692 	/* Assumes validrole and validrace */
693 	return (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
694 		(roles[rolenum].allow & races[racenum].allow &
695 		 aligns[alignnum].allow & ROLE_ALIGNMASK));
696 }
697 
698 
699 int
randalign(rolenum,racenum)700 randalign(rolenum, racenum)
701 	int rolenum, racenum;
702 {
703 	int i, n = 0;
704 
705 	/* Count the number of valid alignments */
706 	for (i = 0; i < ROLE_ALIGNS; i++)
707 	    if (roles[rolenum].allow & races[racenum].allow &
708 	    		aligns[i].allow & ROLE_ALIGNMASK)
709 	    	n++;
710 
711 	/* Pick a random alignment */
712 	if (n) n = rn2(n);
713 	for (i = 0; i < ROLE_ALIGNS; i++)
714 	    if (roles[rolenum].allow & races[racenum].allow &
715 	    		aligns[i].allow & ROLE_ALIGNMASK) {
716 	    	if (n) n--;
717 	    	else return (i);
718 	    }
719 
720 	/* This role/race has no permitted alignments? */
721 	return (rn2(ROLE_ALIGNS));
722 }
723 
724 
725 int
str2align(str)726 str2align(str)
727 	char *str;
728 {
729 	int i, len;
730 
731 	/* Is str valid? */
732 	if (!str || !str[0])
733 	    return ROLE_NONE;
734 
735 	/* Match as much of str as is provided */
736 	len = strlen(str);
737 	for (i = 0; i < ROLE_ALIGNS; i++) {
738 	    /* Does it match the adjective? */
739 	    if (!strncmpi(str, aligns[i].adj, len))
740 		return i;
741 	    /* Or the filecode? */
742 	    if (!strcmpi(str, aligns[i].filecode))
743 		return i;
744 	}
745 	if ((len == 1 && (*str == '*' || *str == '@')) ||
746 		!strncmpi(str, randomstr, len))
747 	    return ROLE_RANDOM;
748 
749 	/* Couldn't find anything appropriate */
750 	return ROLE_NONE;
751 }
752 
753 /* is rolenum compatible with any racenum/gendnum/alignnum constraints? */
754 boolean
ok_role(rolenum,racenum,gendnum,alignnum)755 ok_role(rolenum, racenum, gendnum, alignnum)
756 int rolenum, racenum, gendnum, alignnum;
757 {
758     int i;
759     short allow;
760 
761     if (rolenum >= 0 && rolenum < SIZE(roles)-1) {
762 	allow = roles[rolenum].allow;
763 	if (racenum >= 0 && racenum < SIZE(races)-1 &&
764 		!(allow & races[racenum].allow & ROLE_RACEMASK))
765 	    return FALSE;
766 	if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
767 		!(allow & genders[gendnum].allow & ROLE_GENDMASK))
768 	    return FALSE;
769 	if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
770 		!(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
771 	    return FALSE;
772 	return TRUE;
773     } else {
774 	for (i = 0; i < SIZE(roles)-1; i++) {
775 	    allow = roles[i].allow;
776 	    if (racenum >= 0 && racenum < SIZE(races)-1 &&
777 		    !(allow & races[racenum].allow & ROLE_RACEMASK))
778 		continue;
779 	    if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
780 		    !(allow & genders[gendnum].allow & ROLE_GENDMASK))
781 		continue;
782 	    if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
783 		    !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
784 		continue;
785 	    return TRUE;
786 	}
787 	return FALSE;
788     }
789 }
790 
791 /* pick a random role subject to any racenum/gendnum/alignnum constraints */
792 int
pick_role(racenum,gendnum,alignnum)793 pick_role(racenum, gendnum, alignnum)
794 int racenum, gendnum, alignnum;
795 {
796     int i;
797     int roles_ok = 0;
798 
799     for (i = 0; i < SIZE(roles)-1; i++) {
800 	if (ok_role(i, racenum, gendnum, alignnum))
801 	    roles_ok++;
802     }
803     if (roles_ok == 0)
804 	return ROLE_NONE;
805     roles_ok = rn2(roles_ok);
806     for (i = 0; i < SIZE(roles)-1; i++) {
807 	if (ok_role(i, racenum, gendnum, alignnum)) {
808 	    if (roles_ok == 0)
809 		return i;
810 	    else
811 		roles_ok--;
812 	}
813     }
814     return ROLE_NONE;
815 }
816 
817 /* is racenum compatible with any rolenum/gendnum/alignnum constraints? */
818 boolean
ok_race(rolenum,racenum,gendnum,alignnum)819 ok_race(rolenum, racenum, gendnum, alignnum)
820 int rolenum, racenum, gendnum, alignnum;
821 {
822     int i;
823     short allow;
824 
825     if (racenum >= 0 && racenum < SIZE(races)-1) {
826 	allow = races[racenum].allow;
827 	if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
828 		!(allow & roles[rolenum].allow & ROLE_RACEMASK))
829 	    return FALSE;
830 	if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
831 		!(allow & genders[gendnum].allow & ROLE_GENDMASK))
832 	    return FALSE;
833 	if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
834 		!(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
835 	    return FALSE;
836 	return TRUE;
837     } else {
838 	for (i = 0; i < SIZE(races)-1; i++) {
839 	    allow = races[i].allow;
840 	    if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
841 		    !(allow & roles[rolenum].allow & ROLE_RACEMASK))
842 		continue;
843 	    if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
844 		    !(allow & genders[gendnum].allow & ROLE_GENDMASK))
845 		continue;
846 	    if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
847 		    !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
848 		continue;
849 	    return TRUE;
850 	}
851 	return FALSE;
852     }
853 }
854 
855 /* pick a random race subject to any rolenum/gendnum/alignnum constraints */
856 int
pick_race(rolenum,gendnum,alignnum)857 pick_race(rolenum, gendnum, alignnum)
858 int rolenum, gendnum, alignnum;
859 {
860     int i;
861     int races_ok = 0;
862 
863     for (i = 0; i < SIZE(races)-1; i++) {
864 	if (ok_race(rolenum, i, gendnum, alignnum))
865 	    races_ok++;
866     }
867     if (races_ok == 0)
868 	return ROLE_NONE;
869     races_ok = rn2(races_ok);
870     for (i = 0; i < SIZE(races)-1; i++) {
871 	if (ok_race(rolenum, i, gendnum, alignnum)) {
872 	    if (races_ok == 0)
873 		return i;
874 	    else
875 		races_ok--;
876 	}
877     }
878     return ROLE_NONE;
879 }
880 
881 /* is gendnum compatible with any rolenum/racenum/alignnum constraints? */
882 /* gender and alignment are not comparable (and also not constrainable) */
883 boolean
ok_gend(rolenum,racenum,gendnum,alignnum)884 ok_gend(rolenum, racenum, gendnum, alignnum)
885 int rolenum, racenum, gendnum, alignnum;
886 {
887     int i;
888     short allow;
889 
890     if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
891 	allow = genders[gendnum].allow;
892 	if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
893 		!(allow & roles[rolenum].allow & ROLE_GENDMASK))
894 	    return FALSE;
895 	if (racenum >= 0 && racenum < SIZE(races)-1 &&
896 		!(allow & races[racenum].allow & ROLE_GENDMASK))
897 	    return FALSE;
898 	return TRUE;
899     } else {
900 	for (i = 0; i < ROLE_GENDERS; i++) {
901 	    allow = genders[i].allow;
902 	    if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
903 		    !(allow & roles[rolenum].allow & ROLE_GENDMASK))
904 		continue;
905 	    if (racenum >= 0 && racenum < SIZE(races)-1 &&
906 		    !(allow & races[racenum].allow & ROLE_GENDMASK))
907 		continue;
908 	    return TRUE;
909 	}
910 	return FALSE;
911     }
912 }
913 
914 /* pick a random gender subject to any rolenum/racenum/alignnum constraints */
915 /* gender and alignment are not comparable (and also not constrainable) */
916 int
pick_gend(rolenum,racenum,alignnum)917 pick_gend(rolenum, racenum, alignnum)
918 int rolenum, racenum, alignnum;
919 {
920     int i;
921     int gends_ok = 0;
922 
923     for (i = 0; i < ROLE_GENDERS; i++) {
924 	if (ok_gend(rolenum, racenum, i, alignnum))
925 	    gends_ok++;
926     }
927     if (gends_ok == 0)
928 	return ROLE_NONE;
929     gends_ok = rn2(gends_ok);
930     for (i = 0; i < ROLE_GENDERS; i++) {
931 	if (ok_gend(rolenum, racenum, i, alignnum)) {
932 	    if (gends_ok == 0)
933 		return i;
934 	    else
935 		gends_ok--;
936 	}
937     }
938     return ROLE_NONE;
939 }
940 
941 /* is alignnum compatible with any rolenum/racenum/gendnum constraints? */
942 /* alignment and gender are not comparable (and also not constrainable) */
943 boolean
ok_align(rolenum,racenum,gendnum,alignnum)944 ok_align(rolenum, racenum, gendnum, alignnum)
945 int rolenum, racenum, gendnum, alignnum;
946 {
947     int i;
948     short allow;
949 
950     if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
951 	allow = aligns[alignnum].allow;
952 	if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
953 		!(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
954 	    return FALSE;
955 	if (racenum >= 0 && racenum < SIZE(races)-1 &&
956 		!(allow & races[racenum].allow & ROLE_ALIGNMASK))
957 	    return FALSE;
958 	return TRUE;
959     } else {
960 	for (i = 0; i < ROLE_ALIGNS; i++) {
961 	    allow = races[i].allow;
962 	    if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
963 		    !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
964 		continue;
965 	    if (racenum >= 0 && racenum < SIZE(races)-1 &&
966 		    !(allow & races[racenum].allow & ROLE_ALIGNMASK))
967 		continue;
968 	    return TRUE;
969 	}
970 	return FALSE;
971     }
972 }
973 
974 /* pick a random alignment subject to any rolenum/racenum/gendnum constraints */
975 /* alignment and gender are not comparable (and also not constrainable) */
976 int
pick_align(rolenum,racenum,gendnum)977 pick_align(rolenum, racenum, gendnum)
978 int rolenum, racenum, gendnum;
979 {
980     int i;
981     int aligns_ok = 0;
982 
983     for (i = 0; i < ROLE_ALIGNS; i++) {
984 	if (ok_align(rolenum, racenum, gendnum, i))
985 	    aligns_ok++;
986     }
987     if (aligns_ok == 0)
988 	return ROLE_NONE;
989     aligns_ok = rn2(aligns_ok);
990     for (i = 0; i < ROLE_ALIGNS; i++) {
991 	if (ok_align(rolenum, racenum, gendnum, i)) {
992 	    if (aligns_ok == 0)
993 		return i;
994 	    else
995 		aligns_ok--;
996 	}
997     }
998     return ROLE_NONE;
999 }
1000 
1001 
1002 void
plnamesuffix()1003 plnamesuffix()
1004 {
1005 	char *sptr, *eptr;
1006 	int i;
1007 
1008 	/* Look for tokens delimited by '-' */
1009 	if ((eptr = index(plname, '-')) != (char *) 0)
1010 	    *eptr++ = '\0';
1011 	while (eptr) {
1012 	    /* Isolate the next token */
1013 	    sptr = eptr;
1014 	    if ((eptr = index(sptr, '-')) != (char *)0)
1015 		*eptr++ = '\0';
1016 
1017 	    /* Try to match it to something */
1018 	    if ((i = str2role(sptr)) != ROLE_NONE)
1019 		flags.initrole = i;
1020 	    else if ((i = str2race(sptr)) != ROLE_NONE)
1021 		flags.initrace = i;
1022 	    else if ((i = str2gend(sptr)) != ROLE_NONE)
1023 		flags.initgend = i;
1024 	    else if ((i = str2align(sptr)) != ROLE_NONE)
1025 		flags.initalign = i;
1026 	}
1027 	if(!plname[0]) {
1028 	    askname();
1029 	    plnamesuffix();
1030 	}
1031 
1032 	/* commas in the plname confuse the record file, convert to spaces */
1033 	for (sptr = plname; *sptr; sptr++) {
1034 		if (*sptr == ',') *sptr = ' ';
1035 	}
1036 }
1037 
1038 
1039 /*
1040  *	Special setup modifications here:
1041  *
1042  *	Unfortunately, this is going to have to be done
1043  *	on each newgame or restore, because you lose the permonst mods
1044  *	across a save/restore.  :-)
1045  *
1046  *	1 - The Rogue Leader is the Tourist Nemesis.
1047  *	2 - Priests start with a random alignment - convert the leader and
1048  *	    guardians here.
1049  *	3 - Elves can have one of two different leaders, but can't work it
1050  *	    out here because it requires hacking the level file data (see
1051  *	    sp_lev.c).
1052  *
1053  * This code also replaces quest_init().
1054  */
1055 void
role_init()1056 role_init()
1057 {
1058 	int alignmnt;
1059 
1060 	/* Strip the role letter out of the player name.
1061 	 * This is included for backwards compatibility.
1062 	 */
1063 	plnamesuffix();
1064 
1065 	/* Check for a valid role.  Try flags.initrole first. */
1066 	if (!validrole(flags.initrole)) {
1067 	    /* Try the player letter second */
1068 	    if ((flags.initrole = str2role(pl_character)) < 0)
1069 	    	/* None specified; pick a random role */
1070 	    	flags.initrole = randrole();
1071 	}
1072 
1073 	/* We now have a valid role index.  Copy the role name back. */
1074 	/* This should become OBSOLETE */
1075 	Strcpy(pl_character, roles[flags.initrole].name.m);
1076 	pl_character[PL_CSIZ-1] = '\0';
1077 
1078 	/* Check for a valid race */
1079 	if (!validrace(flags.initrole, flags.initrace))
1080 	    flags.initrace = randrace(flags.initrole);
1081 
1082 	/* Check for a valid gender.  Try flags.igend first. */
1083 	if (!validgend(flags.initrole, flags.initrace, flags.initgend))
1084 	    /* Use flags.female second.  Note that there is no way
1085 	     * to check for an unspecified gender.
1086 	     */
1087 	    flags.initgend = flags.female;
1088 	/* Don't change flags.female; this may be a restore */
1089 
1090 	/* Check for a valid alignment */
1091 	if (!validalign(flags.initrole, flags.initrace, flags.initalign))
1092 	    /* Pick a random alignment */
1093 	    flags.initalign = randalign(flags.initrole, flags.initrace);
1094 	alignmnt = aligns[flags.initalign].value;
1095 
1096 	/* Initialize urole and urace */
1097 	urole = roles[flags.initrole];
1098 	urace = races[flags.initrace];
1099 
1100 	/* Fix up the quest leader */
1101 	if (urole.ldrnum != NON_PM) {
1102 	    mons[urole.ldrnum].msound = MS_LEADER;
1103 	    mons[urole.ldrnum].mflags2 |= (M2_PEACEFUL);
1104 	    mons[urole.ldrnum].mflags3 |= M3_CLOSE;
1105 	    mons[urole.ldrnum].maligntyp = alignmnt * 3;
1106 	}
1107 
1108 	/* Fix up the quest guardians */
1109 	if (urole.guardnum != NON_PM) {
1110 	    mons[urole.guardnum].mflags2 |= (M2_PEACEFUL);
1111 	    mons[urole.guardnum].maligntyp = alignmnt * 3;
1112 	}
1113 
1114 	/* Fix up the quest nemesis */
1115 	if (urole.neminum != NON_PM) {
1116 	    mons[urole.neminum].msound = MS_NEMESIS;
1117 	    mons[urole.neminum].mflags2 &= ~(M2_PEACEFUL);
1118 	    mons[urole.neminum].mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE);
1119 	    mons[urole.neminum].mflags3 |= M3_WANTSARTI | M3_WAITFORU;
1120 	}
1121 
1122 	/* Fix up the god names */
1123 	if (flags.pantheon == -1) {		/* new game */
1124 	    flags.pantheon = flags.initrole;	/* use own gods */
1125 	    while (!roles[flags.pantheon].lgod)	/* unless they're missing */
1126 		flags.pantheon = randrole();
1127 	}
1128 	if (!urole.lgod) {
1129 	    urole.lgod = roles[flags.pantheon].lgod;
1130 	    urole.ngod = roles[flags.pantheon].ngod;
1131 	    urole.cgod = roles[flags.pantheon].cgod;
1132 	}
1133 
1134 	/* Fix up infravision */
1135 	if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {
1136 	    /* although an infravision intrinsic is possible, infravision
1137 	     * is purely a property of the physical race.  This means that we
1138 	     * must put the infravision flag in the player's current race
1139 	     * (either that or have separate permonst entries for
1140 	     * elven/non-elven members of each class).  The side effect is that
1141 	     * all NPCs of that class will have (probably bogus) infravision,
1142 	     * but since infravision has no effect for NPCs anyway we can
1143 	     * ignore this.
1144 	     */
1145 	    mons[urole.malenum].mflags3 |= M3_INFRAVISION;
1146 	    if (urole.femalenum != NON_PM)
1147 	    	mons[urole.femalenum].mflags3 |= M3_INFRAVISION;
1148 	}
1149 
1150 	/* Artifacts are fixed in hack_artifacts() */
1151 
1152 	/* Success! */
1153 	return;
1154 }
1155 
1156 const char *
Hello(mtmp)1157 Hello(mtmp)
1158 struct monst *mtmp;
1159 {
1160 	switch (Role_switch) {
1161 	case PM_KNIGHT:
1162 	    return ("Salutations"); /* Olde English */
1163 	case PM_SAMURAI:
1164 	    return (mtmp && mtmp->data == &mons[PM_SHOPKEEPER] ?
1165 	    		"Irasshaimase" : "Konnichi wa"); /* Japanese */
1166 #ifdef TOURIST
1167 	case PM_TOURIST:
1168 	    return ("Aloha");       /* Hawaiian */
1169 #endif
1170 	case PM_VALKYRIE:
1171 	    return (
1172 #ifdef MAIL
1173 	    		mtmp && mtmp->data == &mons[PM_MAIL_DAEMON] ? "Hallo" :
1174 #endif
1175 	    		"Velkommen");   /* Norse */
1176 	default:
1177 	    return ("Hello");
1178 	}
1179 }
1180 
1181 const char *
Goodbye()1182 Goodbye()
1183 {
1184 	switch (Role_switch) {
1185 	case PM_KNIGHT:
1186 	    return ("Fare thee well");  /* Olde English */
1187 	case PM_SAMURAI:
1188 	    return ("Sayonara");        /* Japanese */
1189 #ifdef TOURIST
1190 	case PM_TOURIST:
1191 	    return ("Aloha");           /* Hawaiian */
1192 #endif
1193 	case PM_VALKYRIE:
1194 	    return ("Farvel");          /* Norse */
1195 	default:
1196 	    return ("Goodbye");
1197 	}
1198 }
1199 
1200 /* role.c */
1201