~ubuntu-branches/ubuntu/intrepid/nethack/intrepid

« back to all changes in this revision

Viewing changes to src/role.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2004-04-28 22:20:28 UTC
  • Revision ID: james.westby@ubuntu.com-20040428222028-xxg55fuf5dxiaogu
Tags: upstream-3.4.3
ImportĀ upstreamĀ versionĀ 3.4.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      SCCS Id: @(#)role.c     3.4     2003/01/08      */
 
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
        {"Medicus ossium", "Medica ossium"},
 
112
        {"Herbalist",      0},
 
113
        {"Magister",       "Magistra"},
 
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, 5 },
 
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",   "Chevaliere"},
 
139
        {"Seignieur",   "Dame"},
 
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
        {  30, 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",       "Kunoichi"},  /* 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,  8, 30, 14,  8 },
 
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 Lonely Tower", "the Tower of Darkness",
 
366
        PM_WIZARD, NON_PM, PM_KITTEN,
 
367
        PM_NEFERET_THE_GREEN, 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
STATIC_DCL char * FDECL(promptsep, (char *, int));
 
506
STATIC_DCL int FDECL(role_gendercount, (int));
 
507
STATIC_DCL int FDECL(race_alignmentcount, (int));
 
508
 
 
509
/* used by str2XXX() */
 
510
static char NEARDATA randomstr[] = "random";
 
511
 
 
512
 
 
513
boolean
 
514
validrole(rolenum)
 
515
        int rolenum;
 
516
{
 
517
        return (rolenum >= 0 && rolenum < SIZE(roles)-1);
 
518
}
 
519
 
 
520
 
 
521
int
 
522
randrole()
 
523
{
 
524
        return (rn2(SIZE(roles)-1));
 
525
}
 
526
 
 
527
 
 
528
int
 
529
str2role(str)
 
530
        char *str;
 
531
{
 
532
        int i, len;
 
533
 
 
534
        /* Is str valid? */
 
535
        if (!str || !str[0])
 
536
            return ROLE_NONE;
 
537
 
 
538
        /* Match as much of str as is provided */
 
539
        len = strlen(str);
 
540
        for (i = 0; roles[i].name.m; i++) {
 
541
            /* Does it match the male name? */
 
542
            if (!strncmpi(str, roles[i].name.m, len))
 
543
                return i;
 
544
            /* Or the female name? */
 
545
            if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len))
 
546
                return i;
 
547
            /* Or the filecode? */
 
548
            if (!strcmpi(str, roles[i].filecode))
 
549
                return i;
 
550
        }
 
551
 
 
552
        if ((len == 1 && (*str == '*' || *str == '@')) ||
 
553
                !strncmpi(str, randomstr, len))
 
554
            return ROLE_RANDOM;
 
555
 
 
556
        /* Couldn't find anything appropriate */
 
557
        return ROLE_NONE;
 
558
}
 
559
 
 
560
 
 
561
boolean
 
562
validrace(rolenum, racenum)
 
563
        int rolenum, racenum;
 
564
{
 
565
        /* Assumes validrole */
 
566
        return (racenum >= 0 && racenum < SIZE(races)-1 &&
 
567
                (roles[rolenum].allow & races[racenum].allow & ROLE_RACEMASK));
 
568
}
 
569
 
 
570
 
 
571
int
 
572
randrace(rolenum)
 
573
        int rolenum;
 
574
{
 
575
        int i, n = 0;
 
576
 
 
577
        /* Count the number of valid races */
 
578
        for (i = 0; races[i].noun; i++)
 
579
            if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK)
 
580
                n++;
 
581
 
 
582
        /* Pick a random race */
 
583
        /* Use a factor of 100 in case of bad random number generators */
 
584
        if (n) n = rn2(n*100)/100;
 
585
        for (i = 0; races[i].noun; i++)
 
586
            if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) {
 
587
                if (n) n--;
 
588
                else return (i);
 
589
            }
 
590
 
 
591
        /* This role has no permitted races? */
 
592
        return (rn2(SIZE(races)-1));
 
593
}
 
594
 
 
595
 
 
596
int
 
597
str2race(str)
 
598
        char *str;
 
599
{
 
600
        int i, len;
 
601
 
 
602
        /* Is str valid? */
 
603
        if (!str || !str[0])
 
604
            return ROLE_NONE;
 
605
 
 
606
        /* Match as much of str as is provided */
 
607
        len = strlen(str);
 
608
        for (i = 0; races[i].noun; i++) {
 
609
            /* Does it match the noun? */
 
610
            if (!strncmpi(str, races[i].noun, len))
 
611
                return i;
 
612
            /* Or the filecode? */
 
613
            if (!strcmpi(str, races[i].filecode))
 
614
                return i;
 
615
        }
 
616
 
 
617
        if ((len == 1 && (*str == '*' || *str == '@')) ||
 
618
                !strncmpi(str, randomstr, len))
 
619
            return ROLE_RANDOM;
 
620
 
 
621
        /* Couldn't find anything appropriate */
 
622
        return ROLE_NONE;
 
623
}
 
624
 
 
625
 
 
626
boolean
 
627
validgend(rolenum, racenum, gendnum)
 
628
        int rolenum, racenum, gendnum;
 
629
{
 
630
        /* Assumes validrole and validrace */
 
631
        return (gendnum >= 0 && gendnum < ROLE_GENDERS &&
 
632
                (roles[rolenum].allow & races[racenum].allow &
 
633
                 genders[gendnum].allow & ROLE_GENDMASK));
 
634
}
 
