home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1777 < prev    next >
Internet Message Format  |  1990-12-28  |  28KB

  1. From: lee@sq.sq.com (Liam R. E. Quin)
  2. Newsgroups: rec.games.frp,alt.sources
  3. Subject: Rolemaster FRP NPC stat-generating program
  4. Message-ID: <1990Sep4.020648.6157@sq.sq.com>
  5. Date: 4 Sep 90 02:06:48 GMT
  6.  
  7. I wrote this program several years ago when I first started running rolemaster.
  8. It doesn't compile on our sun4 (the C compiler chokes) but it works fine on a
  9. Sun3 and under Saber-C (which helped me fix some five-year-old bugs).
  10.  
  11. Sample output:
  12.  
  13. Name: Vartayn
  14. Class: Magician
  15. Stat    Pot    Temp    Mod
  16. Str    93    93    10
  17. Qu    81    81    5
  18. Pr    90    48    0
  19. In    78    21    -5
  20. Em    94    94    10
  21. Co    95    92    10
  22. Ag    76    46    0
  23. SD    38    24    -5
  24. Me    98    98    20
  25. Re    85    72    0
  26.  
  27. If this means nothing to you, you probably don't want it!
  28. There is some ifdef'd code for generating lists of skills, but it looks to
  29. me as if it was barely started and doesn't work.
  30. A more useful program would generate notes on the peoples' personalities...
  31.  
  32. The random names are generated by opening in pipe to "names -i", which
  33. generates an "infinite" stream of random names.
  34.  
  35. I am not sure I like this coding style very much.  I don't use it now...
  36. But it's free :-)
  37.  
  38. Just do
  39.     cc -o npc npc.c
  40.  
  41. It takes a single optional argument, the number of people to make.
  42.  
  43.  
  44. The stat selection algorithm is table driven -- it chooses the most suitable
  45. class for a character given its stats.  It uses the PC rules for rerolling
  46. stats less than 20.  You can chenge this table -- see the end of tables.h --
  47. the stats are multiplied by the weights given in the table, and the highest
  48. result is used.  You could outlaw strong bards, for example, by making the
  49. first number in the last column of ClassStatWeightingTable[] be -10000, or
  50. make strong bards less likely by setting it to -0.1 if you wanted.
  51. Suggestions for improvements [not involving the "rm" utility :-)] welcomed.
  52.  
  53. If you don't have a random names program, I could post the ones I have.
  54.  
  55.  
  56. Lee
  57.  
  58.  
  59. : To unbundle, sh this file
  60. echo x - npc.c 1>&2
  61. sed 's/^X//' >npc.c <<'@@@End of npc.c'
  62. X/******************************************************************************
  63. X*
  64. X* chargen -- generate Rolemaster characters
  65. X*
  66. X* Liam Quin, 1990 (from an earlier version written in 1985 or so)
  67. X*
  68. X*******************************************************************************/
  69. X
  70. X#include <stdio.h>
  71. X
  72. X#define NAMEPIPE "names -i"
  73. X
  74. X#define etoiskill(e) ((int) e)
  75. X
  76. X#ifndef lint
  77. X static char *Revision = "@(#) $Header: /home/lee/russ1/req/frp/rolemaster/src/npc.c,v 1.2 90/09/03 21:53:38 lee Exp $";
  78. X /* This is to enable what(1) to identify the program */
  79. X#endif
  80. X
  81. X#define RANDPRIME 37    /* divide rand() by this */
  82. X
  83. X
  84. X#define NumberOfStats    10
  85. Xtypedef int t_statarray[NumberOfStats];
  86. X
  87. Xtypedef enum {
  88. X     StatStr, StatQu, StatPr, StatIn, StatEm,
  89. X     StatCo,  StatAg, StatSD, StatMe, StatRe,
  90. X     NoSuchStat    /* catchall! */
  91. X} te_stat;
  92. X
  93. X#define is_development_stat(x)    ( (x) <= StatEm )
  94. X
  95. Xetoistat(stat)
  96. X     te_stat stat;
  97. X{
  98. X     switch (stat) {
  99. X      case StatStr:    return 0;
  100. X      case StatQu:    return 1;
  101. X      case StatPr:    return 2;
  102. X      case StatIn:    return 3;
  103. X      case StatEm:    return 4;
  104. X      case StatCo:    return 5;
  105. X      case StatAg:    return 6;
  106. X      case StatSD:    return 7;
  107. X      case StatMe:    return 8;
  108. X      case StatRe:    return 9;
  109. X      default:     return -1;
  110. X     }
  111. X}
  112. X
  113. Xte_stat
  114. Xitoestat(i)
  115. X     int i;
  116. X{
  117. X     switch (i) {
  118. X      case 0:    return    StatStr;
  119. X      case 1:    return    StatQu;
  120. X      case 2:    return    StatPr;
  121. X      case 3:    return    StatIn;
  122. X      case 4:    return    StatEm;
  123. X      case 5:    return    StatCo;
  124. X      case 6:    return    StatAg;
  125. X      case 7:    return    StatSD;
  126. X      case 8:    return    StatMe;
  127. X      case 9:    return    StatRe;
  128. X      default:     return  NoSuchStat;
  129. X     }
  130. X}
  131. X
  132. X
  133. Xchar *
  134. Xetosstat(stat)
  135. X     te_stat stat;
  136. X{
  137. X     switch (stat) {
  138. X      case StatStr:    return "Str" ;
  139. X      case StatQu:    return "Qu" ;
  140. X      case StatPr:    return "Pr" ;
  141. X      case StatIn:    return "In" ;
  142. X      case StatEm:    return "Em" ;
  143. X      case StatCo:    return "Co" ;
  144. X      case StatAg:    return "Ag" ;
  145. X      case StatSD:    return "SD" ;
  146. X      case StatMe:    return "Me" ;
  147. X      case StatRe:    return "Re" ;
  148. X      default:     return "Unknown stat type" ;
  149. X     }
  150. X}
  151. X
  152. X
  153. Xtypedef enum {
  154. X     ClassFighter,    ClassThief,        ClassRogue,
  155. X     ClassWarriorMonk,
  156. X     ClassMagician,    ClassIllusionist,    ClassAlchemist,
  157. X     ClassCleric,    ClassAnimist,        ClassHealer,
  158. X     ClassMentalist,    ClassLayHealer,        ClassSeer,
  159. X     ClassSorceror,    ClassMystic,        ClassAstrologer,
  160. X     ClassMonk,        ClassRanger,        ClassBard
  161. X} te_cclass;
  162. X
  163. X#define MAXCCLASSLENGTH 12 /* length of the longest enum, excluding a null */
  164. X#define NumberOfCClasses 19
  165. X
  166. Xchar *
  167. Xetoscclass(class)
  168. X     te_cclass class;
  169. X{
  170. X     switch(class) {
  171. X      case ClassFighter:        return "Fighter";
  172. X      case ClassThief:        return "Thief";
  173. X      case ClassRogue:        return "Rogue";
  174. X      case ClassWarriorMonk:    return "Warrior Monk";
  175. X      case ClassMagician:        return "Magician";
  176. X      case ClassIllusionist:    return "Illusionist";
  177. X      case ClassAlchemist:        return "Alchemist";
  178. X      case ClassCleric:        return "Cleric";
  179. X      case ClassAnimist:        return "Animist";
  180. X      case ClassHealer:        return "Healer";
  181. X      case ClassMentalist:        return "Mentalist";
  182. X      case ClassLayHealer:        return "Lay Healer";
  183. X      case ClassSeer:        return "Seer";
  184. X      case ClassSorceror:        return "Sorceror";
  185. X      case ClassMystic:        return "Mystic";
  186. X      case ClassAstrologer:        return "Astrologer";
  187. X      case ClassMonk:        return "Monk";
  188. X      case ClassRanger:        return "Ranger";
  189. X      case ClassBard:        return "Bard";
  190. X      default:            return "Unknown Profession";
  191. X     }
  192. X}
  193. X
  194. Xtypedef enum {
  195. X     SkillSoftLeather, SkillRigidLeather, SkillChain, SkillPlate,
  196. X
  197. X     SkillWeapon1, SkillWeapon2, SkillWeapon3,
  198. X     SkillWeapon4, SkillWeapon5, SkillWeapon6,
  199. X
  200. X     SkillClimbing, SkillSwimming, SkillRiding, SkillDisarmTraps,
  201. X     SkillPickLocks, SkillStalkandHide, SkillPerception,
  202. X
  203. X     SkillSpellLists, SkillRunes, SkillStavesAndWands,
  204. X     SkillChanneling, SkillDirectedSpells,
  205. X
  206. X     SkillAmbush, SkillLinguistics, SkillAdrenalMoves,
  207. X     SkillAdrenalDefense, SkillMartialArts, SkillBodyDevelopment
  208. X} te_skill;
  209. X
  210. X#define NumberOfSkills 28
  211. X
  212. Xchar *
  213. Xetosskill(skill)
  214. X     te_skill skill;
  215. X{
  216. X     switch (skill) {
  217. X      case SkillSoftLeather:    return "Soft Leather";
  218. X      case SkillRigidLeather:    return "Rigid Leather";
  219. X      case SkillChain:        return "Chain";
  220. X      case SkillPlate:        return "Plate";
  221. X      case SkillWeapon1:        return "Weapon 1";
  222. X      case SkillWeapon2:        return "Weapon 2";
  223. X      case SkillWeapon3:        return "Weapon 3";
  224. X      case SkillWeapon4:        return "Weapon 4";
  225. X      case SkillWeapon5:        return "Weapon 5";
  226. X      case SkillWeapon6:        return "Weapon 6";
  227. X      case SkillClimbing:        return "Climbing";
  228. X      case SkillSwimming:        return "Swimming";
  229. X      case SkillRiding:        return "Riding";
  230. X      case SkillDisarmTraps:    return "Disarm Traps";
  231. X      case SkillPickLocks:        return "Pick Locks";
  232. X      case SkillStalkandHide:    return "Stalking and Hiding";
  233. X      case SkillPerception:        return "Perception";
  234. X      case SkillSpellLists:        return "Spell Lists";
  235. X      case SkillRunes:        return "Runes";
  236. X      case SkillStavesAndWands:    return "Staves And Wands";
  237. X      case SkillChanneling:        return "Channeling";
  238. X      case SkillDirectedSpells:    return "Directed Spells";
  239. X      case SkillAmbush:        return "Ambush";
  240. X      case SkillLinguistics:    return "Linguistics";
  241. X      case SkillAdrenalMoves:    return "Adrenal Moves";
  242. X      case SkillAdrenalDefense:    return "Adrenal Defense";
  243. X      case SkillMartialArts:    return "Martial Arts";
  244. X      case SkillBodyDevelopment:    return "Body Development";
  245. X      default:            return "No Such Skill!";
  246. X     }
  247. X}
  248. X
  249. Xtypedef enum { BonusStat, BonusDP, BonusPP } te_bonustype;
  250. X
  251. Xchar *
  252. Xetosbonustype(t)
  253. X     te_bonustype t;
  254. X{
  255. X     switch(t) {
  256. X      case BonusStat:    return "Stat" ;
  257. X      case BonusDP:        return "DP"   ;
  258. X      case BonusPP:        return "PP"   ;
  259. X      default:        return "Unknown bonus type";
  260. X     }
  261. X}
  262. X
  263. X
  264. Xtypedef struct {
  265. X     int  firstcost,    /* DP cost for 1 skill level */
  266. X      secondcost;    /* DP cost for next; -ve if any amount allowed. */
  267. X} ts_skillcostpair;
  268. X
  269. Xtypedef struct {
  270. X     char *skillname;
  271. X     te_skill whichskill;
  272. X     int  level,    /* expertise in this skill (in LEVELS) */
  273. X      totalslashes;    /* how many LEVELS we go up at the next oppertunity */
  274. X     ts_skillcostpair cost;
  275. X} t_skillslist;
  276. X
  277. X
  278. Xtypedef struct {
  279. X     te_cclass whom;
  280. X     ts_skillcostpair skills[NumberOfSkills];
  281. X} t_skilltable[ NumberOfCClasses ];
  282. X
  283. Xtypedef struct {
  284. X     t_statarray stats;
  285. X     t_statarray potentials;
  286. X     t_statarray mods;
  287. X     te_cclass cclass;
  288. X     t_skillslist skills[(int) SkillBodyDevelopment + 1];
  289. X     int hitpoints;
  290. X     int powerpoints,
  291. X     developmentpoints;
  292. X     char *name;
  293. X     int level;
  294. X} t_person;
  295. X
  296. X#include "tables.h"
  297. X
  298. Xmain(argc, argv)
  299. X     int argc;
  300. X     char *argv[];
  301. X{
  302. X     int count = 0;
  303. X     int crowdsize = 1;
  304. X     int leveltobe = 1;
  305. X     t_person hitpoints(), statpotentials(), chooseprofession(), rollstats();
  306. X     char *choosename();
  307. X
  308. X     if (argc > 1)
  309. X      crowdsize = atoi(argv[1]);
  310. X
  311. X     srand(getpid());
  312. X
  313. X     while (count++ < crowdsize) {
  314. X#ifdef DOSKILLS
  315. X      int training = 0;
  316. X#endif
  317. X      t_person thisbod;
  318. X
  319. X      thisbod.hitpoints = 0;
  320. X      thisbod = hitpoints(statpotentials(chooseprofession(rollstats(thisbod))));
  321. X#if DOSKILLS
  322. X      do {
  323. X           chooseskills(thisbod);
  324. X           skillsandbonuses(thisbod);
  325. X      } while (training++ < leveltobe);
  326. X      chooseskills(thisbod);
  327. X#endif
  328. X      thisbod.name = choosename(thisbod);
  329. X      printcharsheet(thisbod);
  330. X     }
  331. X}
  332. X
  333. Xt_person
  334. Xrollstats(bod)
  335. X     t_person bod;
  336. X{
  337. X     int i = 0;
  338. X
  339. X     for (i = 0; i < NumberOfStats; i++) {
  340. X      /* ignore throws less than 20 for attributes...
  341. X       * actually this is probably a mistake for an npc...
  342. X       */
  343. X      while ((bod.stats[i] = d(100)) < 20)
  344. X           ;
  345. X     }
  346. X     return bod;
  347. X}
  348. X
  349. Xt_person
  350. Xchooseprofession(thisfellow)
  351. X     t_person thisfellow;
  352. X{
  353. X     double weight[ NumberOfCClasses ];
  354. X     int maxweight = 0;
  355. X     int i, j;
  356. X
  357. X     for (i = 0; i < NumberOfCClasses; i++) {
  358. X      weight[i] = 0.0;
  359. X
  360. X      for (j = 0; j < NumberOfStats; j++) {
  361. X           weight[i] += ClassStatWeightingTable[i].weightings[j] * thisfellow.stats[j];
  362. X      }
  363. X      if (weight[i] > weight[maxweight]) {    /* "best so far" */
  364. X           maxweight = i;
  365. X      }
  366. X     }
  367. X
  368. X     thisfellow.cclass = ClassStatWeightingTable[maxweight].cclass;
  369. X     return thisfellow;
  370. X}
  371. X
  372. Xt_person
  373. Xstatpotentials(bod)
  374. X     t_person bod;
  375. X{
  376. X     int i = 0;
  377. X
  378. X     bod.powerpoints = bod.developmentpoints = 0;
  379. X     for (i = 0; i < NumberOfStats; i++) {
  380. X      bod.potentials[i] = RollOnStatPotentialTable(bod.stats[i], d(100));
  381. X      bod.mods[i] = ConsultBonusTable(bod.stats[i], BonusStat);
  382. X      if (etoistat(StatEm) >= i) { /* should use is_development_stat */
  383. X           bod.developmentpoints += ConsultBonusTable(bod.stats[i], BonusDP);
  384. X      }
  385. X     }
  386. X     return bod;
  387. X}
  388. X
  389. XRollOnStatPotentialTable(originalstat, n)
  390. X     int originalstat, n;
  391. X{
  392. X     int x = StatPotentialTable[maptable15p11[n-1]][map15p11(originalstat-1)];
  393. X     return (x <= 0) ? originalstat : x;
  394. X}
  395. X
  396. XConsultBonusTable(statroll, reason)
  397. X     int statroll;
  398. X     te_bonustype reason;
  399. X{
  400. X     int row;
  401. X     int col;
  402. X
  403. X     switch (reason) {
  404. X      case BonusStat:    col = 0; break;
  405. X      case BonusDP:        col = 1; break;
  406. X      case BonusPP:        col = 2; break;
  407. X      default: /* can't happen :-) */
  408. X           error(__LINE__, __FILE__, "reason = %d\n", (int) reason);
  409. X           abort();
  410. X     }
  411. X
  412. X     if (statroll == 1) row = 0;
  413. X     else if (statroll == 2) row = 1;
  414. X     else if (statroll <= 4) row = 2;
  415. X     else if (statroll <= 9) row = 3;
  416. X     else if (statroll <= 14) row = 4;
  417. X     else if (statroll <= 24) row = 5;
  418. X     else if (statroll <= 39) row = 6;
  419. X     else if (statroll <= 59) row = 7;
  420. X     else if (statroll <= 74) row = 8;
  421. X     else if (statroll <= 84) row = 9;
  422. X     else if (statroll <= 89) row = 10;
  423. X     else if (statroll <= 94) row = 11;
  424. X     else if (statroll <= 97) row = 12;
  425. X     else if (statroll <= 99) row = 13;
  426. X     else if (statroll <= 100) row = 14;
  427. X     else if (statroll <= 101) row = 15;
  428. X     else if (statroll <= 102) row = 16;
  429. X     else row = 17;
  430. X
  431. X     return StatBonusTable[row][col];
  432. X}
  433. X
  434. Xd(n)
  435. X     int n;
  436. X{
  437. X     return ( ( rand() / RANDPRIME ) % n ) + 1;
  438. X}
  439. X
  440. Xt_person
  441. Xhitpoints(bod)
  442. X     t_person bod;
  443. X{
  444. X     bod.hitpoints += d(10);
  445. X     return bod;
  446. X}
  447. X
  448. Xmap15p11(stat)
  449. X     int stat;
  450. X{
  451. X     if (stat < 25) return 0;
  452. X     else if (stat < 40) return 1;
  453. X     else if (stat < 60) return 2;
  454. X     else if (stat < 75) return 3;
  455. X     else if (stat < 85) return 4;
  456. X     else if (stat < 90) return 5;
  457. X     else if (stat < 95) return 6;
  458. X     else if (stat < 98) return 7;
  459. X     else if (stat < 100) return 8;
  460. X     else return 9;
  461. X}
  462. X
  463. X/* print the fellow out...
  464. X */
  465. X
  466. Xprintcharsheet(bod)
  467. X     t_person bod;
  468. X{
  469. X     int i = 0;
  470. X
  471. X     printf("Name: %s\nClass: %s\n",
  472. X        (bod.name && bod.name[0]) ? bod.name : "Rasputin",
  473. X        etoscclass(bod.cclass));
  474. X     puts("Stat\tPot\tTemp\tMod");
  475. X     for (i = 0; i < NumberOfStats; i++) {
  476. X      printf("%s\t%d\t%d\t%d\n",    etosstat( (te_stat) i),
  477. X                    bod.potentials[i],
  478. X                    bod.stats[i],
  479. X                    bod.mods[i]);
  480. X     }
  481. X     printskills(bod);
  482. X     puts("\n\n");
  483. X}
  484. X
  485. X#ifdef DOSKILLS
  486. X
  487. Xchooseskills(bod)
  488. X     t_person bod;
  489. X{
  490. X
  491. X     /* build a list of skills that are available to us            */
  492. X     /* and then choose the best selection therefrom            */
  493. X     /* Finally, add the skills to the ones that the bod already have    */
  494. X     /* but we don't get the benefits yet.... */
  495. X
  496. X     addpendingskills(bod, makeselection(bod, buildlistofskills(bod)));
  497. X}
  498. X
  499. X#endif
  500. X
  501. X
  502. Xprintskills(bod)
  503. X     t_person bod;
  504. X{
  505. X     int i;
  506. X
  507. X     for (i = 0; i <= etoiskill(SkillBodyDevelopment); i++) {
  508. X      if (bod.skills[i].level > 0) {
  509. X           printf("%d\t%s\n", bod.skills[i], etosskill(i));
  510. X      }
  511. X     }
  512. X}
  513. X
  514. X
  515. X#ifdef DOSKILLS
  516. Xskillsandbonuses(bod)
  517. X     t_person bod;
  518. X{
  519. X     chooseskills(bod);
  520. X     benefitsforskills(bod);
  521. X     skillbonuses(bod);
  522. X}
  523. X
  524. Xlist *
  525. Xbuildlistofskills(bod)
  526. X     t_person bod;
  527. X{
  528. X      static skill_n firstval;
  529. X
  530. X     /* here we have to make a list of all the skill selections that bod could
  531. X      * make, together with a `desireability rating' GAIN for each.
  532. X      */
  533. X      firstval.next = NULL;
  534. X      firstval.gain = 2.0;    /* too big so it stays at the front... */
  535. X      for (skill_n = 0; skill_n <= (int) SkillBodyDevelopment; skill_n++) {
  536. X      /* do multiple selections here. NOTDONE */
  537. X      list *this = (skill *) malloc(sizeof(skill));
  538. X      list *p;    /* for list-marching later... */
  539. X
  540. X      this->oldlevel = bod.skills[skill_n];
  541. X      this->newlevel = this->oldlevel[skill_n];
  542. X      this->which = skill_n;
  543. X      this->gain = desireability(bod,this);
  544. X      this->next = NULL;
  545. X      for (p = &firstval; p->next != NULL; p = p->next) {
  546. X           if (p->gain < this->gain ||
  547. X                   (p-gain == this->gain && rand() % 2)) {
  548. X            break;
  549. X           }
  550. X      }
  551. X      if (p->next == NULL) {
  552. X           /* end of the list */
  553. X           p->next = this;
  554. X      } else {
  555. X           this->next = p->next;
  556. X           p->next = this;
  557. X      }
  558. X     }
  559. X     return firstval.next;
  560. X}
  561. X#endif /* DOSKILLS */
  562. X
  563. Xchar *
  564. Xchoosename(bod)
  565. X     t_person bod;
  566. X{
  567. X     /* choose a suitable name... */
  568. X     static FILE *NamePipe = 0;
  569. X     static char Result[100];
  570. X
  571. X     if (!NamePipe) {
  572. X      if ((NamePipe = popen(NAMEPIPE, "r")) == (FILE *) 0) {
  573. X           error(__LINE__, __FILE__, "can't open pipe %s\n", NAMEPIPE);
  574. X           exit(1);
  575. X      }
  576. X     }
  577. X
  578. X     return fgets(Result, sizeof(Result) - 1, NamePipe);
  579. X}
  580. X
  581. X
  582. X#ifdef DOSKILLS
  583. X
  584. XstratagyP(l, dp, q)
  585. X     list *l, *q;
  586. X     int dp;
  587. X{
  588. X     in v, v1;
  589. X     list *q1 = NULL, *q2 = NULL, *p = l;
  590. X
  591. X     while (p && p->cost > dp)
  592. X      p = p->next;
  593. X
  594. X     if (p == NULL)
  595. X      return 0;
  596. X
  597. X     if (p->next == NULL) {
  598. X      append1(q, p);
  599. X      return p->gain;
  600. X     }
  601. X
  602. X     v1 = p->gain + strategyP(p->next, dp - p->cost, q1);    /* buy p */
  603. X     v2 = strategyP(p->next, dp, q2);    /* or pass it by... ? */
  604. X
  605. X     if (v1 > v2) {
  606. X      /* so it's a good idea to but p */
  607. X      append1(q, p);
  608. X      append(q, q1);
  609. X      return v1;
  610. X     } else {
  611. X      append(q, q1);
  612. X      return v2;
  613. X     }
  614. X}
  615. X
  616. Xappend1(l1, l2)
  617. X     list *l1, *l2;
  618. X{
  619. X     register list *ptr = l1;
  620. X     list *p = new(list);
  621. X
  622. X     *p = l2;
  623. X     p->next = NULL;
  624. X     while (l1 && l1->next)
  625. X      l1 = l1->next;
  626. X     if (l1 == NULL)
  627. X      return -1;
  628. X     l1->next = p;
  629. X}
  630. X
  631. X
  632. Xappend(l1, l2)
  633. X     list *l1, *l2;
  634. X{
  635. X     register list *ptr = l1;
  636. X
  637. X     p->next = NULL;
  638. X     while (l1 && l1->next)
  639. X      l1 = l1->next;
  640. X     if (l1 == NULL)
  641. X      return -1;
  642. X     l1->next = l2;
  643. X}
  644. X
  645. X#endif
  646. X
  647. X
  648. Xerror(file, line, msg, a, b, c)
  649. X     char *file;
  650. X     int line;
  651. X     char *msg;
  652. X{
  653. X     fprintf(stderr, "%s:%d:", file, line);
  654. X     fprintf(stderr, msg, a, b, c);
  655. X}
  656. X
  657. X/* $Log:    npc.c,v $
  658. X * Revision 1.2  90/09/03  21:53:38  lee
  659. X * Fixed some typos and an out-by-one error in maptable lookup.
  660. X * Added input pipe to random names program.
  661. X * 
  662. X * Revision 1.1  90/09/03  21:16:25  lee
  663. X * Initial revision
  664. X * 
  665. X *
  666. X */
  667. @@@End of npc.c
  668. echo x - tables.h 1>&2
  669. sed 's/^X//' >tables.h <<'@@@End of tables.h'
  670. X/* maptable for 15.11 -- given the d100 roll, which row of the stat potential
  671. X * table should we use?
  672. X */
  673. Xint maptable15p11[] = {
  674. X/* 01-10 */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  675. X/* 11-20 */    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  676. X/* 21-30 */    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  677. X/* 31-35 */    3, 3, 3, 3, 3,
  678. X/* 36-40 */    4, 4, 4, 4, 4,
  679. X/* 41-45 */    5, 5, 5, 5, 5,
  680. X/* 46-49 */    6, 6, 6, 6,
  681. X/* 50-51 */    7, 7,
  682. X/* 52-53 */    8, 8,
  683. X/* 54-55 */    9, 9,
  684. X/* 56-57 */    10, 10,
  685. X/* 58-59 */    11, 11,
  686. X/* 60-61 */    12, 12,
  687. X/* 62-63 */    13, 13,
  688. X/* 64-65 */    14, 14,
  689. X/* 66-67 */    15, 15,
  690. X/* 68-69 */    16, 16,
  691. X/* 70-71 */    17, 17,
  692. X/* 72-73 */    18, 18,
  693. X/* 74-75 */    19, 19,
  694. X/* 76-77 */    20, 20,
  695. X/* 78-79 */    21, 21,
  696. X/* 80-81 */    22, 22,
  697. X/* 82-83 */    23, 23,
  698. X/* 84-85 */    24, 24,
  699. X/* 86-87 */    25, 25,
  700. X/* 88-89 */    26, 26,
  701. X/* 90 */    27,
  702. X/* 91 */    28,
  703. X/* 92 */    29,
  704. X/* 93 */    30,
  705. X/* 94 */    31,
  706. X/* 95 */    32,
  707. X/* 96 */    33,
  708. X/* 97 */    34,
  709. X/* 98 */    35,
  710. X/* 99 */    36,
  711. X/* 100 */    37,
  712. X/* oops! */    -1
  713. X};
  714. X
  715. X/* table 15.11 */
  716. Xint StatPotentialTable[][10] = {
  717. X/* 01-10 */    { 25, 0, },
  718. X/* 11-20 */    { 30, 0, },
  719. X/* 21-30 */    { 35, 39, 0, },
  720. X/* 31-35 */    { 38, 42, 59, 0, },
  721. X/* 36-40 */    { 40, 45, 62, 0, },
  722. X/* 41-45 */    { 42, 47, 64, 0, },
  723. X/* 46-49 */    { 44, 49, 66, 0, },
  724. X/* 50-51 */    { 46, 51, 68, 0, },
  725. X/* 52-53 */    { 48, 53, 70, 0, },
  726. X/* 54-55 */    { 50, 55, 71, 0, },
  727. X/* 56-57 */    { 52, 57, 72, 74, 84, 0, },
  728. X/* 58-59 */    { 54, 59, 73, 75, 85, 0, },
  729. X/* 60-61 */    { 56, 61, 74, 76, 86, 0, },
  730. X/* 62-63 */    { 58, 63, 75, 77, 87, 0, },
  731. X/* 64-65 */    { 60, 65, 76, 78, 88, 0, },
  732. X/* 66-67 */    { 62, 67, 77, 79, 88, 89, 0, },
  733. X/* 68-69 */    { 64, 69, 78, 80, 89, 89, 0, },
  734. X/* 70-71 */    { 66, 71, 79, 81, 89, 90, 0, },
  735. X/* 72-73 */    { 68, 73, 80, 82, 90, 90, 0, },
  736. X/* 74-75 */    { 70, 75, 81, 83, 90, 91, 0, },
  737. X/* 76-77 */    { 72, 77, 82, 84, 91, 91, 0, },
  738. X/* 78-79 */    { 74, 79, 83, 85, 91, 92, 0, },
  739. X/* 80-81 */    { 76, 81, 84, 86, 92, 92, 0, },
  740. X/* 82-83 */    { 78, 83, 85, 87, 92, 93, 0, },
  741. X/* 84-85 */    { 80, 85, 86, 88, 93, 93, 94, 0, },
  742. X/* 86-87 */    { 82, 86, 87, 89, 93, 94, 94, 0, },
  743. X/* 88-89 */    { 84, 87, 88, 90, 94, 94, 95, 0, },
  744. X/* 90 */    { 86, 88, 89, 91, 94, 95, 95, 97, 0, },
  745. X/* 91 */    { 88, 89, 90, 92, 95, 95, 96, 97, 0, },
  746. X/* 92 */    { 90, 90, 91, 93, 95, 96, 96, 97, 0, },
  747. X/* 93 */    { 91, 91, 92, 94, 96, 96, 97, 98, 0, },
  748. X/* 94 */    { 92, 92, 93, 95, 96, 97, 97, 98, 99, 0 },
  749. X/* 95 */    { 93, 93, 94, 96, 97, 97, 98, 98, 99, 0 },
  750. X/* 96 */    { 94, 94, 95, 97, 97, 98, 98, 99, 99, 0 },
  751. X/* 97 */    { 95, 95, 96, 97, 98, 98, 99, 99, 99, 0 },
  752. X/* 98 */    { 96, 96, 97, 98, 98, 99, 99, 99, 100, 0 },
  753. X/* 99 */    { 97, 97, 98, 98, 99, 99, 100, 100, 100, 0 },
  754. X/* 100 */    { 98, 98, 99, 99, 99, 100, 100, 100, 100, 101 },
  755. X/* oops! */    { -1, -1, -1, -1, -1, -01, -01, -01, -01, -01 }
  756. X};
  757. X
  758. X/* table 15.13 */
  759. Xint StatBonusTable[][3] = {
  760. X/* 1 */        { -25,1, 0 },
  761. X/* 2 */        { -20,1, 0 },
  762. X/* 3-4 */    { -15,1, 0 },
  763. X/* 5-9 */    { -10,2, 0 },
  764. X/* 10-14 */    { -5, 2, 0 },
  765. X/* 15-24 */    { -5, 3, 0 },
  766. X/* 25-39 */    { 0,  4, 0 },
  767. X/* 40-59 */    { 0,  5, 0 },
  768. X/* 60-74 */    { 0,  6, 0 },
  769. X/* 75-84 */    { 5,  7, 1 },
  770. X/* 85-89 */    { 5,  8, 1 },
  771. X/* 90-94 */    { 10, 8, 1 },
  772. X/* 95-97 */    { 15, 9, 2 },
  773. X/* 98-99 */    { 20, 9, 2 },
  774. X/* 100 */    { 25, 10,3 },
  775. X/* 101 */    { 30, 10,3 },
  776. X/* 102+ */    { 35, 11,4 }
  777. X};
  778. X
  779. Xt_skilltable SkillTable = {
  780. X     { ClassFighter,    {
  781. X      {1,-1},{1,-1},{2,-1},{2,-2},                /* armour  */
  782. X      {1,5}, {2,5}, {2,7}, {2,7}, {2,7}, {5,0},        /* weapons */
  783. X      {3,7}, {2,6}, {2,6}, {3,8}, {3,9}, {2,5}, {2,5},    /* general */
  784. X      {20,0},{7,0}, {9,0}, {25,0},{20,0},            /* magical */
  785. X      {3,8}, {3,-3},{2,6}, {20,0},{3,7}, {1,3}}},        /* special */
  786. X     { ClassThief,    {
  787. X      {1,-1},{2,-2},{3,-3},{4,-4},                /* armour  */
  788. X      {2,7}, {3,8}, {4,0}, {4,0}, {4,0}, {6,0},        /* weapons */
  789. X      {2,5}, {1,3}, {2,6}, {1,3}, {1,3}, {1,3}, {1,3},    /* general */
  790. X      {10,0},{6,0}, {7,0}, {20,0},{20,0},            /* magical */
  791. X      {1,3}, {3,-3},{2,6}, {20,0},{3,7}, {3,7}}},        /* special */
  792. X     { ClassRogue,    {
  793. X      {1,-1},{1,-1},{2,-2},{3,-3},                /* armour  */
  794. X      {2,5}, {3,8}, {3,9}, {3,9}, {3,9}, {6,0},        /* weapons */
  795. X      {3,7}, {2,5}, {2,5}, {2,5}, {2,6}, {1,3}, {1,3},    /* general */
  796. X      {8,0}, {6,0}, {8,0}, {20,0},{20,0},            /* magical */
  797. X      {2,5}, {3,-3},{2,6}, {20,0},{3,7}, {2,5}}},        /* special */
  798. X     { ClassWarriorMonk,{
  799. X      {9,0}, {9,0}, {10,0},{10,0},                /* armour  */
  800. X      {4,0}, {6,0}, {8,0}, {8,0}, {8,0}, {15,0},        /* weapons */
  801. X      {3,7}, {1,5}, {2,7}, {3,9}, {3,9}, {2,4}, {2,5},    /* general */
  802. X      {10,0},{6,0}, {9,0}, {19,0},{20,0},            /* magical */
  803. X      {3,9}, {3,-3},{1,3}, {3,7}, {1,3}, {2,7}}},        /* special */
  804. X     { ClassMagician,    {
  805. X      {9,0}, {9,0}, {10,0},{11,0},                /* armour  */
  806. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  807. X      {6,0}, {3,0}, {3,0}, {7,0}, {8,0}, {5,0}, {3,0},    /* general */
  808. X      {1,-1},{1,4}, {1,4}, {7,0}, {2,5},            /* magical */
  809. X      {9,0}, {2,-2},{6,0}, {20,0},{9,0}, {8,0}}},        /* special */
  810. X     { ClassIllusionist,{
  811. X      {9,0}, {9,0}, {10,0},{11,0},                /* armour  */
  812. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  813. X      {7,0}, {3,0}, {3,0}, {8,0}, {8,0}, {3,0}, {2,0},    /* general */
  814. X      {1,-1},{1,4}, {1,4}, {7,0}, {2,6},            /* magical */
  815. X      {5,0}, {1,-1},{6,0}, {20,0},{9,0}, {8,0}}},        /* special */
  816. X     { ClassAlchemist,    {
  817. X      {9,0}, {9,0}, {10,0},{11,0},                /* armour  */
  818. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  819. X      {7,0}, {3,0}, {3,0}, {4,0}, {4,0}, {6,0}, {3,0},    /* general */
  820. X      {1,-1},{1,3}, {1,3}, {7,0}, {2,7},            /* magical */
  821. X      {9,0}, {1,-1},{6,0}, {20,0},{9,0}, {6,0}}},        /* special */
  822. X     { ClassCleric,    {
  823. X      {1,-1},{2,-2},{10,0},{11,0},                /* armour  */
  824. X      {6,0}, {7,0}, {9,0}, {9,0}, {9,0}, {20,0},        /* weapons */
  825. X      {5,0}, {3,0}, {3,0}, {7,0}, {8,0}, {5,0}, {3,0},    /* general */
  826. X      {1,-1},{2,5}, {2,5}, {1,4}, {3,0},            /* magical */
  827. X      {9,0}, {2,-2},{5,0}, {20,0},{6,0}, {6,0}}},        /* special */
  828. X     { ClassAnimist,    {
  829. X      {2,-2},{3,-3},{10,0},{11,0},                /* armour  */
  830. X      {6,0}, {7,0}, {9,0}, {9,0}, {9,0}, {20,0},        /* weapons */
  831. X      {4,0}, {3,0}, {1,3}, {8,0}, {8,0}, {3,0}, {3,0},    /* general */
  832. X      {1,-1},{2,6}, {2,6}, {2,5}, {3,0},            /* magical */
  833. X      {6,0}, {2,-2},{5,0}, {20,0},{6,0}, {4,0}}},        /* special */
  834. X     { ClassHealer,    {
  835. X      {2,-2},{3,-3},{10,0},{11,0},                /* armour  */
  836. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  837. X      {6,0}, {3,0}, {3,0}, {8,0}, {8,0}, {6,0}, {3,0},    /* general */
  838. X      {1,-1},{2,6}, {3,7}, {2,5}, {3,0},            /* magical */
  839. X      {9,0}, {2,-2},{5,0}, {20,0}, {6,0}, {1,-3}}},        /* special */
  840. X     { ClassMentalist,    {
  841. X      {4,-4},{5,-5},{6,-6},{7,-7},                /* armour  */
  842. X      {6,0}, {8,0}, {15,0},{20,0},{20,0},{20,0},        /* weapons */
  843. X      {5,0}, {3,0}, {2,0}, {7,0}, {8,0}, {5,0}, {3,0},    /* general */
  844. X      {1,-1},{2,5}, {2,5}, {8,0}, {2,6},            /* magical */
  845. X      {9,0}, {2,-2},{3,0}, {15,0},{3,0}, {6,0}}},        /* special */
  846. X     { ClassLayHealer,    {
  847. X      {2,-2},{3,-3},{4,-4},{5,-5},                /* armour  */
  848. X      {8,0}, {8,0}, {15,0},{20,0},{20,0},{20,0},        /* weapons */
  849. X      {6,0}, {3,0}, {2,0}, {8,0}, {8,0}, {6,0}, {3,0},    /* general */
  850. X      {1,-1},{2,6}, {2,6}, {8,0}, {2,7},            /* magical */
  851. X      {9,0}, {2,-2},{3,0}, {15,0}, {3,0}, {6,0}}},        /* special */
  852. X     { ClassSeer,    {
  853. X      {4,-4},{5,-5},{6,-6},{7,-7},                /* armour  */
  854. X      {6,0}, {8,0}, {15,0},{20,0},{20,0},{20,0},        /* weapons */
  855. X      {4,0}, {3,0}, {2,0}, {7,0}, {7,0}, {6,0}, {1,-1},    /* general */
  856. X      {1,-1},{2,6}, {2,6}, {8,0}, {2,7},            /* magical */
  857. X      {9,0}, {1,-1},{3,0}, {15,0}, {3,0}, {6,0}}},        /* special */
  858. X     { ClassSorceror,    {
  859. X      {9,0}, {9,0}, {10,0},{11,0},                /* armour  */
  860. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  861. X      {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {6,0}, {3,0},    /* general */
  862. X      {1,-1},{2,5}, {2,5}, {2,5}, {2,5},            /* magical */
  863. X      {9,0}, {2,-2},{5,0}, {20,0},{9,0}, {8,0}}},        /* special */
  864. X     { ClassMystic,    {
  865. X      {4,-4},{5,-5},{6,-6},{7,-7},                /* armour  */
  866. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  867. X      {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {2,0}, {2,0},    /* general */
  868. X      {1,-1},{2,5}, {2,5}, {8,0}, {2,6},            /* magical */
  869. X      {4,0}, {1,-1},{5,0}, {15,0}, {6,0}, {8,0}}},        /* special */
  870. X     { ClassAstrologer,    {
  871. X      {4,-4},{5,-5},{6,-6},{7,-7},                /* armour  */
  872. X      {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0},        /* weapons */
  873. X      {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {6,0}, {2,0},    /* general */
  874. X      {1,-1},{2,6}, {2,6}, {1,5}, {2,7},            /* magical */
  875. X      {9,0}, {1,-1},{5,0}, {15,0},{6,0}, {6,0}}},        /* special */
  876. X     { ClassMonk,    {
  877. X      {9,0}, {9,0}, {10,0},{11,0},                /* armour  */
  878. X      {5,0}, {8,0}, {8,0}, {8,0}, {15,0},{15,0},        /* weapons */
  879. X      {3,7}, {2,6}, {3,0}, {4,0}, {4,0}, {2,7}, {2,7},    /* general */
  880. X      {4,-4},{4,0}, {5,0}, {13,0},{9,0},            /* magical */
  881. X      {4,0}, {3,-3},{2,4}, {6,0}, {2,5}, {3,7}}},        /* special */
  882. X     { ClassRanger,    {
  883. X      {1,-1},{2,-2},{3,-3},{4,-4},                /* armour  */
  884. X      {3,7}, {4,0}, {6,0}, {6,0}, {6,0}, {9,0},        /* weapons */
  885. X      {3,9}, {2,6}, {2,6}, {4,0}, {4,0}, {1,5}, {2,7},    /* general */
  886. X      {4,-4},{5,0}, {6,0}, {3,0}, {15,0},            /* magical */
  887. X      {3,0}, {3,-3},{2,7}, {20,0},{4,0}, {2,7}}},        /* special */
  888. X     { ClassBard,    {
  889. X      {2,-2},{3,-3},{4,-4},{5,5},                /* armour  */
  890. X      {3,9}, {6,0}, {7,0}, {7,0}, {7,0}, {15,0},        /* weapons */
  891. X      {3,9}, {2,6}, {2,6}, {4,0}, {4,0}, {2,7}, {2,7},    /* general */
  892. X      {4,-4},{5,0}, {6,0}, {13,0},{10,0},            /* magical */
  893. X      {6,0}, {1,-1},{2,7}, {15,0},{3,0}, {3,8}}}        /* special */
  894. X};
  895. X
  896. X
  897. Xstruct ClassStatWeightingTable {
  898. X     te_cclass    cclass;
  899. X     float weightings[NumberOfStats];
  900. X} ClassStatWeightingTable[] = {
  901. X     /* characterclass    Str  Qu   Pr   In   Em   Co   Ag   SD   Re   Me */
  902. X     { ClassFighter,    { 1.0, .01, .01, .01, .01, 1.0, .01, .01, .01, .01 } },
  903. X     { ClassThief,    { .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01, .01 } },
  904. X     { ClassRogue,    { 1.0, .01, .01, .01, .01, .01, 1.0, .01, .01, .01 } },
  905. X     { ClassWarriorMonk,{ .01, 1.0, .01, .01, .01, .01, .01, 1.0, .01, .01 } },
  906. X     { ClassMagician,    { .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } },
  907. X     { ClassIllusionist,{ .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } },
  908. X     { ClassAlchemist,    { .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } },
  909. X     { ClassCleric,    { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } },
  910. X     { ClassAnimist,    { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } },
  911. X     { ClassHealer,    { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } },
  912. X     { ClassMentalist,    { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } },
  913. X     { ClassLayHealer,    { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } },
  914. X     { ClassSeer,    { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } },
  915. X     { ClassSorceror,    { .01, .01, .01, 1.0, 1.0, .01, .01, .01, .01, .01 } },
  916. X     { ClassMystic,    { .01, .01, 1.0, .01, 1.0, .01, .01, .01, .01, .01 } },
  917. X     { ClassAstrologer,    { .01, .01, 1.0, 1.0, .01, .01, .01, .01, .01, .01 } },
  918. X     { ClassMonk,    { .01, .01, .01, .01, 1.0, .01, .01, 1.0, .01, .01 } },
  919. X     { ClassRanger,    { .01, .01, .01, 1.0, .01, 1.0, .01, .01, .01, .01 } },
  920. X     { ClassBard,    { .01, .01, 1.0, .01, .01, .01, .01, .01, .01, 1.0 } }
  921. X     /* characterclass    Str  Qu   Pr   In   Em   Co   Ag   SD   Re   Me */
  922. X};
  923. X
  924. @@@End of tables.h
  925.  
  926. exit 0
  927.  
  928. -- 
  929. Liam R. E. Quin,  lee@sq.com, {utai,utzoo}!sq!lee,  SoftQuad Inc., Toronto
  930. Nicholas: [...]  The best/ Thing we can do is to make wherever we're lost in
  931. Look as much like home as we can. [Christopher Fry, The Lady's Not For Burning]
  932.