rendered paste body<html><head><script language="javascript">/*Copyright (C) 2007 Chris Hennick This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.Name lists are taken from:Dancey, Ryan, Noonan, David and Ratcliff, John (2000). Hero Builder's Guidebook.Used with permission. ("Feel free to adapt these, combine them, truncatethem, or use them how you see fit.")NOTES:Lycanthropes' ability scores are those of their human forms, and doppelgangers' are those of their natural forms.All strings can contain any HTML tags except script.? indicates no canonical data.TODO:performance optimizationmenu, so user can choose size, power centers and/or racial mix rather than leave them to chance*/function random (x) { if (x <= 1) return 0; else return Math.floor(Math.random()*x);}function half (x) { if (x <= 1) return 0; else return Math.ceil(x/2);}var sizeResults = new Array(0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 2,2,2,2,2, 2,2,2,2,2, 2,2,2,2,2, 2,2,2,2,2, 3,3,3,3,3, 3,3,3,3,3, 3,3,3,3,3, 3,3,3,3,3, 4,4,4,4,4, 4,4,4,4,4, 4,4,4,4,4, 5,5,5,5,5, 5,5,5,5,5, 6,6,6,6,7);var ECMResults = new Array(0,0,0,0,0,1,2,3);var alignmentResults = new Array(0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1, 2,2, 3,3,3,3,3, 3,3,3,3,3, 3,3,3,3,3, 3,3,3,3,3, 4,4, 5, 6,6,6,6,6, 6,6,6,6,6, 6,6,6,6,6, 6,6,6,6,6, 6,6,6,6,6, 6, 7,7,7,7,7,7,7,7, 8,8);var classNames = new Array("Bbn", "Brd", "Clr", "Drd", "Ftr", "Mnk", "Pal", "Rgr", "Rog", "Sor", "Wiz", "Adp", "Ari", "Com", "Exp", "War");var alignmentNames = new Array("LG","NG","CG","LN","N","CN","LE","NE","CE");var preferredAlignments = new Array(5,5,-1,4,-1,3,0,2,5,-1,3);var allowedAlignments = new Array( new Array(0,1,1,0,1,1,0,1,1), new Array(0,1,1,0,1,1,0,1,1), new Array(1,1,1,1,1,1,1,1,1), new Array(0,1,0,1,1,1,0,1,0), new Array(1,1,1,1,1,1,1,1,1), new Array(1,0,0,1,0,0,1,0,0), new Array(1,0,0,0,0,0,0,0,0), new Array(1,1,1,1,1,1,1,1,1), new Array(1,1,1,1,1,1,1,1,1), new Array(1,1,1,1,1,1,1,1,1), new Array(1,1,1,1,1,1,1,1,1));var raceNames = new Array("Human", "Dwarf, hill", "Elf, high", "Gnome, rock", "Half-elf", "Half-orc", "Halfling, lightfoot", //0-6 "<b>Aasimar</b>", "<b>Tiefling</b>", //7-8 "Dwarf, <b>deep</b>", "Dwarf, <b>mountain</b>", "Dwarf, <b>duergar</b>", //9-11 "Elf, <b>gray</b>", "Elf, <b>wild</b>", "Elf, <b>wood</b>", "Elf, <b>drow</b>", //12-15 "Gnome, <b>forest</b>", "Gnome, <b>svirfneblin</b>", //16-17 "Halfling, <b>deep</b>", "Halfling, <b>tallfellow</b>", //18-19 "<b>Half-celestial</b>/", "<b>Half-fiend</b>/", //20-21 "<b>Half brass dragon</b>/", "<b>Half bronze dragon</b>/", "<b>Half copper dragon</b>/", "<b>Half silver dragon</b>/", "<b>Half gold dragon</b>/", //22-26 "<b>Half black dragon</b>/", "<b>Half blue dragon</b>/", "<b>Half green dragon</b>/", "<b>Half red dragon</b>/", "<b>Half white dragon</b>/", //27-31 "<b>Werebear</b> (afflicted)/", "<b>Wereboar</b> (afflicted)/", "<b>Weretiger</b> (afflicted)/", "<b>Wererat</b> (afflicted)/", "<b>Werewolf</b> (afflicted)/", //32-36 "<b>Werebear</b> (natural)/", "<b>Wereboar</b> (natural)/", "<b>Weretiger</b> (natural)/", "<b>Wererat</b> (natural)/", "<b>Werewolf</b> (natural)/", //37-41 "<b>Lizardfolk</b>", "<b>Doppelganger</b>", "<b>Goblin</b>", "<b>Hobgoblin</b>", "<b>Kobold</b>", "<b>Orc</b>", "<b>Derro</b> (insane)", "<b>Derro</b> (sane)", "<b>Gnoll</b>", "<b>Troglodyte</b>", "<b>Bugbear</b>", "<b>Ogre</b>", "<b>Minotaur</b>", "<b>Mind flayer</b>", "<b>Ogre mage</b>", //42-56 "");var raceBaseAges = new Array(15,40,110,40,20,14,20, 15,15, 40,40,40, 110,110,110,110, 40,40, 20,20, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1);var raceMilestoneAges = new Array( new Array(35,125,175,100,62,30,50, 35,35, 125,125,125, 175,175,175,175, 100,100, 50,50, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,25,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1), new Array(53,188,263,150,93,45,75, 53,53, 188,188,188, 263,263,263,263, 150,150, 75,75, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,37,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1), new Array(70,250,350,200,125,60,100, 70,70, 250,250,250, 350,350,350,350, 200,200, 100,100, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1));var raceAgeMods = new Array( // number of d6s at first level; d4 is treated as 0.7d6 new Array(0.7,3,4,4,1,0.7,1.4, // brb, rog, sor 0.7,0.7, 3,3,3, 4,4,4,4, 4,4, 1.4,1.4, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,0.7,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1), new Array(1,5,6,6,2,1,3, // brd, ftr, pal, rgr, war 1,1, 5,5,5, 6,6,6,6, 6,6, 3,3, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1), new Array(2,7,10,9,3,2,4, // clr, drd, mnk, wiz, adp, exp, com*, ari* 2,2, 7,7,7, 10,10,10,10, 9,9, 4,4, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1));var classAgeModSelectors = new Array(0,1,2,2,1,2,1,1,0,0,2, 2,2,2,2,1);var raceBaseHeights = new Array( // X where height is X+2dY new Array(58,45,53,36,55,58,32, // males 58,58, 45,45,45, 57,53,53,53, 36,36, 25,46, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 66,63,34,73,22,58,45,45,85,55,79,105,82,58,111, -1), new Array(53,43,53,34,53,53,30, // females 53,53, 43,43,43, 57,53,53,53, 34,34, 23,44, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 66,63,34,73,22,53,43,43,85,55,79,105,82,53,111, -1));var raceHeightMods = new Array(10,4,6,4,8,12,4, // Y where height is X+2dY; same for both sexes 10,10, 4,4,4, 6,6,6,6, 4,4, 4,4, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 10,2,4,4,4,14,4,4,4,4,4,8,4,10,8, -1);var raceBaseWeights = new Array( new Array(120,130,85,40,100,150,30, // males 120,120, 130,130,130, 85,85,85,85, 40,40, 28,28, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 190,142,38,-1,30,180,130,130,285,135,-1,590,685,-1,640, -1), new Array(85,100,80,35,80,110,25, // females 85,85, 100,100,100, 80,80,80,80, 35,35, 27,27, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 190,142,37,-1,30,135,100,100,285,135,-1,590,685,-1,640, -1));var raceMaxWeightMods = new Array(8,12,6,1,8,12,1, 8,8, 12,12,12, 6,6,6,6, 1,1, 1,1, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 4,4,1,-1,3,16,12,12,4,4,-1,6,4,-1,4, -1);var raceMinWeightMods = new Array(2,2,1,1,2,2,1, 2,2, 2,2,2, 1,1,1,1, 1,1, 1,1, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 1,1,1,-1,1,2,2,2,1,1,-1,1,1,-1,1, -1); var racialHDcounts = new Array(0,0,0,0,0,0,0, 0,0, 0,0,0, 0,0,0,0, 0,0, 0,0, 0,0, 0,0,0,0,0, 0,0,0,0,0, 6,3,6,1,2, 6,3,6,1,2, 2,4,0,0,0,0,3,3,2,2,3,4,6,8,5, 0); // all these races' HD are 8-sidedvar raceNeedsBaseCreature = new Array(0,0,0,0,0,0,0, 0,0, 0,0,0, 0,0,0,0, 0,0, 0,0, 1,1, 2,2,2,2,2, 2,2,2,2,2, 1,1,1,1,1, 1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0); //0=no, 1=yes, 2=yes and change base creature's HD to 10-sidedvar racialAbilAdjs = new Array( new Array(0,0,0,0,0,0), new Array(0,0,2,0,0,-2), new Array(0,2,-2,0,0,0), new Array(-2,0,2,0,0,0), new Array(0,0,0,0,0,0), new Array(2,0,0,-2,0,-2), new Array(-2,2,0,0,0,0), new Array(0,0,0,0,2,2), new Array(0,2,0,2,0,-2), new Array(0,0,2,0,0,-2), new Array(0,0,2,0,0,-2), new Array(0,0,2,0,0,-2), new Array(-2,2,-2,2,0,0), new Array(0,2,0,-2,0,0), new Array(2,0,0,-2,0,0), new Array(0,2,-2,2,0,2), new Array(-2,0,2,0,0,0), new Array(-2,2,0,0,2,-4), new Array(-2,2,0,0,0,0), new Array(-2,2,0,0,0,0), new Array(4,2,4,2,4,4), new Array(4,4,2,4,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(8,0,2,2,0,2), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(0,0,0,0,2,0), new Array(2,0,2,-2,0,0), new Array(2,2,2,2,4,2), new Array(-2,2,0,0,0,-2), new Array(0,2,2,0,0,0), new Array(-4,2,-2,0,0,0), new Array(4,0,0,-2,-2,-2), new Array(0,4,2,0,-6,6), new Array(0,4,2,0,0,0), new Array(4,0,2,-2,0,-2), new Array(0,-2,4,-2,0,0), new Array(4,2,2,0,0,-2), new Array (10,-2,4,-4,0,-4), new Array(8,0,4,-4,0,-2), new Array(2,4,2,8,6,6), new Array(10,0,6,4,4,6), new Array(0,0,0,0,0,0));var racialCumDistroHero = new Array( new Array( new Array(.37,.39,0,0,.40,.65,.66, // good bbn 0,0, 0,0,0, 0,.96,.98,0, 0,0, 0,0, .99,0, .992,.994,.996,.998,1.00, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.40,.45,.70,.75,.84,.85,.86, // good brd .87,0, 0,0,0, .92,.93,.94,0, .95,.96, .97,.98, .99,0, .992,.994,.996,.998,1.00, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.25,.45,.55,.64,.69,.70,.80, // good clr .81,0, .82,.84,0, .85,.90,.91,0, .92,.93, .94,.96, .98,0, .982,.984,.986,.988,.990, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.50,0,.60,.61,.70,.71,.72, // good drd 0,0, 0,0,0, .73,.83,.93,0, .98,0, 0,.99, 1.00,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.40,.70,.75,.76,.78,.83,.84, // good ftr 0,0, .87,.95,0, .96,0,0,0, 0,0, .97,0, .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.72,.73,.83,0,.88,.93,.94, // good mnk .96,0, 0,0,0, 0,0,0,0, 0,0, .97,0, .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.67,.77,0,.78,.83,.84,.86, // good pal .96,0, 0,0,0, 0,0,0,0, 0,0, .97,0, .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.33,.38,.53,.54,.69,.74,.75, // good rgr 0,0, 0,0,0, 0,0.76,.91,0, .96,0, 0,.97, .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.19,.24,.37,.42,.52,.57,.82, // good rog 0,0, 0,.83,0, 0,0,0,0, .84,.85, .91,.97, .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.37,.39,.42,.44,.49,.51,.60, // good sor .62,0, .63,.64,0, .66,.91,.92,0, .93,.94, .95,.96, .97,0, .974,.978,.982,.986,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.28,.29,.63,.68,.78,.79,.84, // good wiz .85,0, 0,0,0, //dwarf subraces .90,0,.91,0, //elf subraces .92,.93, // gnome subraces .94,.97, // halfling subraces .98,0, .982,.984,.986,.988,.99, 0,0,0,0,0, .998,0,0,0,0, 1.00,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ), new Array( new Array(.29,.30,0,0,.32,.71,.73, // neut bbn 0,0, .74,0,0, 0,.85,.86,0, 0,0, .87,0, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.878,.886,0,0, 0,.888,.89,0,0, 1.00,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.58,.60,.70,.72,.82,.84,.87, // neut brd 0,0, .88,0,0, .90,.91,.96,0, 0,0, .97,.98, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.988,.996,0,0, 0,.998,1.00,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.28,.38,.39,.40,.49,.51,.61, // neut clr 0,0, .76,.77,0, 0,.78,.88,0, 0,0, .89,.90, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.908,.916,0,0, 0,.918,.920,0,0, .99,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.48,0,.53,0,.58,.59,.60, // neut drd 0,0, 0,0,0, // dwarf .61,.66,.86,0, //elf .87,0, // gnome 0,.88, // halfling 0,0, // half-cel & half-fiend 0,0,0,0,0, // half met drag 0,0,0,0,0, // half chrom drag 0,.888,.896,0,0, //aff lyc 0,.898,.9,0,0, //nat lyc 1.00,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.38,.57,.58,0,.63,.73,.74, // neut ftr 0,0, .84,.89,0, 0,0,.95,0, 0,0, .96,0, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.968,.976,0,0, //aff lyc 0,.978,.98,0,0, //nat lyc .99,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.75,0,.77,0,.87,.97,.98, // neut mnk 0,0, 0,0,0, 0,0,.99,0, 0,0, 1.00,0, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.38,.57,.58,0,.63,.73,.74, // neut pal does not exist, so we use neut ftr as placeholder 0,0, .84,.89,0, 0,0,.95,0, 0,0, .96,0, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.968,.976,0,0, //aff lyc 0,.978,.98,0,0, //nat lyc .99,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.29,.30,.35,.36,.53,.63,.64, // neut rgr 0,0, 0,0,0, 0,.65,.94,0, .95,0, 0,.96, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.968,.976,0,0, //aff lyc 0,.978,.98,0,0, //nat lyc 1.00,0,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.24,.27,.31,.32,.47,.57,.85, // neut rog 0,0, .86,0,0, 0,0,.87,0, 0,0, .92,.97, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.978,.986,0,0, //aff lyc 0,.988,.99,0,0, //nat lyc 0,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.47,.48,.49,.50,.65,.70,.80, //neut sor 0,0, 0,0,0, 0,.90,.93,0, 0,0, .94,.95, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.958,.966,0,0, 0,.968,.97,0,0, .99,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.47,0,.72,.73,.88,.89,.92, //neut wiz 0,0, 0,0,0, .93,0,.95,0, 0,0, 0,.97, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,.978,.986,0,0, //aff lyc 0,.988,.99,0,0, //nat lyc 0,1.00,0,0,0,0,0,0,0,0,0,0,0,0,0) ), new Array ( new Array(.10,0,0,0,.11,.34,.35, // evil bbn 0,.36, // aasimar, tiefling 0,0,0, // dwarf 0,.37,.39,0, // elf 0,0, // gnome .40,0, // halfling 0,.42, // half-cel, half-fiend 0,0,0,0,0, // half met drag .424,.428,.432,.436,.44, // half chrom drag 0,0,0,0,.456, // aff lyc 0,0,0,0,.46, // nat lyc .51,0,.52,.53,.54,.84,0,0,.89,.90,.92,.96,1.00,0,0), new Array(.75,0,.76,0,.91,.93,.94, // evil brd 0,.95, 0,0,0, 0,0,.96,0, // elf 0,0, .97,.98, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,.988, 0,0,0,0,.99, 0,0,1.00,0,0,0,0,0,0,0,0,0,0,0,0), new Array(.31,.32,.33,0,.43,.46,.48, // evil clr 0,.49, .51,0,.52, 0,.53,.56,.59, 0,0, .60,.61, 0,.63, 0,0,0,0,0, .632,.634,.636,.638,.64, 0,0,0,.648,.656, 0,0,0,.658,.66, .73,0,.74,.75,.76,.79,0,0,0,.94,.96,.97,.98,.99,1.00), new Array(.50,0,0,0,.51,.53,0, // evil drd 0,0, 0,0,0, 0,0,.55,0, 0,0, 0,.56, 0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, .71,0,.72,.73,.74,.75,0,0,1.00,0,0,0,0,0,0), new Array(.30,.32,.33,0,.38,.47,.48, // evil ftr 0,0, .50,0,.51, 0,0,.53,.55, 0,0, .56,0, 0,.57, 0,0,0,0,0, .572,.574,.576,.578,.580, 0,0,0,.588,.596, 0,0,0,.598,.60, .61,0,.62,.87,.88,.93,.938,.94,.95,.96,.97,.98,0,.99,1.00), new Array(.70,0,0,0,.80,.90,0, // evil mnk 0,.91, 0,0,0, 0,0,0,0, 0,0, 0,0, 0,.92, 0,0,0,0,0, .922,.924,.926,.928,.93, 0,0,0,.946,0, 0,0,0,.95,0, 0,0,0,.98,0,0,0,0, 0,0,0,0, 0,0,1.00), new Array(.30,.32,.33,0,.38,.47,.48, // evil pal does not exist, so we use evil ftr as placeholder 0,0, .50,0,.51, 0,0,.53,.55, 0,0, .56,0, 0,.57, 0,0,0,0,0, .572,.574,.576,.578,.580, 0,0,0,.588,.596, 0,0,0,.598,.60, .61,0,.62,.87,.88,.93,.938,.94,.95,.96,.97,.98,0,.99,1.00), new Array(.30,0,.31,0,.48,.57,.58, //evil rgr 0,0, 0,0,0, 0,0,.68,0, 0,0, 0,.69, 0,.70, 0,0,0,0,0, .702,.704,.706,.708,.71, 0,0,0,.718,.734, 0,0,0,.736,.74, .76,0,0,.77,0,0,0,0, .97,.98,.99,1.00,0,0,0), new Array(.20,0,.21,0,.36,.46,.66, //evil rog 0,.68, .69,0,0, 0,0,.70,0, 0,0, .71,.72, 0,.74, 0,0,0,0,0, .742,.744,.746,.748,.75, 0,0,0,.766,.774, 0,0,0,.778,.78, 0,0,.93,.94,.95,0,0,0,0,0,.99,0,0,1.00,0), new Array(.40,0,0,0,.55,.60,.65, //evil sor 0,0, 0,0,0, 0,.66,0,0, 0,0, .67,.68, 0,.69, 0,0,0,0,0, .694,.698,.702,.706,.71, 0,0,0,.718,.726, 0,0,0,.728,.73, .74,0,.75,.76,.91,0,0,0, .92,.95,.96,.97,.98,.99,1.00), new Array(.50,0,.60,0,.75,0,.76, //evil wiz 0,.77, 0,0,0, 0,0,.78,.88, 0,0, 0,.89, 0,.90, 0,0,0,0,0, .902,.904,.906,.908,.91, 0,0,0,.918,.926, 0,0,0,.928,.93, 0,0,0,.95,0,0,0,0,.96,0,.97,0,0,.98,1.00) // "Lizardfolk", "Doppelganger", "Goblin", "Hobgoblin", "Kobold", "Orc", "Derro (insane)", "Derro (sane)", "Gnoll", "Troglodyte", "Bugbear", "Ogre", "Minotaur", "Mind flayer", "Ogre mage", ));racialLA = new Array(0,0,0,0,0,0,0, 0,0, 0,0,0, 0,0,0,-1, 0,-1, 0,0, -1,-2, -2,-2,-2,-2,-2, -2,-2,-2,-2,-2, -2,-1,-1,-1,-1, -2,-1,-1,-1,-1, 0,0,0,0,0,0,-1,-1,-1,-1,-2,-2,-4,-8,-8, 0);var racialCumDistroNormal = new Array( new Array(.96,.98,.99,.9925,.995,.9975), new Array(.79,.88,.93,.96,.98,.99), new Array(.37,.57,.75,.85,.92,.97));var traitResults = new Array( //77 sub-arrays new Array("distinctive scar"), new Array("missing tooth"), new Array("missing finger"), new Array("bad breath"), new Array("strong body odour", "pleasantly perfumed"), new Array("sweaty"), new Array("shaky hands"), new Array("unusual eye colour"), new Array("hacking cough"), new Array("sneezes and sniffles"), new Array("particularly low voice", "particularly high voice"), new Array("slurs words", "lisps", "stutters", "enunciates very clearly"), new Array("speaks loudly", "whispers"), new Array("hard of hearing"), new Array("tattoo"), new Array("birthmark"), new Array("unusual skin colour"), new Array("bald", "particularly long hair", "unusual hair colour"), new Array("walks with a limp"), new Array("distinctive jewelry"), new Array("flamboyant clothes"), new Array("outlandish clothes"), new Array("underdressed", "overdressed"), new Array("nervous eye twitch"), new Array("fidgets nervously"), new Array("whistles a lot", "sings a lot"), new Array("flips a coin"), new Array("good posture", "stooped back"), new Array("visible wounds", "visible sores"), new Array("squints"), new Array("stares off into distance"), new Array("frequently chewing something"), new Array("dirty and unkempt", "clean"), new Array("distinctive nose"), new Array("selfish"), new Array("obsequious", "aloof"), new Array("drowsy"), new Array("bookish"), new Array("observant", "not very observant"), new Array("overly critical"), new Array("passionate artist", "passionate art lover"), new Array("passionate fisher", "passionate hunter", "passionate board gamer", "passionate card gamer", "passionate about animals", "passionate hobbyist (misc.)"), new Array("collects books", "collects trophies", "collects coins", "collects weapons", "collector (misc.)"), new Array("skinflint", "spendthrift"), new Array("pessimist", "optimist"), new Array("drunkard", "teetotaler"), new Array("well-mannered", "rude"), new Array("jumpy"), new Array("foppish"), new Array("overbearing"), new Array("proud"), new Array("individualist", "conformist"), new Array("hot-tempered", "even-tempered"), new Array("neurotic"), new Array("jealous"), new Array("brave", "cowardly"), new Array("careless"), new Array("curious"), new Array("truthful", "liar"), new Array("lazy"), new Array("energetic"), new Array("reverent", "irreverent"), new Array("pious", "irreligious"), new Array("strong political opinions"), new Array("strong moral opinions"), new Array("moody"), new Array("cruel"), new Array("uses flowery speech"), new Array("uses long words"), new Array("uses the same phrases over and over"), new Array("sexist"), new Array("racist"), new Array("prejudiced (misc.)"), new Array("fascinated by magic"), new Array("distrustful of magic"), new Array("prefers barbarians over everyone else", "prefers bards over everyone else", "prefers clerics over everyone else", "prefers druids over everyone else", "prefers fighters over everyone else", "prefers monks over everyone else", "prefers paladins over everyone else", "prefers rangers over everyone else", "prefers rogues over everyone else", "prefers sorcerers over everyone else", "prefers wizards over everyone else", "prefers adepts over everyone else", "prefers aristocrats over everyone else", "prefers commoners over everyone else"), new Array("jokester", "no sense of humour"));// -1 = use base type, 0 = none, 1 = human, 2 = dwarf, 3 = elf, 4 = gnome, 5 = orc, 6 = halfling,var nameSelector = new Array(1,2,3,4,3,5,6, 1,1, 2,2,2, 3,3,3,3, 4,4, 6,6, -1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, 0,0,0,0,0,5,0,0,0,0,0,0,0,0,0, -1);var firstNames = new Array( new Array("?"), new Array( "Aber", "Ablamar", "Accolon", "Adlar", "Alhandra", "Almax", "Alper", "Alysan", "Amandis", "Amidee", "Andrella", "Anglides", "Anneth", "Annowre", "Anrod", "Ansirus", "Arla", "Ardel", "Arian", "Arlen", "Arlenda", "Arlis", "Arpad", "Arrness", "Arthad", "Aseneth", "Astra", "Avenal", "Bae", "Bailey", "Ballard", "Bedwyr", "Belinase", "Belloc", "Belnoy", "Bendekar", "Bernal", "Bersalles", "Berwyn", "Blaise", "Bodwyn", "Bret", "Brianna", "Brilman", "Bryman", "Burlac", "Burne", "Cadwyn", "Calista", "Calley", "Callum", "Calmert", "Candella", "Cathloy", "Cathra", "Cedras", "Chantel", "Charl", "Claudus", "Claisant", "Cobb", "Coburne", "Cole", "Colvin", "Corbin", "Corwyn", "Dafyn", "Damas", "Danel", "Danly", "Dara", "Darian", "Darla", "Darley", "Decius", "Denira", "Deraks", "Devereau", "Devis", "Dilys", "Dinadus", "Dor", "Dorian", "Dubricus", "Dudley", "Durga", "Durnsay", "Dynas", "Ebb", "Eckusan", "Elayne", "Eliph", "Elizar", "Elyas", "Emher", "Enide", "Erbin", "Erroll", "Ettard", "Evaine", "Fen", "Fliban", "Galashin", "Galen", "Gar", "Garath", "Garlon", "Gelpas", "Genievre", "Gerard", "Gevies", "Gilles", "Greeves", "Grellyn", "Gristla", "Gwenta", "Gwenelan", "Gwenned", "Gwydion", "Gwydre", "Gwyon", "Hacasin", "Hacmed", "Harkin", "Harlonus", "Helain", "Helyes", "Hemisal", "Hennet", "Herlew", "Herm", "Hervor", "Hodge", "Hoel", "Huber", "Hydwen", "Jacasin", "Jadale", "Jader", "Jankin", "Jarri", "Jarvis", "Jerick", "Jenelle", "Jess", "Joachim", "Jolan", "Jordanus", "Jozan", "Jud", "Kae", "Kaywen", "Kebel", "Karris", "Kendall", "Keriann", "Kimber", "Kira", "Kither", "Kyanus", "Lacenor", "Lamork", "Leigh", "Lin", "Llywellan", "Londa", "Loy", "Luce", "Lum", "Lunete", "Lyge", "Lyman", "Lynette", "Lynores", "Lyons", "Lyssette", "Lyzanor", "Maevis", "Magh", "Magoun", "Maharis", "Mara", "Marieka", "Marly", "Mathias", "Mede", "Megaera", "Menander", "Mere", "Migdalia", "Miles", "Mobley", "Myla", "Myrr", "Nadya", "Naramis", "Nascen", "Neanne", "Neb", "Nedaph", "Neith", "Nessi", "Neva", "Nira", "Nissa", "Noch", "Norgalis", "Noewll", "Nyfer", "Obyn", "Omig", "Orbri", "Orm", "Orph", "Peta", "Petrique", "Plase", "Ponj", "Priadan", "Quint", "Rafe", "Reece", "Regdar", "Relkin", "Reswald", "Ruther", "Rydel", "Reyott", "Sabine", "Sapphira", "Seith", "Sephora", "Serpe", "Sigfa", "Sinnoch", "Surmal", "Tabra", "Taff", "Tagli", "Tallis", "Tam", "Tangye", "Tanith", "Tarlach", "Tarpeia", "Tathal", "Tegyr", "Tessa", "Therise", "Thoms", "Travers", "Trig", "Tulloch", "Tully", "Tydd", "Unwyn", "Valdis", "Vardalon", "Varlay", "Varn", "Vayshor", "Wace", "Walther", "Welcar", "Weldun", "Wigan", "Wilton", "Wledig", "Woller", "Wort", "Wulik", "Wylie", "Xavia", "Ydey", "Yelda", "Yon", "Yvette", "Ywaine", "Zander", "Zahrdahl"), new Array("Agnar", "Algar", "Andred", "Angantyr", "Asgrim", "Atli", "Auda", "Aurgelmyr", "Aurus", "Aylor", "Balmek", "Batava", "Belvar", "Bethnos", "Beyla", "Blaine", "Blon", "Bothvar", "Brueyan", "Cardon", "Carduel", "Colmark", "Dagmar", "Dorag", "Dorin", "Dormar", "Dorn", "Durbar", "Durifer", "Durney", "Duwas", "Dyall", "Eja", "Enton", "Erac", "Erall", "Ercan", "Eris", "Esgir", "Euwas", "Eyjulf", "Falco", "Fech", "Ferh", "Finbar", "Fijar", "Foriel", "Framm", "Fraunk", "Fumok", "Galapas", "Gangleri", "Geirmund", "Geirrod", "Gerar", "Gloier", "Gofnyr", "Gorwinay", "Gothrom", "Grennel", "Griff", "Grimm", "Grimnyr", "Grimslad", "Grummore", "Grummer", "Gulrod", "Gulnyr", "Guthorm", "Gymir", "Halco", "Halprek", "Hamnyr", "Harvarr", "Hedrieks", "Heimyr", "Heliap", "Helcar", "Heth", "Himlung", "Hleid", "Hluahl", "Hodd", "Hoff", "Hreidmar", "Hrif", "Hringrim", "Hrottyr", "Hrusk", "Hrund", "Izhilem", "Jaer", "Jarnuk", "Jemrik", "Jodmar", "Jormun", "Kogyr", "Kord", "Krelar", "Laufney", "Lorac", "Lucan", "Lutor", "Macsen", "Magnus", "Magnyr", "Mal", "Malgrim", "Manasen", "Marrok", "Maros", "Martel", "Mellard", "Melnyr", "Merla", "Minadus", "Murfils", "Naegel", "Narbeth", "Naripaul", "Narivissal", "Narr", "Nartach", "Ndils", "Neson", "Norvi", "Ogmi", "Ogmore", "Ormund", "Ossan", "Ost", "Otar", "Pharien", "Pharnos", "Phiden", "Prellis", "Quanzar", "Rannos", "Rathyen", "Raynor", "Reaf", "Relmar", "Roake", "Rostenoc", "Sadoc", "Sanam", "Sargen", "Sarras", "Segwares", "Silmon", "Snaevar", "Somer", "Svava", "Tammell", "Tarran", "Taudoc", "Telvar", "Terjon", "Theneus", "Therlan", "Thoas", "Thurdev", "Toffa", "Tordek", "Toreck", "Torq", "Tosta", "Turan", "Turquin", "Tyrra", "Ubron", "Ulf", "Vardoc", "Varr", "Veor", "Verlad", "Vidnyr", "Vor-grim", "Walgrim", "Woller", "Xaq", "Xorax", "Yotis", "Yter", "Zert", "Barendd", "Brottor", "Eberk", "Einkil", "Oskar", "Rurik", "Taklinn", "Tordek", "Traubon", "Ulfgar", "Veit", "Artin", "Audhild", "Dagnal", "Diesa", "Gunnloda", "Hlin", "Ilde", "Liftrasa", "Sannl", "Torgga"), new Array("Aerlyn", "Aiaruen", "Alwyn", "Amlaith", "Amyr", "Aneiryn", "Anwyn", "Aravar", "Arcalinte", "Arden", "Ardis", "Arlanna", "Artigol", "Arundel", "Arwaine", "Arwyl", "Auruewyn", "Benrodyr", "Berethani", "Bethal", "Branwyn", "Brisaine", "Britomar", "Caedrus", "Caendun", "Caeradwyn", "Caercarwyn", "Calahir", "Carados", "Carrick", "Cathbar", "Cea", "Celedor", "Cerene", "Charivar", "Corbesont", "Damaera", "Deruwyn", "Dolartu", "Dydd", "Ehangwyn", "Elenwyd", "Elferin", "Emerwen", "Emrys", "Enuren", "Ethren", "Evaryan", "Fallon", "Felwyn", "Florimel", "Gennal", "Guiomart", "Heilyn", "Jaheel", "Jelanen", "Jelenneth", "Jelifer", "Jocelyn", "Karasin", "Kessa", "Killian", "Kyrian", "Laith", "Lareth", "Laurl", "Lavayn", "Lorrim", "Maeve", "Maidel", "Malmagor", "Marlys", "Melias", "Melimae", "Merissa", "Mialee", "Moenna", "Morgan", "Myrdivar", "Myrrath", "Narwain", "Ninafer", "Nyatar", "Olmas", "Olwain", "Oreth", "Panwyr", "Parlee", "Parwyn", "Pelltar", "Peren", "Raede", "Rahasia", "Raniel", "Remaelde", "Rentar", "Reuel", "Rhaine", "Rianneth", "Rinya", "Roedyn", "Runir", "Selcar", "Seledra", "Selwyn", "Seriade", "Shanna", "Sharlea", "Shay", "Silenna", "Silevran", "Soveliss", "Taleraed", "Tarbenay", "Taratar", "Taulured", "Telmar", "Terari", "Thaniel", "Thaedras", "Twyll", "Uel", "Vadania", "Veasse", "Venye", "Verraine", "Wendelain", "Ysberyl", "Yslar", "Zelmar", "Aramil", "Aust", "Enialis", "Heian", "Himo", "Ivellios", "Laucian", "Quarion", "Soveliss", "Thamior", "Tharivol", "Anastrianna", "Antinua", "Drusilia", "Felosial", "Ielenia", "Lia", "Mialee", "Qillathe", "Silaqui", "Vadania", "Valanthe", "Xanaphia"), new Array("Ahtva", "Annikko", "Aolor", "Apnee", "Arn", "Balto", "Birzoon", "Bitha", "Bramo", "Cirilli", "Cline", "Crayloon", "Cuirboly", "Dak", "Eckel", "Ensu", "Erb", "Erkenwald", "Finla", "Furduch", "Gormadoc", "Gostegottl", "Gundigoot", "Gwaylar", "Halanan", "Hallap", "Hamarka", "Hensu", "Hewett", "Hoch", "Hoose", "Igsenki", "Ikitur", "Jaroo", "Juutar", "Kantelleki", "Kasma", "Kutar", "Kyliki", "Lakajan", "Larimo", "Lelmose", "Lotch", "Lynen", "Malesacar", "Miep", "Mirge", "Moczama", "Myroc", "Nebin", "Nizam", "Noj", "Norbor", "Notar", "Nuados", "Osomo", "Oyun", "Pello", "Penabwa", "Piletti", "Pinker", "Poot", "Quonzar", "Ramne", "Redef", "Sahir", "Samoinan", "Sahtwyrn", "Spah", "Spugnor", "Suram", "Swa", "Tahir", "Tamatar", "Tamora", "Tamoinen", "Thrang", "Uani", "Uli", "Unferth", "Unqin", "Verhoo", "Veter", "Vlodge", "Voynan", "Wilf", "Yarol", "Yipwyg", "Zupesh", "Zygur", "Boddynock", "Dimble", "Fonkin", "Gimble", "Glim", "Gerbo", "Jebeddo", "Namfoodle", "Roondar", "Seebo", "Zook", "Bimpnottin", "Caramip", "Duvamil", "Ellywick", "Ellyjobell", "Loopmottin", "Mardnab", "Roywyn", "Shamil", "Waywocket"), new Array("Agar", "Akaros", "Arrakk", "Augh", "Bree", "Bruegar", "Dahk", "Derkk", "Devdas", "Dgul", "Drood", "Druuk", "Eagol", "Edals", "Ekk", "Franch", "Fukel", "Gaaki", "Gar", "Garlak", "Ghorn", "Gnarsh", "Gnarsht", "Gobar", "Gogar", "Grai", "Gremog", "Grigri", "Grimslade", "Grinkel", "Gronz", "Grumbar", "Gugal", "Guzud", "Gynk", "Hargul", "Harll", "Hogar", "Honzu", "Hoog", "Hool", "Hordar", "Horrach", "Hoygh", "Huagh", "Huru", "Jhanzur", "Jutor", "Jzets", "Kalip", "Karash", "Kol", "Korgul", "Krell", "Krusk", "Lagazi", "Lorzak", "Lubash", "Lugh", "Mimerk", "Mord", "Murook", "Nizam", "Nogu", "Nyarl", "Omotar", "Ohr", "Ohtar", "Ootah", "Orngart", "Ordich", "Oth", "Parih", "Puyet", "Puyetto", "Raorr", "Rendar", "Rheen", "Sark", "Scrag", "Sorgh", "Taing", "Tanglar", "Tarak", "Targ", "Tawar", "Thar", "Thoin", "Toemor", "Tomph", "Toop", "Trood", "Tulmak", "Tupacu", "Tzens", "Ubada", "Udhgar", "Ugarth", "Ungar", "Ungvar", "Urzad", "Vaath", "Vanchu", "Vtam", "Whudu", "Wogg", "Wogar", "Wrnach", "Wung", "Wykks", "Xar", "Xtec", "Yark", "Yazar", "Yetto", "Yurk", "Zarx", "Zotl", "Zuboko", "Dench", "Feng", "Gell", "Henk", "Holg", "Imsh", "Keth", "Krusk", "Ront", "Shump", "Thokk", "Baggi", "Emen", "Engong", "Myev", "Neega", "Ovak", "Ownka", "Shautha", "Vola", "Volen"), new Array("Achim", "Albie", "Alton", "Amabelle", "Asham", "Ashford", "Astin", "Barthony", "Beasley", "Beaswell", "Bertik", "Bertrad", "Blasco", "Bredon", "Bree", "Briley", "Burgis", "Burke", "Canty", "Carruthers", "Chandry", "Chibald", "Cibber", "Cottington", "Crowley", "Cubbardy", "Dee", "Dekker", "Dendy", "Dobb", "Drayton", "Dudney", "Dugal", "Dunleary", "Dyer", "Eldren", "Ellyot", "Eucken", "Fashi", "Fenton", "Fenwark", "Gascoyn", "Gentry", "Giles", "Googe", "Gosson", "Hesselwhite", "Hobb", "Hobbin", "Hoby", "Hodkin", "Holquiss", "Jaq", "Jenkin", "Joop", "Joost", "Kelsoe", "Kemble", "Kent", "Ketta", "Lane", "Leese", "Lidda", "Linshey", "Linton", "Lodge", "Lollard", "Ludwedge", "Lyly", "Lynwerd", "Maere", "Map", "Marlow", "Marston", "Martobee", "Mendel", "Merrick", "Merridee", "Misha", "Mosely", "Moss", "Murr", "Nashe", "Niles", "Nivers", "Norbe", "Nython", "Orlane", "Otem", "Parse", "Pence", "Penge", "Plunkett", "Pomme", "Pons", "Poole", "Quettery", "Quillan", "Quince", "Quinn", "Reene", "Reeve", "Reswald", "Ruskin", "Seldon", "Sime", "Spence", "Syler", "Talbot", "Tananger", "Taqi", "Tarby", "Tarquin", "Tasse", "Taum", "Tavi", "Tella", "Tew", "Thame", "Thorne", "Tibbs", "Tichbourne", "Tilbury", "Tillyard", "Tish", "Tobus", "Tolquist", "Tuck", "Tyldan", "Tyman", "Tyndal", "Valens", "Vaughn", "Vicars", "Wade", "Warwyck", "Wat", "Watters", "Wim", "Wyatt", "Alton", "Beau", "Cade", "Eldon", "Garret", "Lyle", "Milo", "Osborn", "Roscoe", "Wellby", "Amaryllis", "Charmaine", "Cora", "Euphemia", "Jillian", "Lavinia", "Lidda", "Merla", "Portia", "Seraphina", "Verna"));var lastNames = new Array( new Array(""), new Array("Aberdil", "Avenigart", "Breitheim", "Beilunn", "Creegan", "Druskeden", "Duril", "Fadenheim", "Frushnakt", "Fruthban", "Garenil", "Gurart", "Hartellen", "Hjortgar", "Jarevar", "Joterhun", "Korvath", "Kragenart", "Kreilun", "Letoshek", "Lovoth", "Mankathun", "Muskevart", "Naruun", "Nekaril", "Paradur", "Prosakil", "Sabreheim", "Shuldek", "Sorkol", "Taerun", "Toledun", "Turgar", "Vastek", "Voldort", "Vultheim", "Yoritak", "Zosenheim", "Balderk", "Dankil", "Gorunn", "Holderhek", "Loderr", "Lutgehr", "Rumnaheim", "Strakeln", "Torunn", "Ungart","Abrekiir", "Adarion", "Alanadel", "Calashadir", "Covakel", "Dailastacia", "Derunadel", "Filiadir", "Furivel", "Galacia", "Galenedel", "Ganatea", "Ganascient", "Ineskadel", "Jalacia", "Jemuir", "Jetenedon", "Jorudel", "Kavilion", "Keinkiir", "Kundenir", "Lanshanakiir", "Laremion", "Levanadel", "Lurecia", "Mendeliir", "Milikidel", "Muriir", "Naraskedel", "Nielecia", "Pavaliir", "Peretacia", "Praevilo", "Quilacia", "Quirion", "Saskiir", "Shailicia", "Shazemne", "Talaviir", "Valarion", "Voleyiir", "Walacia", "Whilemne", "Yanacia", "Amastacia", "Starflower", "Amakiir", "Gemflower", "Galanodel", "Moonwhisper", "Holimion", "Diamonddew", "Liadon", "Silverfrond", "Meliamne", "Oakenheel", "Naïlo", "Nightbreeze", "Siannodel", "Moonbrook", "Ilphukiir", "Gemblossom", "Xiloscient", "Goldpetal","Abren", "Aelnor", "Bachin", "Banilor", "Danask", "Durim", "Fasketel", "Furnak", "Galeb", "Grosko", "Hardin", "Hymnir", "Jarnak", "Kellen", "Kyri", "Lundor", "Merren", "Nessik", "Pernor", "Quindal", "Ranadal", "Rustek", "Rutvor", "Sasken", "Shasto", "Skerrit", "Tamble", "Terrick", "Turco", "Urvor", "Vandek", "Vilio", "Walnir", "Yimble", "Beren", "Daergel", "Folkor", "Garrick", "Nackle", "Murnig", "Ningel", "Raulnor", "Scheppen", "Turen"), new Array("Aberdil", "Avenigart", "Breitheim", "Beilunn", "Creegan", "Druskeden", "Duril", "Fadenheim", "Frushnakt", "Fruthban", "Garenil", "Gurart", "Hartellen", "Hjortgar", "Jarevar", "Joterhun", "Korvath", "Kragenart", "Kreilun", "Letoshek", "Lovoth", "Mankathun", "Muskevart", "Naruun", "Nekaril", "Paradur", "Prosakil", "Sabreheim", "Shuldek", "Sorkol", "Taerun", "Toledun", "Turgar", "Vastek", "Voldort", "Vultheim", "Yoritak", "Zosenheim", "Balderk", "Dankil", "Gorunn", "Holderhek", "Loderr", "Lutgehr", "Rumnaheim", "Strakeln", "Torunn", "Ungart"), new Array("Abrekiir", "Adarion", "Alanadel", "Calashadir", "Covakel", "Dailastacia", "Derunadel", "Filiadir", "Furivel", "Galacia", "Galenedel", "Ganatea", "Ganascient", "Ineskadel", "Jalacia", "Jemuir", "Jetenedon", "Jorudel", "Kavilion", "Keinkiir", "Kundenir", "Lanshanakiir", "Laremion", "Levanadel", "Lurecia", "Mendeliir", "Milikidel", "Muriir", "Naraskedel", "Nielecia", "Pavaliir", "Peretacia", "Praevilo", "Quilacia", "Quirion", "Saskiir", "Shailicia", "Shazemne", "Talaviir", "Valarion", "Voleyiir", "Walacia", "Whilemne", "Yanacia", "Amastacia", "Starflower", "Amakiir", "Gemflower", "Galanodel", "Moonwhisper", "Holimion", "Diamonddew", "Liadon", "Silverfrond", "Meliamne", "Oakenheel", "Naïlo", "Nightbreeze", "Siannodel", "Moonbrook", "Ilphukiir", "Gemblossom", "Xiloscient", "Goldpetal"), new Array("Abren", "Aelnor", "Bachin", "Banilor", "Danask", "Durim", "Fasketel", "Furnak", "Galeb", "Grosko", "Hardin", "Hymnir", "Jarnak", "Kellen", "Kyri", "Lundor", "Merren", "Nessik", "Pernor", "Quindal", "Ranadal", "Rustek", "Rutvor", "Sasken", "Shasto", "Skerrit", "Tamble", "Terrick", "Turco", "Urvor", "Vandek", "Vilio", "Walnir", "Yimble", "Beren", "Daergel", "Folkor", "Garrick", "Nackle", "Murnig", "Ningel", "Raulnor", "Scheppen", "Turen"), new Array(""), new Array("Brushgather", "Goodbarrel", "Greenbottle", "Highhill", "Hilltopple", "Leagallow", "Tealeaf", "Thorngage", "Tosscobble", "Underbough"));var HDranges = new Array(12,6,8,8,10,8,10,8,6,4,4, 6,8,4,6,8);var gpLimitResults = new Array(40, 100, 200, 800, 3000, 15000, 40000, 100000); var commModResults = new Array(-3,-2,-1,0,3,6,9,12);var numPowerCtrsResults = new Array(1,1,1,1,1,2,3,4);var popMin = new Array(20,81,401,901,2001,5001,12001,25001);var popRange = new Array (61,320,500,1100,3000,7000,13000,25000);var levelMin = new Array (1,1,1,1,1,1,1,1,1,1,1, 1,1,4,3,2);var levelRange = new Array(4,6,6,6,8,4,3,3,8,4,4, 6,4,13,10,7);var size = sizeResults[random(100)];var ecm = ECMResults[size];var gplimit = gpLimitResults[size];var comm_mod = commModResults[size];var numpowerctrs = numPowerCtrsResults[size];var powerctrtypes = new Array();var powerctralignments = new Array();var population = popMin[size] + random(popRange[size]);var assets = Math.floor( gplimit * population / 20 );var guards = Math.floor( population / 100 );var militia = Math.floor( population / 20 );var l, m, n, p, q, r; //loop countersvar classes = new Array();var levels = new Array();var races = new Array();var baseraces = new Array();var alignments = new Array();var HP = new Array();var fnames = new Array();var lnames = new Array();var heights = new Array();var weights = new Array();var genders = new Array();var ages = new Array();var traits = new Array();var abils = new Array(new Array(), new Array(), new Array(), new Array(), new Array(), new Array());var elitePrimaryAbils = new Array(0,5,4,4,0,0,5,4,1,5,3); // nonelites' abilities are put in order rolledvar leftoverDistro = new Array(0.005,0.005,0.91,0.03,0.05);var racialMix;l=random(10)+size; // d10-1 modified by size categoryif (l >= 10) racialMix = 2; //integrated on a result of 10 or higher else if (l >= 8) racialMix = 1; //mixed on a result of 8 or 9else racialMix = 0; //isolated on a result of 7 or lowervar domRace = random(7); // pick a PHB race at random to be dominantif (racialMix > 0 && domRace == 1) domRace = 0; // all dwarven communities are isolated, but more human communities are integrated or mixedfor (n=0; n < numpowerctrs; n++) { var roll = random(20) + size; // sizes are offset by +1, but random(20) is offset by -1 since it's 0..19 instead of 1..20 if (roll <= 13) { powerctrtypes[n] = "Conventional"; if (random(20) == 0) { numpowerctrs++; n++; powerctrtypes[n] = "Monstrous"; } } else if (roll >= 19) powerctrtypes[n] = "Magical ("+(random(2)?"arcane)":"divine)"); else powerctrtypes[n] = "Nonstandard";}for (n=0; n < numpowerctrs; n++) { powerctralignments[n] = alignmentResults[random(100)];}var nextNPC = 0;//ELITE NPC GENERATIONfor (l=1; l<=numPowerCtrsResults[size]; l++) {for (m=0; m<11; m++) { var highestLevel = 1 + random(levelRange[m]) + comm_mod; if (size < 2 && (m == 3 || m == 7) && random(20) == 0) highestLevel += 10; // occasionally thorps and hamlets have high-level druids or rangers if (highestLevel >= 1) { var numAtThisLevel = 1; for (n=highestLevel; n>=1; n=half(n)) { for (p=0; p < numAtThisLevel; p++) { classes[nextNPC] = m; levels[nextNPC] = n; if (preferredAlignments[m] >= 0 && random(2) == 0) { // if there's a preferred alignment, use it 50% of the time alignments[nextNPC] = preferredAlignments[m]; } else { do { alignments[nextNPC] = random(9); } while (allowedAlignments[m][alignments[nextNPC]] == 0); // roll randomly until we get an allowed alignment for this class } if ((random(10) + 3*racialMix) >= 9) // use NPC tables 10% of time in isolated communities, 40% in mixed, 70% in integrated { q=Math.random(); for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][m][r]) { races[nextNPC] = r; r=58; // stop the for loop early } } if (raceNeedsBaseCreature[races[nextNPC]] > 0) { // race is a template, generate a base creature do { q=Math.random(); for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][m][r]) { baseraces[nextNPC] = r; r=58; // stop the for loop early } } } while (raceNeedsBaseCreature[baseraces[nextNPC]] > 0); // make sure the "base creature" isn't another template } else baseraces[nextNPC] = 57; // use the "nothing" element for the base creature } else { q=Math.random(); if ( q < racialCumDistroNormal[racialMix][0] ) races[nextNPC] = domRace; else if (q < racialCumDistroNormal[racialMix][1]) { if ( domRace == 0 ) races[nextNPC] = 6; //halfling else races[nextNPC] = 0; //human } else if (q < racialCumDistroNormal[racialMix][2]) { if ( domRace == 0 || domRace == 6) races[nextNPC] = 2; //elf else races[nextNPC] = 6; //halfling } else if (q < racialCumDistroNormal[racialMix][3]) { if ( domRace == 0 || domRace == 6 || domRace == 2 ) races[nextNPC] = 1; //dwarf else races[nextNPC] = 2; //elf } else if (q < racialCumDistroNormal[racialMix][4]) { if ( domRace <= 2 || domRace == 6 ) races[nextNPC] = 3; //gnome else races[nextNPC] = 1; //dwarf } else if (q < racialCumDistroNormal[racialMix][5]) { if ( domRace <= 3 || domRace == 6 ) races[nextNPC] = 4; //half-elf else races[nextNPC] = 3; //gnome } else { if ( domRace <= 4) // exception: elf-dominated towns have no half-orcs races[nextNPC] = 5; //half-orc else if (domRace == 5 || domRace == 6) races[nextNPC] = 4; //half-elf else // non-PHB dominant race races[nextNPC] = random(2)+4; // half-elf or half-orc, equal prob } baseraces[nextNPC] = 57; // no template, so no base race } levels[nextNPC] += racialLA[races[nextNPC]] + racialLA[baseraces[nextNPC]]; if (levels[nextNPC] > 20) levels[nextNPC] = 20; // apply cap AFTER racial LA if (levels[nextNPC] < 1) levels[nextNPC] = 1; for (q=0; q<6; q++) { var rolls = new Array(random(6), random(6), random(6), random(6)); // roll 4d6 [-4] var lowroll = 5, sumrolls = 0; for (r=0; r<4; r++) { if (rolls[r] < lowroll) lowroll = rolls[r]; //find the lowest sumrolls += rolls[r]; } abils[q][nextNPC] = sumrolls - lowroll + 3; // drop the lowest and compensate for the offset } for (q=0; q<6; q++) { if ( abils[q][nextNPC] > abils[elitePrimaryAbils[m]][nextNPC] ) //swap them, primary should be highest { r = abils[elitePrimaryAbils[m]][nextNPC]; abils[elitePrimaryAbils[m]][nextNPC] = abils[q][nextNPC]; abils[q][nextNPC] = r; } } if (raceBaseAges[races[nextNPC]] >= 0) { ages[nextNPC] = raceBaseAges[races[nextNPC]]; // starting age r = levels[nextNPC]/2 + 0.5; r*= raceAgeMods[classAgeModSelectors[m]][races[nextNPC]]; // choose age mod by race: this is number of d6s to roll for age for (q=0; q<r; q++) { ages[nextNPC] += random(6) + 1; } ages[nextNPC] += Math.round((random(6) + 1) * (r % 1)); // handle fractional die if there is one if (ages[nextNPC] >= raceMilestoneAges[0][races[nextNPC]] ) { // middle age: -1 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]--; abils[1][nextNPC]--; abils[2][nextNPC]--; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[1][races[nextNPC]] ) { // old age: further -2 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=2; abils[1][nextNPC]-=2; abils[2][nextNPC]-=2; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[2][races[nextNPC]] ) { // venerable age: further -3 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=3; abils[1][nextNPC]-=3; abils[2][nextNPC]-=3; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } } else if (raceBaseAges[baseraces[nextNPC]] >= 0) { ages[nextNPC] = raceBaseAges[baseraces[nextNPC]]; // starting age r = levels[nextNPC]/2 + 0.5; r*= raceAgeMods[classAgeModSelectors[m]][baseraces[nextNPC]]; // choose age mod by base race: this is number of d6s to roll for age for (q=0; q<r; q++) { ages[nextNPC] += random(6) + 1; } ages[nextNPC] += Math.round((random(6) + 1) * (r % 1)); // handle fractional die if there is one if (ages[nextNPC] >= raceMilestoneAges[0][baseraces[nextNPC]] ) { // middle age: -1 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]--; abils[1][nextNPC]--; abils[2][nextNPC]--; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[1][baseraces[nextNPC]] ) { // old age: further -2 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=2; abils[1][nextNPC]-=2; abils[2][nextNPC]-=2; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[2][baseraces[nextNPC]] ) { // venerable age: further -3 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=3; abils[1][nextNPC]-=3; abils[2][nextNPC]-=3; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } } else ages[nextNPC] = "?"; for (q=0; q<6; q++) { // apply racial abil adjs abils[q][nextNPC] += racialAbilAdjs[races[nextNPC]][q] + racialAbilAdjs[baseraces[nextNPC]][q]; if (abils[q][nextNPC] < 1) abils[q][nextNPC] = 1; // all abilities are always at least 1 } if (abils[3][nextNPC] < 3) abils[3][nextNPC] = 3; // Int is always at least 3 abils[elitePrimaryAbils[m]][nextNPC] += Math.floor (n/4); // ability score increase every 4 levels HP[nextNPC] = HDranges[m] + Math.floor (abils[2][nextNPC]/2 - 5); // max the first HD if (n > 1) { for (q=1; q<levels[nextNPC]; q++) { HP[nextNPC] += random(HDranges[m]) + Math.floor (abils[2][nextNPC]/2 - 4); // -4 instead of -5 compensates for the offset } } if (racialHDcounts[races[nextNPC]]>0) { r = (raceNeedsBaseCreature[baseraces[nextNPC]] == 2 ) ? 10 : 8; //some templates raise racial HD to d10s for (q=0; q<racialHDcounts[races[nextNPC]]; q++) { HP[nextNPC] += random(r) + Math.floor (abils[2][nextNPC]/2 - 4); } } if (racialHDcounts[baseraces[nextNPC]]>0) { for (q=0; q<racialHDcounts[baseraces[nextNPC]]; q++) { HP[nextNPC] += random(8) + Math.floor (abils[2][nextNPC]/2 - 4); } } r = levels[nextNPC]+racialHDcounts[races[nextNPC]]+racialHDcounts[baseraces[nextNPC]]; if (HP[nextNPC] < r) HP[nextNPC] = r; //always at least 1 HP per level/HD genders[nextNPC] = random(2); if (raceBaseHeights[0][races[nextNPC]] == -1) { q = 2 + random(raceHeightMods[baseraces[nextNPC]]) + random(raceHeightMods[baseraces[nextNPC]]); r = raceBaseHeights[genders[nextNPC]][baseraces[nextNPC]] + q; } else { q = 2 + random(raceHeightMods[races[nextNPC]]) + random(raceHeightMods[races[nextNPC]]); // height modifier, used to calculate weight r = raceBaseHeights[genders[nextNPC]][races[nextNPC]] + q; } heights[nextNPC] = Math.floor(r/12) + "\'" + (r % 12) + "\""; if ( raceMinWeightMods[races[nextNPC]] == -1 ) { if ( raceMinWeightMods[baseraces[nextNPC]] == -1 ) { weights[nextNPC] = "?"; } else { r = raceMinWeightMods[baseraces[nextNPC]] + random(raceMaxWeightMods[baseraces[nextNPC]] - raceMinWeightMods[baseraces[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][baseraces[nextNPC]] + r; } } else { r = raceMinWeightMods[races[nextNPC]] + random(raceMaxWeightMods[races[nextNPC]] - raceMinWeightMods[races[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][races[nextNPC]] + r; } traits[nextNPC] = ""; for( q = 0; q < traitResults.length; q++) { if (random(100) == 0 ) { if( traits[nextNPC] != "" ) traits[nextNPC] += "; "; traits[nextNPC] += traitResults[q][random(traitResults[q].length)]; } } if (nameSelector[races[nextNPC]] == -1 ) { fnames[nextNPC] = firstNames[nameSelector[baseraces[nextNPC]]][random(firstNames[nameSelector[baseraces[nextNPC]]].length)]; if (random(2)) lnames[nextNPC] = lastNames[nameSelector[baseraces[nextNPC]]][random(lastNames[nameSelector[baseraces[nextNPC]]].length)]; else lnames[nextNPC] = ""; } else { fnames[nextNPC] = firstNames[nameSelector[races[nextNPC]]][random(firstNames[nameSelector[races[nextNPC]]].length)]; if (random(2)) lnames[nextNPC] = lastNames[nameSelector[races[nextNPC]]][random(lastNames[nameSelector[races[nextNPC]]].length)]; else lnames[nextNPC] = ""; } nextNPC++; } numAtThisLevel *= 2; } }}//LEVEL 2+ NONELITE NPC GENERATIONfor (m=11; m<16; m++) { var highestLevel = levelMin[m] + random(levelRange[m]) + comm_mod; if (highestLevel >= 2) { var numAtThisLevel = 1; for (n=highestLevel; n>=2; n=half(n)) { for (p=0; p < numAtThisLevel; p++) { classes[nextNPC] = m; levels[nextNPC] = n; if (levels[nextNPC] > 20) levels[nextNPC] = 20; // apply cap AFTER generating lower-level characters alignments[nextNPC] = random(2)?random(9):powerctralignments[random(numpowerctrs)]; // use the alignment of a power center half the time if ((random(100) + racialMix) >= 99) // use NPC tables 1% of time in isolated communities, 2% in mixed, 3% in integrated { q=Math.random(); var c = random(11); // choose a random PC class to base the race off for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][c][r]) { races[nextNPC] = r; r=58; // stop the for loop early } } if (raceNeedsBaseCreature[races[nextNPC]] > 0) { // race is a template, generate a base creature do { q=Math.random(); for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][c][r]) { baseraces[nextNPC] = r; r=58; // stop the for loop early } } } while (raceNeedsBaseCreature[baseraces[nextNPC]] > 0); // make sure the "base creature" isn't another template } else baseraces[nextNPC] = 57; // use the "nothing" element for the base creature } else { q=Math.random(); if ( q < racialCumDistroNormal[racialMix][0] ) races[nextNPC] = domRace; else if (q < racialCumDistroNormal[racialMix][1]) { if ( domRace == 0 ) races[nextNPC] = 6; //halfling else races[nextNPC] = 0; //human } else if (q < racialCumDistroNormal[racialMix][2]) { if ( domRace == 0 || domRace == 6) races[nextNPC] = 2; //elf else races[nextNPC] = 6; //halfling } else if (q < racialCumDistroNormal[racialMix][3]) { if ( domRace == 0 || domRace == 6 || domRace == 2 ) races[nextNPC] = 1; //dwarf else races[nextNPC] = 2; //elf } else if (q < racialCumDistroNormal[racialMix][4]) { if ( domRace <= 2 || domRace == 6 ) races[nextNPC] = 3; //gnome else races[nextNPC] = 1; //dwarf } else if (q < racialCumDistroNormal[racialMix][5]) { if ( domRace <= 3 || domRace == 6 ) races[nextNPC] = 4; //half-elf else races[nextNPC] = 3; //gnome } else { if ( domRace <= 4) // exception: elf-dominated towns have no half-orcs races[nextNPC] = 5; //half-orc else if (domRace == 5 || domRace == 6) races[nextNPC] = 4; //half-elf else // non-PHB dominant race races[nextNPC] = random(2)+4; // half-elf or half-orc, equal prob } baseraces[nextNPC] = 57; // no template, so no base race } if (raceBaseAges[races[nextNPC]] >= 0) { ages[nextNPC] = raceBaseAges[races[nextNPC]] + random( raceMilestoneAges[0][races[nextNPC]] - raceBaseAges[races[nextNPC]]); // starting age r = (levels[nextNPC] - 1) * raceAgeMods[classAgeModSelectors[m]][races[nextNPC]]; // choose age mod by race: this is number of d6s to roll for age for (q=0; q<r; q++) { ages[nextNPC] += random(6) + 1; } ages[nextNPC] += Math.round((random(6) + 1) * (r % 1)); // handle fractional die if there is one if (ages[nextNPC] >= raceMilestoneAges[0][races[nextNPC]] ) { // middle age: -1 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]--; abils[1][nextNPC]--; abils[2][nextNPC]--; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[1][races[nextNPC]] ) { // old age: further -2 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=2; abils[1][nextNPC]-=2; abils[2][nextNPC]-=2; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[2][races[nextNPC]] ) { // venerable age: further -3 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=3; abils[1][nextNPC]-=3; abils[2][nextNPC]-=3; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } } else if (raceBaseAges[baseraces[nextNPC]] >= 0) { ages[nextNPC] = raceBaseAges[baseraces[nextNPC]] + random( raceMilestoneAges[0][baseraces[nextNPC]] - raceBaseAges[baseraces[nextNPC]]); // starting age r = (levels[nextNPC] - 1) * raceAgeMods[classAgeModSelectors[m]][baseraces[nextNPC]]; // choose age mod by base race: this is number of d6s to roll for age for (q=0; q<r; q++) { ages[nextNPC] += random(6) + 1; } ages[nextNPC] += Math.round((random(6) + 1) * (r % 1)); // handle fractional die if there is one if (ages[nextNPC] >= raceMilestoneAges[0][baseraces[nextNPC]] ) { // middle age: -1 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]--; abils[1][nextNPC]--; abils[2][nextNPC]--; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[1][baseraces[nextNPC]] ) { // old age: further -2 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=2; abils[1][nextNPC]-=2; abils[2][nextNPC]-=2; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } if (ages[nextNPC] >= raceMilestoneAges[2][baseraces[nextNPC]] ) { // venerable age: further -3 Str,Dex,Con, +1 Int,Wis,Cha abils[0][nextNPC]-=3; abils[1][nextNPC]-=3; abils[2][nextNPC]-=3; abils[3][nextNPC]++; abils[4][nextNPC]++; abils[5][nextNPC]++; } } else ages[nextNPC] = "?"; for (q=0; q<6; q++) { abils[q][nextNPC] = random(6) + random(6) + random(6) + 3; // 3d6 } for (q=0; q<6; q++) { // apply racial abil adjs abils[q][nextNPC] += racialAbilAdjs[races[nextNPC]][q] + racialAbilAdjs[baseraces[nextNPC]][q]; if (abils[q][nextNPC] < 1) abils[q][nextNPC] = 1; // all abilities are always at least 1 } if (abils[3][nextNPC] < 3) abils[3][nextNPC] = 3; // Int is always at least 3 // increase a random stat every 4 levels if (n >= 4) { for (q=1; q<=levels[nextNPC]/4; q++) { abils[random(6)][nextNPC]++; } } HP[nextNPC] = 0; for (q=0; q<levels[nextNPC]; q++) { HP[nextNPC] += random(HDranges[m]) + Math.floor (abils[2][nextNPC]/2) - 4; // -4 instead of -5 compensates for the offset } if (HP[nextNPC] < levels[nextNPC]) HP[nextNPC] = levels[nextNPC]; //always at least 1 HP per level genders[nextNPC] = random(2); if (raceBaseHeights[0][races[nextNPC]] == -1) { q = 2 + random(raceHeightMods[baseraces[nextNPC]]) + random(raceHeightMods[baseraces[nextNPC]]); r = raceBaseHeights[genders[nextNPC]][baseraces[nextNPC]] + q; } else { q = 2 + random(raceHeightMods[races[nextNPC]]) + random(raceHeightMods[races[nextNPC]]); // height modifier, used to calculate weight r = raceBaseHeights[genders[nextNPC]][races[nextNPC]] + q; } heights[nextNPC] = Math.floor(r/12) + "\'" + (r % 12) + "\""; if ( raceMinWeightMods[races[nextNPC]] == -1 ) { if ( raceMinWeightMods[baseraces[nextNPC]] == -1 ) { weights[nextNPC] = "?"; } else { r = raceMinWeightMods[baseraces[nextNPC]] + random(raceMaxWeightMods[baseraces[nextNPC]] - raceMinWeightMods[baseraces[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][baseraces[nextNPC]] + r; } } else { r = raceMinWeightMods[races[nextNPC]] + random(raceMaxWeightMods[races[nextNPC]] - raceMinWeightMods[races[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][races[nextNPC]] + r; } traits[nextNPC] = ""; for( q = 0; q < traitResults.length; q++) { if (random(100) == 0 ) { if( traits[nextNPC] != "" ) traits[nextNPC] += "; "; traits[nextNPC] += traitResults[q][random(traitResults[q].length)]; } } if (nameSelector[races[nextNPC]] == -1 ) { fnames[nextNPC] = firstNames[nameSelector[baseraces[nextNPC]]][random(firstNames[nameSelector[baseraces[nextNPC]]].length)]; if ((random(10) + 3*(m==12) - 3*(m==13)) >= 5) lnames[nextNPC] = lastNames[nameSelector[baseraces[nextNPC]]][random(lastNames[nameSelector[baseraces[nextNPC]]].length)]; else lnames[nextNPC] = ""; } else { fnames[nextNPC] = firstNames[nameSelector[races[nextNPC]]][random(firstNames[nameSelector[races[nextNPC]]].length)]; if ((random(10) + 3*(m==12) - 3*(m==13)) >= 5) lnames[nextNPC] = lastNames[nameSelector[races[nextNPC]]][random(lastNames[nameSelector[races[nextNPC]]].length)]; else lnames[nextNPC] = ""; } nextNPC++; } numAtThisLevel *= 2; } }}}if (nextNPC < population ) { // LEVEL-1 NONELITE NPC GENERATION var num = new Array(); //holds numbers of leftover NPCs for (m=0; m<5; m++) { num[m] = Math.round(leftoverDistro[m] * (population - nextNPC)); } num[2] = population - nextNPC - num[0] - num[1] - num[3] - num[4]; // adjust the number of commoners to make sure the final population is exact for (m=0; m<5; m++) { if (num[m] > 0) { for (p=0; p < num[m]; p++) { classes[nextNPC] = m+11; levels[nextNPC] = 1; alignments[nextNPC] = random(2)?random(9):powerctralignments[random(numpowerctrs)]; // use the alignment of a power center half the time if ((random(100) + racialMix) >= 99) // use NPC tables 1% of time in isolated communities, 2% in mixed, 3% in integrated { q=Math.random(); var c = random(11); // choose a random PC class to base the race off for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][c][r]) { races[nextNPC] = r; r=58; // stop the for loop early } } if (raceNeedsBaseCreature[races[nextNPC]] > 0) { // race is a template, generate a base creature do { q=Math.random(); for (r=0; r<57; r++) { if (q<=racialCumDistroHero[Math.floor(alignments[nextNPC]/3)][c][r]) { baseraces[nextNPC] = r; r=58; // stop the for loop early } } } while (raceNeedsBaseCreature[baseraces[nextNPC]] > 0); // make sure the "base creature" isn't another template } else baseraces[nextNPC] = 57; // use the "nothing" element for the base creature } else { q=Math.random(); if ( q < racialCumDistroNormal[racialMix][0] ) { races[nextNPC] = domRace; } else if (q < racialCumDistroNormal[racialMix][1]) { if ( domRace == 0 ) races[nextNPC] = 6; //halfling else races[nextNPC] = 0; //human } else if (q < racialCumDistroNormal[racialMix][2]) { if ( domRace == 0 || domRace == 6) races[nextNPC] = 2; //elf else races[nextNPC] = 6; //halfling } else if (q < racialCumDistroNormal[racialMix][3]) { if ( domRace == 0 || domRace == 6 || domRace == 2 ) races[nextNPC] = 1; //dwarf else races[nextNPC] = 2; //elf } else if (q < racialCumDistroNormal[racialMix][4]) { if ( domRace <= 2 || domRace == 6 ) races[nextNPC] = 3; //gnome else races[nextNPC] = 1; //dwarf } else if (q < racialCumDistroNormal[racialMix][5]) { if ( domRace <= 3 || domRace == 6 ) races[nextNPC] = 4; //half-elf else races[nextNPC] = 3; //gnome } else { if ( domRace <= 4) // exception: elf-dominated towns have no half-orcs races[nextNPC] = 5; //half-orc else if (domRace == 5 || domRace == 6) races[nextNPC] = 4; //half-elf else // non-PHB dominant race races[nextNPC] = random(2)+4; // half-elf or half-orc, equal prob } baseraces[nextNPC] = 57; // no template, so no base race } if ( raceBaseAges[races[nextNPC]] >= 0 ) { ages[nextNPC] = raceBaseAges[races[nextNPC]] + random( raceMilestoneAges[0][races[nextNPC]] - raceBaseAges[races[nextNPC]]); //set NPC anywhere from threshold of adulthood to just shy of middle age } else if ( raceBaseAges[baseraces[nextNPC]] >= 0 ) { ages[nextNPC] = raceBaseAges[baseraces[nextNPC]] + random( raceMilestoneAges[0][baseraces[nextNPC]] - raceBaseAges[baseraces[nextNPC]]); } else ages[nextNPC] = "?"; for (q=0; q<6; q++) { abils[q][nextNPC] = random(6) + random(6) + random(6) + 3; // 3d6 } for (q=0; q<6; q++) { // apply racial abil adjs abils[q][nextNPC] += racialAbilAdjs[races[nextNPC]][q] + racialAbilAdjs[baseraces[nextNPC]][q]; if (abils[q][nextNPC] < 1) abils[q][nextNPC] = 1; // all abilities are always at least 1 } if (abils[3][nextNPC] < 3) abils[3][nextNPC] = 3; // Int is always at least 3 HP[nextNPC] = random(HDranges[11+m]) + Math.floor (abils[2][nextNPC]/2) - 4; // -4 instead of -5 compensates for the offset if (HP[nextNPC] < 1) HP[nextNPC] = 1; // always at least 1 HP genders[nextNPC] = random(2); if (raceBaseHeights[0][races[nextNPC]] == -1) { q = 2 + random(raceHeightMods[baseraces[nextNPC]]) + random(raceHeightMods[baseraces[nextNPC]]); r = raceBaseHeights[genders[nextNPC]][baseraces[nextNPC]] + q; } else { q = 2 + random(raceHeightMods[races[nextNPC]]) + random(raceHeightMods[races[nextNPC]]); // height modifier, used to calculate weight r = raceBaseHeights[genders[nextNPC]][races[nextNPC]] + q; } heights[nextNPC] = Math.floor(r/12) + "\'" + (r % 12) + "\""; if ( raceMinWeightMods[races[nextNPC]] == -1 ) { if ( raceMinWeightMods[baseraces[nextNPC]] == -1 ) { weights[nextNPC] = "?"; } else { r = raceMinWeightMods[baseraces[nextNPC]] + random(raceMaxWeightMods[baseraces[nextNPC]] - raceMinWeightMods[baseraces[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][baseraces[nextNPC]] + r; } } else { r = raceMinWeightMods[races[nextNPC]] + random(raceMaxWeightMods[races[nextNPC]] - raceMinWeightMods[races[nextNPC]] + 1); // weight modifier-multiplier r *= q; weights[nextNPC] = raceBaseWeights[genders[nextNPC]][races[nextNPC]] + r; } traits[nextNPC] = ""; for( q = 0; q < traitResults.length; q++) { if (random(100) == 0 ) { if( traits[nextNPC] != "" ) traits[nextNPC] += "; "; traits[nextNPC] += traitResults[q][random(traitResults[q].length)]; } } if (nameSelector[races[nextNPC]] == -1 ) { fnames[nextNPC] = firstNames[nameSelector[baseraces[nextNPC]]][random(firstNames[nameSelector[baseraces[nextNPC]]].length)]; if ((random(10) + 3*(m==12) - 3*(m==13)) >= 5) lnames[nextNPC] = lastNames[nameSelector[baseraces[nextNPC]]][random(lastNames[nameSelector[baseraces[nextNPC]]].length)]; else lnames[nextNPC] = ""; } else { fnames[nextNPC] = firstNames[nameSelector[races[nextNPC]]][random(firstNames[nameSelector[races[nextNPC]]].length)]; if ((random(10) + 3*(m==12) - 3*(m==13)) >= 5) lnames[nextNPC] = lastNames[nameSelector[races[nextNPC]]][random(lastNames[nameSelector[races[nextNPC]]].length)]; else lnames[nextNPC] = ""; } nextNPC++; } } }}if (nextNPC > population) population=nextNPC; // can sometimes happen in thorps</script><style type="text/css"> th.label { text-align: left; } th td { text-align: center; border: 1px solid #999999; } .alternate { background-color: #cccccc; } td.number { text-align: right; } td.smalltext { font-size: 50%; } td.feetinches { text-align: "\'"; } colgroup, table { border: 4px ridge #000000; } table { border-collapse: collapse; } tr.rowheader { border-bottom: 4px ridge #000000; }</style></head><body><h1>City</h1><h2>Vital Statistics</h2><table border="1px"><tr class="alternate"><th class="label">Adult Population</th><td class="number"><script language="javascript">document.write(population);</script></td></tr><tr><th class="label">GP Limit</th><td class="number"><script language="javascript">document.write(gplimit);</script> gp</td></tr><tr class="alternate"><th class="label">Asset Limit</th><td class="number"><script language="javascript">document.write(assets);</script> gp</td></tr><tr><th class="label">Encounter Check Modifier</th><td class="number">+<script language="javascript">document.write(ecm);</script></td></tr></table><h2>Power Centers</h2><table border="1px"><tr class="alternate rowheader"><th>Type</th><th>Alignment</th><script language="javascript">for (n=0; n< numpowerctrs; n++) { document.write("<tr"+(n%2?" class='alternate'":"")+"><td>"+powerctrtypes[n]+"</td><td>"+alignmentNames[powerctralignments[n]]+"</td></tr>");}</script></table><h2>Armed Forces</h2><table border="1px"><tr class="alternate"><th class="label">Guards or Regular Soldiers</th><td class="number"><script language="javascript">document.write(guards);</script></td></tr><tr><th class="label">Militia</th><td class="number"><script language="javascript">document.write(militia);</script></td></tr></table><h2>NPCs</h2><table border="1px" style="font-size: 75%"><colgroup span=2/><colgroup span=2/><colgroup span=2/><colgroup span=1/><colgroup span=1/><colgroup span=6/><colgroup span=3/><tr class="alternate rowheader"><th>Last name</th><th>First name</th><th>Race</th><th>S</th><th>Class</th><th>Lvl</th><th>Al</th><th>HP</th><th>Str</th><th>Dex</th><th>Con</th><th>Int</th><th>Wis</th><th>Cha</th><th>Ht</th><th>Wt</th><th>Age</th><th>Traits</th><script language="javascript">for (n=0; n < population; n++) { document.write("<tr"+(n%2?" class='alternate'":"")+"><td>"+lnames[n]+"</td><td>"+fnames[n]+ "</td><td style='width: 15em'>"+raceNames[races[n]]+raceNames[baseraces[n]]+"</td><td>"+(genders[n]?"F":"M")+"</td><td>"+classNames[classes[n]]+"</td><td class='number'>"+levels[n]+"</td><td>"+alignmentNames[alignments[n]]+"<td class='number'>"+HP[n]+"</td>"); for (p=0; p <= 5; p++) { document.write("<td class='number'>"+abils[p][n]+"</td>"); } document.write("<td class='feetinches'>"+heights[n]+"</td><td class='number'>"+weights[n]+"</td><td class='number'>"+ages[n]+"<td>"+traits[n]+"</td></tr>");}</script></table></body></html>