635
 
 
636
 
 
637
int
 
638
randgend(rolenum, racenum)
 
639
        int rolenum, racenum;
 
640
{
 
641
        int i, n = 0;
 
642
 
 
643
        /* Count the number of valid genders */
 
644
        for (i = 0; i < ROLE_GENDERS; i++)
 
645
            if (roles[rolenum].allow & races[racenum].allow &
 
646
                        genders[i].allow & ROLE_GENDMASK)
 
647
                n++;
 
648
 
 
649
        /* Pick a random gender */
 
650
        if (n) n = rn2(n);
 
651
        for (i = 0; i < ROLE_GENDERS; i++)
 
652
            if (roles[rolenum].allow & races[racenum].allow &
 
653
                        genders[i].allow & ROLE_GENDMASK) {
 
654
                if (n) n--;
 
655
                else return (i);
 
656
            }
 
657
 
 
658
        /* This role/race has no permitted genders? */
 
659
        return (rn2(ROLE_GENDERS));
 
660
}
 
661
 
 
662
 
 
663
int
 
664
str2gend(str)
 
665
        char *str;
 
666
{
 
667
        int i, len;
 
668
 
 
669
        /* Is str valid? */
 
670
        if (!str || !str[0])
 
671
            return ROLE_NONE;
 
672
 
 
673
        /* Match as much of str as is provided */
 
674
        len = strlen(str);
 
675
        for (i = 0; i < ROLE_GENDERS; i++) {
 
676
            /* Does it match the adjective? */
 
677
            if (!strncmpi(str, genders[i].adj, len))
 
678
                return i;
 
679
            /* Or the filecode? */
 
680
            if (!strcmpi(str, genders[i].filecode))
 
681
                return i;
 
682
        }
 
683
        if ((len == 1 && (*str == '*' || *str == '@')) ||
 
684
                !strncmpi(str, randomstr, len))
 
685
            return ROLE_RANDOM;
 
686
 
 
687
        /* Couldn't find anything appropriate */
 
688
        return ROLE_NONE;
 
689
}
 
690
 
 
691
 
 
692
boolean
 
693
validalign(rolenum, racenum, alignnum)
 
694
        int rolenum, racenum, alignnum;
 
695
{
 
696
        /* Assumes validrole and validrace */
 
697
        return (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
 
698
                (roles[rolenum].allow & races[racenum].allow &
 
699
                 aligns[alignnum].allow & ROLE_ALIGNMASK));
 
700
}
 
701
 
 
702
 
 
703
int
 
704
randalign(rolenum, racenum)
 
705
        int rolenum, racenum;
 
706
{
 
707
        int i, n = 0;
 
708
 
 
709
        /* Count the number of valid alignments */
 
710
        for (i = 0; i < ROLE_ALIGNS; i++)
 
711
            if (roles[rolenum].allow & races[racenum].allow &
 
712
                        aligns[i].allow & ROLE_ALIGNMASK)
 
713
                n++;
 
714
 
 
715
        /* Pick a random alignment */
 
716
        if (n) n = rn2(n);
 
717
        for (i = 0; i < ROLE_ALIGNS; i++)
 
718
            if (roles[rolenum].allow & races[racenum].allow &
 
719
                        aligns[i].allow & ROLE_ALIGNMASK) {
 
720
                if (n) n--;
 
721
                else return (i);
 
722
            }
 
723
 
 
724
        /* This role/race has no permitted alignments? */
 
725
        return (rn2(ROLE_ALIGNS));
 
726
}
 
727
 
 
728
 
 
729
int
 
730
str2align(str)
 
731
        char *str;
 
732
{
 
733
        int i, len;
 
734
 
 
735
        /* Is str valid? */
 
736
        if (!str || !str[0])
 
737
            return ROLE_NONE;
 
738
 
 
739
        /* Match as much of str as is provided */
 
740
        len = strlen(str);
 
741
        for (i = 0; i < ROLE_ALIGNS; i++) {
 
742
            /* Does it match the adjective? */
 
743
            if (!strncmpi(str, aligns[i].adj, len))
 
744
                return i;
 
745
            /* Or the filecode? */
 
746
            if (!strcmpi(str, aligns[i].filecode))
 
747
                return i;
 
748
        }
 
749
        if ((len == 1 && (*str == '*' || *str == '@')) ||
 
750
                !strncmpi(str, randomstr, len))
 
751
            return ROLE_RANDOM;
 
752
 
 
753
        /* Couldn't find anything appropriate */
 
754
        return ROLE_NONE;
 
755
}
 
756
 
 
757
/* is rolenum compatible with any racenum/gendnum/alignnum constraints? */
 
758
boolean
 
759
ok_role(rolenum, racenum, gendnum, alignnum)
 
760
int rolenum, racenum, gendnum, alignnum;
 
761
{
 
762
    int i;
 
763
    short allow;
 
764
 
 
765
    if (rolenum >= 0 && rolenum < SIZE(roles)-1) {
 
766
        allow = roles[rolenum].allow;
 
767
        if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
768
                !(allow & races[racenum].allow & ROLE_RACEMASK))
 
769
            return FALSE;
 
770
        if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
 
771
                !(allow & genders[gendnum].allow & ROLE_GENDMASK))
 
772
            return FALSE;
 
773
        if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
 
