Below is the full text to src/role.c from NetHack 3.4.3. To link to a particular line, write [[role.c#line123]], for example.
Top of file[]
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.
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
5. #include "hack.h" 6. 7.
Roles[]
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. */
Archeologist[]
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. },
Barbarian[]
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. },
Caveman[]
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. },
Healer[]
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. },
Knight[]
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. },
Monk[]
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. },
Priest[]
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. },
Rogue[]
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. },
Ranger[]
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. },
Samurai[]
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. },
Tourist[]
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
Valkyrie[]
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. },
Wizard[]
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.
Races[]
405. /* Table of all races */ 406. const struct Race races[] = {
Human[]
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. },
Elf[]
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. },
Dwarf[]
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. },
Gnome[]
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. },
Orc[]
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.
Genders[]
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.
Alignments[]
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.
validrole[]
513. boolean 514. validrole(rolenum) 515. int rolenum; 516. { 517. return (rolenum >= 0 && rolenum < SIZE(roles)-1); 518. } 519. 520.
randrole[]
521. int 522. randrole() 523. { 524. return (rn2(SIZE(roles)-1)); 525. } 526. 527.
str2role[]
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.
validrace[]
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.
randrace[]
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.
str2race[]
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.
validgend[]
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.
randgend[]
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.
str2gend[]
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.
validalign[]
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.
randalign[]
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.
str2align[]
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? */
ok_role[]
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.
pick_role[]
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.
ok_race[]
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.
pick_race[]
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.
ok_gend[]
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.
pick_gend[]
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.
ok_align[]
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.
pick_align[]
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.
rigid_role_checks[]
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.
promptsep[]
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.
role_gendercount[]
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.
race_alignmentcount[]
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.
root_plselection_prompt[]
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.
build_plselection_prompt[]
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.
plnamesuffix[]
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. */
role_init[]
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.
Hello[]
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.
Main article: Welcome message
Goodbye[]
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. }
Main article: Welcome message#Goodbye message
1490. 1491. /* role.c */