Source:NetHack 3.3.0/role.c

Below is the full text to role.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/role.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)role.c	3.3	1999/11/26	*/ 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 the Stone path", 0}, 161. 	{"Student of the Waters",     0}, 162. 	{"Student of Metals",         0}, 163. 	{"Student of the 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_ARTEMIS, 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.   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.   506.  boolean 507. validrole(rolenum) 508. 	int rolenum; 509. {  510.  	return (rolenum >= 0 && rolenum < SIZE(roles)-1); 511. }  512.   513.   514.  int 515. randrole 516. {  517.  	return (rn2(SIZE(roles)-1)); 518. }  519.   520.   521.  int 522. str2role(str) 523. 	char *str; 524. {  525.  	int i, len; 526.  527.  	/* Is str valid? */ 528.  	if (!str || !str[0]) 529. 	    return (-1); 530.  531.  	/* "@" returns a random role */ 532. 	if (str[0] == '@') 533. 		return (randrole); 534.  535.  	/* Match as much of str as is provided */ 536. 	len = strlen(str); 537. 	for (i = 0; roles[i].name.m; i++) { 538. 	    /* Does it match the male name? */ 539.  	    if (!strncmpi(str, roles[i].name.m, len)) 540. 	    	return (i); 541. 	    /* Or the female name? */ 542.  	    if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len)) 543. 	    	return (i); 544. 	    /* Or the filecode? */ 545.  	    if (!strcmpi(str, roles[i].filecode)) 546. 	    	return (i); 547. 	}  548.   549.  	/* Couldn't find anything appropriate */ 550. 	return (-1); 551. }  552.   553.   554.  boolean 555. validrace(rolenum, racenum) 556. 	int rolenum, racenum; 557. {  558.  	/* Assumes validrole */ 559. 	return (racenum >= 0 && racenum < SIZE(races)-1 &&  560.  		(roles[rolenum].allow & races[racenum].allow & ROLE_RACEMASK)); 561. }  562.   563.   564.  int 565. randrace(rolenum) 566. 	int rolenum; 567. {  568.  	int i, n = 0; 569.  570.  	/* Count the number of valid races */ 571. 	for (i = 0; races[i].noun; i++) 572. 	    if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) 573. 	    	n++; 574.  575.  	/* Pick a random race */ 576. 	/* Use a factor of 100 in case of bad random number generators */ 577. 	if (n) n = rn2(n*100)/100; 578. 	for (i = 0; races[i].noun; i++) 579. 	    if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) { 580. 	    	if (n) n--; 581. 	    	else return (i); 582. 	    }  583.   584.  	/* This role has no permitted races? */ 585.  	return (rn2(SIZE(races)-1)); 586. }  587.   588.   589.  int 590. str2race(str) 591. 	char *str; 592. {  593.  	int i, len; 594.  595.  	/* Is str valid? */ 596.  	if (!str || !str[0]) 597. 	    return (-1); 598.  599.  	/* Match as much of str as is provided */ 600. 	len = strlen(str); 601. 	for (i = 0; races[i].noun; i++) { 602. 	    /* Does it match the noun? */ 603.  	    if (!strncmpi(str, races[i].noun, len)) 604. 	    	return (i); 605. 	    /* Or the filecode? */ 606.  	    if (!strcmpi(str, races[i].filecode)) 607. 	    	return (i); 608. 	}  609.   610.  	/* Couldn't find anything appropriate */ 611. 	return (-1); 612. }  613.   614.   615.  boolean 616. validgend(rolenum, racenum, gendnum) 617. 	int rolenum, racenum, gendnum; 618. {  619.  	/* Assumes validrole and validrace */ 620. 	return (gendnum >= 0 && gendnum < ROLE_GENDERS &&  621.  		(roles[rolenum].allow & races[racenum].allow & 622. 		 genders[gendnum].allow & ROLE_GENDMASK)); 623. }  624.   625.   626.  int 627. randgend(rolenum, racenum) 628. 	int rolenum, racenum; 629. {  630.  	int i, n = 0; 631.  632.  	/* Count the number of valid genders */ 633. 	for (i = 0; i < ROLE_GENDERS; i++) 634. 	    if (roles[rolenum].allow & races[racenum].allow &  635.  	    		genders[i].allow & ROLE_GENDMASK) 636. 	    	n++; 637.  638.  	/* Pick a random gender */ 639. 	if (n) n = rn2(n); 640. 	for (i = 0; i < ROLE_GENDERS; i++) 641. 	    if (roles[rolenum].allow & races[racenum].allow &  642.  	    		genders[i].allow & ROLE_GENDMASK) { 643. 	    	if (n) n--; 644. 	    	else return (i); 645. 	    }  646.   647.  	/* This role/race has no permitted genders? */ 648.  	return (rn2(ROLE_GENDERS)); 649. }  650.   651.   652.  int 653. str2gend(str) 654. 	char *str; 655. {  656.  	int i, len; 657.  658.  	/* Is str valid? */ 659.  	if (!str || !str[0]) 660. 	    return (-1); 661.  662.  	/* Match as much of str as is provided */ 663. 	len = strlen(str); 664. 	for (i = 0; i < ROLE_GENDERS; i++) { 665. 	    /* Does it match the adjective? */ 666.  	    if (!strncmpi(str, genders[i].adj, len)) 667. 	    	return (i); 668. 	    /* Or the filecode? */ 669.  	    if (!strcmpi(str, genders[i].filecode)) 670. 	    	return (i); 671. 	}  672.   673.  	/* Couldn't find anything appropriate */ 674. 	return (-1); 675. }  676.   677.   678.  boolean 679. validalign(rolenum, racenum, alignnum) 680. 	int rolenum, racenum, alignnum; 681. {  682.  	/* Assumes validrole and validrace */ 683. 	return (alignnum >= 0 && alignnum < ROLE_ALIGNS &&  684.  		(roles[rolenum].allow & races[racenum].allow & 685. 		 aligns[alignnum].allow & ROLE_ALIGNMASK)); 686. }  687.   688.   689.  int 690. randalign(rolenum, racenum) 691. 	int rolenum, racenum; 692. {  693.  	int i, n = 0; 694.  695.  	/* Count the number of valid alignments */ 696. 	for (i = 0; i < ROLE_ALIGNS; i++) 697. 	    if (roles[rolenum].allow & races[racenum].allow &  698.  	    		aligns[i].allow & ROLE_ALIGNMASK) 699. 	    	n++; 700.  701.  	/* Pick a random alignment */ 702. 	if (n) n = rn2(n); 703. 	for (i = 0; i < ROLE_ALIGNS; i++) 704. 	    if (roles[rolenum].allow & races[racenum].allow &  705.  	    		aligns[i].allow & ROLE_ALIGNMASK) { 706. 	    	if (n) n--; 707. 	    	else return (i); 708. 	    }  709.   710.  	/* This role/race has no permitted alignments? */ 711.  	return (rn2(ROLE_ALIGNS)); 712. }  713.   714.   715.  int 716. str2align(str) 717. 	char *str; 718. {  719.  	int i, len; 720.  721.  	/* Is str valid? */ 722.  	if (!str || !str[0]) 723. 	    return (-1); 724.  725.  	/* Match as much of str as is provided */ 726. 	len = strlen(str); 727. 	for (i = 0; i < ROLE_ALIGNS; i++) { 728. 	    /* Does it match the adjective? */ 729.  	    if (!strncmpi(str, aligns[i].adj, len)) 730. 	    	return (i); 731. 	    /* Or the filecode? */ 732.  	    if (!strcmpi(str, aligns[i].filecode)) 733. 	    	return (i); 734. 	}  735.   736.  	/* Couldn't find anything appropriate */ 737. 	return (-1); 738. }  739.   740.   741.  void 742. plnamesuffix 743. {  744.  	char *sptr, *eptr; 745. 	int i;  746. 747. 	/* Look for tokens delimited by '-' */ 748. 	if ((eptr = index(plname, '-')) != (char *) 0) 749. 	    *eptr++ = '\0'; 750. 	while (eptr) { 751. 	    /* Isolate the next token */ 752. 	    sptr = eptr; 753. 	    if ((eptr = index(sptr, '-')) != (char *)0) 754. 	    	*eptr++ = '\0'; 755.  756.  	    /* Try to match it to something */ 757. 	    if ((i = str2role(sptr)) >= 0) 758. 	    	flags.initrole = i;  759. else if ((i = str2race(sptr)) >= 0) 760. 	    	flags.initrace = i;  761. else if ((i = str2gend(sptr)) >= 0) 762. 	    	flags.initgend = i;  763. else if ((i = str2align(sptr)) >= 0) 764. 	    	flags.initalign = i;  765. } 766.  	if(!plname[0]) { 767. 	    askname; 768. 	    plnamesuffix; 769. 	}  770.  	return; 771. }  772.   773.   774.  /*  775.   *	Special setup modifications here: 776.  *  777.   *	Unfortunately, this is going to have to be done 778.  *	on each newgame or restore, because you lose the permonst mods 779.  *	across a save/restore. :-) 780.   *  781.   *	1 - The Rogue Leader is the Tourist Nemesis.  782.   *	2 - Priests start with a random alignment - convert the leader and  783.   *	    guardians here.  784.   *	3 - Elves can have one of two different leaders, but can't work it  785.   *	    out here because it requires hacking the level file data (see 786.  *	    sp_lev.c).  787.   *  788.   * This code also replaces quest_init.  789.   */  790.  void  791.  role_init  792.  {  793.  	int alignmnt;  794.   795.  	/* Strip the role letter out of the player name.  796.  	 * This is included for backwards compatibility.  797.  	 */  798.  	plnamesuffix;  799.   800.  	/* Check for a valid role.  Try flags.initrole first. */  801.  	if (!validrole(flags.initrole)) {  802.  	    /* Try the player letter second */  803.  	    if ((flags.initrole = str2role(pl_character)) < 0)  804.  	    	/* None specified; pick a random role */  805.  	    	flags.initrole = randrole;  806.  	}  807.   808.  	/* We now have a valid role index.  Copy the role name back. */  809.  	/* This should become OBSOLETE */  810.  	Strcpy(pl_character, roles[flags.initrole].name.m);  811.  	pl_character[PL_CSIZ-1] = '\0';  812.   813.  	/* Check for a valid race */ 814. 	if (!validrace(flags.initrole, flags.initrace)) 815. 	    flags.initrace = randrace(flags.initrole); 816.  817.  	/* Check for a valid gender. Try flags.igend first. */ 818.  	if (!validgend(flags.initrole, flags.initrace, flags.initgend)) 819. 	    /* Use flags.female second. Note that there is no way 820. 	     * to check for an unspecified gender. 821. 	     */  822.  	    flags.initgend = flags.female; 823. 	/* Don't change flags.female; this may be a restore */ 824.  825.  	/* Check for a valid alignment */ 826. 	if (!validalign(flags.initrole, flags.initrace, flags.initalign)) 827. 	    /* Pick a random alignment */ 828. 	    flags.initalign = randalign(flags.initrole, flags.initrace); 829. 	alignmnt = aligns[flags.initalign].value; 830.  831.  	/* Initialize urole and urace */ 832. 	urole = roles[flags.initrole]; 833. 	urace = races[flags.initrace]; 834.  835.  	/* Fix up the quest leader */ 836. 	if (urole.ldrnum != NON_PM) { 837. 	    mons[urole.ldrnum].msound = MS_LEADER; 838. 	    mons[urole.ldrnum].mflags2 |= (M2_PEACEFUL); 839. 	    mons[urole.ldrnum].mflags3 = M3_CLOSE; 840. 	    mons[urole.ldrnum].maligntyp = alignmnt * 3; 841. 	}  842.   843.  	/* Fix up the quest guardians */ 844. 	if (urole.guardnum != NON_PM) { 845. 	    mons[urole.guardnum].mflags2 |= (M2_PEACEFUL); 846. 	    mons[urole.guardnum].maligntyp = alignmnt * 3; 847. 	}  848.   849.  	/* Fix up the quest nemesis */ 850. 	if (urole.neminum != NON_PM) { 851. 	    mons[urole.neminum].msound = MS_NEMESIS; 852. 	    mons[urole.neminum].mflags2 &= ~(M2_PEACEFUL); 853. 	    mons[urole.neminum].mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE); 854. 	    mons[urole.neminum].mflags3 = M3_WANTSARTI | M3_WAITFORU; 855. 	}  856.   857.  	/* Fix up the god names */ 858. 	if (flags.pantheon == -1) {		/* new game */ 859. 	    flags.pantheon = flags.initrole;	/* use own gods */ 860. 	    while (!roles[flags.pantheon].lgod)	/* unless they're missing */ 861. 		flags.pantheon = randrole; 862. 	}  863.  	if (!urole.lgod) { 864. 	    urole.lgod = roles[flags.pantheon].lgod; 865. 	    urole.ngod = roles[flags.pantheon].ngod; 866. 	    urole.cgod = roles[flags.pantheon].cgod; 867. 	}  868.   869.  	/* Fix up infravision */ 870. 	if (mons[urace.malenum].mflags3 & M3_INFRAVISION) { 871. 	    /* although an infravision intrinsic is possible, infravision 872. 	     * is purely a property of the physical race. This means that we 873. * must put the infravision flag in the player's current race 874. 	     * (either that or have separate permonst entries for  875.  	     * elven/non-elven members of each class). The side effect is that 876. 	     * all NPCs of that class will have (probably bogus) infravision, 877. 	     * but since infravision has no effect for NPCs anyway we can 878. 	     * ignore this. 879. 	     */  880.  	    mons[urole.malenum].mflags3 |= M3_INFRAVISION; 881. 	    if (urole.femalenum != NON_PM) 882. 	    	mons[urole.femalenum].mflags3 |= M3_INFRAVISION; 883. 	}  884.   885.  	/* Artifacts are fixed in hack_artifacts */ 886.  887.  	/* Success! */ 888.  	return; 889. }  890.   891.  const char * 892. Hello 893. {  894.  	switch (Role_switch) { 895. 	case PM_KNIGHT: 896. 	    return ("Salutations"); /* Olde English */ 897. 	case PM_SAMURAI: 898. 	    return ("Konnichi wa"); /* Japanese */ 899. #ifdef TOURIST 900. 	case PM_TOURIST: 901. 	    return ("Aloha");       /* Hawaiian */ 902. #endif 903. 	case PM_VALKYRIE: 904. 	    return ("Velkommen");   /* Norse */ 905. 	default: 906. 	    return ("Hello"); 907. 	}  908.  }  909.   910.  const char * 911. Goodbye 912. {  913.  	switch (Role_switch) { 914. 	case PM_KNIGHT: 915. 	    return ("Fare thee well");  /* Olde English */ 916. 	case PM_SAMURAI: 917. 	    return ("Sayonara");        /* Japanese */ 918. #ifdef TOURIST 919. 	case PM_TOURIST: 920. 	    return ("Aloha");           /* Hawaiian */ 921. #endif 922. 	case PM_VALKYRIE: 923. 	    return ("Farvel");          /* Norse */ 924. 	default: 925. 	    return ("Goodbye"); 926. 	}  927.  }  928.   929.  /* role.c */