774
                !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
 
775
            return FALSE;
 
776
        return TRUE;
 
777
    } else {
 
778
        for (i = 0; i < SIZE(roles)-1; i++) {
 
779
            allow = roles[i].allow;
 
780
            if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
781
                    !(allow & races[racenum].allow & ROLE_RACEMASK))
 
782
                continue;
 
783
            if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
 
784
                    !(allow & genders[gendnum].allow & ROLE_GENDMASK))
 
785
                continue;
 
786
            if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
 
787
                    !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
 
788
                continue;
 
789
            return TRUE;
 
790
        }
 
791
        return FALSE;
 
792
    }
 
793
}
 
794
 
 
795
/* pick a random role subject to any racenum/gendnum/alignnum constraints */
 
796
/* If pickhow == PICK_RIGID a role is returned only if there is  */
 
797
/* a single possibility */
 
798
int
 
799
pick_role(racenum, gendnum, alignnum, pickhow)
 
800
int racenum, gendnum, alignnum, pickhow;
 
801
{
 
802
    int i;
 
803
    int roles_ok = 0;
 
804
 
 
805
    for (i = 0; i < SIZE(roles)-1; i++) {
 
806
        if (ok_role(i, racenum, gendnum, alignnum))
 
807
            roles_ok++;
 
808
    }
 
809
    if (roles_ok == 0 || (roles_ok > 1 && pickhow == PICK_RIGID))
 
810
        return ROLE_NONE;
 
811
    roles_ok = rn2(roles_ok);
 
812
    for (i = 0; i < SIZE(roles)-1; i++) {
 
813
        if (ok_role(i, racenum, gendnum, alignnum)) {
 
814
            if (roles_ok == 0)
 
815
                return i;
 
816
            else
 
817
                roles_ok--;
 
818
        }
 
819
    }
 
820
    return ROLE_NONE;
 
821
}
 
822
 
 
823
/* is racenum compatible with any rolenum/gendnum/alignnum constraints? */
 
824
boolean
 
825
ok_race(rolenum, racenum, gendnum, alignnum)
 
826
int rolenum, racenum, gendnum, alignnum;
 
827
{
 
828
    int i;
 
829
    short allow;
 
830
 
 
831
    if (racenum >= 0 && racenum < SIZE(races)-1) {
 
832
        allow = races[racenum].allow;
 
833
        if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
834
                !(allow & roles[rolenum].allow & ROLE_RACEMASK))
 
835
            return FALSE;
 
836
        if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
 
837
                !(allow & genders[gendnum].allow & ROLE_GENDMASK))
 
838
            return FALSE;
 
839
        if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
 
840
                !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
 
841
            return FALSE;
 
842
        return TRUE;
 
843
    } else {
 
844
        for (i = 0; i < SIZE(races)-1; i++) {
 
845
            allow = races[i].allow;
 
846
            if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
847
                    !(allow & roles[rolenum].allow & ROLE_RACEMASK))
 
848
                continue;
 
849
            if (gendnum >= 0 && gendnum < ROLE_GENDERS &&
 
850
                    !(allow & genders[gendnum].allow & ROLE_GENDMASK))
 
851
                continue;
 
852
            if (alignnum >= 0 && alignnum < ROLE_ALIGNS &&
 
853
                    !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
 
854
                continue;
 
855
            return TRUE;
 
856
        }
 
857
        return FALSE;
 
858
    }
 
859
}
 
860
 
 
861
/* pick a random race subject to any rolenum/gendnum/alignnum constraints */
 
862
/* If pickhow == PICK_RIGID a race is returned only if there is  */
 
863
/* a single possibility */
 
864
int
 
865
pick_race(rolenum, gendnum, alignnum, pickhow)
 
866
int rolenum, gendnum, alignnum, pickhow;
 
867
{
 
868
    int i;
 
869
    int races_ok = 0;
 
870
 
 
871
    for (i = 0; i < SIZE(races)-1; i++) {
 
872
        if (ok_race(rolenum, i, gendnum, alignnum))
 
873
            races_ok++;
 
874
    }
 
875
    if (races_ok == 0 || (races_ok > 1 && pickhow == PICK_RIGID))
 
876
        return ROLE_NONE;
 
877
    races_ok = rn2(races_ok);
 
878
    for (i = 0; i < SIZE(races)-1; i++) {
 
879
        if (ok_race(rolenum, i, gendnum, alignnum)) {
 
880
            if (races_ok == 0)
 
881
                return i;
 
882
            else
 
883
                races_ok--;
 
884
        }
 
885
    }
 
886
    return ROLE_NONE;
 
887
}
 
888
 
 
889
/* is gendnum compatible with any rolenum/racenum/alignnum constraints? */
 
890
/* gender and alignment are not comparable (and also not constrainable) */
 
891
boolean
 
892
ok_gend(rolenum, racenum, gendnum, alignnum)
 
893
int rolenum, racenum, gendnum, alignnum;
 
894
{
 
895
    int i;
 
896
    short allow;
 
897
 
 
898
    if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
 
899
        allow = genders[gendnum].allow;
 
900
        if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
901
                !(allow & roles[rolenum].allow & ROLE_GENDMASK))
 
902
            return FALSE;
 
903
        if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
904
                !(allow & races[racenum].allow & ROLE_GENDMASK))
 
905
            return FALSE;
 
906
        return TRUE;
 
