I wrote this script to build characters for my World War Cthulhu game. The original version goes all the way through without user involvement, generates all the elements and puts them into a character sheet and a handout with further instructions.
The idea for this version is to allow the player to roll the various sections and write the results to the chat. They can then reroll until they are satisfied and the final selection will be saved to a character sheet. The results are written to the screen. The saving part isn't done yet.
The problem I'm having now, is other than generating the stats, all the other options, which are table rolls, always come up as undefined the first time. If you do it again, you get a result, but not the first time.
Suggestions?
/** * Generates World War Cthulhu Characters * * Syntax: !WWCGen option * */ var WWCGen = WWCGen || { version: "0.0.4", output: [], listen: function () { on('chat:message', function (msg) { // Exit if not an api command if (msg.type != "api") { return; } switch (msg.content) { case '!GenStats': WWCGen.GenStats(msg); break; case '!GenNationality': WWCGen.GenNationality(msg); break; case '!GenUpbringing': WWCGen.GenUpbringing(msg); break; case '!GenPersonality': WWCGen.GenPersonality(msg); break; case '!GenPreWar': WWCGen.GenPreWar(msg); break; case '!GenMilServ': WWCGen.GenMilServ(msg); break; case '!GenEncounter': WWCGen.GenEncounter(msg); break; case '!GenRecruitment': WWCGen.GenRecruitment(msg); break; case '!GenIncome': WWCGen.GenIncome(msg); break; default: WWCGen.showHelp(); } } ); }, showHelp: function () { sendChat("API", "/direct <table style='background: #DCD9D5; border-radius: 20px; font-size: 10px;'>" + "<thead><tr><th>Help</th></tr></thead>" + "<tbody>" + "<tr><td><strong>!WWCGen</strong><br><strong>!fodder help</strong><br>Show this help screen.</td></tr>" + "<tr><td><strong>!WWCGen core</strong><br>Runs the script.</td></tr>" + "<tr><td> </td></tr>" + "</td></tr></tbody></table>"); }, GenStats: function (msg) { WWCGen.STR_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.CON_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.POW_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.DEX_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.APP_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.SIZ_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.INT_roll = randomInteger(6) + randomInteger(6) + 6; WWCGen.EDU_roll = randomInteger(6) + randomInteger(6) + randomInteger(6) + 6; WWCGen.STR = WWCGen.STR_roll * 5; WWCGen.CON = WWCGen.CON_roll * 5; WWCGen.POW = WWCGen.POW_roll * 5; WWCGen.DEX = WWCGen.DEX_roll * 5; WWCGen.APP = WWCGen.APP_roll * 5; WWCGen.SIZ = WWCGen.SIZ_roll * 5; WWCGen.INT = WWCGen.INT_roll * 5; WWCGen.EDU = WWCGen.EDU_roll * 5; WWCGen.SAN = WWCGen.POW_roll * 5; x = (WWCGen.CON_roll + WWCGen.SIZ_roll) / 2; WWCGen.HP = parseInt(x); WWCGen.MP = WWCGen.POW_roll; WWCGen.Age = WWCGen.EDU_roll + 6; WWCGen.MOV = 8; WWCGen.PER = WWCGen.INT_roll * 10; WWCGen.OCC = WWCGen.EDU_roll * 20; WWCGen.DODGE = WWCGen.DEX_roll * 2; WWCGen.RADIO = WWCGen.INT_roll * 2; WWCGen.LO = WWCGen.EDU_roll * 5; WWCGen.CR = WWCGen.APP_roll; d = (WWCGen.STR_roll + WWCGen.SIZ_roll) / 2; if (d <= 13) { WWCGen.DB = "-2"; } else if (d <= 17) { WWCGen.DB = "-1"; } else if (d <= 25) { WWCGen.DB = "0"; } else if (d <= 33) { WWCGen.DB = "1d4"; } else { WWCGen.DB = "1d6"; } WWCGen.output['Attributes'] = "<tr><td style='font-weight: bold; padding: 5px;'>Instructions</td><td style='padding: 5px;'>Are these values acceptable?" + "</td></tr>"; WWCGen.output['STR'] = "<tr><td style='font-weight: bold; padding: 5px;'>STR</td><td style='padding: 5px;'>" + WWCGen.STR + "</td></tr>"; WWCGen.output['CON'] = "<tr><td style='font-weight: bold; padding: 5px;'>CON</td><td style='padding: 5px;'>" + WWCGen.CON + "</td></tr>"; WWCGen.output['SIZ'] = "<tr><td style='font-weight: bold; padding: 5px;'>SIZ</td><td style='padding: 5px;'>" + WWCGen.SIZ + "</td></tr>"; WWCGen.output['DEX'] = "<tr><td style='font-weight: bold; padding: 5px;'>DEX</td><td style='padding: 5px;'>" + WWCGen.DEX + "</td></tr>"; WWCGen.output['APP'] = "<tr><td style='font-weight: bold; padding: 5px;'>APP</td><td style='padding: 5px;'>" + WWCGen.APP + "</td></tr>"; WWCGen.output['INT'] = "<tr><td style='font-weight: bold; padding: 5px;'>INT</td><td style='padding: 5px;'>" + WWCGen.INT + "</td></tr>"; WWCGen.output['POW'] = "<tr><td style='font-weight: bold; padding: 5px;'>POW</td><td style='padding: 5px;'>" + WWCGen.POW + "</td></tr>"; WWCGen.output['EDU'] = "<tr><td style='font-weight: bold; padding: 5px;'>EDU</td><td style='padding: 5px;'>" + WWCGen.EDU + "</td></tr>"; WWCGen.output['HP'] = "<tr><td style='font-weight: bold; padding: 5px;'>HP</td><td style='padding: 5px;'>" + WWCGen.HP + "</td></tr>"; WWCGen.output['MP'] = "<tr><td style='font-weight: bold; padding: 5px;'>MP</td><td style='padding: 5px;'>" + WWCGen.MP + "</td></tr>"; WWCGen.output['DB'] = "<tr><td style='font-weight: bold; padding: 5px;'>DB</td><td style='padding: 5px;'>STR+SIZ/10" + "</td></tr>"; WWCGen.output['Age'] = "<tr><td style='font-weight: bold; padding: 5px;'>Age</td><td style='padding: 5px;'>" + WWCGen.Age + "</td></tr>"; WWCGen.output['SAN'] = "<tr><td style='font-weight: bold; padding: 5px;'>SAN</td><td style='padding: 5px;'>" + WWCGen.SAN + "</td></tr>"; WWCGen.output['MOV'] = "<tr><td style='font-weight: bold; padding: 5px;'>Movement</td><td style='padding: 5px;'>" + WWCGen.MOV + "</td></tr>"; WWCText1 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['STR'] + WWCGen.output['CON'] + WWCGen.output['SIZ'] + WWCGen.output['DEX'] + WWCGen.output['APP'] + WWCGen.output['INT'] + WWCGen.output['POW'] + WWCGen.output['EDU'] + WWCGen.output['SAN'] + WWCGen.output['HP'] + WWCGen.output['MP'] + WWCGen.output['Age'] + WWCGen.output['MOV'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText1); }, GenNationality: function (msg) { sendChat("API", "/roll 1t[Nationality]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Birthplace = values[0]; WWCGen.Nationality = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Birthplace'] = "<tr><td style='font-weight: bold; padding: 5px;'>Nationality</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Birthplace + "</td></tr>"; WWCText3 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Birthplace'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText3); }, GenUpbringing: function (msg) { sendChat("API", "/roll 1t[Upbringing]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Childhood = values[0]; WWCGen.Upbringing = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Childhood'] = "<tr><td style='font-weight: bold; padding: 5px;'>Upbringing</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Childhood + "</td></tr>"; WWCText4 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Childhood'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText4); }, GenPersonality: function (msg) { sendChat("API", "/roll 1t[Personality]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Personality = values[0]; WWCGen.History = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Personality'] = "<tr><td style='font-weight: bold; padding: 5px;'>Personality</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Personality + "</td></tr>"; WWCText6 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Personality'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText6); }, GenPreWar: function (msg) { sendChat("API", "/roll 1t[Pre-War_Occupation]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.PreWar = values[0]; WWCGen.Job = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['PreWar'] = "<tr><td style='font-weight: bold; padding: 5px;'>Pre-War Occupation</td></tr><tr><td style='padding: 5px;'>" + WWCGen.PreWar + "</td></tr>"; WWCText7 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['PreWar'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText7); }, GenMilServ: function (msg) { sendChat("API", "/roll 1t[Military_Service]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Military_Service = values[0]; WWCGen.Service = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Military_Service'] = "<tr><td style='font-weight: bold; padding: 5px;'>Military Service</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Military_Service + "</td></tr>"; WWCText8 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Military_Service'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText8); }, GenEncounter: function (msg) { sendChat("API", "/roll 1t[Mythos_Encounter]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Mythos_Encounter = values[0]; WWCGen.Encounter = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Mythos_Encounter'] = "<tr><td style='font-weight: bold; padding: 5px;'>Initial Mythos Encounter</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Mythos_Encounter + "</td></tr>"; WWCText9 = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Mythos_Encounter'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCText9); }, GenRecruitment: function (msg) { sendChat("API", "/roll 1t[Reason_for_Joining]", function (result) { var content = JSON.parse(result[0].content); var values = content.rolls[0].results[0].tableItem.name.split(':'); WWCGen.Recruitment = values[0]; WWCGen.Reason_for_Joining = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Recruitment'] = "<tr><td style='font-weight: bold; padding: 5px;'>Reason for Joining</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Recruitment + "</td></tr>"; WWCTextA = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Recruitment'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCTextA); }, GenIncome: function (msg) { sendChat("API", "/roll 1t[Income]", function (result) { var content = JSON.parse(result[0].content); WWCGen.Income = content.rolls[0].results[0].tableItem.name; }); WWCGen.output['Income'] = "<tr><td style='font-weight: bold; padding: 5px;'>Income</td></tr><tr><td style='padding: 5px;'>" + WWCGen.Income + "</td></tr>"; WWCTextB = "<table font-size: 10px;'> <tbody>" + WWCGen.output['Income'] + "</tbody></table>"; sendChat(msg.who, "/direct " + WWCTextB); }, save: function (msg, saveCallback) { var handout = createObj('handout', { name: WWCGen.name + ' Instructions', inplayerjournals: "all", archived: false }); handout.set('notes', WWCPrint); // }, // save: function () { var character = createObj("character", { name: WWCGen.name, archived: false, inplayerjournals: "all", controlledby: "all" }); character.set('bio', WWCText); createObj('attribute', { name: 'player_name', current: WWCGen.player, _characterid: character.id }); createObj('attribute', { name: 'recruitment', current: WWCGen.Recruitment, _characterid: character.id }); createObj('attribute', { name: 'STR', current: WWCGen.STR, _characterid: character.id }); createObj('attribute', { name: 'CON', current: WWCGen.CON, _characterid: character.id }); createObj('attribute', { name: 'SIZ', current: WWCGen.SIZ, _characterid: character.id }); createObj('attribute', { name: 'DEX', current: WWCGen.DEX, _characterid: character.id }); createObj('attribute', { name: 'APP', current: WWCGen.APP, _characterid: character.id }); createObj('attribute', { name: 'INT', current: WWCGen.INT, _characterid: character.id }); createObj('attribute', { name: 'POW', current: WWCGen.POW, _characterid: character.id }); createObj('attribute', { name: 'EDU', current: WWCGen.EDU, _characterid: character.id }); createObj('attribute', { name: 'san', current: WWCGen.SAN, _characterid: character.id }); createObj('attribute', { name: 'hp', current: WWCGen.HP, _characterid: character.id }); createObj('attribute', { name: 'hp_max', current: WWCGen.HP, _characterid: character.id }); createObj('attribute', { name: 'mp', current: WWCGen.MP, _characterid: character.id }); createObj('attribute', { name: 'mp_Max', current: WWCGen.MP, _characterid: character.id }); createObj('attribute', { name: 'MOV', current: '8', _characterid: character.id }); createObj('attribute', { name: 'Age', current: WWCGen.Age, _characterid: character.id }); createObj('attribute', { name: 'birthplace', current: WWCGen.Birthplace, _characterid: character.id }); createObj('attribute', { name: 'dodge', current: WWCGen.DODGE, _characterid: character.id }); createObj('attribute', { name: 'language_own', current: WWCGen.LO, _characterid: character.id }); createObj('attribute', { name: 'operate_radio', current: WWCGen.RADIO, _characterid: character.id }); createObj('attribute', { name: 'credit_rating', current: WWCGen.CR, _characterid: character.id }); createObj('attribute', { name: 'Nationality', current: WWCGen.Nationality, _characterid: character.id }); createObj('attribute', { name: 'Upbringing', current: WWCGen.Upbringing, _characterid: character.id }); createObj('attribute', { name: 'Personality', current: WWCGen.Personality, _characterid: character.id }); createObj('attribute', { name: 'occupation', current: WWCGen.PreWar, _characterid: character.id }); createObj('attribute', { name: 'milserv', current: WWCGen.Military_Service, _characterid: character.id }); createObj('attribute', { name: 'mythos_encounter', current: WWCGen.Mythos_Encounter, _characterid: character.id }); createObj('attribute', { name: 'reason_for_joining', current: WWCGen.Reason_for_Joining, _characterid: character.id }); createObj('attribute', { name: 'wealth', current: WWCGen.Income, _characterid: character.id }); sendChat('', 'Created <a href="http://journal.roll20.net/character/' + character.id + '" style="color:blue;text-decoration:underline;">WWCGen ' + WWCGen.name + '</a>'); sendChat('', 'Created instructions for completing <a href="http://journal.roll20.net/handout/' + handout.id + '" style="color:blue;text-decoration:underline;">WWCGen ' + WWCGen.name + '</a>'); } }; on("ready", function () { WWCGen.listen(); });