lee@sq.sq.com (Liam R. E. Quin) (09/04/90)
I wrote this program several years ago when I first started running rolemaster. It doesn't compile on our sun4 (the C compiler chokes) but it works fine on a Sun3 and under Saber-C (which helped me fix some five-year-old bugs). Sample output: Name: Vartayn Class: Magician Stat Pot Temp Mod Str 93 93 10 Qu 81 81 5 Pr 90 48 0 In 78 21 -5 Em 94 94 10 Co 95 92 10 Ag 76 46 0 SD 38 24 -5 Me 98 98 20 Re 85 72 0 If this means nothing to you, you probably don't want it! There is some ifdef'd code for generating lists of skills, but it looks to me as if it was barely started and doesn't work. A more useful program would generate notes on the peoples' personalities... The random names are generated by opening in pipe to "names -i", which generates an "infinite" stream of random names. I am not sure I like this coding style very much. I don't use it now... But it's free :-) Just do cc -o npc npc.c It takes a single optional argument, the number of people to make. The stat selection algorithm is table driven -- it chooses the most suitable class for a character given its stats. It uses the PC rules for rerolling stats less than 20. You can chenge this table -- see the end of tables.h -- the stats are multiplied by the weights given in the table, and the highest result is used. You could outlaw strong bards, for example, by making the first number in the last column of ClassStatWeightingTable[] be -10000, or make strong bards less likely by setting it to -0.1 if you wanted. Suggestions for improvements [not involving the "rm" utility :-)] welcomed. If you don't have a random names program, I could post the ones I have. Lee : To unbundle, sh this file echo x - npc.c 1>&2 sed 's/^X//' >npc.c <<'@@@End of npc.c' X/****************************************************************************** X* X* chargen -- generate Rolemaster characters X* X* Liam Quin, 1990 (from an earlier version written in 1985 or so) X* X*******************************************************************************/ X X#include <stdio.h> X X#define NAMEPIPE "names -i" X X#define etoiskill(e) ((int) e) X X#ifndef lint 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 $"; X /* This is to enable what(1) to identify the program */ X#endif X X#define RANDPRIME 37 /* divide rand() by this */ X X X#define NumberOfStats 10 Xtypedef int t_statarray[NumberOfStats]; X Xtypedef enum { X StatStr, StatQu, StatPr, StatIn, StatEm, X StatCo, StatAg, StatSD, StatMe, StatRe, X NoSuchStat /* catchall! */ X} te_stat; X X#define is_development_stat(x) ( (x) <= StatEm ) X Xetoistat(stat) X te_stat stat; X{ X switch (stat) { X case StatStr: return 0; X case StatQu: return 1; X case StatPr: return 2; X case StatIn: return 3; X case StatEm: return 4; X case StatCo: return 5; X case StatAg: return 6; X case StatSD: return 7; X case StatMe: return 8; X case StatRe: return 9; X default: return -1; X } X} X Xte_stat Xitoestat(i) X int i; X{ X switch (i) { X case 0: return StatStr; X case 1: return StatQu; X case 2: return StatPr; X case 3: return StatIn; X case 4: return StatEm; X case 5: return StatCo; X case 6: return StatAg; X case 7: return StatSD; X case 8: return StatMe; X case 9: return StatRe; X default: return NoSuchStat; X } X} X X Xchar * Xetosstat(stat) X te_stat stat; X{ X switch (stat) { X case StatStr: return "Str" ; X case StatQu: return "Qu" ; X case StatPr: return "Pr" ; X case StatIn: return "In" ; X case StatEm: return "Em" ; X case StatCo: return "Co" ; X case StatAg: return "Ag" ; X case StatSD: return "SD" ; X case StatMe: return "Me" ; X case StatRe: return "Re" ; X default: return "Unknown stat type" ; X } X} X X Xtypedef enum { X ClassFighter, ClassThief, ClassRogue, X ClassWarriorMonk, X ClassMagician, ClassIllusionist, ClassAlchemist, X ClassCleric, ClassAnimist, ClassHealer, X ClassMentalist, ClassLayHealer, ClassSeer, X ClassSorceror, ClassMystic, ClassAstrologer, X ClassMonk, ClassRanger, ClassBard X} te_cclass; X X#define MAXCCLASSLENGTH 12 /* length of the longest enum, excluding a null */ X#define NumberOfCClasses 19 X Xchar * Xetoscclass(class) X te_cclass class; X{ X switch(class) { X case ClassFighter: return "Fighter"; X case ClassThief: return "Thief"; X case ClassRogue: return "Rogue"; X case ClassWarriorMonk: return "Warrior Monk"; X case ClassMagician: return "Magician"; X case ClassIllusionist: return "Illusionist"; X case ClassAlchemist: return "Alchemist"; X case ClassCleric: return "Cleric"; X case ClassAnimist: return "Animist"; X case ClassHealer: return "Healer"; X case ClassMentalist: return "Mentalist"; X case ClassLayHealer: return "Lay Healer"; X case ClassSeer: return "Seer"; X case ClassSorceror: return "Sorceror"; X case ClassMystic: return "Mystic"; X case ClassAstrologer: return "Astrologer"; X case ClassMonk: return "Monk"; X case ClassRanger: return "Ranger"; X case ClassBard: return "Bard"; X default: return "Unknown Profession"; X } X} X Xtypedef enum { X SkillSoftLeather, SkillRigidLeather, SkillChain, SkillPlate, X X SkillWeapon1, SkillWeapon2, SkillWeapon3, X SkillWeapon4, SkillWeapon5, SkillWeapon6, X X SkillClimbing, SkillSwimming, SkillRiding, SkillDisarmTraps, X SkillPickLocks, SkillStalkandHide, SkillPerception, X X SkillSpellLists, SkillRunes, SkillStavesAndWands, X SkillChanneling, SkillDirectedSpells, X X SkillAmbush, SkillLinguistics, SkillAdrenalMoves, X SkillAdrenalDefense, SkillMartialArts, SkillBodyDevelopment X} te_skill; X X#define NumberOfSkills 28 X Xchar * Xetosskill(skill) X te_skill skill; X{ X switch (skill) { X case SkillSoftLeather: return "Soft Leather"; X case SkillRigidLeather: return "Rigid Leather"; X case SkillChain: return "Chain"; X case SkillPlate: return "Plate"; X case SkillWeapon1: return "Weapon 1"; X case SkillWeapon2: return "Weapon 2"; X case SkillWeapon3: return "Weapon 3"; X case SkillWeapon4: return "Weapon 4"; X case SkillWeapon5: return "Weapon 5"; X case SkillWeapon6: return "Weapon 6"; X case SkillClimbing: return "Climbing"; X case SkillSwimming: return "Swimming"; X case SkillRiding: return "Riding"; X case SkillDisarmTraps: return "Disarm Traps"; X case SkillPickLocks: return "Pick Locks"; X case SkillStalkandHide: return "Stalking and Hiding"; X case SkillPerception: return "Perception"; X case SkillSpellLists: return "Spell Lists"; X case SkillRunes: return "Runes"; X case SkillStavesAndWands: return "Staves And Wands"; X case SkillChanneling: return "Channeling"; X case SkillDirectedSpells: return "Directed Spells"; X case SkillAmbush: return "Ambush"; X case SkillLinguistics: return "Linguistics"; X case SkillAdrenalMoves: return "Adrenal Moves"; X case SkillAdrenalDefense: return "Adrenal Defense"; X case SkillMartialArts: return "Martial Arts"; X case SkillBodyDevelopment: return "Body Development"; X default: return "No Such Skill!"; X } X} X Xtypedef enum { BonusStat, BonusDP, BonusPP } te_bonustype; X Xchar * Xetosbonustype(t) X te_bonustype t; X{ X switch(t) { X case BonusStat: return "Stat" ; X case BonusDP: return "DP" ; X case BonusPP: return "PP" ; X default: return "Unknown bonus type"; X } X} X X Xtypedef struct { X int firstcost, /* DP cost for 1 skill level */ X secondcost; /* DP cost for next; -ve if any amount allowed. */ X} ts_skillcostpair; X Xtypedef struct { X char *skillname; X te_skill whichskill; X int level, /* expertise in this skill (in LEVELS) */ X totalslashes; /* how many LEVELS we go up at the next oppertunity */ X ts_skillcostpair cost; X} t_skillslist; X X Xtypedef struct { X te_cclass whom; X ts_skillcostpair skills[NumberOfSkills]; X} t_skilltable[ NumberOfCClasses ]; X Xtypedef struct { X t_statarray stats; X t_statarray potentials; X t_statarray mods; X te_cclass cclass; X t_skillslist skills[(int) SkillBodyDevelopment + 1]; X int hitpoints; X int powerpoints, X developmentpoints; X char *name; X int level; X} t_person; X X#include "tables.h" X Xmain(argc, argv) X int argc; X char *argv[]; X{ X int count = 0; X int crowdsize = 1; X int leveltobe = 1; X t_person hitpoints(), statpotentials(), chooseprofession(), rollstats(); X char *choosename(); X X if (argc > 1) X crowdsize = atoi(argv[1]); X X srand(getpid()); X X while (count++ < crowdsize) { X#ifdef DOSKILLS X int training = 0; X#endif X t_person thisbod; X X thisbod.hitpoints = 0; X thisbod = hitpoints(statpotentials(chooseprofession(rollstats(thisbod)))); X#if DOSKILLS X do { X chooseskills(thisbod); X skillsandbonuses(thisbod); X } while (training++ < leveltobe); X chooseskills(thisbod); X#endif X thisbod.name = choosename(thisbod); X printcharsheet(thisbod); X } X} X Xt_person Xrollstats(bod) X t_person bod; X{ X int i = 0; X X for (i = 0; i < NumberOfStats; i++) { X /* ignore throws less than 20 for attributes... X * actually this is probably a mistake for an npc... X */ X while ((bod.stats[i] = d(100)) < 20) X ; X } X return bod; X} X Xt_person Xchooseprofession(thisfellow) X t_person thisfellow; X{ X double weight[ NumberOfCClasses ]; X int maxweight = 0; X int i, j; X X for (i = 0; i < NumberOfCClasses; i++) { X weight[i] = 0.0; X X for (j = 0; j < NumberOfStats; j++) { X weight[i] += ClassStatWeightingTable[i].weightings[j] * thisfellow.stats[j]; X } X if (weight[i] > weight[maxweight]) { /* "best so far" */ X maxweight = i; X } X } X X thisfellow.cclass = ClassStatWeightingTable[maxweight].cclass; X return thisfellow; X} X Xt_person Xstatpotentials(bod) X t_person bod; X{ X int i = 0; X X bod.powerpoints = bod.developmentpoints = 0; X for (i = 0; i < NumberOfStats; i++) { X bod.potentials[i] = RollOnStatPotentialTable(bod.stats[i], d(100)); X bod.mods[i] = ConsultBonusTable(bod.stats[i], BonusStat); X if (etoistat(StatEm) >= i) { /* should use is_development_stat */ X bod.developmentpoints += ConsultBonusTable(bod.stats[i], BonusDP); X } X } X return bod; X} X XRollOnStatPotentialTable(originalstat, n) X int originalstat, n; X{ X int x = StatPotentialTable[maptable15p11[n-1]][map15p11(originalstat-1)]; X return (x <= 0) ? originalstat : x; X} X XConsultBonusTable(statroll, reason) X int statroll; X te_bonustype reason; X{ X int row; X int col; X X switch (reason) { X case BonusStat: col = 0; break; X case BonusDP: col = 1; break; X case BonusPP: col = 2; break; X default: /* can't happen :-) */ X error(__LINE__, __FILE__, "reason = %d\n", (int) reason); X abort(); X } X X if (statroll == 1) row = 0; X else if (statroll == 2) row = 1; X else if (statroll <= 4) row = 2; X else if (statroll <= 9) row = 3; X else if (statroll <= 14) row = 4; X else if (statroll <= 24) row = 5; X else if (statroll <= 39) row = 6; X else if (statroll <= 59) row = 7; X else if (statroll <= 74) row = 8; X else if (statroll <= 84) row = 9; X else if (statroll <= 89) row = 10; X else if (statroll <= 94) row = 11; X else if (statroll <= 97) row = 12; X else if (statroll <= 99) row = 13; X else if (statroll <= 100) row = 14; X else if (statroll <= 101) row = 15; X else if (statroll <= 102) row = 16; X else row = 17; X X return StatBonusTable[row][col]; X} X Xd(n) X int n; X{ X return ( ( rand() / RANDPRIME ) % n ) + 1; X} X Xt_person Xhitpoints(bod) X t_person bod; X{ X bod.hitpoints += d(10); X return bod; X} X Xmap15p11(stat) X int stat; X{ X if (stat < 25) return 0; X else if (stat < 40) return 1; X else if (stat < 60) return 2; X else if (stat < 75) return 3; X else if (stat < 85) return 4; X else if (stat < 90) return 5; X else if (stat < 95) return 6; X else if (stat < 98) return 7; X else if (stat < 100) return 8; X else return 9; X} X X/* print the fellow out... X */ X Xprintcharsheet(bod) X t_person bod; X{ X int i = 0; X X printf("Name: %s\nClass: %s\n", X (bod.name && bod.name[0]) ? bod.name : "Rasputin", X etoscclass(bod.cclass)); X puts("Stat\tPot\tTemp\tMod"); X for (i = 0; i < NumberOfStats; i++) { X printf("%s\t%d\t%d\t%d\n", etosstat( (te_stat) i), X bod.potentials[i], X bod.stats[i], X bod.mods[i]); X } X printskills(bod); X puts("\n\n"); X} X X#ifdef DOSKILLS X Xchooseskills(bod) X t_person bod; X{ X X /* build a list of skills that are available to us */ X /* and then choose the best selection therefrom */ X /* Finally, add the skills to the ones that the bod already have */ X /* but we don't get the benefits yet.... */ X X addpendingskills(bod, makeselection(bod, buildlistofskills(bod))); X} X X#endif X X Xprintskills(bod) X t_person bod; X{ X int i; X X for (i = 0; i <= etoiskill(SkillBodyDevelopment); i++) { X if (bod.skills[i].level > 0) { X printf("%d\t%s\n", bod.skills[i], etosskill(i)); X } X } X} X X X#ifdef DOSKILLS Xskillsandbonuses(bod) X t_person bod; X{ X chooseskills(bod); X benefitsforskills(bod); X skillbonuses(bod); X} X Xlist * Xbuildlistofskills(bod) X t_person bod; X{ X static skill_n firstval; X X /* here we have to make a list of all the skill selections that bod could X * make, together with a `desireability rating' GAIN for each. X */ X firstval.next = NULL; X firstval.gain = 2.0; /* too big so it stays at the front... */ X for (skill_n = 0; skill_n <= (int) SkillBodyDevelopment; skill_n++) { X /* do multiple selections here. NOTDONE */ X list *this = (skill *) malloc(sizeof(skill)); X list *p; /* for list-marching later... */ X X this->oldlevel = bod.skills[skill_n]; X this->newlevel = this->oldlevel[skill_n]; X this->which = skill_n; X this->gain = desireability(bod,this); X this->next = NULL; X for (p = &firstval; p->next != NULL; p = p->next) { X if (p->gain < this->gain || X (p-gain == this->gain && rand() % 2)) { X break; X } X } X if (p->next == NULL) { X /* end of the list */ X p->next = this; X } else { X this->next = p->next; X p->next = this; X } X } X return firstval.next; X} X#endif /* DOSKILLS */ X Xchar * Xchoosename(bod) X t_person bod; X{ X /* choose a suitable name... */ X static FILE *NamePipe = 0; X static char Result[100]; X X if (!NamePipe) { X if ((NamePipe = popen(NAMEPIPE, "r")) == (FILE *) 0) { X error(__LINE__, __FILE__, "can't open pipe %s\n", NAMEPIPE); X exit(1); X } X } X X return fgets(Result, sizeof(Result) - 1, NamePipe); X} X X X#ifdef DOSKILLS X XstratagyP(l, dp, q) X list *l, *q; X int dp; X{ X in v, v1; X list *q1 = NULL, *q2 = NULL, *p = l; X X while (p && p->cost > dp) X p = p->next; X X if (p == NULL) X return 0; X X if (p->next == NULL) { X append1(q, p); X return p->gain; X } X X v1 = p->gain + strategyP(p->next, dp - p->cost, q1); /* buy p */ X v2 = strategyP(p->next, dp, q2); /* or pass it by... ? */ X X if (v1 > v2) { X /* so it's a good idea to but p */ X append1(q, p); X append(q, q1); X return v1; X } else { X append(q, q1); X return v2; X } X} X Xappend1(l1, l2) X list *l1, *l2; X{ X register list *ptr = l1; X list *p = new(list); X X *p = l2; X p->next = NULL; X while (l1 && l1->next) X l1 = l1->next; X if (l1 == NULL) X return -1; X l1->next = p; X} X X Xappend(l1, l2) X list *l1, *l2; X{ X register list *ptr = l1; X X p->next = NULL; X while (l1 && l1->next) X l1 = l1->next; X if (l1 == NULL) X return -1; X l1->next = l2; X} X X#endif X X Xerror(file, line, msg, a, b, c) X char *file; X int line; X char *msg; X{ X fprintf(stderr, "%s:%d:", file, line); X fprintf(stderr, msg, a, b, c); X} X X/* $Log: npc.c,v $ X * Revision 1.2 90/09/03 21:53:38 lee X * Fixed some typos and an out-by-one error in maptable lookup. X * Added input pipe to random names program. X * X * Revision 1.1 90/09/03 21:16:25 lee X * Initial revision X * X * X */ @@@End of npc.c echo x - tables.h 1>&2 sed 's/^X//' >tables.h <<'@@@End of tables.h' X/* maptable for 15.11 -- given the d100 roll, which row of the stat potential X * table should we use? X */ Xint maptable15p11[] = { X/* 01-10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X/* 11-20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X/* 21-30 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, X/* 31-35 */ 3, 3, 3, 3, 3, X/* 36-40 */ 4, 4, 4, 4, 4, X/* 41-45 */ 5, 5, 5, 5, 5, X/* 46-49 */ 6, 6, 6, 6, X/* 50-51 */ 7, 7, X/* 52-53 */ 8, 8, X/* 54-55 */ 9, 9, X/* 56-57 */ 10, 10, X/* 58-59 */ 11, 11, X/* 60-61 */ 12, 12, X/* 62-63 */ 13, 13, X/* 64-65 */ 14, 14, X/* 66-67 */ 15, 15, X/* 68-69 */ 16, 16, X/* 70-71 */ 17, 17, X/* 72-73 */ 18, 18, X/* 74-75 */ 19, 19, X/* 76-77 */ 20, 20, X/* 78-79 */ 21, 21, X/* 80-81 */ 22, 22, X/* 82-83 */ 23, 23, X/* 84-85 */ 24, 24, X/* 86-87 */ 25, 25, X/* 88-89 */ 26, 26, X/* 90 */ 27, X/* 91 */ 28, X/* 92 */ 29, X/* 93 */ 30, X/* 94 */ 31, X/* 95 */ 32, X/* 96 */ 33, X/* 97 */ 34, X/* 98 */ 35, X/* 99 */ 36, X/* 100 */ 37, X/* oops! */ -1 X}; X X/* table 15.11 */ Xint StatPotentialTable[][10] = { X/* 01-10 */ { 25, 0, }, X/* 11-20 */ { 30, 0, }, X/* 21-30 */ { 35, 39, 0, }, X/* 31-35 */ { 38, 42, 59, 0, }, X/* 36-40 */ { 40, 45, 62, 0, }, X/* 41-45 */ { 42, 47, 64, 0, }, X/* 46-49 */ { 44, 49, 66, 0, }, X/* 50-51 */ { 46, 51, 68, 0, }, X/* 52-53 */ { 48, 53, 70, 0, }, X/* 54-55 */ { 50, 55, 71, 0, }, X/* 56-57 */ { 52, 57, 72, 74, 84, 0, }, X/* 58-59 */ { 54, 59, 73, 75, 85, 0, }, X/* 60-61 */ { 56, 61, 74, 76, 86, 0, }, X/* 62-63 */ { 58, 63, 75, 77, 87, 0, }, X/* 64-65 */ { 60, 65, 76, 78, 88, 0, }, X/* 66-67 */ { 62, 67, 77, 79, 88, 89, 0, }, X/* 68-69 */ { 64, 69, 78, 80, 89, 89, 0, }, X/* 70-71 */ { 66, 71, 79, 81, 89, 90, 0, }, X/* 72-73 */ { 68, 73, 80, 82, 90, 90, 0, }, X/* 74-75 */ { 70, 75, 81, 83, 90, 91, 0, }, X/* 76-77 */ { 72, 77, 82, 84, 91, 91, 0, }, X/* 78-79 */ { 74, 79, 83, 85, 91, 92, 0, }, X/* 80-81 */ { 76, 81, 84, 86, 92, 92, 0, }, X/* 82-83 */ { 78, 83, 85, 87, 92, 93, 0, }, X/* 84-85 */ { 80, 85, 86, 88, 93, 93, 94, 0, }, X/* 86-87 */ { 82, 86, 87, 89, 93, 94, 94, 0, }, X/* 88-89 */ { 84, 87, 88, 90, 94, 94, 95, 0, }, X/* 90 */ { 86, 88, 89, 91, 94, 95, 95, 97, 0, }, X/* 91 */ { 88, 89, 90, 92, 95, 95, 96, 97, 0, }, X/* 92 */ { 90, 90, 91, 93, 95, 96, 96, 97, 0, }, X/* 93 */ { 91, 91, 92, 94, 96, 96, 97, 98, 0, }, X/* 94 */ { 92, 92, 93, 95, 96, 97, 97, 98, 99, 0 }, X/* 95 */ { 93, 93, 94, 96, 97, 97, 98, 98, 99, 0 }, X/* 96 */ { 94, 94, 95, 97, 97, 98, 98, 99, 99, 0 }, X/* 97 */ { 95, 95, 96, 97, 98, 98, 99, 99, 99, 0 }, X/* 98 */ { 96, 96, 97, 98, 98, 99, 99, 99, 100, 0 }, X/* 99 */ { 97, 97, 98, 98, 99, 99, 100, 100, 100, 0 }, X/* 100 */ { 98, 98, 99, 99, 99, 100, 100, 100, 100, 101 }, X/* oops! */ { -1, -1, -1, -1, -1, -01, -01, -01, -01, -01 } X}; X X/* table 15.13 */ Xint StatBonusTable[][3] = { X/* 1 */ { -25,1, 0 }, X/* 2 */ { -20,1, 0 }, X/* 3-4 */ { -15,1, 0 }, X/* 5-9 */ { -10,2, 0 }, X/* 10-14 */ { -5, 2, 0 }, X/* 15-24 */ { -5, 3, 0 }, X/* 25-39 */ { 0, 4, 0 }, X/* 40-59 */ { 0, 5, 0 }, X/* 60-74 */ { 0, 6, 0 }, X/* 75-84 */ { 5, 7, 1 }, X/* 85-89 */ { 5, 8, 1 }, X/* 90-94 */ { 10, 8, 1 }, X/* 95-97 */ { 15, 9, 2 }, X/* 98-99 */ { 20, 9, 2 }, X/* 100 */ { 25, 10,3 }, X/* 101 */ { 30, 10,3 }, X/* 102+ */ { 35, 11,4 } X}; X Xt_skilltable SkillTable = { X { ClassFighter, { X {1,-1},{1,-1},{2,-1},{2,-2}, /* armour */ X {1,5}, {2,5}, {2,7}, {2,7}, {2,7}, {5,0}, /* weapons */ X {3,7}, {2,6}, {2,6}, {3,8}, {3,9}, {2,5}, {2,5}, /* general */ X {20,0},{7,0}, {9,0}, {25,0},{20,0}, /* magical */ X {3,8}, {3,-3},{2,6}, {20,0},{3,7}, {1,3}}}, /* special */ X { ClassThief, { X {1,-1},{2,-2},{3,-3},{4,-4}, /* armour */ X {2,7}, {3,8}, {4,0}, {4,0}, {4,0}, {6,0}, /* weapons */ X {2,5}, {1,3}, {2,6}, {1,3}, {1,3}, {1,3}, {1,3}, /* general */ X {10,0},{6,0}, {7,0}, {20,0},{20,0}, /* magical */ X {1,3}, {3,-3},{2,6}, {20,0},{3,7}, {3,7}}}, /* special */ X { ClassRogue, { X {1,-1},{1,-1},{2,-2},{3,-3}, /* armour */ X {2,5}, {3,8}, {3,9}, {3,9}, {3,9}, {6,0}, /* weapons */ X {3,7}, {2,5}, {2,5}, {2,5}, {2,6}, {1,3}, {1,3}, /* general */ X {8,0}, {6,0}, {8,0}, {20,0},{20,0}, /* magical */ X {2,5}, {3,-3},{2,6}, {20,0},{3,7}, {2,5}}}, /* special */ X { ClassWarriorMonk,{ X {9,0}, {9,0}, {10,0},{10,0}, /* armour */ X {4,0}, {6,0}, {8,0}, {8,0}, {8,0}, {15,0}, /* weapons */ X {3,7}, {1,5}, {2,7}, {3,9}, {3,9}, {2,4}, {2,5}, /* general */ X {10,0},{6,0}, {9,0}, {19,0},{20,0}, /* magical */ X {3,9}, {3,-3},{1,3}, {3,7}, {1,3}, {2,7}}}, /* special */ X { ClassMagician, { X {9,0}, {9,0}, {10,0},{11,0}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {6,0}, {3,0}, {3,0}, {7,0}, {8,0}, {5,0}, {3,0}, /* general */ X {1,-1},{1,4}, {1,4}, {7,0}, {2,5}, /* magical */ X {9,0}, {2,-2},{6,0}, {20,0},{9,0}, {8,0}}}, /* special */ X { ClassIllusionist,{ X {9,0}, {9,0}, {10,0},{11,0}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {7,0}, {3,0}, {3,0}, {8,0}, {8,0}, {3,0}, {2,0}, /* general */ X {1,-1},{1,4}, {1,4}, {7,0}, {2,6}, /* magical */ X {5,0}, {1,-1},{6,0}, {20,0},{9,0}, {8,0}}}, /* special */ X { ClassAlchemist, { X {9,0}, {9,0}, {10,0},{11,0}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {7,0}, {3,0}, {3,0}, {4,0}, {4,0}, {6,0}, {3,0}, /* general */ X {1,-1},{1,3}, {1,3}, {7,0}, {2,7}, /* magical */ X {9,0}, {1,-1},{6,0}, {20,0},{9,0}, {6,0}}}, /* special */ X { ClassCleric, { X {1,-1},{2,-2},{10,0},{11,0}, /* armour */ X {6,0}, {7,0}, {9,0}, {9,0}, {9,0}, {20,0}, /* weapons */ X {5,0}, {3,0}, {3,0}, {7,0}, {8,0}, {5,0}, {3,0}, /* general */ X {1,-1},{2,5}, {2,5}, {1,4}, {3,0}, /* magical */ X {9,0}, {2,-2},{5,0}, {20,0},{6,0}, {6,0}}}, /* special */ X { ClassAnimist, { X {2,-2},{3,-3},{10,0},{11,0}, /* armour */ X {6,0}, {7,0}, {9,0}, {9,0}, {9,0}, {20,0}, /* weapons */ X {4,0}, {3,0}, {1,3}, {8,0}, {8,0}, {3,0}, {3,0}, /* general */ X {1,-1},{2,6}, {2,6}, {2,5}, {3,0}, /* magical */ X {6,0}, {2,-2},{5,0}, {20,0},{6,0}, {4,0}}}, /* special */ X { ClassHealer, { X {2,-2},{3,-3},{10,0},{11,0}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {6,0}, {3,0}, {3,0}, {8,0}, {8,0}, {6,0}, {3,0}, /* general */ X {1,-1},{2,6}, {3,7}, {2,5}, {3,0}, /* magical */ X {9,0}, {2,-2},{5,0}, {20,0}, {6,0}, {1,-3}}}, /* special */ X { ClassMentalist, { X {4,-4},{5,-5},{6,-6},{7,-7}, /* armour */ X {6,0}, {8,0}, {15,0},{20,0},{20,0},{20,0}, /* weapons */ X {5,0}, {3,0}, {2,0}, {7,0}, {8,0}, {5,0}, {3,0}, /* general */ X {1,-1},{2,5}, {2,5}, {8,0}, {2,6}, /* magical */ X {9,0}, {2,-2},{3,0}, {15,0},{3,0}, {6,0}}}, /* special */ X { ClassLayHealer, { X {2,-2},{3,-3},{4,-4},{5,-5}, /* armour */ X {8,0}, {8,0}, {15,0},{20,0},{20,0},{20,0}, /* weapons */ X {6,0}, {3,0}, {2,0}, {8,0}, {8,0}, {6,0}, {3,0}, /* general */ X {1,-1},{2,6}, {2,6}, {8,0}, {2,7}, /* magical */ X {9,0}, {2,-2},{3,0}, {15,0}, {3,0}, {6,0}}}, /* special */ X { ClassSeer, { X {4,-4},{5,-5},{6,-6},{7,-7}, /* armour */ X {6,0}, {8,0}, {15,0},{20,0},{20,0},{20,0}, /* weapons */ X {4,0}, {3,0}, {2,0}, {7,0}, {7,0}, {6,0}, {1,-1}, /* general */ X {1,-1},{2,6}, {2,6}, {8,0}, {2,7}, /* magical */ X {9,0}, {1,-1},{3,0}, {15,0}, {3,0}, {6,0}}}, /* special */ X { ClassSorceror, { X {9,0}, {9,0}, {10,0},{11,0}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {6,0}, {3,0}, /* general */ X {1,-1},{2,5}, {2,5}, {2,5}, {2,5}, /* magical */ X {9,0}, {2,-2},{5,0}, {20,0},{9,0}, {8,0}}}, /* special */ X { ClassMystic, { X {4,-4},{5,-5},{6,-6},{7,-7}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {2,0}, {2,0}, /* general */ X {1,-1},{2,5}, {2,5}, {8,0}, {2,6}, /* magical */ X {4,0}, {1,-1},{5,0}, {15,0}, {6,0}, {8,0}}}, /* special */ X { ClassAstrologer, { X {4,-4},{5,-5},{6,-6},{7,-7}, /* armour */ X {9,0}, {20,0},{20,0},{20,0},{20,0},{20,0}, /* weapons */ X {7,0}, {3,0}, {3,0}, {7,0}, {7,0}, {6,0}, {2,0}, /* general */ X {1,-1},{2,6}, {2,6}, {1,5}, {2,7}, /* magical */ X {9,0}, {1,-1},{5,0}, {15,0},{6,0}, {6,0}}}, /* special */ X { ClassMonk, { X {9,0}, {9,0}, {10,0},{11,0}, /* armour */ X {5,0}, {8,0}, {8,0}, {8,0}, {15,0},{15,0}, /* weapons */ X {3,7}, {2,6}, {3,0}, {4,0}, {4,0}, {2,7}, {2,7}, /* general */ X {4,-4},{4,0}, {5,0}, {13,0},{9,0}, /* magical */ X {4,0}, {3,-3},{2,4}, {6,0}, {2,5}, {3,7}}}, /* special */ X { ClassRanger, { X {1,-1},{2,-2},{3,-3},{4,-4}, /* armour */ X {3,7}, {4,0}, {6,0}, {6,0}, {6,0}, {9,0}, /* weapons */ X {3,9}, {2,6}, {2,6}, {4,0}, {4,0}, {1,5}, {2,7}, /* general */ X {4,-4},{5,0}, {6,0}, {3,0}, {15,0}, /* magical */ X {3,0}, {3,-3},{2,7}, {20,0},{4,0}, {2,7}}}, /* special */ X { ClassBard, { X {2,-2},{3,-3},{4,-4},{5,5}, /* armour */ X {3,9}, {6,0}, {7,0}, {7,0}, {7,0}, {15,0}, /* weapons */ X {3,9}, {2,6}, {2,6}, {4,0}, {4,0}, {2,7}, {2,7}, /* general */ X {4,-4},{5,0}, {6,0}, {13,0},{10,0}, /* magical */ X {6,0}, {1,-1},{2,7}, {15,0},{3,0}, {3,8}}} /* special */ X}; X X Xstruct ClassStatWeightingTable { X te_cclass cclass; X float weightings[NumberOfStats]; X} ClassStatWeightingTable[] = { X /* characterclass Str Qu Pr In Em Co Ag SD Re Me */ X { ClassFighter, { 1.0, .01, .01, .01, .01, 1.0, .01, .01, .01, .01 } }, X { ClassThief, { .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01, .01 } }, X { ClassRogue, { 1.0, .01, .01, .01, .01, .01, 1.0, .01, .01, .01 } }, X { ClassWarriorMonk,{ .01, 1.0, .01, .01, .01, .01, .01, 1.0, .01, .01 } }, X { ClassMagician, { .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } }, X { ClassIllusionist,{ .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } }, X { ClassAlchemist, { .01, .01, .01, .01, 1.0, .01, .01, .01, 1.0, .01 } }, X { ClassCleric, { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } }, X { ClassAnimist, { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } }, X { ClassHealer, { .01, .01, .01, 1.0, .01, .01, .01, .01, .01, 1.0 } }, X { ClassMentalist, { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } }, X { ClassLayHealer, { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } }, X { ClassSeer, { .01, .01, 1.0, .01, .01, .01, .01, 1.0, .01, .01 } }, X { ClassSorceror, { .01, .01, .01, 1.0, 1.0, .01, .01, .01, .01, .01 } }, X { ClassMystic, { .01, .01, 1.0, .01, 1.0, .01, .01, .01, .01, .01 } }, X { ClassAstrologer, { .01, .01, 1.0, 1.0, .01, .01, .01, .01, .01, .01 } }, X { ClassMonk, { .01, .01, .01, .01, 1.0, .01, .01, 1.0, .01, .01 } }, X { ClassRanger, { .01, .01, .01, 1.0, .01, 1.0, .01, .01, .01, .01 } }, X { ClassBard, { .01, .01, 1.0, .01, .01, .01, .01, .01, .01, 1.0 } } X /* characterclass Str Qu Pr In Em Co Ag SD Re Me */ X}; X @@@End of tables.h exit 0 -- Liam R. E. Quin, lee@sq.com, {utai,utzoo}!sq!lee, SoftQuad Inc., Toronto Nicholas: [...] The best/ Thing we can do is to make wherever we're lost in Look as much like home as we can. [Christopher Fry, The Lady's Not For Burning]