907
    } else {
 
908
        for (i = 0; i < ROLE_GENDERS; i++) {
 
909
            allow = genders[i].allow;
 
910
            if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
911
                    !(allow & roles[rolenum].allow & ROLE_GENDMASK))
 
912
                continue;
 
913
            if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
914
                    !(allow & races[racenum].allow & ROLE_GENDMASK))
 
915
                continue;
 
916
            return TRUE;
 
917
        }
 
918
        return FALSE;
 
919
    }
 
920
}
 
921
 
 
922
/* pick a random gender subject to any rolenum/racenum/alignnum constraints */
 
923
/* gender and alignment are not comparable (and also not constrainable) */
 
924
/* If pickhow == PICK_RIGID a gender is returned only if there is  */
 
925
/* a single possibility */
 
926
int
 
927
pick_gend(rolenum, racenum, alignnum, pickhow)
 
928
int rolenum, racenum, alignnum, pickhow;
 
929
{
 
930
    int i;
 
931
    int gends_ok = 0;
 
932
 
 
933
    for (i = 0; i < ROLE_GENDERS; i++) {
 
934
        if (ok_gend(rolenum, racenum, i, alignnum))
 
935
            gends_ok++;
 
936
    }
 
937
    if (gends_ok == 0 || (gends_ok > 1 && pickhow == PICK_RIGID))
 
938
        return ROLE_NONE;
 
939
    gends_ok = rn2(gends_ok);
 
940
    for (i = 0; i < ROLE_GENDERS; i++) {
 
941
        if (ok_gend(rolenum, racenum, i, alignnum)) {
 
942
            if (gends_ok == 0)
 
943
                return i;
 
944
            else
 
945
                gends_ok--;
 
946
        }
 
947
    }
 
948
    return ROLE_NONE;
 
949
}
 
950
 
 
951
/* is alignnum compatible with any rolenum/racenum/gendnum constraints? */
 
952
/* alignment and gender are not comparable (and also not constrainable) */
 
953
boolean
 
954
ok_align(rolenum, racenum, gendnum, alignnum)
 
955
int rolenum, racenum, gendnum, alignnum;
 
956
{
 
957
    int i;
 
958
    short allow;
 
959
 
 
960
    if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
 
961
        allow = aligns[alignnum].allow;
 
962
        if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
963
                !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
 
964
            return FALSE;
 
965
        if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
966
                !(allow & races[racenum].allow & ROLE_ALIGNMASK))
 
967
            return FALSE;
 
968
        return TRUE;
 
969
    } else {
 
970
        for (i = 0; i < ROLE_ALIGNS; i++) {
 
971
            allow = races[i].allow;
 
972
            if (rolenum >= 0 && rolenum < SIZE(roles)-1 &&
 
973
                    !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
 
974
                continue;
 
975
            if (racenum >= 0 && racenum < SIZE(races)-1 &&
 
976
                    !(allow & races[racenum].allow & ROLE_ALIGNMASK))
 
977
                continue;
 
978
            return TRUE;
 
979
        }
 
980
        return FALSE;
 
981
    }
 
982
}
 
983
 
 
984
/* pick a random alignment subject to any rolenum/racenum/gendnum constraints */
 
985
/* alignment and gender are not comparable (and also not constrainable) */
 
986
/* If pickhow == PICK_RIGID an alignment is returned only if there is  */
 
987
/* a single possibility */
 
988
int
 
989
pick_align(rolenum, racenum, gendnum, pickhow)
 
990
int rolenum, racenum, gendnum, pickhow;
 
991
{
 
992
    int i;
 
993
    int aligns_ok = 0;
 
994
 
 
995
    for (i = 0; i < ROLE_ALIGNS; i++) {
 
996
        if (ok_align(rolenum, racenum, gendnum, i))
 
997
            aligns_ok++;
 
998
    }
 
999
    if (aligns_ok == 0 || (aligns_ok > 1 && pickhow == PICK_RIGID))
 
1000
        return ROLE_NONE;
 
1001
    aligns_ok = rn2(aligns_ok);
 
1002
    for (i = 0; i < ROLE_ALIGNS; i++) {
 
1003
        if (ok_align(rolenum, racenum, gendnum, i)) {
 
1004
            if (aligns_ok == 0)
 
1005
                return i;
 
1006
            else
 
1007
                aligns_ok--;
 
1008
        }
 
1009
    }
 
1010
    return ROLE_NONE;
 
1011
}
 
1012
 
 
1013
void
 
1014
rigid_role_checks()
 
1015
{
 
1016
    /* Some roles are limited to a single race, alignment, or gender and
 
1017
     * calling this routine prior to XXX_player_selection() will help
 
1018
     * prevent an extraneous prompt that actually doesn't allow
 
1019
     * you to choose anything further. Note the use of PICK_RIGID which
 
1020
     * causes the pick_XX() routine to return a value only if there is one
 
1021
     * single possible selection, otherwise it returns ROLE_NONE.
 
1022
     *
 
1023
     */
 
1024
    if (flags.initrole == ROLE_RANDOM) {
 
1025
        /* If the role was explicitly specified as ROLE_RANDOM
 
1026
         * via -uXXXX-@ then choose the role in here to narrow down
 
1027
         * later choices. Pick a random role in this case.
 
1028
         */
 
1029
        flags.initrole = pick_role(flags.initrace, flags.initgend,
 
1030
                                        flags.initalign, PICK_RANDOM);
 
1031
        if (flags.initrole < 0)
 
1032
            flags.initrole = randrole();
 
1033
    }
 
1034
    if (flags.initrole != ROLE_NONE) {
 
1035
        if (flags.initrace == ROLE_NONE)
 
1036
             flags.initrace = pick_race(flags.initrole, flags.initgend,
 
1037
                                                flags.initalign, PICK_RIGID);
 
1038
        if (flags.initalign == ROLE_NONE)
 
1039
             flags.initalign = pick_align(flags.initrole, flags.initrace,
 
1040
                                                flags.initgend, PICK_RIGID);
 
1041
        if (flags.initgend == ROLE_NONE)
 
1042
             flags.initgend = pick_gend(flags.initrole, flags.initrace,
 
1043
                                                flags.initalign, PICK_RIGID);
 
1044
    }
 
1045
}
 
