1 /* NetHack 3.6 role.c $NHDT-Date: 1463561393 2016/05/18 08:49:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.38 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 /*** Table of all roles ***/
14 /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
15 * (4-sided for wizards). But this is not AD&D, and using the AD&D
16 * rule here produces an unplayable character. Thus I have used a minimum
17 * of an 10-sided hit die for everything. Another AD&D change: wizards get
18 * a minimum strength of 4 since without one you can't teleport or cast
21 * As the wizard has been updated (wizard patch 5 jun '96) their HD can be
22 * brought closer into line with AD&D. This forces wizards to use magic more
23 * and distance themselves from their attackers. --LSZ
25 * With the introduction of races, some hit points and energy
26 * has been reallocated for each race. The values assigned
27 * to the roles has been reduced by the amount allocated to
30 * God names use a leading underscore to flag goddesses.
32 const struct Role roles[] = {
34 { { "Archeologist", 0 },
36 { "Field Worker", 0 },
37 { "Investigator", 0 },
41 { "Speleologist", 0 },
44 "Quetzalcoatl", "Camaxtli", "Huhetotl", /* Central American */
46 { { "
\8dl
\8cÃ
\8aw
\8eÒ", 0 },
48 { "
\98J
\93
\8eÒ", 0 },
49 { "
\92²
\8d¸
\8eÒ", 0 },
50 { "
\94
\8c@
\8eÒ", 0 },
51 { "
\8c@
\8dí
\8eÒ", 0 },
52 { "
\92T
\8c\9f\8eÒ", 0 },
53 { "
\93´
\8cA
\8aw
\8eÒ", 0 },
54 { "
\94ü
\8fp
\8eû
\8fW
\8eÒ", 0 },
56 "
\83P
\83c
\83A
\83\8b\83J
\83g
\83\8b", "
\83J
\83}
\83L
\83V
\83g
\83\8a", "
\83t
\83w
\83g
\83g
\83\8b", /* Central American */
60 "the College of Archeology",
61 "the Tomb of the Toltec Kings",
63 "
\8dl
\8cÃ
\8aw
\91å
\8aw",
64 "
\83g
\83\8b\83e
\83J
\89¤
\89Æ
\82Ì
\95æ",
71 PM_MINION_OF_HUHETOTL,
77 MH_HUMAN | MH_DWARF | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL
79 /* Str Int Wis Dex Con Cha */
80 { 7, 10, 10, 7, 7, 7 },
81 { 20, 20, 20, 10, 20, 10 },
82 /* Init Lower Higher */
83 { 11, 0, 0, 8, 1, 0 }, /* Hit points */
96 { { "Plunderer", "Plunderess" },
103 { "Chieftain", "Chieftainess" },
104 { "Conqueror", "Conqueress" } },
105 "Mitra", "Crom", "Set", /* Hyborian */
107 { { "
\96ì
\94Ø
\90l", 0 },
108 { { "
\93\90\91¯", 0 },
109 { "
\97ª
\92D
\8eÒ", 0 },
112 { "
\90N
\97ª
\8eÒ", 0 },
114 { "
\8eE
\9dC
\8eÒ", 0 },
116 { "
\90ª
\95\9e\8eÒ", 0 } },
117 "
\83~
\83g
\83\89", "
\83N
\83\8d\83\80", "
\83Z
\83g", /* Hyborian */
121 "the Camp of the Duali Tribe",
124 "
\83f
\83\85\83A
\83\8a\91°
\82Ì
\83L
\83\83\83\93\83v",
125 "
\83f
\83\85\83A
\83\8a\91°
\82Ì
\83I
\83A
\83V
\83X",
137 ART_HEART_OF_AHRIMAN,
138 MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL
140 /* Str Int Wis Dex Con Cha */
141 { 16, 7, 7, 15, 16, 6 },
142 { 30, 6, 7, 20, 30, 7 },
143 /* Init Lower Higher */
144 { 14, 0, 0, 10, 2, 0 }, /* Hit points */
145 { 1, 0, 0, 1, 0, 1 },
156 { { "Caveman", "Cavewoman" },
157 { { "Troglodyte", 0 },
166 "Anu", "_Ishtar", "Anshar", /* Babylonian */
168 { { "
\93´
\8cA
\90l", 0 },
169 { { "
\8c\8a\8b\8f\90l", 0 },
170 { "
\8c´
\8fZ
\96¯", 0 },
171 { "
\95ú
\98Q
\8eÒ", 0 },
172 { "
\95\82\98Q
\8eÒ", 0 },
173 { "
\97·
\8ds
\8eÒ", 0 },
174 { "
\95ú
\97V
\8eÒ", 0 },
175 { "
\97V
\96q
\96¯", 0 },
176 { "
\97¬
\98Q
\8eÒ", 0 },
177 { "
\90æ
\8bì
\8eÒ", 0 } },
178 "
\83A
\83k", "_
\83C
\83V
\83\85\83^
\83\8b", "
\83A
\83\93\83V
\83\83\83\8b", /* Babylonian */
182 "the Caves of the Ancestors",
185 "
\91¾
\8cÃ
\82Ì
\93´
\8cA",
186 "
\97³
\82Ì
\89B
\82ê
\89Æ",
198 ART_SCEPTRE_OF_MIGHT,
199 MH_HUMAN | MH_DWARF | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL
201 /* Str Int Wis Dex Con Cha */
202 { 10, 7, 7, 7, 8, 6 },
203 { 30, 6, 7, 20, 30, 7 },
204 /* Init Lower Higher */
205 { 14, 0, 0, 8, 2, 0 }, /* Hit points */
206 { 1, 0, 0, 1, 0, 1 },
218 { { "Rhizotomist", 0 },
222 { "Medicus ossium", "Medica ossium" },
224 { "Magister", "Magistra" },
226 { "Chirurgeon", 0 } },
227 "_Athena", "Hermes", "Poseidon", /* Greek */
230 { { "
\8c©
\8fK
\82¢", 0 },
231 { "
\88ã
\8et
\8c©
\8fK
\82¢", 0 },
232 { "
\8aÅ
\8cì
\8et", "
\8aÅ
\8cì
\95w" },
233 { "
\88ã
\8et
\8f\95\8eè", 0 },
234 { "
\96ò
\95¨
\8eå
\94C", 0 },
235 { "
\8a¿
\95û
\88ã", 0 },
236 { "
\88ã
\8et
\8eå
\94C", 0 },
237 { "
\93à
\89È
\88ã", 0 },
238 { "
\8aO
\89È
\88ã", 0 } },
239 "_
\83A
\83e
\83i", "
\83w
\83\8b\83\81\83X", "
\83|
\83Z
\83C
\83h
\83\93", /* Greek */
243 "the Temple of Epidaurus",
244 "the Temple of Coeus",
246 "
\83G
\83s
\83_
\83E
\83\8d\83X
\8e\9b\89@",
247 "
\83R
\83C
\83I
\83X
\8e\9b\89@",
259 ART_STAFF_OF_AESCULAPIUS,
260 MH_HUMAN | MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
261 /* Str Int Wis Dex Con Cha */
262 { 7, 7, 13, 7, 11, 16 },
263 { 15, 20, 20, 15, 25, 5 },
264 /* Init Lower Higher */
265 { 11, 0, 0, 8, 1, 0 }, /* Hit points */
266 { 1, 4, 0, 1, 0, 2 },
284 { "Chevalier", "Chevaliere" },
285 { "Seignieur", "Dame" },
287 "Lugh", "_Brigit", "Manannan Mac Lir", /* Celtic */
290 { { "
\8c©
\8fK
\82¢", 0 },
294 { "
\8fd
\90í
\8em", 0 },
296 { "
\8fd
\8bR
\8em", 0 },
297 { "
\8cM
\8bR
\8em", 0 },
298 { "
\90¹
\8bR
\8em", 0 } },
299 "
\83\8b\81[
\83t", "_
\83u
\83\8a\83W
\83b
\83g", "
\83}
\83i
\83\93\83i
\83\93\81E
\83}
\83N
\83\8a\81[
\83\8b", /* Celtic */
306 "
\83L
\83\83\83\81\83\8d\83b
\83g
\8fé",
307 "
\83K
\83\89\83X
\82Ì
\93\87",
319 ART_MAGIC_MIRROR_OF_MERLIN,
320 MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
321 /* Str Int Wis Dex Con Cha */
322 { 13, 7, 14, 8, 10, 17 },
323 { 30, 15, 15, 10, 20, 10 },
324 /* Init Lower Higher */
325 { 14, 0, 0, 8, 2, 0 }, /* Hit points */
326 { 1, 4, 0, 1, 0, 2 },
338 { { "Candidate", 0 },
341 { "Student of Stones", 0 },
342 { "Student of Waters", 0 },
343 { "Student of Metals", 0 },
344 { "Student of Winds", 0 },
345 { "Student of Fire", 0 },
347 "Shan Lai Ching", "Chih Sung-tzu", "Huan Ti", /* Chinese */
349 { { "
\95\90\93¬
\89Æ", 0 },
350 { { "
\93ü
\96å
\8aó
\96]
\8eÒ", 0 },
351 { "
\8f\89\90S
\8eÒ", 0 },
352 { "
\93ü
\96å
\8eÒ
\93`", 0 },
353 { "
\93y
\82Ì
\8fK
\82¢
\8eè", 0 },
354 { "
\90\85\82Ì
\8fK
\82¢
\8eè", 0 },
355 { "
\8bà
\82Ì
\8fK
\82¢
\8eè", 0 },
356 { "
\96Ø
\82Ì
\8fK
\82¢
\8eè", 0 },
357 { "
\89Î
\82Ì
\8fK
\82¢
\8eè", 0 },
358 { "
\96Æ
\8b\96\8aF
\93`", 0 } },
359 "
\8eR
\97\8b\90¸", "
\90Ô
\8f¼
\8eq", "
\89©
\92é", /* Chinese */
363 "the Monastery of Chan-Sune",
364 "the Monastery of the Earth-Lord",
366 "
\83`
\83\83\83\93\81E
\83X
\81[
\8fC
\93¹
\89@",
367 "
\92n
\89¤
\82Ì
\8fC
\93¹
\89@",
379 ART_EYES_OF_THE_OVERWORLD,
380 MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
382 /* Str Int Wis Dex Con Cha */
383 { 10, 7, 8, 8, 7, 7 },
384 { 25, 10, 20, 20, 15, 10 },
385 /* Init Lower Higher */
386 { 12, 0, 0, 8, 1, 0 }, /* Hit points */
387 { 2, 2, 0, 2, 0, 2 },
398 { { "Priest", "Priestess" },
402 { "Priest", "Priestess" },
404 { "Canon", "Canoness" },
406 { "Patriarch", "Matriarch" },
407 { "High Priest", "High Priestess" } },
408 0, 0, 0, /* deities from a randomly chosen other role will be used */
410 { { "
\91m
\97µ", "
\93ò
\91m" },
411 { { "
\8fC
\93¹
\8eÒ", "
\8fC
\93¹
\8f\97" },
414 { "
\91m
\97µ", "
\93ò
\91m" },
415 { "
\8f\95\94C
\8ei
\8dÕ", 0 },
416 { "
\90¹
\8eÒ", "
\90¹
\8f\97" },
418 { "
\91å
\8ei
\8b³", 0 },
419 { "
\91å
\91m
\8fã", 0 } },
420 0, 0, 0, /* deities from a randomly chosen other role will be used */
425 "the Temple of Nalzok",
427 "
\88Ì
\91å
\82È
\82é
\8e\9b\89@",
428 "
\83i
\83\8b\83]
\83N
\8e\9b\89@",
440 ART_MITRE_OF_HOLINESS,
441 MH_HUMAN | MH_ELF | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
443 /* Str Int Wis Dex Con Cha */
444 { 7, 7, 10, 7, 7, 7 },
445 { 15, 10, 30, 15, 20, 10 },
446 /* Init Lower Higher */
447 { 12, 0, 0, 8, 1, 0 }, /* Hit points */
448 { 4, 3, 0, 2, 0, 2 },
458 /* Note: Rogue precedes Ranger so that use of `-R' on the command line
459 retains its traditional meaning. */
469 { "Magsman", "Magswoman" },
471 "Issek", "Mog", "Kos", /* Nehwon */
473 { { "
\93\90\91¯", 0 },
474 { { "
\92Ç
\82¢
\82Í
\82¬", 0 },
475 { "
\82Ð
\82Á
\82½
\82
\82è", 0 },
477 { "
\82²
\82ë
\82Â
\82«", 0 },
478 { "
\82±
\82»
\82Ç
\82ë", 0 },
482 { "
\91å
\93D
\96_", 0 } },
483 "
\83C
\83Z
\83b
\83N", "
\83\82\83O", "
\83R
\83X", /* Nehwon */
487 "the Thieves' Guild Hall",
488 "the Assassins' Guild Hall",
490 "
\93\90\91¯
\83M
\83\8b\83h",
491 "
\88Ã
\8eE
\8eÒ
\83M
\83\8b\83h",
496 PM_MASTER_OF_THIEVES,
503 ART_MASTER_KEY_OF_THIEVERY,
504 MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
505 /* Str Int Wis Dex Con Cha */
506 { 7, 7, 7, 10, 7, 6 },
507 { 20, 10, 10, 30, 20, 10 },
508 /* Init Lower Higher */
509 { 10, 0, 0, 8, 1, 0 }, /* Hit points */
510 { 1, 0, 0, 1, 0, 1 },
525 {"Edhel", "Elleth"}, /* elf-maid */
526 {"Ohtar", "Ohtie"}, /* warrior */
527 {"Kano", "Kanie"}, /* commander (Q.) ['a] educated guess,
528 until further research- SAC */
529 {"Arandur"," Aranduriel"}, /* king's servant, minister (Q.) - guess */
530 {"Hir", "Hiril"}, /* lord, lady (S.) ['ir] */
531 {"Aredhel", "Arwen"}, /* noble elf, maiden (S.) */
532 {"Ernil", "Elentariel"}, /* prince (S.), elf-maiden (Q.) */
533 {"Elentar", "Elentari"}, /* Star-king, -queen (Q.) */
534 "Solonor Thelandira", "Aerdrie Faenya", "Lolth", /* Elven */
538 { "Trailblazer", 0 },
539 { "Reconnoiterer", "Reconnoiteress" },
541 { "Arbalester", 0 }, /* One skilled at crossbows */
543 { "Sharpshooter", 0 },
544 { "Marksman", "Markswoman" } },
545 "Mercury", "_Venus", "Mars", /* Roman/planets */
547 { { "
\83\8c\83\93\83W
\83\83\81[", 0 },
549 { "
\8c©
\92£
\82è", 0 },
553 { "
\8b|
\95º", 0 }, /* One skilled at crossbows */
554 { "
\92\86\8b\89\8b|
\95º", 0 },
555 { "
\8fã
\8b\89\8b|
\95º", 0 },
556 { "
\8fã
\8b\89\8b|
\95º", 0 } },
557 "
\83}
\81[
\83L
\83\85\83\8a\81[", "_
\83r
\81[
\83i
\83X", "
\83}
\81[
\83Y", /* Roman/planets */
562 "the cave of the wumpus",
564 "
\83I
\83\8a\83I
\83\93\82Ì
\83L
\83\83\83\93\83v",
565 "
\83\8f\83\93\83p
\83X
\82Ì
\93´
\8cA",
569 PM_LITTLE_DOG /* Orion & canis major */,
577 ART_LONGBOW_OF_DIANA,
578 MH_HUMAN | MH_ELF | MH_GNOME | MH_ORC | ROLE_MALE | ROLE_FEMALE
579 | ROLE_NEUTRAL | ROLE_CHAOTIC,
580 /* Str Int Wis Dex Con Cha */
581 { 13, 13, 13, 9, 13, 7 },
582 { 30, 10, 10, 20, 20, 10 },
583 /* Init Lower Higher */
584 { 13, 0, 0, 6, 1, 0 }, /* Hit points */
585 { 1, 0, 0, 1, 0, 1 },
597 { { "Hatamoto", 0 }, /* Banner Knight */
598 { "Ronin", 0 }, /* no allegiance */
599 { "Ninja", "Kunoichi" }, /* secret society */
600 { "Joshu", 0 }, /* heads a castle */
601 { "Ryoshu", 0 }, /* has a territory */
602 { "Kokushu", 0 }, /* heads a province */
603 { "Daimyo", 0 }, /* a samurai lord */
604 { "Kuge", 0 }, /* Noble of the Court */
605 { "Shogun", 0 } }, /* supreme commander, warlord */
606 "_Amaterasu Omikami", "Raijin", "Susanowo", /* Japanese */
609 { { "
\8aø
\96{", 0 }, /* Banner Knight */
610 { "
\98Q
\90l", 0 }, /* no allegiance */
611 { "
\94E
\8eÒ", "
\82
\83m
\88ê" }, /* secret society */
612 { "
\8fé
\8eå", 0 }, /* heads a castle */
613 { "
\97Ì
\8eå", 0 }, /* has a territory */
614 { "
\97Ì
\8eå", 0 }, /* heads a province */
615 { "
\91å
\96¼", "
\8d\98\8c³" }, /* a samurai lord */
616 { "
\8cö
\89Æ", 0 }, /* Noble of the Court */
617 { "
\8cö
\89Æ", "
\91å
\89\9c" } }, /* supreme commander, warlord */
618 "_
\93V
\8fÆ
\91å
\90_", "
\97\8b\90_", "
\90{
\8d²
\94V
\92j", /* Japanese */
622 "the Castle of the Taro Clan",
623 "the Shogun's Castle",
625 "
\91¾
\98Y
\88ê
\91°
\82Ì
\8fé",
638 ART_TSURUGI_OF_MURAMASA,
639 MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
640 /* Str Int Wis Dex Con Cha */
641 { 10, 8, 7, 10, 17, 6 },
642 { 30, 10, 8, 30, 14, 8 },
643 /* Init Lower Higher */
644 { 13, 0, 0, 8, 1, 0 }, /* Hit points */
645 { 1, 0, 0, 1, 0, 1 },
659 { "Excursionist", 0 },
660 { "Peregrinator", "Peregrinatrix" },
665 { "Adventurer", 0 } },
666 "Blind Io", "_The Lady", "Offler", /* Discworld */
668 { { "
\8aÏ
\8cõ
\8bq", 0 },
669 { { "
\83v
\81[
\91¾
\98Y", "
\83v
\81[
\8eq" },
670 { "
\8aÏ
\8cõ
\8bq", 0 },
671 { "
\8eü
\97V
\97·
\8ds
\8eÒ", 0 },
672 { "
\95Õ
\97ð
\8eÒ", 0 },
673 { "
\97·
\8ds
\8eÒ", 0 },
675 { "
\8dq
\8aC
\8eÒ", 0 },
676 { "
\92T
\8c\9f\89Æ", 0 },
677 { "
\96`
\8c¯
\8eÒ", 0 } },
678 "
\96Ó
\96Ú
\82Ì
\83C
\83I", "_
\81\83\8f\97\90_
\81\84", "
\83I
\83t
\83\89\81[", /* Discworld */
683 "the Thieves' Guild Hall",
685 "
\83A
\83\93\83N
\83\82\83\8b\83|
\81[
\83N",
686 "
\93\90\91¯
\83M
\83\8b\83h",
693 PM_MASTER_OF_THIEVES,
698 ART_YENDORIAN_EXPRESS_CARD,
699 MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
700 /* Str Int Wis Dex Con Cha */
701 { 7, 10, 6, 7, 7, 10 },
702 { 15, 10, 10, 15, 30, 20 },
703 /* Init Lower Higher */
704 { 8, 0, 0, 8, 0, 0 }, /* Hit points */
705 { 1, 0, 0, 1, 0, 1 },
717 { { "Stripling", 0 },
720 { "Man-at-arms", "Woman-at-arms" },
722 { "Swashbuckler", 0 },
723 { "Hero", "Heroine" },
725 { "Lord", "Lady" } },
726 "Tyr", "Odin", "Loki", /* Norse */
728 { { "
\83\8f\83\8b\83L
\83\85\81[
\83\8c", 0 },
729 { { "
\8c©
\8fK
\82¢", 0 },
733 { "
\90í
\93¬
\95º", 0 },
734 { "
\8dU
\8c\82\95º", 0 },
736 { "
\90æ
\93±
\8eÒ", 0 },
737 { "
\83\8d\81[
\83h", "
\83\8c\83f
\83B" } },
738 "
\83`
\83\85\81[
\83\8b", "
\83I
\81[
\83f
\83B
\83\93", "
\83\8d\83L", /* Norse */
742 "the Shrine of Destiny",
743 "the cave of Surtur",
745 "
\89^
\96½
\82Ì
\90¹
\93°",
746 "
\83X
\83\8b\83g
\82Ì
\93´
\8cA",
750 NON_PM /*PM_WINTER_WOLF_CUB*/,
759 MH_HUMAN | MH_DWARF | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL,
760 /* Str Int Wis Dex Con Cha */
761 { 10, 7, 7, 7, 10, 7 },
762 { 30, 6, 7, 20, 30, 7 },
763 /* Init Lower Higher */
764 { 14, 0, 0, 8, 2, 0 }, /* Hit points */
765 { 1, 0, 0, 1, 0, 1 },
779 { "Thaumaturge", 0 },
781 { "Enchanter", "Enchantress" },
782 { "Sorcerer", "Sorceress" },
783 { "Necromancer", 0 },
786 "Ptah", "Thoth", "Anhur", /* Egyptian */
788 { { "
\96\82\96@
\8eg
\82¢", 0 },
789 { { "
\8eè
\95i
\8et", 0 },
790 { "
\8aï
\8fp
\8et", 0 },
791 { "
\90è
\82¢
\8et", 0 },
792 { "
\97ì
\8a´
\8et", 0 },
793 { "
\8f¢
\8a«
\8et", 0 },
794 { "
\97d
\8fp
\8et", 0 },
795 { "
\96\82\8fp
\8et", 0 },
796 { "
\96\82\96@
\8eg
\82¢", 0 },
797 { "
\91å
\96\82\96@
\8eg
\82¢", 0 } },
798 "
\83v
\83^
\83n", "
\83g
\81[
\83g", "
\83A
\83\93\83t
\83\8b", /* Egyptian */
803 "the Tower of Darkness",
805 "
\8cÇ
\8d\82\82Ì
\93\83",
806 "
\88Ã
\8d\95\82Ì
\93\83",
811 PM_NEFERET_THE_GREEN,
818 ART_EYE_OF_THE_AETHIOPICA,
819 MH_HUMAN | MH_ELF | MH_GNOME | MH_ORC | ROLE_MALE | ROLE_FEMALE
820 | ROLE_NEUTRAL | ROLE_CHAOTIC,
821 /* Str Int Wis Dex Con Cha */
822 { 7, 10, 7, 7, 7, 7 },
823 { 10, 30, 10, 20, 20, 10 },
824 /* Init Lower Higher */
825 { 10, 0, 0, 8, 1, 0 }, /* Hit points */
826 { 4, 3, 0, 2, 0, 3 },
836 /* Array terminator */
840 /* The player's role, created at runtime from initial
841 * choices. This may be munged in role_init().
843 struct Role urole = {
845 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
846 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
848 "Xxx", "home", "locate",
849 NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM, NON_PM,
851 /* Str Int Wis Dex Con Cha */
852 { 7, 7, 7, 7, 7, 7 },
853 { 20, 15, 15, 20, 20, 10 },
854 /* Init Lower Higher */
855 { 10, 0, 0, 8, 1, 0 }, /* Hit points */
856 { 2, 0, 0, 2, 0, 3 },
868 /* Table of all races */
869 const struct Race races[] = {
884 { "
\92j", "
\8f\97" },
890 MH_HUMAN | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL | ROLE_NEUTRAL
895 /* Str Int Wis Dex Con Cha */
896 { 3, 3, 3, 3, 3, 3 },
897 { STR18(100), 18, 18, 18, 18, 18 },
898 /* Init Lower Higher */
899 { 2, 0, 0, 2, 1, 0 }, /* Hit points */
900 { 1, 0, 2, 0, 2, 0 } /* Energy */
909 "
\83G
\83\8b\83t
\82Ì",
918 MH_ELF | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
922 /* Str Int Wis Dex Con Cha */
923 { 3, 3, 3, 3, 3, 3 },
924 { 18, 20, 20, 18, 16, 18 },
925 /* Init Lower Higher */
926 { 1, 0, 0, 1, 1, 0 }, /* Hit points */
927 { 2, 0, 3, 0, 3, 0 } /* Energy */
935 "
\83h
\83\8f\81[
\83t",
936 "
\83h
\83\8f\81[
\83t
\82Ì",
937 "
\83h
\83\8f\81[
\83t",
945 MH_DWARF | ROLE_MALE | ROLE_FEMALE | ROLE_LAWFUL,
949 /* Str Int Wis Dex Con Cha */
950 { 3, 3, 3, 3, 3, 3 },
951 { STR18(100), 16, 16, 20, 20, 16 },
952 /* Init Lower Higher */
953 { 4, 0, 0, 3, 2, 0 }, /* Hit points */
954 { 0, 0, 0, 0, 0, 0 } /* Energy */
963 "
\83m
\81[
\83\80\82Ì",
972 MH_GNOME | ROLE_MALE | ROLE_FEMALE | ROLE_NEUTRAL,
976 /* Str Int Wis Dex Con Cha */
977 { 3, 3, 3, 3, 3, 3 },
978 { STR18(50), 19, 18, 18, 18, 18 },
979 /* Init Lower Higher */
980 { 1, 0, 0, 1, 0, 0 }, /* Hit points */
981 { 2, 0, 2, 0, 2, 0 } /* Energy */
999 MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
1002 MH_HUMAN | MH_ELF | MH_DWARF,
1003 /* Str Int Wis Dex Con Cha */
1004 { 3, 3, 3, 3, 3, 3 },
1005 { STR18(50), 16, 16, 18, 18, 16 },
1006 /* Init Lower Higher */
1007 { 1, 0, 0, 1, 0, 0 }, /* Hit points */
1008 { 1, 0, 1, 0, 1, 0 } /* Energy */
1010 /* Array terminator */
1014 /* The player's race, created at runtime from initial
1015 * choices. This may be munged in role_init().
1017 struct Race urace = {
1031 /* Str Int Wis Dex Con Cha */
1032 { 3, 3, 3, 3, 3, 3 },
1033 { STR18(100), 18, 18, 18, 18, 18 },
1034 /* Init Lower Higher */
1035 { 2, 0, 0, 2, 1, 0 }, /* Hit points */
1036 { 1, 0, 2, 0, 2, 0 } /* Energy */
1039 /* Table of all genders */
1041 - steed.c kick_steed() He[]
\82É
\92l
\82ª
\83R
\83s
\81[
\82³
\82ê
\82é
\82Ì
\82Å
\92·
\82³
\82ð
\95Ï
\82¦
\82½
\82Æ
\82«
\82É
\82Í
1042 \8aY
\93\96\95\94\82à
\97v
\8fC
\90³
\81B
1044 const struct Gender genders[] = {
1046 { "male", "he", "him", "his", "Mal", ROLE_MALE },
1047 { "female", "she", "her", "her", "Fem", ROLE_FEMALE },
1048 { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER }
1050 { "
\92j
\90«", "
\94Þ", "
\94Þ", "
\94Þ
\82Ì", "Mal", ROLE_MALE },
1051 { "
\8f\97\90«", "
\94Þ
\8f\97", "
\94Þ
\8f\97", "
\94Þ
\8f\97\82Ì", "Fem", ROLE_FEMALE },
1052 { "
\92\86\90«", "
\82»
\82ê", "
\82»
\82ê", "
\82»
\82Ì", "Ntr", ROLE_NEUTER }
1056 /* Table of all alignments */
1057 const struct Align aligns[] = {
1059 { "law", "lawful", "Law", ROLE_LAWFUL, A_LAWFUL },
1060 { "balance", "neutral", "Neu", ROLE_NEUTRAL, A_NEUTRAL },
1061 { "chaos", "chaotic", "Cha", ROLE_CHAOTIC, A_CHAOTIC },
1062 { "evil", "unaligned", "Una", 0, A_NONE }
1064 { "
\92\81\8f\98", "
\92\81\8f\98\82Ì", "Law", ROLE_LAWFUL, A_LAWFUL },
1065 { "
\92\86\97§", "
\92\86\97§
\82Ì", "Neu", ROLE_NEUTRAL, A_NEUTRAL },
1066 { "
\8d¬
\93×", "
\8d¬
\93×
\82Ì", "Cha", ROLE_CHAOTIC, A_CHAOTIC },
1067 { "
\96³
\90S", "
\96³
\90S
\82Ì", "Una", 0, A_NONE }
1073 boolean roles[SIZE(roles)];
1077 STATIC_DCL int NDECL(randrole_filtered);
1078 STATIC_DCL char *FDECL(promptsep, (char *, int));
1079 STATIC_DCL int FDECL(role_gendercount, (int));
1080 STATIC_DCL int FDECL(race_alignmentcount, (int));
1082 /* used by str2XXX() */
1084 static char NEARDATA randomstr[] = "random";
1086 static char NEARDATA randomstr[] = "
\83\89\83\93\83_
\83\80";
1092 return (boolean) (rolenum >= 0 && rolenum < SIZE(roles) - 1);
1098 return rn2(SIZE(roles) - 1);
1104 int i, n = 0, set[SIZE(roles)];
1106 /* this doesn't rule out impossible combinations but attempts to
1107 honor all the filter masks */
1108 for (i = 0; i < SIZE(roles); ++i)
1109 if (ok_role(i, ROLE_NONE, ROLE_NONE, ROLE_NONE)
1110 && ok_race(i, ROLE_RANDOM, ROLE_NONE, ROLE_NONE)
1111 && ok_gend(i, ROLE_NONE, ROLE_RANDOM, ROLE_NONE)
1112 && ok_align(i, ROLE_NONE, ROLE_NONE, ROLE_RANDOM))
1114 return n ? set[rn2(n)] : randrole();
1124 if (!str || !str[0])
1127 /* Match as much of str as is provided */
1129 for (i = 0; roles[i].name.m; i++) {
1130 /* Does it match the male name? */
1131 if (!strncmpi(str, roles[i].name.m, len))
1133 /* Or the female name? */
1134 if (roles[i].name.f && !strncmpi(str, roles[i].name.f, len))
1136 /* Or the filecode? */
1137 if (!strcmpi(str, roles[i].filecode))
1141 if ((len == 1 && (*str == '*' || *str == '@'))
1142 || !strncmpi(str, randomstr, len))
1145 /* Couldn't find anything appropriate */
1150 validrace(rolenum, racenum)
1151 int rolenum, racenum;
1153 /* Assumes validrole */
1154 return (boolean) (racenum >= 0 && racenum < SIZE(races) - 1
1155 && (roles[rolenum].allow & races[racenum].allow
1165 /* Count the number of valid races */
1166 for (i = 0; races[i].noun; i++)
1167 if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK)
1170 /* Pick a random race */
1171 /* Use a factor of 100 in case of bad random number generators */
1173 n = rn2(n * 100) / 100;
1174 for (i = 0; races[i].noun; i++)
1175 if (roles[rolenum].allow & races[i].allow & ROLE_RACEMASK) {
1182 /* This role has no permitted races? */
1183 return rn2(SIZE(races) - 1);
1193 if (!str || !str[0])
1196 /* Match as much of str as is provided */
1198 for (i = 0; races[i].noun; i++) {
1199 /* Does it match the noun? */
1200 if (!strncmpi(str, races[i].noun, len))
1202 /* Or the filecode? */
1203 if (!strcmpi(str, races[i].filecode))
1207 if ((len == 1 && (*str == '*' || *str == '@'))
1208 || !strncmpi(str, randomstr, len))
1211 /* Couldn't find anything appropriate */
1216 validgend(rolenum, racenum, gendnum)
1217 int rolenum, racenum, gendnum;
1219 /* Assumes validrole and validrace */
1220 return (boolean) (gendnum >= 0 && gendnum < ROLE_GENDERS
1221 && (roles[rolenum].allow & races[racenum].allow
1222 & genders[gendnum].allow & ROLE_GENDMASK));
1226 randgend(rolenum, racenum)
1227 int rolenum, racenum;
1231 /* Count the number of valid genders */
1232 for (i = 0; i < ROLE_GENDERS; i++)
1233 if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1237 /* Pick a random gender */
1240 for (i = 0; i < ROLE_GENDERS; i++)
1241 if (roles[rolenum].allow & races[racenum].allow & genders[i].allow
1249 /* This role/race has no permitted genders? */
1250 return rn2(ROLE_GENDERS);
1260 if (!str || !str[0])
1263 /* Match as much of str as is provided */
1265 for (i = 0; i < ROLE_GENDERS; i++) {
1266 /* Does it match the adjective? */
1267 if (!strncmpi(str, genders[i].adj, len))
1269 /* Or the filecode? */
1270 if (!strcmpi(str, genders[i].filecode))
1273 if ((len == 1 && (*str == '*' || *str == '@'))
1274 || !strncmpi(str, randomstr, len))
1277 /* Couldn't find anything appropriate */
1282 validalign(rolenum, racenum, alignnum)
1283 int rolenum, racenum, alignnum;
1285 /* Assumes validrole and validrace */
1286 return (boolean) (alignnum >= 0 && alignnum < ROLE_ALIGNS
1287 && (roles[rolenum].allow & races[racenum].allow
1288 & aligns[alignnum].allow & ROLE_ALIGNMASK));
1292 randalign(rolenum, racenum)
1293 int rolenum, racenum;
1297 /* Count the number of valid alignments */
1298 for (i = 0; i < ROLE_ALIGNS; i++)
1299 if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1303 /* Pick a random alignment */
1306 for (i = 0; i < ROLE_ALIGNS; i++)
1307 if (roles[rolenum].allow & races[racenum].allow & aligns[i].allow
1315 /* This role/race has no permitted alignments? */
1316 return rn2(ROLE_ALIGNS);
1326 if (!str || !str[0])
1329 /* Match as much of str as is provided */
1331 for (i = 0; i < ROLE_ALIGNS; i++) {
1332 /* Does it match the adjective? */
1333 if (!strncmpi(str, aligns[i].adj, len))
1335 /* Or the filecode? */
1336 if (!strcmpi(str, aligns[i].filecode))
1339 if ((len == 1 && (*str == '*' || *str == '@'))
1340 || !strncmpi(str, randomstr, len))
1343 /* Couldn't find anything appropriate */
1347 /* is rolenum compatible with any racenum/gendnum/alignnum constraints? */
1349 ok_role(rolenum, racenum, gendnum, alignnum)
1350 int rolenum, racenum, gendnum, alignnum;
1355 if (rolenum >= 0 && rolenum < SIZE(roles) - 1) {
1356 if (rfilter.roles[rolenum])
1358 allow = roles[rolenum].allow;
1359 if (racenum >= 0 && racenum < SIZE(races) - 1
1360 && !(allow & races[racenum].allow & ROLE_RACEMASK))
1362 if (gendnum >= 0 && gendnum < ROLE_GENDERS
1363 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1365 if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1366 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1370 /* random; check whether any selection is possible */
1371 for (i = 0; i < SIZE(roles) - 1; i++) {
1372 if (rfilter.roles[i])
1374 allow = roles[i].allow;
1375 if (racenum >= 0 && racenum < SIZE(races) - 1
1376 && !(allow & races[racenum].allow & ROLE_RACEMASK))
1378 if (gendnum >= 0 && gendnum < ROLE_GENDERS
1379 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1381 if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1382 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1390 /* pick a random role subject to any racenum/gendnum/alignnum constraints */
1391 /* If pickhow == PICK_RIGID a role is returned only if there is */
1392 /* a single possibility */
1394 pick_role(racenum, gendnum, alignnum, pickhow)
1395 int racenum, gendnum, alignnum, pickhow;
1398 int roles_ok = 0, set[SIZE(roles)];
1400 for (i = 0; i < SIZE(roles) - 1; i++) {
1401 if (ok_role(i, racenum, gendnum, alignnum)
1402 && ok_race(i, (racenum >= 0) ? racenum : ROLE_RANDOM,
1404 && ok_gend(i, racenum,
1405 (gendnum >= 0) ? gendnum : ROLE_RANDOM, alignnum)
1406 && ok_race(i, racenum,
1407 gendnum, (alignnum >= 0) ? alignnum : ROLE_RANDOM))
1408 set[roles_ok++] = i;
1410 if (roles_ok == 0 || (roles_ok > 1 && pickhow == PICK_RIGID))
1412 return set[rn2(roles_ok)];
1415 /* is racenum compatible with any rolenum/gendnum/alignnum constraints? */
1417 ok_race(rolenum, racenum, gendnum, alignnum)
1418 int rolenum, racenum, gendnum, alignnum;
1423 if (racenum >= 0 && racenum < SIZE(races) - 1) {
1424 if (rfilter.mask & races[racenum].selfmask)
1426 allow = races[racenum].allow;
1427 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1428 && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1430 if (gendnum >= 0 && gendnum < ROLE_GENDERS
1431 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1433 if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1434 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1438 /* random; check whether any selection is possible */
1439 for (i = 0; i < SIZE(races) - 1; i++) {
1440 if (rfilter.mask & races[i].selfmask)
1442 allow = races[i].allow;
1443 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1444 && !(allow & roles[rolenum].allow & ROLE_RACEMASK))
1446 if (gendnum >= 0 && gendnum < ROLE_GENDERS
1447 && !(allow & genders[gendnum].allow & ROLE_GENDMASK))
1449 if (alignnum >= 0 && alignnum < ROLE_ALIGNS
1450 && !(allow & aligns[alignnum].allow & ROLE_ALIGNMASK))
1458 /* Pick a random race subject to any rolenum/gendnum/alignnum constraints.
1459 If pickhow == PICK_RIGID a race is returned only if there is
1460 a single possibility. */
1462 pick_race(rolenum, gendnum, alignnum, pickhow)
1463 int rolenum, gendnum, alignnum, pickhow;
1468 for (i = 0; i < SIZE(races) - 1; i++) {
1469 if (ok_race(rolenum, i, gendnum, alignnum))
1472 if (races_ok == 0 || (races_ok > 1 && pickhow == PICK_RIGID))
1474 races_ok = rn2(races_ok);
1475 for (i = 0; i < SIZE(races) - 1; i++) {
1476 if (ok_race(rolenum, i, gendnum, alignnum)) {
1486 /* is gendnum compatible with any rolenum/racenum/alignnum constraints? */
1487 /* gender and alignment are not comparable (and also not constrainable) */
1489 ok_gend(rolenum, racenum, gendnum, alignnum)
1490 int rolenum, racenum, gendnum;
1491 int alignnum UNUSED;
1496 if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
1497 if (rfilter.mask & genders[gendnum].allow)
1499 allow = genders[gendnum].allow;
1500 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1501 && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1503 if (racenum >= 0 && racenum < SIZE(races) - 1
1504 && !(allow & races[racenum].allow & ROLE_GENDMASK))
1508 /* random; check whether any selection is possible */
1509 for (i = 0; i < ROLE_GENDERS; i++) {
1510 if (rfilter.mask & genders[i].allow)
1512 allow = genders[i].allow;
1513 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1514 && !(allow & roles[rolenum].allow & ROLE_GENDMASK))
1516 if (racenum >= 0 && racenum < SIZE(races) - 1
1517 && !(allow & races[racenum].allow & ROLE_GENDMASK))
1525 /* pick a random gender subject to any rolenum/racenum/alignnum constraints */
1526 /* gender and alignment are not comparable (and also not constrainable) */
1527 /* If pickhow == PICK_RIGID a gender is returned only if there is */
1528 /* a single possibility */
1530 pick_gend(rolenum, racenum, alignnum, pickhow)
1531 int rolenum, racenum, alignnum, pickhow;
1536 for (i = 0; i < ROLE_GENDERS; i++) {
1537 if (ok_gend(rolenum, racenum, i, alignnum))
1540 if (gends_ok == 0 || (gends_ok > 1 && pickhow == PICK_RIGID))
1542 gends_ok = rn2(gends_ok);
1543 for (i = 0; i < ROLE_GENDERS; i++) {
1544 if (ok_gend(rolenum, racenum, i, alignnum)) {
1554 /* is alignnum compatible with any rolenum/racenum/gendnum constraints? */
1555 /* alignment and gender are not comparable (and also not constrainable) */
1557 ok_align(rolenum, racenum, gendnum, alignnum)
1558 int rolenum, racenum;
1565 if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
1566 if (rfilter.mask & aligns[alignnum].allow)
1568 allow = aligns[alignnum].allow;
1569 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1570 && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1572 if (racenum >= 0 && racenum < SIZE(races) - 1
1573 && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1577 /* random; check whether any selection is possible */
1578 for (i = 0; i < ROLE_ALIGNS; i++) {
1579 if (rfilter.mask & aligns[i].allow)
1581 allow = aligns[i].allow;
1582 if (rolenum >= 0 && rolenum < SIZE(roles) - 1
1583 && !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
1585 if (racenum >= 0 && racenum < SIZE(races) - 1
1586 && !(allow & races[racenum].allow & ROLE_ALIGNMASK))
1594 /* Pick a random alignment subject to any rolenum/racenum/gendnum constraints;
1595 alignment and gender are not comparable (and also not constrainable).
1596 If pickhow == PICK_RIGID an alignment is returned only if there is
1597 a single possibility. */
1599 pick_align(rolenum, racenum, gendnum, pickhow)
1600 int rolenum, racenum, gendnum, pickhow;
1605 for (i = 0; i < ROLE_ALIGNS; i++) {
1606 if (ok_align(rolenum, racenum, gendnum, i))
1609 if (aligns_ok == 0 || (aligns_ok > 1 && pickhow == PICK_RIGID))
1611 aligns_ok = rn2(aligns_ok);
1612 for (i = 0; i < ROLE_ALIGNS; i++) {
1613 if (ok_align(rolenum, racenum, gendnum, i)) {
1628 /* Some roles are limited to a single race, alignment, or gender and
1629 * calling this routine prior to XXX_player_selection() will help
1630 * prevent an extraneous prompt that actually doesn't allow
1631 * you to choose anything further. Note the use of PICK_RIGID which
1632 * causes the pick_XX() routine to return a value only if there is one
1633 * single possible selection, otherwise it returns ROLE_NONE.
1636 if (flags.initrole == ROLE_RANDOM) {
1637 /* If the role was explicitly specified as ROLE_RANDOM
1638 * via -uXXXX-@ or OPTIONS=role:random then choose the role
1639 * in here to narrow down later choices.
1641 flags.initrole = pick_role(flags.initrace, flags.initgend,
1642 flags.initalign, PICK_RANDOM);
1643 if (flags.initrole < 0)
1644 flags.initrole = randrole_filtered();
1646 if (flags.initrace == ROLE_RANDOM
1647 && (tmp = pick_race(flags.initrole, flags.initgend,
1648 flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1649 flags.initrace = tmp;
1650 if (flags.initalign == ROLE_RANDOM
1651 && (tmp = pick_align(flags.initrole, flags.initrace,
1652 flags.initgend, PICK_RANDOM)) != ROLE_NONE)
1653 flags.initalign = tmp;
1654 if (flags.initgend == ROLE_RANDOM
1655 && (tmp = pick_gend(flags.initrole, flags.initrace,
1656 flags.initalign, PICK_RANDOM)) != ROLE_NONE)
1657 flags.initgend = tmp;
1659 if (flags.initrole != ROLE_NONE) {
1660 if (flags.initrace == ROLE_NONE)
1661 flags.initrace = pick_race(flags.initrole, flags.initgend,
1662 flags.initalign, PICK_RIGID);
1663 if (flags.initalign == ROLE_NONE)
1664 flags.initalign = pick_align(flags.initrole, flags.initrace,
1665 flags.initgend, PICK_RIGID);
1666 if (flags.initgend == ROLE_NONE)
1667 flags.initgend = pick_gend(flags.initrole, flags.initrace,
1668 flags.initalign, PICK_RIGID);
1677 boolean reslt = TRUE;
1679 if ((i = str2role(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1680 rfilter.roles[i] = TRUE;
1681 else if ((i = str2race(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1682 rfilter.mask |= races[i].selfmask;
1683 else if ((i = str2gend(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1684 rfilter.mask |= genders[i].allow;
1685 else if ((i = str2align(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
1686 rfilter.mask |= aligns[i].allow;
1699 for (i = 0; i < SIZE(roles); ++i)
1700 if (rfilter.roles[i])
1710 for (i = 0; i < SIZE(roles); ++i)
1711 rfilter.roles[i] = FALSE;
1721 STATIC_VAR char pa[NUM_BP], post_attribs;
1724 promptsep(buf, num_post_attribs)
1726 int num_post_attribs;
1729 const char *conjuct = "and ";
1731 if (num_post_attribs > 1 && post_attribs < num_post_attribs
1732 && post_attribs > 1)
1736 if (!post_attribs && num_post_attribs > 1)
1737 Strcat(buf, conjuct);
1739 /*JP:
\93ú
\96{
\8cê
\82Å
\82Í "A, B, and C"
\82Æ
\82¢
\82¤
\8f\88\97\9d\82Í
\95s
\97v */
1740 if(num_post_attribs > post_attribs){
1741 Strcat(buf, "
\81C");
1749 role_gendercount(rolenum)
1754 if (validrole(rolenum)) {
1755 if (roles[rolenum].allow & ROLE_MALE)
1757 if (roles[rolenum].allow & ROLE_FEMALE)
1759 if (roles[rolenum].allow & ROLE_NEUTER)
1766 race_alignmentcount(racenum)
1771 if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1772 if (races[racenum].allow & ROLE_CHAOTIC)
1774 if (races[racenum].allow & ROLE_LAWFUL)
1776 if (races[racenum].allow & ROLE_NEUTRAL)
1783 root_plselection_prompt(suppliedbuf, buflen, rolenum, racenum, gendnum,
1786 int buflen, rolenum, racenum, gendnum, alignnum;
1788 int k, gendercount = 0, aligncount = 0;
1791 static char err_ret[] = " character's";
1793 static char err_ret[] = "
\83L
\83\83\83\89\83N
\83^
\81[
\82Ì";
1795 boolean donefirst = FALSE;
1798 if (!suppliedbuf || buflen < 1)
1801 /* initialize these static variables each time this is called */
1803 for (k = 0; k < NUM_BP; ++k)
1806 *suppliedbuf = '\0';
1808 /* How many alignments are allowed for the desired race? */
1809 if (racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1810 aligncount = race_alignmentcount(racenum);
1812 if (alignnum != ROLE_NONE && alignnum != ROLE_RANDOM
1813 && ok_align(rolenum, racenum, gendnum, alignnum)) {
1814 /* if race specified, and multiple choice of alignments for it */
1815 if ((racenum >= 0) && (aligncount > 1)) {
1820 Strcat(buf, aligns[alignnum].adj);
1829 Strcat(buf, aligns[alignnum].adj);
1835 /* in case we got here by failing the ok_align() test */
1836 if (alignnum != ROLE_RANDOM)
1837 alignnum = ROLE_NONE;
1838 /* if alignment not specified, but race is specified
1839 and only one choice of alignment for that race then
1840 don't include it in the later list */
1841 if ((((racenum != ROLE_NONE && racenum != ROLE_RANDOM)
1842 && ok_race(rolenum, racenum, gendnum, alignnum))
1843 && (aligncount > 1))
1844 || (racenum == ROLE_NONE || racenum == ROLE_RANDOM)) {
1851 /* How many genders are allowed for the desired role? */
1852 if (validrole(rolenum))
1853 gendercount = role_gendercount(rolenum);
1855 if (gendnum != ROLE_NONE && gendnum != ROLE_RANDOM) {
1856 if (validrole(rolenum)) {
1857 /* if role specified, and multiple choice of genders for it,
1858 and name of role itself does not distinguish gender */
1859 if ((rolenum != ROLE_NONE) && (gendercount > 1)
1860 && !roles[rolenum].name.f) {
1865 Strcat(buf, genders[gendnum].adj);
1875 Strcat(buf, genders[gendnum].adj);
1881 /* if gender not specified, but role is specified
1882 and only one choice of gender then
1883 don't include it in the later list */
1884 if ((validrole(rolenum) && (gendercount > 1))
1885 || !validrole(rolenum)) {
1890 /* <your lawful female> */
1892 if (racenum != ROLE_NONE && racenum != ROLE_RANDOM) {
1893 if (validrole(rolenum)
1894 && ok_race(rolenum, racenum, gendnum, alignnum)) {
1899 Strcat(buf, (rolenum == ROLE_NONE) ? races[racenum].noun
1900 : races[racenum].adj);
1904 } else if (!validrole(rolenum)) {
1909 Strcat(buf, races[racenum].noun);
1921 /* <your lawful female gnomish> || <your lawful female gnome> */
1923 if (validrole(rolenum)) {
1928 if (gendnum != ROLE_NONE) {
1929 if (gendnum == 1 && roles[rolenum].name.f)
1930 Strcat(buf, roles[rolenum].name.f);
1932 Strcat(buf, roles[rolenum].name.m);
1934 if (roles[rolenum].name.f) {
1935 Strcat(buf, roles[rolenum].name.m);
1937 Strcat(buf, roles[rolenum].name.f);
1939 Strcat(buf, roles[rolenum].name.m);
1944 } else if (rolenum == ROLE_NONE) {
1949 if ((racenum == ROLE_NONE || racenum == ROLE_RANDOM)
1950 && !validrole(rolenum)) {
1956 Strcat(buf, "character");
1958 Strcat(buf, "
\83L
\83\83\83\89\83N
\83^
\81[");
1963 /* <your lawful female gnomish cavewoman> || <your lawful female gnome>
1964 * || <your lawful female character>
1966 if (buflen > (int) (strlen(buf) + 1)) {
1967 Strcpy(suppliedbuf, buf);
1974 build_plselection_prompt(buf, buflen, rolenum, racenum, gendnum, alignnum)
1976 int buflen, rolenum, racenum, gendnum, alignnum;
1979 const char *defprompt = "Shall I pick a character for you? [ynaq] ";
1981 const char *defprompt = "
\93K
\93\96\82É
\83L
\83\83\83\89\83N
\83^
\81[
\82ð
\91I
\82ñ
\82Å
\82æ
\82¢
\82Å
\82·
\82©
\81H[ynaq] ";
1982 int num_post_attribs = 0;
1984 char tmpbuf[BUFSZ], *p;
1989 if (buflen < QBUFSZ)
1990 return (char *) defprompt;
1993 Strcpy(tmpbuf, "Shall I pick ");
1994 if (racenum != ROLE_NONE || validrole(rolenum))
1995 Strcat(tmpbuf, "your ");
1997 Strcat(tmpbuf, "a ");
2004 (void) root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf),
2005 rolenum, racenum, gendnum, alignnum);
2007 Sprintf(buf, "%s", s_suffix(tmpbuf));
2009 Sprintf(buf, "%s
\82Ì", tmpbuf);
2011 #if 0 /*JP:
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
2012 /* don't bother splitting caveman/cavewoman or priest/priestess
2013 in order to apply possessive suffix to both halves, but do
2014 change "priest/priestess'" to "priest/priestess's" */
2015 if ((p = strstri(buf, "priest/priestess'")) != 0
2016 && p[sizeof "priest/priestess'" - sizeof ""] == '\0')
2017 strkitten(buf, 's');
2020 /* buf should now be:
2021 * <your lawful female gnomish cavewoman's>
2022 * || <your lawful female gnome's>
2023 * || <your lawful female character's>
2025 * Now append the post attributes to it
2027 num_post_attribs = post_attribs;
2028 if (!num_post_attribs) {
2029 /* some constraints might have been mutually exclusive, in which case
2030 some prompting that would have been omitted is needed after all */
2031 if (flags.initrole == ROLE_NONE && !pa[BP_ROLE])
2032 pa[BP_ROLE] = ++post_attribs;
2033 if (flags.initrace == ROLE_NONE && !pa[BP_RACE])
2034 pa[BP_RACE] = ++post_attribs;
2035 if (flags.initalign == ROLE_NONE && !pa[BP_ALIGN])
2036 pa[BP_ALIGN] = ++post_attribs;
2037 if (flags.initgend == ROLE_NONE && !pa[BP_GEND])
2038 pa[BP_GEND] = ++post_attribs;
2039 num_post_attribs = post_attribs;
2041 if (num_post_attribs) {
2043 (void) promptsep(eos(buf), num_post_attribs);
2045 Strcat(buf, "race");
2047 Strcat(buf, "
\8eí
\91°");
2050 (void) promptsep(eos(buf), num_post_attribs);
2052 Strcat(buf, "role");
2054 Strcat(buf, "
\90E
\8bÆ");
2057 (void) promptsep(eos(buf), num_post_attribs);
2059 Strcat(buf, "gender");
2061 Strcat(buf, "
\90«
\95Ê");
2064 (void) promptsep(eos(buf), num_post_attribs);
2066 Strcat(buf, "alignment");
2068 Strcat(buf, "
\91®
\90«");
2072 Strcat(buf, " for you? [ynaq] ");
2074 Strcat(buf, "
\82ð
\93K
\93\96\82É
\91I
\82ñ
\82Å
\82æ
\82ë
\82µ
\82¢
\82Å
\82·
\82©
\81H[ynq] ");
2090 /* some generic user names will be ignored in favor of prompting */
2091 if (sysopt.genericusers) {
2092 if (*sysopt.genericusers == '*') *plname = '\0';
2094 i = (int)strlen(plname);
2095 if ((sptr = strstri(sysopt.genericusers, plname)) != 0
2096 && (sptr == sysopt.genericusers || sptr[-1] == ' ')
2097 && (sptr[i] == ' ' || sptr[i] == '\0'))
2098 *plname = '\0'; /* call askname() */
2104 askname(); /* fill plname[] if necessary, or set defer_plname */
2106 /* Look for tokens delimited by '-' */
2107 if ((eptr = index(plname, '-')) != (char *) 0)
2110 /* Isolate the next token */
2112 if ((eptr = index(sptr, '-')) != (char *) 0)
2115 /* Try to match it to something */
2116 if ((i = str2role(sptr)) != ROLE_NONE)
2118 else if ((i = str2race(sptr)) != ROLE_NONE)
2120 else if ((i = str2gend(sptr)) != ROLE_NONE)
2122 else if ((i = str2align(sptr)) != ROLE_NONE)
2123 flags.initalign = i;
2125 } while (!*plname && !iflags.defer_plname);
2127 /* commas in the plname confuse the record file, convert to spaces */
2128 for (sptr = plname; *sptr; sptr++) {
2134 /* show current settings for name, role, race, gender, and alignment
2135 in the specified window */
2137 role_selection_prolog(which, where)
2142 static const char NEARDATA choosing[] = " choosing now",
2144 static const char NEARDATA choosing[] = "
\8c»
\8dÝ
\91I
\91ð
\92\86",
2146 not_yet[] = " not yet specified",
2148 not_yet[] = "
\96¢
\91I
\91ð",
2150 rand_choice[] = " random";
2152 rand_choice[] = "
\83\89\83\93\83_
\83\80";
2154 int r, c, g, a, allowmask;
2159 a = flags.initalign;
2161 allowmask = roles[r].allow;
2162 if ((allowmask & ROLE_RACEMASK) == MH_HUMAN)
2163 c = 0; /* races[human] */
2164 else if (c >= 0 && !(allowmask & ROLE_RACEMASK & races[c].allow))
2166 if ((allowmask & ROLE_GENDMASK) == ROLE_MALE)
2167 g = 0; /* role forces male (hypothetical) */
2168 else if ((allowmask & ROLE_GENDMASK) == ROLE_FEMALE)
2169 g = 1; /* role forces female (valkyrie) */
2170 if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2171 a = 0; /* aligns[lawful] */
2172 else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2173 a = 1; /* aligns[neutral] */
2174 else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2175 a = 2; /* alings[chaotic] */
2178 allowmask = races[c].allow;
2179 if ((allowmask & ROLE_ALIGNMASK) == AM_LAWFUL)
2180 a = 0; /* aligns[lawful] */
2181 else if ((allowmask & ROLE_ALIGNMASK) == AM_NEUTRAL)
2182 a = 1; /* aligns[neutral] */
2183 else if ((allowmask & ROLE_ALIGNMASK) == AM_CHAOTIC)
2184 a = 2; /* alings[chaotic] */
2185 /* [c never forces gender] */
2187 /* [g and a don't constrain anything sufficiently
2188 to narrow something done to a single choice] */
2191 Sprintf(buf, "%12s ", "name:");
2193 Sprintf(buf, "%12s ", "
\96¼
\91O:");
2194 Strcat(buf, (which == RS_NAME) ? choosing : !*plname ? not_yet : plname);
2195 putstr(where, 0, buf);
2197 Sprintf(buf, "%12s ", "role:");
2199 Sprintf(buf, "%12s ", "
\90E
\8bÆ:");
2200 Strcat(buf, (which == RS_ROLE) ? choosing : (r == ROLE_NONE)
2202 : (r == ROLE_RANDOM)
2205 if (r >= 0 && roles[r].name.f) {
2206 /* distinct female name [caveman/cavewoman, priest/priestess] */
2208 /* female specified; replace male role name with female one */
2209 Sprintf(index(buf, ':'), ": %s", roles[r].name.f);
2211 /* gender unspecified; append slash and female role name */
2212 Sprintf(eos(buf), "/%s", roles[r].name.f);
2214 putstr(where, 0, buf);
2216 Sprintf(buf, "%12s ", "race:");
2218 Sprintf(buf, "%12s ", "
\8eí
\91°:");
2219 Strcat(buf, (which == RS_RACE) ? choosing : (c == ROLE_NONE)
2221 : (c == ROLE_RANDOM)
2224 putstr(where, 0, buf);
2226 Sprintf(buf, "%12s ", "gender:");
2228 Sprintf(buf, "%12s ", "
\90«
\95Ê:");
2229 Strcat(buf, (which == RS_GENDER) ? choosing : (g == ROLE_NONE)
2231 : (g == ROLE_RANDOM)
2234 putstr(where, 0, buf);
2236 Sprintf(buf, "%12s ", "alignment:");
2238 Sprintf(buf, "%12s ", "
\91®
\90«:");
2239 #if 0 /*JP:
\93ú
\96{
\8cê
\82Å
\82Í
\96¼
\8e\8c\82ª
\8e©
\91R*/
2240 Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
2242 : (a == ROLE_RANDOM)
2246 Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
2248 : (a == ROLE_RANDOM)
2252 putstr(where, 0, buf);
2255 /* add a "pick alignment first"-type entry to the specified menu */
2257 role_menu_extra(which, where, preselect)
2262 static NEARDATA const char RS_menu_let[] = {
2267 '[', /* alignment */
2271 const char *what = 0, *constrainer = 0, *forcedvalue = 0;
2272 int f = 0, r, c, g, a, i, allowmask;
2289 for (i = 0; i < SIZE(roles); ++i)
2290 if (i != f && !rfilter.roles[i])
2292 if (i == SIZE(roles)) {
2294 constrainer = "filter";
2296 constrainer = "
\8di
\82è
\8d\9e\82Ý";
2298 forcedvalue = "role";
2300 forcedvalue = "
\90E
\8bÆ";
2309 c = ROLE_NONE; /* override player's setting */
2311 allowmask = roles[r].allow & ROLE_RACEMASK;
2312 if (allowmask == MH_HUMAN)
2313 c = 0; /* races[human] */
2316 constrainer = "role";
2318 constrainer = "
\90E
\8bÆ";
2319 forcedvalue = races[c].noun;
2321 && (allowmask & ~rfilter.mask) == races[f].selfmask) {
2322 /* if there is only one race choice available due to user
2323 options disallowing others, race menu entry is disabled */
2325 constrainer = "filter";
2327 constrainer = "
\8di
\82è
\8d\9e\82Ý";
2329 forcedvalue = "race";
2331 forcedvalue = "
\8eí
\91°";
2343 allowmask = roles[r].allow & ROLE_GENDMASK;
2344 if (allowmask == ROLE_MALE)
2345 g = 0; /* genders[male] */
2346 else if (allowmask == ROLE_FEMALE)
2347 g = 1; /* genders[female] */
2350 constrainer = "role";
2352 constrainer = "
\90E
\8bÆ";
2353 forcedvalue = genders[g].adj;
2355 && (allowmask & ~rfilter.mask) == genders[f].allow) {
2356 /* if there is only one gender choice available due to user
2357 options disallowing other, gender menu entry is disabled */
2359 constrainer = "filter";
2361 constrainer = "
\8di
\82è
\8d\9e\82Ý";
2363 forcedvalue = "gender";
2365 forcedvalue = "
\90«
\95Ê";
2374 f = flags.initalign;
2377 allowmask = roles[r].allow & ROLE_ALIGNMASK;
2378 if (allowmask == AM_LAWFUL)
2379 a = 0; /* aligns[lawful] */
2380 else if (allowmask == AM_NEUTRAL)
2381 a = 1; /* aligns[neutral] */
2382 else if (allowmask == AM_CHAOTIC)
2383 a = 2; /* aligns[chaotic] */
2386 constrainer = "role";
2388 constrainer = "
\90E
\8bÆ";
2390 if (c >= 0 && !constrainer) {
2391 allowmask = races[c].allow & ROLE_ALIGNMASK;
2392 if (allowmask == AM_LAWFUL)
2393 a = 0; /* aligns[lawful] */
2394 else if (allowmask == AM_NEUTRAL)
2395 a = 1; /* aligns[neutral] */
2396 else if (allowmask == AM_CHAOTIC)
2397 a = 2; /* aligns[chaotic] */
2400 constrainer = "race";
2402 constrainer = "
\8eí
\91°";
2404 if (f >= 0 && !constrainer
2405 && (ROLE_ALIGNMASK & ~rfilter.mask) == aligns[f].allow) {
2406 /* if there is only one alignment choice available due to user
2407 options disallowing others, algn menu entry is disabled */
2409 constrainer = "filter";
2411 constrainer = "
\8di
\82è
\8d\9e\82Ý";
2413 forcedvalue = "alignment";
2415 forcedvalue = "
\91®
\90«";
2418 #if 0 /*JP:
\93ú
\96{
\8cê
\82Å
\82Í
\96¼
\8e\8c\82ª
\8e©
\91R*/
2419 forcedvalue = aligns[a].adj;
2421 forcedvalue = aligns[a].noun;
2426 any = zeroany; /* zero out all bits */
2429 /* use four spaces of padding to fake a grayed out menu choice */
2431 Sprintf(buf, "%4s%s forces %s", "", constrainer, forcedvalue);
2433 Sprintf(buf, "%4s
\82±
\82Ì%s
\82Å
\82Í%s
\82Ì
\82Ý", "", constrainer, forcedvalue);
2434 add_menu(where, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
2437 any.a_int = RS_menu_arg(which);
2439 Sprintf(buf, "Pick%s %s first", (f >= 0) ? " another" : "", what);
2441 Sprintf(buf, "%s%s
\82ð
\90æ
\82É
\91I
\82Ô", (f >= 0) ? "
\91¼
\82Ì" : "", what);
2442 add_menu(where, NO_GLYPH, &any, RS_menu_let[which], 0, ATR_NONE, buf,
2444 } else if (which == RS_filter) {
2445 any.a_int = RS_menu_arg(RS_filter);
2447 add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2448 "Reset role/race/&c filtering", MENU_UNSELECTED);
2450 add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
2451 "
\90E
\8bÆ/
\8eí
\91°
\82È
\82Ç
\82Ì
\8di
\82è
\8d\9e\82Ý
\82ð
\89ð
\8f\9c\82·
\82é", MENU_UNSELECTED);
2453 } else if (which == ROLE_RANDOM) {
2454 any.a_int = ROLE_RANDOM;
2456 add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
2457 preselect ? MENU_SELECTED : MENU_UNSELECTED);
2459 add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "
\83\89\83\93\83_
\83\80",
2462 } else if (which == ROLE_NONE) {
2463 any.a_int = ROLE_NONE;
2465 add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
2466 preselect ? MENU_SELECTED : MENU_UNSELECTED);
2468 add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "
\94²
\82¯
\82é",
2472 impossible("role_menu_extra: bad arg (%d)", which);
2477 * Special setup modifications here:
2479 * Unfortunately, this is going to have to be done
2480 * on each newgame or restore, because you lose the permonst mods
2481 * across a save/restore. :-)
2483 * 1 - The Rogue Leader is the Tourist Nemesis.
2484 * 2 - Priests start with a random alignment - convert the leader and
2486 * 3 - Priests also get their of deities from a randomly chosen role.
2487 * 4 - [obsolete] Elves can have one of two different leaders,
2488 * but can't work it out here because it requires hacking the
2489 * level file data (see sp_lev.c).
2491 * This code also replaces quest_init().
2497 struct permonst *pm;
2499 /* Strip the role letter out of the player name.
2500 * This is included for backwards compatibility.
2504 /* Check for a valid role. Try flags.initrole first. */
2505 if (!validrole(flags.initrole)) {
2506 /* Try the player letter second */
2507 if ((flags.initrole = str2role(pl_character)) < 0)
2508 /* None specified; pick a random role */
2509 flags.initrole = randrole_filtered();
2512 /* We now have a valid role index. Copy the role name back. */
2513 /* This should become OBSOLETE */
2514 Strcpy(pl_character, roles[flags.initrole].name.m);
2515 pl_character[PL_CSIZ - 1] = '\0';
2517 /* Check for a valid race */
2518 if (!validrace(flags.initrole, flags.initrace))
2519 flags.initrace = randrace(flags.initrole);
2521 /* Check for a valid gender. If new game, check both initgend
2522 * and female. On restore, assume flags.female is correct. */
2523 if (flags.pantheon == -1) { /* new game */
2524 if (!validgend(flags.initrole, flags.initrace, flags.female))
2525 flags.female = !flags.female;
2527 if (!validgend(flags.initrole, flags.initrace, flags.initgend))
2528 /* Note that there is no way to check for an unspecified gender. */
2529 flags.initgend = flags.female;
2531 /* Check for a valid alignment */
2532 if (!validalign(flags.initrole, flags.initrace, flags.initalign))
2533 /* Pick a random alignment */
2534 flags.initalign = randalign(flags.initrole, flags.initrace);
2535 alignmnt = aligns[flags.initalign].value;
2537 /* Initialize urole and urace */
2538 urole = roles[flags.initrole];
2539 urace = races[flags.initrace];
2541 /* Fix up the quest leader */
2542 if (urole.ldrnum != NON_PM) {
2543 pm = &mons[urole.ldrnum];
2544 pm->msound = MS_LEADER;
2545 pm->mflags2 |= (M2_PEACEFUL);
2546 pm->mflags3 |= M3_CLOSE;
2547 pm->maligntyp = alignmnt * 3;
2548 /* if gender is random, we choose it now instead of waiting
2549 until the leader monster is created */
2550 quest_status.ldrgend =
2551 is_neuter(pm) ? 2 : is_female(pm) ? 1 : is_male(pm)
2556 /* Fix up the quest guardians */
2557 if (urole.guardnum != NON_PM) {
2558 pm = &mons[urole.guardnum];
2559 pm->mflags2 |= (M2_PEACEFUL);
2560 pm->maligntyp = alignmnt * 3;
2563 /* Fix up the quest nemesis */
2564 if (urole.neminum != NON_PM) {
2565 pm = &mons[urole.neminum];
2566 pm->msound = MS_NEMESIS;
2567 pm->mflags2 &= ~(M2_PEACEFUL);
2568 pm->mflags2 |= (M2_NASTY | M2_STALK | M2_HOSTILE);
2569 pm->mflags3 &= ~(M3_CLOSE);
2570 pm->mflags3 |= M3_WANTSARTI | M3_WAITFORU;
2571 /* if gender is random, we choose it now instead of waiting
2572 until the nemesis monster is created */
2573 quest_status.nemgend = is_neuter(pm) ? 2 : is_female(pm) ? 1
2574 : is_male(pm) ? 0 : (rn2(100) < 50);
2577 /* Fix up the god names */
2578 if (flags.pantheon == -1) { /* new game */
2579 flags.pantheon = flags.initrole; /* use own gods */
2580 while (!roles[flags.pantheon].lgod) /* unless they're missing */
2581 flags.pantheon = randrole();
2584 urole.lgod = roles[flags.pantheon].lgod;
2585 urole.ngod = roles[flags.pantheon].ngod;
2586 urole.cgod = roles[flags.pantheon].cgod;
2588 /* 0 or 1; no gods are neuter, nor is gender randomized */
2590 quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess");
2592 quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "
\8f\97\90_");
2594 /* Fix up infravision */
2595 if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {
2596 /* although an infravision intrinsic is possible, infravision
2597 * is purely a property of the physical race. This means that we
2598 * must put the infravision flag in the player's current race
2599 * (either that or have separate permonst entries for
2600 * elven/non-elven members of each class). The side effect is that
2601 * all NPCs of that class will have (probably bogus) infravision,
2602 * but since infravision has no effect for NPCs anyway we can
2605 mons[urole.malenum].mflags3 |= M3_INFRAVISION;
2606 if (urole.femalenum != NON_PM)
2607 mons[urole.femalenum].mflags3 |= M3_INFRAVISION;
2610 /* Artifacts are fixed in hack_artifacts() */
2621 switch (Role_switch) {
2623 return "Salutations"; /* Olde English */
2625 return (mtmp && mtmp->data == &mons[PM_SHOPKEEPER])
2627 : "Konnichi wa"; /* Japanese */
2629 return "Aloha"; /* Hawaiian */
2633 (mtmp && mtmp->data == &mons[PM_MAIL_DAEMON]) ? "Hallo" :
2635 "Velkommen"; /* Norse */
2641 \82 \82¢
\82³
\82Â
\82Í
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\8e©
\91R
\82É
\82È
\82é
\82æ
\82¤
\91å
\82«
\82
\8ed
\97l
\82ð
\95Ï
\8dX
2643 static char helo_buf[BUFSZ];
2645 switch (Role_switch) {
2647 Sprintf(helo_buf, "
\82æ
\82
\82¼
\8eQ
\82Á
\82½%s
\82æ", plname);
2650 Sprintf(helo_buf, "
\82æ
\82
\82¼
\8eQ
\82ç
\82ê
\82½%s
\82æ", plname);
2653 Sprintf(helo_buf, "
\83A
\83\8d\81[
\83n%s", plname);
2656 Sprintf(helo_buf, "
\8d°
\82Ì
\8eç
\8cì
\8eÒ%s
\82æ", plname);
2659 Sprintf(helo_buf, "
\82æ
\82¤
\82±
\82»%s", plname);
2671 switch (Role_switch) {
2673 return "Fare thee well"; /* Olde English */
2675 return "Sayonara"; /* Japanese */
2677 return "Aloha"; /* Hawaiian */
2679 return "Farvel"; /* Norse */
2684 static char helo_buf[BUFSZ];
2686 switch (Role_switch) {
2688 Sprintf(helo_buf, "
\82³
\82ç
\82Î
\8chåi
\82È
\82é");
2691 Sprintf(helo_buf, "
\82³
\82ç
\82Î
\95\90\8em
\93¹
\82ð
\8eu
\82·");
2694 Sprintf(helo_buf, "
\83A
\83\8d\81[
\83n");
2697 Sprintf(helo_buf, "
\82³
\82ç
\82Î
\8d°
\82Ì
\8eç
\8cì
\8eÒ");
2700 Sprintf(helo_buf, "
\82³
\82æ
\82¤
\82È
\82ç");