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

Whisper results to a specific player

1723816386

Edited 1723816406
I have a api script that outputs a random result of drinking a potion, but it outputs the result to everyone.  I was hoping to be able to just output it to the character I select. The current output looks like this: var PEL1 = (function() { 'use strict'; const positiveEffectLevel1 = [ {low: 1, high: 1, result: "Sense other Fey within 2 miles."}, {low: 2, high: 2, result: "Find Water within 2 miles."}, {low: 3, high: 3, result: "Detect poisons."}, {low: 4, high: 4, result: "Identify plants."}, {low: 5, high: 5, result: "Sense weather."}, {low: 6, high: 6, result: "Cantrips: Roll on Cantrip Chart."} ]; function registerEventHandlers() { on('chat:message', PEL1.handleChatMessage); } /** * Grab chat message objects * * @param {object} msg */ function handleChatMessage(msg) { // Check if we are dealing with a !critical command. //if (msg.type === "api" && msg.content.indexOf("!critical") !== -1) //JDP if (msg.type === "api" && msg.content.indexOf("!positiveEffectLevel1") !== -1) { var content = msg.content; var words = content.split(' '); // Sanity check if (words.length > 0) { // Sanity check if (words[0] === '!positiveEffectLevel1') { var rolled = 0; // Was a roll amount given? If so parse the second "word" as an int, otherwise create a randomInteger. if (words.length === 2) { rolled = parseInt(words[1]); } else { rolled = randomInteger(6); } // Sanity check if (typeof rolled !== 'number' || rolled === 0) { rolled = randomInteger(6); } // Get the smack object as a smash variable var smash = PEL1._determineCritical(rolled); // Sanity check if (smash) { // Send the critical result as a formatted string in chat //sendChat('Critical Hit', rolled.toString() + "% <b>" + smash.result + "</b><br><i><b>Slash: </b>" + smash.slash + '</i><br><i><b>Blunt: </b>' + smash.blunt + '</i><br><i><b>Pierce: </b>' + smash.pierce + '</i>'); //JDP' sendChat('Positive Effect Level 1', smash.result); } else { sendChat('Positive Effect Level 1', 'Invalid % roll given, or something went wrong. GM makes something up.'); } } } } } /** * Internal function given the roll value returns the object indicating the result and effect. * * @param {int} roll * @return {object} smack * @private */ function _determineCritical(roll) { // Use _.find to figure out what happened. return _.find(positiveEffectLevel1, function (hit) { return (roll >= hit.low && roll <= hit.high); }); } return { registerEventHandlers: registerEventHandlers, handleChatMessage: handleChatMessage, _determineCritical: _determineCritical } }()); But I would like to incorporate something like this so I can select the character I want to see it: /w ?{Whisper|Jethro Hammerstroke|Skylar Battlebend|Dahk Turnskull|Macy Maples|Flick|Arno|Aiden}
1723824183

Edited 1723824252
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hi Drifter 96! Without getting into the actual coding (I assume you wrote the above and are familiar with JavaScript), it should be easy to iterate through the player objects to get their names. This would allow you to select by screen name. A longer method would be to go through all of the character objects and filter them by those that have one of the player ids in their controlledby property. This would allow you to select by character names, if that's more important. Whatever you do, remember to enclose names in quote marks to avoid breaking on spaces. Example: /w Jethro Hammerstroke Hello Will whisper "Hammerstroke Hello" to a character named Jethro /w "Jethro Hammerstroke" Hello Will whisper "Hello" to a character named Jethro Hammerstroke. So this is what you will need to construct: /w ?{Whisper|"Jethro Hammerstroke"|"Skylar Battlebend"|"Dahk Turnskull"|"Macy Maples"|"Flick"|"Arno"|"Aiden"}
Hi keithcurtis, Thank you for responding, but no, I did not write the code.  I found it online and was able to modify it for my needs, but I have no idea how to accomplish what you suggested.
Hey Drifter, Are you open to other suggestions as to what you want to do? It seems to me like you could use a rollable table to roll on those options and then use your roll query to whisper to a player: /w ?{Whisper|Jethro Hammerstroke|Skylar Battlebend|Dahk Turnskull|Macy Maples|Flick|Arno|Aiden} [[1t[postiveEffectLevel1]]] where postiveEffectLevel1 is the table name: Having an option using ScriptCards is also possible which wouldn't require JS coding changes. I'm not a JS expert but you would probably need to add an attribute to pass in the player with something like: --target [CharacterName] and then modify your sendChat to add the /w and whisper target. There are examples of mods that whisper via sendChat. Here is one example in  TokenMod
Hi Joshua, I am definitely up to anything.  The problem is, I haven't done rollable tables, and very little with api's.  I've been able to modify some api's, but never tried to add whispering to someone.
So rollable tables can be pretty handy. At their most basic level, here is a wiki article  that describes them that also includes a youtube video if you prefer that format. I created a rollable table with the 6 entries you have in your script, granted I did typo the name, and that allows me to roll on the table for a random choice. I also put it in a whisper with some character names from my test game. /w ?{Whisper to whom?|Paladin|Wizard|Deer} [[1t[postiveEffectLevel1]] And then when i choose from the drop down it whispers the roll to that character: No mods are required for this. Create the table, add the entries you want in that table, and then roll on the table. If you want to get fancier bells and whistles, then ScriptCards and/or timmaugh's MetaScript Toolbox can allow you to spruce up the display from the tables. If you have a large list of entries, mods are available to help load data,  here is an example in a Nick Olivo video. I also have a ScriptCard that helps me create tables and when I want, automatically set the weights. I can share that if that's of interest but I don't want to complicate things or overwhelm.
Thank you so much!  This is perfect!  I would love to get the ScriptCard from you.
Initial setup: 1. Install ScriptCards mod. It's available in 1Click.  Mod install doc   Nick Olivo installation video 2. Create a character named exactly ScriptCards_Storage this is not strictly necessary but it can be used to save the configuration defaults you want to use. 3. Restart the API Sandbox so that ScriptCards knows about the storage character. Paste this script in chat or in a character's ability. !script {{ --/|HARDCODED VARIABLES --/|Set this to unweighted, 1dX, 2dX, or 3dX --/|unweighted and 1dX result in the same. 1 entry per item. --&tableDiceRoll| --/|Pattern used to separate each entry in the input --/|DO NOT USE A SEMI-COLON ;. This will result in weird issues --/|Note that some special characters may need to be added multiple times below due to Roll20 text parsing --/|Example: # may need to be ### or % may need to say %% below for one to remain as a delimiter --/|Note this is not the case when setting the delimiter below via the roll query --&delimiter| --&savedSettingsPrefix|TblCreator --#reentrant|RollTableCreator --?"[&tableDiceRoll]X" -ne "X" -and "[&delimiter]X" -ne "X"|>DisplayConfig --?"[&tableDiceRoll]X" -eq "X"|[ --l&[&savedSettingsPrefix]|tableDiceRoll --]| --?"[&delimiter]X" -eq "X"|[ --l&[&savedSettingsPrefix]|delimiter --]| --/|Default Values if not hardcoded or saved --?"[&tableDiceRoll]X" -eq "X"|[ --&tableDiceRoll|unweighted --]| --?"[&delimiter]X" -eq "X"|[ --&delimiter|, --]| -->DisplayConfig| --:Done| --X| --:DisplayConfig| --&RQ|? --&RQ|+{ --#title|RollTable Creator --+|[c][b]Current Configuration[/b][/c] --+Table Weighting (Dice)|[&tableDiceRoll] [rbutton]Change::SetWeighting;[&RQ]Table Dice|1dX unweighted,unweighted|2d4|2d6|2d8|2d10|2d12|2d20|2d100|3d4|3d6|3d8|3d10|3d12|3d20}[/rbutton] --+Input Delimiter|[&delimiter] [rbutton]Change::SetDelimiter;[&RQ]Set delimiter}[/rbutton] --+|[rbutton]Save Settings::SaveConfiguration;1[/rbutton] --+|[br] --+Input Format|TableName[&delimiter]Item1[&delimiter]Item2 --+|[rbutton]Enter Table Data::DataInput;[&RQ]Table Data [&delimiter] delimited}[/rbutton] --^Done| --:SetWeighting| --&tableDiceRoll|[&reentryval] --^DisplayConfig| --:SetDelimiter| --&delimiter|[&reentryval] --^DisplayConfig| --:SaveConfiguration| --s&[&savedSettingsPrefix]|tableDiceRoll;delimiter --+SAVED|Saved weighting and delimiter -->DisplayConfig| --^Done| --:DataInput|InputDataToParse --~tableName|string;before;[&delimiter];[&reentryval] --~entryList|string;after;[&delimiter];[&reentryval] --?"[&tableName]X" -eq "X" -or "[&entryList]X" -eq "X" -or "[&reentryval]" -ninc "[&delimiter]"|[ --+ERROR|Data input error. Ensure table name and items are passed. Name:[&tableName] Items:[&entryList] --^Done| --]| --~|array;fromstring;TableItemArr;[&delimiter];[&entryList] --?"[&tableDiceRoll]" -eq "unweighted"|CreateUnweightedTable -->SetTableConfiguration|[&tableDiceRoll];NumDice;DieType;ItemCount --?[&NumDice] -eq 1|CreateUnweightedTable --?[&NumDice] -gt 3|[ --+ERROR|Currently only able to build tables for 1dX (unweighted), 2dX, and 3dX. You attempted [&NumDice] --^Done| --]| --?[&ItemCount] -ne [@TableItemArr(length)]|[ --+ERROR|Expected [&ItemCount] item(s) for [&tableDiceRoll]. Received [@TableItemArr(length)] --^Done| --]| -->CreateTable|[&tableName];tableid --&_iterationCounter|1 --%item|foreach;TableItemArr -->DetermineNumberOfEntries|[&tableid];"[&item]";[&_iterationCounter];[&NumDice];[&DieType];[&ItemCount] --&_iterationCounter|[= [&_iterationCounter] + 1 ] --%| --+Created|[&tableDiceRoll] weighted table named [&tableName] --^Done| --:SetTableConfiguration|OriginalTableDice;StringReturnDiceNum;StringReturnDieType;StringReturnItemCount --&_stcTmpVar|[%1%] --&[%2%]|[&_stcTmpVar(split,d,0)] --&[%3%]|[&_stcTmpVar(split,d,1)] --&[%4%]|[= [&[%2%]] * [&[%3%]] - [&[%2%]] + 1 ] --<| --:CreateUnweightedTable| -->CreateTable|[&tableName];tableid --%item|foreach;TableItemArr -->AddTableEntry|[&tableid];"[&item]" --%| --+Created|unweighted table named [&tableName] --^Done| --:CreateTable|TableName;TableIDReturnString --!o#:[%2%]|[%1%] --<| --:AddTableEntry|TableID;Item;Weight --!oe:entryid|[%1%];[%2%];[%3%] --<| --:DetermineNumberOfEntries|TableID;Item;ItemIndex;NumberOfDice;DieType;ItemCount --?"[&_[%1%]entryCount]X" -eq "X"|&_[%1%]entryCount;1 --?[%3%] -eq [%6%]|&_[%1%]entryCount;1 --?[%3%] -eq 1 -or [%3%] -eq [%6%]|DNELOOPSTART --?[%4%] -eq 2|[ --?[%3%] -le [%5%]|&_[%1%]entryCount;[= [&_[%1%]entryCount] + 1 ]|&_[%1%]entryCount;[= [&_[%1%]entryCount] - 1 ] --]|[ --&_tmpMidPoint|[= [%6%] / 2 ] --?"[&_[%1%]tmpIncrease]X" -eq "X"|&_[%1%]tmpIncrease;[%5%] --?[%3%] -le [%5%]|&_[%1%]entryCount;[= [&_[%1%]entryCount] + [%3%] ] --?[%3%] -gt [%5%] -and [%3%] -le [&_tmpMidPoint]|&_[%1%]tmpIncrease;[= [&_[%1%]tmpIncrease] - 2 ] --?[%3%] -gt [%5%]|&_[%1%]entryCount;[= [&_[%1%]entryCount] + [&_[%1%]tmpIncrease] ] --?[%3%] -le [&_tmpMidPoint]|>libArray_Push;[%1%]TmpEntryArr;[&_[%1%]entryCount]|>libArray_Pop;[%1%]TmpEntryArr;_[%1%]entryCount --]| --:DNELOOPSTART| -->AddTableEntry|[%1%];"[%2%]";[&_[%1%]entryCount] --<| --:libArray_Push|ArrayName;StringValue --~|array;add;[%1%];[%2%] --<| --:libArray_Pop|ArrayName;StringVariableToSet --~[%2%]|array;getlast;[%1%] --~|array;removeat;[%1%];[@[%1%](maxindex)] --<| }} By default, the ScriptCard is comma separated values and unweighted entries, meaning that each entry has the exact same chance as any other entry. These can be set via the buttons in the chat menu. You can change the weighting and the input delimiter if you need to change those and you can persist those with the Save Settings button which is where the ScriptCards_Storage character comes in. If you are wanting to change the delimiter, I recommend doing it via its Change button and saving that setting. It's a lot simpler than hardcoding the delimiter in the ScriptCard since Roll20 has a lot of special parsing for special characters like @, $, %. Setting it via the Change button makes that easy. When you are ready the Enter Table Data button will open a roll query dialog box to paste in values. For example with your Mod above: positiveEffectLevel1,Sense other Fey within 2 miles,Find Water within 2 miles,Detect poisons,Identify plants,Sense weather,Cantrips: Roll on Cantrip Chart That would create a rollable table with a name of positiveEffectLevel1 and 6 entries. I made this cause I have a lot of tables in various old books and things that I didn't want to automatically have to look up the right weights for a table that you'd roll 2d6 on, so this scriptcard will calculate those weights automatically. For 1dX tables they are just unweighted. Hopefully that helps you. Let me know if you have any questions about it.