1046
 
 
1047
#define BP_ALIGN        0
 
1048
#define BP_GEND         1
 
1049
#define BP_RACE         2
 
1050
#define BP_ROLE         3
 
1051
#define NUM_BP          4
 
1052
 
 
1053
STATIC_VAR char pa[NUM_BP], post_attribs;
 
1054
 
 
1055
STATIC_OVL char *
 
1056
promptsep(buf, num_post_attribs)
 
1057
char *buf;
 
1058
int num_post_attribs;
 
1059
{
 
1060
        const char *conj = "and ";
 
1061
        if (num_post_attribs > 1
 
1062
            && post_attribs < num_post_attribs && post_attribs > 1)
 
1063
                Strcat(buf, ","); 
 
1064
        Strcat(buf, " ");
 
1065
        --post_attribs;
 
1066
        if (!post_attribs && num_post_attribs > 1) Strcat(buf, conj);
 
1067
        return buf;
 
1068
}
 
1069
 
 
1070
STATIC_OVL int
 
1071
role_gendercount(rolenum)
 
1072
int rolenum;
 
1073
{
 
1074
        int gendcount = 0;
 
1075
        if (validrole(rolenum)) {
 
1076
                if (roles[rolenum].allow & ROLE_MALE) ++gendcount;
 
1077
                if (roles[rolenum].allow & ROLE_FEMALE) ++gendcount;
 
1078
                if (roles[rolenum].allow & ROLE_NEUTER) ++gendcount;
 
1079
        }
 
1080
        return gendcount;
 
1081
}
 
1082
 
 
1083
STATIC_OVL int
 
1084
race_alignmentcount(racenum)
 
1085
int racenum;
 
1086
{
 
1087
        int aligncount = 0;
 
1088
        if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
 
1089
                if (races[racenum].allow & ROLE_CHAOTIC) ++aligncount;
 
1090
                if (races[racenum].allow & ROLE_LAWFUL) ++aligncount;
 
1091
                if (races[racenum].allow & ROLE_NEUTRAL) ++aligncount;
 
1092
        }
 
1093
        return aligncount;
 
1094
}
 
1095
 
 
1096
char *
 
1097
root_plselection_prompt(suppliedbuf, buflen, rolenum, racenum, gendnum, alignnum)
 
1098
char *suppliedbuf;
 
1099
int buflen, rolenum, racenum, gendnum, alignnum;
 
