Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script and Extension] Purple20 launches with Crawler Companion support

1704041944

Edited 1704054455
Z
Pro
Hello and Happy New Year!&nbsp;&nbsp; Long-time listener, first-time caller.&nbsp; I'm releasing an extension / script pair that I wrote to support my group's desire to integrate Purple Sorcerer's Crawler Companion for DCC with Roll20.&nbsp; I think there may be some value for others.&nbsp; Please let me know if you find it of any interest and/or run into any issues. Cheers, Mike Purple20 ( <a href="https://github.com/Purple20Games/purple20" rel="nofollow">https://github.com/Purple20Games/purple20</a> ) Purple20 is a Chrome extension that supports integration of the DCC Crawler Companion with the Roll20 virtual table top, allowing: rolls made in Crawler Companion (simple rolls, fumbles, crits, etc) to appear in Roll20 chat 0-level characters generated through Crawler Companion to automatically spawn populated character sheets in Roll20 (also requires the 'P20_Bot' Roll20 API script, available at <a href="https://github.com/Purple20Games/roll20_api" rel="nofollow">https://github.com/Purple20Games/roll20_api</a> ) Installation Install via the Chrome store at <a href="https://chromewebstore.google.com/detail/fhefaendccigncfdkfjcaklophndhkkd" rel="nofollow">https://chromewebstore.google.com/detail/fhefaendccigncfdkfjcaklophndhkkd</a> Usage Navigate to Crawler Companion (be sure you're online and broadcasting) In a separate tab, navigate to Roll20 and enter a game Confirm that the Purple 20 extension shows the status of both as "connected" The following dice rolls should appear in Roll20 straight rolls fumble table / crit table spells as well as anything sent through the queue/stream system in Crawler Companion Optional (character generator support) Install P20Bot (see above) In Crawler Companion, generate any 0-level PC character and click Copy/Share P20Bot should recognize it in Roll20 and auto-generate a character sheet for it
1704050121
The Aaron
Pro
API Scripter
Nice first foray into scripting!&nbsp; It looks like you used one of my older templates to get started, but I've moved on a little bit, so here's how I'd suggest reformatting it for modern JS.&nbsp; This also moves your freestanding functions inside the closure of the P20Bot object, so they don't crowd the global namespace: // Github: <a href="https://github.com/Purple20Games/roll20_api/blob/main/p20_mod.js" rel="nofollow">https://github.com/Purple20Games/roll20_api/blob/main/p20_mod.js</a> // By: .... // Contact: .... const P20Bot = (() =&gt; { //eslint-disable-line no-unused-vars const version = '0.1.0'; const lastUpdate = 1704050051; // create a PC attribute and return it const createAttribute = (char_id, attr_name, attr_val) =&gt; { let attr_val_t = String(attr_val).trim(); let attr = createObj("attribute", { name: attr_name, current: attr_val_t, _characterid: char_id }); log("Setting " + attr_name + " to value " + attr_val_t); return attr; }; // return text between two strings const regex_between = (regexp, str) =&gt; { // todo -- make this way more robust let matches = str.match(regexp); return matches[1]; }; // Create a PC character from a raw DCC character message const createCharFromRawMessage = (msg) =&gt; { let charname = regex_between(/Occupation: (.*?)&lt;/, msg); let mychar = createObj('character', { name: charname } ); let str = regex_between(/Strength: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "str", str); createAttribute(mychar.id, "strMax", str); let agi = regex_between(/Agility: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "agi", agi); createAttribute(mychar.id, "agiMax", agi); let per = regex_between(/Personality: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "per", per); createAttribute(mychar.id, "perMax", per); let intt = regex_between(/Intelligence: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "int", intt); createAttribute(mychar.id, "intMax", intt); let sta = regex_between(/Stamina: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "sta", sta); createAttribute(mychar.id, "staMax", sta); let luck = regex_between(/Luck: (.*?) \(.*?\)/, msg); createAttribute(mychar.id, "luck", luck); createAttribute(mychar.id, "luckMax", luck); createAttribute(mychar.id, "REF", regex_between(/Ref: (.*?);/, msg)); createAttribute(mychar.id, "FORT", regex_between(/Fort: (.*?);/, msg)); createAttribute(mychar.id, "WILL", regex_between(/Will: (.*?)&lt;/, msg)); let hp = regex_between(/; HP: (.*?)&lt;/, msg); createObj("attribute", { name: "HP", current: hp, max: hp, _characterid: mychar.id }); createAttribute(mychar.id, "INIT", regex_between(/Init: (.*?);/, msg)); createAttribute(mychar.id, "Speed", regex_between(/Speed: (.*?);/, msg)); createAttribute(mychar.id, "Level", 0); createAttribute(mychar.id, "HPDie", "d4"); createAttribute(mychar.id, "race", ""); createAttribute(mychar.id, "occupation", regex_between(/Occupation: (.*?)&lt;/, msg)); createAttribute(mychar.id, "Alignment", ""); createAttribute(mychar.id, "Title", ""); createAttribute(mychar.id, "className", ""); //createAttribute(mychar.id, "allAtkLuckyRoll", "[[@{luckStartingMod}]]"); createAttribute(mychar.id, "birthAugur", regex_between(/Lucky sign: (.*?) \(/, msg)); createAttribute(mychar.id, "luckyRoll", regex_between(/Lucky sign: .*? \((.*?)\) \(/, msg)); let treasure = regex_between(/Trade good: (.*?)&lt;/, msg) + "\r" + regex_between(/Starting Funds: (.*?)&lt;/, msg) + "\r" + regex_between(/Weapon: (.*?)&lt;/, msg); createAttribute(mychar.id, "treasure", treasure); createAttribute(mychar.id, "Equipment", regex_between(/Equipment: (.*?)&lt;/, msg)); createAttribute(mychar.id, "Languages", regex_between(/Languages: (.*?)&lt;/, msg)); let starting_copper = regex_between(/Starting Funds: (.*?) cp&lt;/, msg); createAttribute(mychar.id, "CP", starting_copper); createAttribute(mychar.id, "SP", 0); createAttribute(mychar.id, "GP", 0); createAttribute(mychar.id, "EP", 0); createAttribute(mychar.id, "PP", 0); return mychar; }; const checkInstall = () =&gt; { log('-=&gt; P20Bot v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); }; const handleInput = (msg) =&gt; { // check for magic strings from Crawler Companion if (/Generator Settings: Source:/.test(msg.content)) { sendChat("P20Bot", "DCC PC statistics detected! Creating character..."); /*let mychar = */ createCharFromRawMessage(msg.content); } if (msg.type !== "api") { return; } let args = msg.content.split(/\s+/); switch(args.shift()) { case '!p20': switch(args.shift()) { case 'ping': sendChat('P20Bot','pong'); break; /*case 'gen': var char = createCharFromRawMessage(msg.content) sendChat('P20Bot','I have created a new character, by your command'); break;*/ } break; } }; const registerEventHandlers = () =&gt; { on('chat:message', handleInput); }; on('ready',() =&gt; { checkInstall(); registerEventHandlers(); }); return {}; })();
1704050471

Edited 1704050856
Z
Pro
Very much appreciated!&nbsp; Javascript is not my natural habitat. :)&nbsp; And yes, I've shamelessly ripped multiple patterns while building this.&nbsp; Thank you for all the material to learn from!
How do I get characters to transfer over?
1704051889

Edited 1704051957
Z
Pro
Sorry -- the documentation is lagging development.&nbsp; :) To use the auto-chargen feature... 1. Confirm you have a fully connected Purple20 session: 1b. Also make sure you have the P20Bot mod installed in Roll20 2. In Crawler Companion, generate a 0-level character (all character types should work, but only DCC types are fully supported) 3. Click Copy/Share, which should cause the stat block to appear in Roll 20 chat, and should be recognized by the P20Bot mod as a stats block: 4. P20Bot should generate a fully populated* PC charsheet... * Currently doesn't include: Random name (uses occupation) Weapons added to weapons sub-block Lucky roll checkbox