1100
{
 
1101
        int k, gendercount = 0, aligncount = 0;
 
1102
        char buf[BUFSZ];
 
1103
        static char err_ret[] = " character's";
 
1104
        boolean donefirst = FALSE;
 
1105
 
 
1106
        if (!suppliedbuf || buflen < 1) return err_ret;
 
1107
 
 
1108
        /* initialize these static variables each time this is called */
 
1109
        post_attribs = 0;
 
1110
        for (k=0; k < NUM_BP; ++k)
 
1111
                pa[k] = 0;
 
1112
        buf[0] = '\0';
 
1113
        *suppliedbuf = '\0';
 
1114
        
 
1115
        /* How many alignments are allowed for the desired race? */
 
1116
        if (racenum != ROLE_NONE && racenum != ROLE_RANDOM)
 
1117
                aligncount = race_alignmentcount(racenum);
 
1118
 
 
1119
        if (alignnum != ROLE_NONE && alignnum != ROLE_RANDOM) {
 
1120
                /* if race specified, and multiple choice of alignments for it */
 
1121
                if ((racenum >= 0) && (aligncount > 1)) {
 
1122
                        if (donefirst) Strcat(buf, " ");
 
1123
                        Strcat(buf, aligns[alignnum].adj);
 
1124
                        donefirst = TRUE;
 
1125
                } else {
 
1126
                        if (donefirst) Strcat(buf, " ");
 
1127
                        Strcat(buf, aligns[alignnum].adj);
 
1128
                        donefirst = TRUE;
 
1129
                }
 
1130
        } else {
 
1131
                /* if alignment not specified, but race is specified
 
1132
                        and only one choice of alignment for that race then
 
1133
                        don't include it in the later list */
 
1134
                if ((((racenum != ROLE_NONE && racenum != ROLE_RANDOM) &&
 
1135
                        ok_race(rolenum, racenum, gendnum, alignnum))
 
1136
                      && (aligncount > 1))
 
1137
                     || (racenum == ROLE_NONE || racenum == ROLE_RANDOM)) {
 
1138
                        pa[BP_ALIGN] = 1;
 
1139
                        post_attribs++;
 
1140
                }
 
1141
        }
 
1142
        /* <your lawful> */
 
1143
 
 
1144
        /* How many genders are allowed for the desired role? */
 
1145
        if (validrole(rolenum))
 
1146
                gendercount = role_gendercount(rolenum);
 
1147
 
 
1148
        if (gendnum != ROLE_NONE  && gendnum != ROLE_RANDOM) {
 
1149
                if (validrole(rolenum)) {
 
1150
                     /* if role specified, and multiple choice of genders for it,
 
1151
                        and name of role itself does not distinguish gender */
 
1152
                        if ((rolenum != ROLE_NONE) && (gendercount > 1)
 
1153
                                                && !roles[rolenum].name.f) {
 
1154
                                if (donefirst) Strcat(buf, " ");
 
1155
                                Strcat(buf, genders[gendnum].adj);
 
1156
                                donefirst = TRUE;
 
1157
                        }
 
1158
                } else {
 
1159
                        if (donefirst) Strcat(buf, " ");
 
1160
                        Strcat(buf, genders[gendnum].adj);
 
1161
                        donefirst = TRUE;
 
1162
                }
 
1163
        } else {
 
1164
                /* if gender not specified, but role is specified
 
1165
                        and only one choice of gender then
 
1166
                        don't include it in the later list */
 
1167
                if ((validrole(rolenum) && (gendercount > 1)) || !validrole(rolenum)) {
 
1168
                        pa[BP_GEND] = 1;
 
1169
                        post_attribs++;
 
1170
                }
 
1171
        }
 
1172
        /* <your lawful female> */
 
1173
 
 
1174
        if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
 
1175
                if (validrole(rolenum) && ok_race(rolenum, racenum, gendnum, alignnum)) {
 
1176
                        if (donefirst) Strcat(buf, " "); 
 
1177
                        Strcat(buf, (rolenum == ROLE_NONE) ?
 
1178
                                races[racenum].noun :
 
1179
                                races[racenum].adj);
 
1180
                        donefirst = TRUE;
 
1181
                } else if (!validrole(rolenum)) {
 
1182
                        if (donefirst) Strcat(buf, " ");
 
1183
                        Strcat(buf, races[racenum].noun);
 
1184
                        donefirst = TRUE;
 
1185
                } else {
 
1186
                        pa[BP_RACE] = 1;
 
1187
                        post_attribs++;
 
1188
                }
 
1189
        } else {
 
1190
                pa[BP_RACE] = 1;
 
1191
                post_attribs++;
 
1192
        }
 
1193
        /* <your lawful female gnomish> || <your lawful female gnome> */
 
1194
 
 
1195
        if (validrole(rolenum)) {
 
1196
                if (donefirst) Strcat(buf, " ");
 
1197
                if (gendnum != ROLE_NONE) {
 
1198
                    if (gendnum == 1  && roles[rolenum].name.f)
 
1199
                        Strcat(buf, roles[rolenum].name.f);
 
1200
                    else
 
1201
                        Strcat(buf, roles[rolenum].name.m);
 
1202
                } else {
 
1203
                        if (roles[rolenum].name.f) {
 
1204
                                Strcat(buf, roles[rolenum].name.m);
 
1205
                                Strcat(buf, "/");
 
1206
                                Strcat(buf, roles[rolenum].name.f);
 
1207
                        } else 
 
1208
                                Strcat(buf, roles[rolenum].name.m);
 
1209
                }
 
1210
                donefirst = TRUE;
 
1211
        } else if (rolenum == ROLE_NONE) {
 
1212
                pa[BP_ROLE] = 1;
 
1213
                post_attribs++;
 
1214
        }
 
1215
        
 
1216
        if ((racenum == ROLE_NONE || racenum == ROLE_RANDOM) && !validrole(rolenum)) {
 
1217
                if (donefirst) Strcat(buf, " ");
 
1218
                Strcat(buf, "character");
 
1219
                donefirst = TRUE;
 
1220
        }
 
1221
        /* <your lawful female gnomish cavewoman> || <your lawful female gnome>
 
1222
         *    || <your lawful female character>
 
1223
         */
 
1224
        if (buflen > (int) (strlen(buf) + 1)) {
 
1225
                Strcpy(suppliedbuf, buf);
 
1226
                return suppliedbuf;
 
1227
        } else
 
1228
                return err_ret;
 
1229
}
 
1230
 
 
1231
char *
 
1232
build_plselection_prompt(buf, buflen, rolenum, racenum, gendnum, alignnum)
 
1233
char *buf;
 
1234
int buflen, rolenum, racenum, gendnum, alignnum;
 
1235
{
 
1236
        const char *defprompt = "Shall I pick a character for you? [ynq] ";
 
1237
        int num_post_attribs = 0;
 
1238
        char tmpbuf[BUFSZ];
 
1239
        
 
1240
        if (buflen < QBUFSZ)
 
1241
                return (char *)defprompt;
 
1242
 
 
1243
        Strcpy(tmpbuf, "Shall I pick ");
 
1244
        if (racenum != ROLE_NONE || validrole(rolenum))
 
1245
                Strcat(tmpbuf, "your ");
 
1246
        else {
 
1247
                Strcat(tmpbuf, "a ");
 
1248
        }
 
1249
        /* <your> */
 
1250
 
 
1251
        (void)  root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf),
 
1252
                                        rolenum, racenum, gendnum, alignnum);
 
1253
        Sprintf(buf, "%s", s_suffix(tmpbuf));
 
1254
 
 
1255
        /* buf should now be:
 
1256
         * < your lawful female gnomish cavewoman's> || <your lawful female gnome's>
 
1257
         *    || <your lawful female character's>
 
1258
         *
 
1259
         * Now append the post attributes to it
 
1260
         */
 
1261
 
 
1262
        num_post_attribs = post_attribs;
 
1263
        if (post_attribs) {
 
1264
                if (pa[BP_RACE]) {
 
1265
                        (void) promptsep(eos(buf), num_post_attribs);
 
1266
                        Strcat(buf, "race");
 
1267
                }
 
1268
                if (pa[BP_ROLE]) {
 
1269
                        (void) promptsep(eos(buf), num_post_attribs);
 
1270
                        Strcat(buf, "role");
 
1271
                }
 
1272
                if (pa[BP_GEND]) {
 
1273
                        (void) promptsep(eos(buf), num_post_attribs);
 
1274
                        Strcat(buf, "gender");
 
1275
                }
 
1276
                if (pa[BP_ALIGN]) {
 
1277
                        (void) promptsep(eos(buf), num_post_attribs);
 
1278
                        Strcat(buf, "alignment");
 
1279
                }
 
1280
        }
 
1281
        Strcat(buf, " for you? [ynq] ");
 
1282
        return buf;
 
1283
}
 
1284
 
 
1285
#undef BP_ALIGN
 
1286
#undef BP_GEND
 
1287
#undef BP_RACE
 
1288
#undef BP_ROLE
 
1289
#undef NUM_BP
 
1290
 
 
1291
void
 
1292
plnamesuffix()
 
1293
{
 
1294
        char *sptr, *eptr;
 
1295
        int i;
 
1296
 
 
1297
        /* Look for tokens delimited by '-' */
 
1298
        if ((eptr = index(plname, '-')) != (char *) 0)
 
1299
            *eptr++ = '\0';
 
1300
        while (eptr) {
 
1301
            /* Isolate the next token */
 
1302
            sptr = eptr;
 
1303
            if ((eptr = index(sptr, '-')) != (char *)0)
 
1304
                *eptr++ = '\0';
 
1305
 
 
1306
            /* Try to match it to something */
 
1307
            if ((i = str2role(sptr)) != ROLE_NONE)
 
1308
                flags.initrole = i;
 
1309
            else if ((i = str2race(sptr)) != ROLE_NONE)
 
1310
                flags.initrace = i;
 
1311
            else if ((i = str2gend(sptr)) != ROLE_NONE)
 
1312
                flags.initgend = i;
 
1313
            else if ((i = str2align(sptr)) != ROLE_NONE)
 
1314
                flags.initalign = i;
 
1315
        }
 
1316
        if(!plname[0]) {
 
1317
            askname();
 
1318
            plnamesuffix();
 
1319
        }
 
1320
 
 
1321
        /* commas in the plname confuse the record file, convert to spaces */
 
1322
        for (sptr = plname; *sptr; sptr++) {
 
1323
                if (*sptr == ',') *sptr = ' ';
 
1324
        }
 
1325
}
 
1326
 
 
1327
 
 
1328
/*
 
1329
 *      Special setup modifications here:
 
1330
 *
 
1331
 *      Unfortunately, this is going to have to be done
 
1332
 *      on each newgame or restore, because you lose the permonst mods
 
1333
 *      across a save/restore.  :-)
 
1334
 *
 
1335
 *      1 - The Rogue Leader is the Tourist Nemesis.
 
1336
 *      2 - Priests start with a random alignment - convert the leader and
 
1337
 *          guardians here.
 
1338
 *      3 - Elves can have one of two different leaders, but can't work it
 
1339
 *          out here because it requires hacking the level file data (see
 
1340
 *          sp_lev.c).
 
1341
 *
 
1342
 * This code also replaces quest_init().
 
1343
 */
 
1344
void
 
1345
role_init()
 
1346
{
 
1347
        int alignmnt;
 
1348
 
 
1349
        /* Strip the role letter out of the player name.
 
1350
         * This is included for backwards compatibility.
 
1351
         */
 
1352
        plnamesuffix();
 
1353
 
 
1354
        /* Check for a valid role.  Try flags.initrole first. */
 
1355
        if (!validrole(flags.initrole)) {
 
1356
            /* Try the player letter second */
 
1357
            if ((flags.initrole = str2role(pl_character)) < 0)
 
1358
                /* None specified; pick a random role */
 
1359
                flags.initrole = randrole();
 
1360
        }
 
1361
 
 
1362
        /* We now have a valid role index.  Copy the role name back. */
 
1363
        /* This should become OBSOLETE */
 
1364
        Strcpy(pl_character, roles[flags.initrole].name.m);
 
1365
        pl_character[PL_CSIZ-1] = '\0';
 
1366
 
 
1367
        /* Check for a valid race */
 
1368
        if (!validrace(flags.initrole, flags.initrace))
 
1369
            flags.initrace = randrace(flags.initrole);
 
1370
 
 
1371
        /* Check for a valid gender.  If new game, check both initgend
 
1372
         * and female.  On restore, assume flags.female is correct. */
 
1373
        if (flags.pantheon == -1) {     /* new game */
 
1374
            if (!validgend(flags.initrole, flags.initrace, flags.female))
 
1375
                flags.female = !flags.female;
 
1376
        }
 
1377
        if (!validgend(flags.initrole, flags.initrace, flags.initgend))
 
1378
            /* Note that there is no way to check for an unspecified gender. */
 
1379
            flags.initgend = flags.female;
 
1380
 
 
1381
        /* Check for a valid alignment */
 
1382
        if (!validalign(flags.initrole, flags.initrace, flags.initalign))
 
1383
            /* Pick a random alignment */
 
1384
            flags.initalign = randalign(flags.initrole, flags.initrace);
 
1385
        alignmnt = aligns[flags.initalign].value;
 
1386
 
 
1387
        /* Initialize urole and urace */
 
1388
        urole = roles[flags.initrole];
 
1389
        urace = races[flags.initrace];
 
1390
 
 
1391
        /* Fix up the quest leader */
 
1392
        if (urole.ldrnum != NON_PM) {
 
1393
            mons[urole.ldrnum].msound = MS_LEADER;
 
1394
            mons[urole.ldrnum].mflags2 |= (M2_PEACEFUL);
 
1395
            mons[urole.ldrnum].mflags3 |= M3_CLOSE;
 
1396
            mons[urole.ldrnum].maligntyp = alignmnt * 3;
 
1397
        }
 
1398
 
 
1399
        /* Fix up the quest guardians */
 
1400
        if (urole.guardnum != NON_PM) {
 
1401
            mons[urole.guardnum].mflags2 |= (M2_PEACEFUL);
 
1402
            mons[urole.guardnum].maligntyp = alignmnt * 3;
 
1403
        }
 
1404
 
 
1405
        /* Fix up the quest nemesis */
 
1406
        if (urole.neminum != NON_PM) {
 
1407
            mons[urole.neminum].msound = MS_NEMESIS;
 
1408
            mons[urole.neminum].mflags2 &= ~(M2_PEACEFUL);
 
1409
            mons[urole.neminum].mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE);
 
1410
            mons[urole.neminum].mflags3 |= M3_WANTSARTI | M3_WAITFORU;
 
1411
        }
 
1412
 
 
1413
        /* Fix up the god names */
 
1414
        if (flags.pantheon == -1) {             /* new game */
 
1415
            flags.pantheon = flags.initrole;    /* use own gods */
 
1416
            while (!roles[flags.pantheon].lgod) /* unless they're missing */
 
1417
                flags.pantheon = randrole();
 
1418
        }
 
1419
        if (!urole.lgod) {
 
1420
            urole.lgod = roles[flags.pantheon].lgod;
 
1421
            urole.ngod = roles[flags.pantheon].ngod;
 
1422
            urole.cgod = roles[flags.pantheon].cgod;
 
1423
        }
 
1424
 
 
1425
        /* Fix up infravision */
 
1426
        if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {
 
1427
            /* although an infravision intrinsic is possible, infravision
 
1428
             * is purely a property of the physical race.  This means that we
 
1429
             * must put the infravision flag in the player's current race
 
1430
             * (either that or have separate permonst entries for
 
1431
             * elven/non-elven members of each class).  The side effect is that
 
1432
             * all NPCs of that class will have (probably bogus) infravision,
 
1433
             * but since infravision has no effect for NPCs anyway we can
 
1434
             * ignore this.
 
1435
             */
 
1436
            mons[urole.malenum].mflags3 |= M3_INFRAVISION;
 
1437
            if (urole.femalenum != NON_PM)
 
1438
                mons[urole.femalenum].mflags3 |= M3_INFRAVISION;
 
1439
        }
 
1440
 
 
1441
        /* Artifacts are fixed in hack_artifacts() */
 
1442
 
 
1443
        /* Success! */
 
1444
        return;
 
1445
}
 
1446
 
 
1447
const char *
 
1448
Hello(mtmp)
 
1449
struct monst *mtmp;
 
1450
{
 
1451
        switch (Role_switch) {
 
1452
        case PM_KNIGHT:
 
1453
            return ("Salutations"); /* Olde English */
 
1454
        case PM_SAMURAI:
 
1455
            return (mtmp && mtmp->data == &mons[PM_SHOPKEEPER] ?
 
1456
                        "Irasshaimase" : "Konnichi wa"); /* Japanese */
 
1457
#ifdef TOURIST
 
1458
        case PM_TOURIST:
 
1459
            return ("Aloha");       /* Hawaiian */
 
1460
#endif
 
1461
        case PM_VALKYRIE:
 
1462
            return (
 
1463
#ifdef MAIL
 
1464
                        mtmp && mtmp->data == &mons[PM_MAIL_DAEMON] ? "Hallo" :
 
1465
#endif
 
1466
                        "Velkommen");   /* Norse */
 
1467
        default:
 
1468
            return ("Hello");
 
1469
        }
 
1470
}
 
1471
 
 
1472
const char *
 
1473
Goodbye()
 
1474
{
 
1475
        switch (Role_switch) {
 
1476
        case PM_KNIGHT:
 
1477
            return ("Fare thee well");  /* Olde English */
 
1478
        case PM_SAMURAI:
 
1479
            return ("Sayonara");        /* Japanese */
 
1480
#ifdef TOURIST
 
1481
        case PM_TOURIST:
 
1482
            return ("Aloha");           /* Hawaiian */
 
1483
#endif
 
1484
        case PM_VALKYRIE:
 
1485
            return ("Farvel");          /* Norse */
 
1486
        default:
 
1487
            return ("Goodbye");
 
1488
        }
 
1489
}
 
1490
 
 
1491
/* role.c */