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] What did he say? File under "Roleplay API"

1383272396

Edited 1383586211
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
(With edits) 1) Make sure each player's display name in one word and distinct. 2) Create a character sheet for each language i.e. "kender" "dwarven" etc 3) Give each player that can speak the language "Can Be Edited & Controlled By" rights. Brian 's suggestion. To speak "kender" in secret just whisper to "kender" and everyone with access can "hear" it and only them. To torture the human fighter that can't speak kender... use the API (draft) below... Example: Stephen enters: "!kender Do all humans look so stupid?" Output in chat if Stephen speaks Kender: Whispered to all players that speak kender: (From Stephen in kender): Do all humans look so stupid? Whispered to all players that do not speak kender: (From Stephen in kender): ss s?l noapduloal ohDmuitk o? Whispered to GM (GM should see this since its not a true whisper but use of language): (From API): Stephen said in kender: Do all humans look so stupid? Output in chat if Stephen doesn't speak kender: Stephen in mocking kender: ss s?l noapduloal ohDmuitk o Also added "!help" to list languages commands (long and short.) <a href="https://gist.github.com/baldar/7306052" rel="nofollow">https://gist.github.com/baldar/7306052</a>
1383360535
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
This script also has "blind" gm rolls.... useful when players make a roll and they should not know the outcome (i.e. "hide in shadows.") Example: !broll 1d100 What the player sees: What the GM sees:
1383361114
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
I am sure this can be made shorter but "whisper" with the display name is touchy. Consider the extreme example of four "Bob"s playing a game together: "Bob M.", "Bob S." "Bob" and "Bob (GM)" The low thought way is force distinct names with no spaces (the "_(GM)" space in forced on you: "BobM", "BobS" "Bob" and "BobGM (GM)" Likely a better way.... but I am not going to head-scratch over it any more.
1383373723
Lithl
Pro
Sheet Author
API Scripter
character.inplayerjournals and character.controlledby are both comma-delimited lists of player.id in the list (or the string "all"), so there's no need to put the player's name in attributes. As far as whispers go, at the trivial end, you can whisper to the language-character and all controlling players will get the whisper. Whispering to all players not controlling that language-character isn't quite so trivial, unfortunately. You don't need to select all players, then loop through the list to find the player with a displayname matching msg.who. First, because findObjs can be given a displayname to find in addition to the type "player". Second, because msg.playerid already has the id of the player who triggered the message event. ( var player = getObj('player', msg.playerid); ) I realize you're using the player list again later to send out the whispers, but there are other means (such as whispering to the language-character). Similarly, you don't need to iterate over all of the characters to find the appropriate language-character. findObjs can do that for you. ( var languageCharacter = findObjs({ _type: 'character', name: command }); ) A personal preference, but the for (var i in list) { var item = list[i]; ... } construct feels awkward in any JS environment where the underscore library is available. _.each(list, function (item) { ... }); seems cleaner and more readable to me.
1383385358

Edited 1383387564
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
"...character.inplayerjournals and character.controlledby are both comma-delimited lists of player.id in the list (or the string "all")..." That is the gem! And leads the rest of your good suggestions! Many thanks! I have been reading through scripts of others and trying to think of ones that encourage the RP aspect and not just game time saves (though both are important.) Something like this gives language another dimension and I think the blind rolls can be lots of fun as well.
1383494584

Edited 1383494661
Wow, what a cool script! the Blind GM rolls is something I've been looking for! Is there a way to seperate the language from blind rolls?
1383494830

Edited 1383495516
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Blind GM roll stand alone. <a href="https://gist.github.com/baldar/7291922" rel="nofollow">https://gist.github.com/baldar/7291922</a>
1383585831
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Updated with Brian 's suggests ... as well I as I could :P
1383595868

Edited 1383595889
aRotondi
Sheet Author
Very cool looking, will use. If we wanted to muck with the output, we would just work around the 'gibberish' generating section, yes? I'm trying to think of how to expand that to other languages and ones that should have a different feel (such as elvish being built from specific phrases or something). Also good job on making the language section expandable easily :).
1383597293
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
That is a good idea... based on the language command given present a different feel. Something simple to code but one that creates a immerse feel... Like reverse string so its about as long but spaces move a bit and then swap with characters ones from the from the ASCII character-sets (i.e ýñë) that give you that "feel" for the language.
1383598360
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
See: <a href="https://app.roll20.net/forum/post/352614/woot-html-ascii-codes-work-in-sendchat#post-353750" rel="nofollow">https://app.roll20.net/forum/post/352614/woot-html-ascii-codes-work-in-sendchat#post-353750</a>
Stephen S. said: That is a good idea... based on the language command given present a different feel. Something simple to code but one that creates a immerse feel... Like reverse string so its about as long but spaces move a bit and then swap with characters ones from the from the ASCII character-sets (i.e ýñë) that give you that "feel" for the language. Yea, about what I was thinking. Could just take the length of the message, divide it by some number to get 'number of phrases' and then pull phrases from a bank based on language. Unfortunately it might make simple things not look so consistent. Joe says in Elvish "stop" twice, first time it says the phrase "tawil", second time it says "ñëit", because that short of a message is just replaced by one phrase randomly from the bank each time. Would still be worth trying out when I have some free time later today though. Will post results.
1383601085
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
I would play with length too... elvens saying something in 10 words a dwarf could say with 3.
I don't think JS Math.random() supports seeding the RNG, but you could implement your own seeded RNG and then seed with either the word or phrase to be 'translated', ensuring it translates the same every time.
John M. said: I don't think JS Math.random() supports seeding the RNG, but you could implement your own seeded RNG and then seed with either the word or phrase to be 'translated', ensuring it translates the same every time. yea that would maybe be a bit too sophisticated for the amount you'd get out of it. A phrase bank would work well for the short term. Am working on it now :)
1383618429
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
<a href="https://gist.github.com/baldar/7312794" rel="nofollow">https://gist.github.com/baldar/7312794</a> Here is a seeded RND ... using ACII in an array for each language. λ∋ΛΓ⊥ΛΓ⊥∋μ¬⊥Πμϖ⊥Γ⌈Π⊥∋π⌋⌋μ⊥ΛΓ⊥Ξ¬⌈±⌉πΓ "This is how you say hello in dwarven" ÎÅÑÍ ÑÍ ÅÛý ×Ûå Íí× ÅßõõÛ ÑÏ ßõñßÏ "This is how you say hello in elven."
ha, you beat me to it. Though that is a few more accented characters than I would have used for elven, it gets the job done. Well done sir. Will grab and modify for personal needs :)
1383623480
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Yea... there are some slit troubles with that..(max count is off) good thing is if you use drow (for example) you just change the seed and can use the same elven array.
1383654855
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Adam R. said: ha, you beat me to it. Though that is a few more accented characters than I would have used for elven, it gets the job done. Well done sir. Will grab and modify for personal needs :) Would you mind sharing? I would like to see what you cook up.
Well my edit was just a simple one if I'm to be honest. I just added a bank of words that sound like what I want immediately after your command arrays: //Language Banks var elfBank = ["ta","ætti","ciénne","dæva","sola","desmondi","aoula","di"]; Then I modified the gibberish code to simply pull from the language bank (in the simplest case, it always just pulled from the same bank). More code would be needed to have it consistently pull from the same language, though It would probably be based on the actual command since you already have that stored and as a nice identifier. if (msgMessage !== null){ var numPhrases = msgMessage.split(' ').length + 1; //count number of phrases by number of spaces log(numPhrases); var gibberish = ""; for(int i=0;i=&lt;numPhrases; i++) { gibberish += elfBank[randomInteger(elfBank.length-1)]; } }; Less sophisticated than your code for random seeding, but it has the advantage of saying x number of things based on the language, such that if I wanted elven to be 'shorter and more elegant' I could edit the numPhrases variable to be a lower number than the original. Unfortunately I was having a bit of trouble testing, and I remembered that my names needs to be 1 word. haha. Will work on more testing of it when I have some free time today. Although you could replace the randomInteger call in the above code to call the 'seed' function you posted and it should work in a consistent hybrid manner based on the message (and a larger word bank), if I understand your code correctly.
1383667452
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Yea... whisper is funking... ROll20 creates "short" names but I don't know the rules that guide that so I can't emulate it in the API. Also..... I can't tell which player is a GM (anyone?) when I loop through the players. Might make GM record sheet "controlled by" GMs to id them.... as it stands right now GM get two messages...(they have a right to see all these message because they are not true whispers.) In an effort to WAY over complicate this.... I am thinking about going after numbers and symbols. Sample: var symbolArrayStandard = ["1","2","3","4","5","6", "7", "8", "9", "0"] var symbolArrayDwarven = [".",":","∴","+","◊","◊.","◊:","◊∴","◊+","°"] var symbolArrayElvish = [".",":","∴","+","¤","¤.","¤:","¤∴","¤+","°"] var symbolArrayCommon = [".",":","∴","+","×","×.","×:","×∴","×+","°"] var symbolArrayEvil = [".",":","∴","+","∏","∏.","∏:","∏∴","∏+","°"]
1383670686

Edited 1383675304
aRotondi
Sheet Author
Its really only limited by however you want to parse the original message. I think both of the current ways would work fine, as the next most complex step is to genuinely create a cipher or something that actually does translate phrases into different symbols (which I can see you are slightly doing here). Also..... I can't tell which player is a GM (anyone?) when I loop through the players. Well more than one player can be a GM, and I would assume it would be part of the player's object structure inside of the campaign mega-object. Will check the wiki quick. EDIT: just checked the object structure for players, there is a _type attribute that is default to "player", so i'm assuming there is something akin to "GM" as a setting. That should help but I will write a script over lunch to check for myself. EDIT2: Double checked the documentation after fiddling. the _type attribute is to be used with the findObjs() call, to match against the type parameter in that call. I'm not sure how the system checks for someone being a GM now. :(
1383678442
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
aRotondi said: Well more than one player can be a GM, and I would assume it would be part of the player's object structure inside of the campaign mega-object. Will check the wiki quick. EDIT2: Double checked the documentation after fiddling. the _type attribute is to be used with the findObjs() call, to match against the type parameter in that call. I'm not sure how the system checks for someone being a GM now. :( We just use Brian's trick for "controlled by" and the languages.... Create a sheet named GM and have it controlled by the players that are to be treated as current GM. Then only whisper to the GMs that don't speak the language... I will work that in (this way the GM will get one whisper if they do or do not speak the language) -------------- Numbers are simple so codify them and make them very common across races that share a root language: Kender (language based on "common" hobbits would also be based on "common") counting zero to ten: °:∴+×××:×∴×+ Gnome (language based on "dwarven" dwarves would also be based on "dwarven") counting zero to ten: °:∴+◊◊◊:◊∴◊+ Elf (language based on "elven" drow would also be based on "elven" for numbers) counting zero to ten: °:∴+¤¤¤:¤∴¤+ Orc (language based on "evil" drow would also be based on "evil" for non-numbers.. whatever you like) counting zero to ten: °:∴+∏∏∏:∏∴∏ Dwarf (based on "dwarven") says: the quick brown fox jumped over the lazy dog [Γ⌈Ξ⌈Π∫⌈M⌈⌈∫⌈iΛMΞ⌋¦⌈¬nΞf⌈ΞΞ|¦VV⌈Ξ⌈|¦Ξ[ΓΞ⌉⌈ΠΠ⌈Ξ⌈⌊ Gnome (based on "dwarven") says: the quick brown fox jumped over the lazy dog [¦⌈Λ|⌈⌈ΓVVΛ⌊¬⌈⌋ΠΛM⌈ΛΛ]⌈¦ΠΠ⌈‡Λ⌈|⌈¬Λ[¦⌈Λ‡⌈||⌈Λd⌈⌉ Elf (based on "elven") says: the quick brown fox jumped over the lazy dog ∪ξí~çíí∫Ψ~Þríq∈~ϒí~~⊇írun∋ífiní∋íd~íφer~∪ξe~çí∂í~díþ Drow (based on "evil") says: the quick brown fox jumped over the lazy dog '∪∋ô∪ξôô∋ç∪∫ςôς⊆∪þô∪∪Ψô∈çô⊇∪ôqôς∪'∪∋ô ξôϖô ⊇ôς Few base arrays and seeded random number make it work (gnome would use the same array but have different seed) switch (msgApiCommand){ case "d": sendChat("API","dwarven"); var symbolArray = symbolArrayDwarven; var lowerArray = lowerArrayDwarven; var upperArray = upperArrayDwarven; var vowelArray = vowelArrayDwarven; var languageSeed = 1; // Language have common root (how they look) but seed varies each language. break;
1383691849

Edited 1383691967
Lithl
Pro
Sheet Author
API Scripter
Stephen S. said: I can't tell which player is a GM (anyone?) when I loop through the players. Unfortunately, the player object does not store such information. The closest you can get automatically is during a chat message event, msg.who will have "(GM)" at the end if the player sending the message was a GM and they weren't speaking as a character... although a non-GM player could conceivably alter their display name to include "(GM)" at the end, making it possible to spoof. Your alternatives are to create a hard-coded array identifying the campaign's GMs, and validate against that. My preferred method is to use d20userid, since it's easy to type (a 6-digit number that will always be the same, vs. name or id, both of which might change between campaigns, making scriting more of a chore, and the latter is long and hard to remember anyway), and nobody can spoof it. The easiest way to find your own userid is to go to your profile page -- it's at the end of the URL to your profile. If you only want to discover the GM(s) for the purpose of whispers, you can use "/w gm text ." That will send whispers to the GM(s) regardless of who's sending the whisper and who the GM(s) is/are.
1383692746
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Brian said: Stephen S. said: I can't tell which player is a GM (anyone?) when I loop through the players. Unfortunately, the player object does not store such information. The closest you can get automatically is during a chat message event, msg.who will have "(GM)" at the end if the player sending the message was a GM and they weren't speaking as a character... although a non-GM player could conceivably alter their display name to include "(GM)" at the end. Your alternatives are to create a hard-coded array identifying the campaign's GMs, and validate against that. My preferred method is to use d20userid, since it's easy to type (a 6-digit number that will always be the same, vs. a long string that might change between campaigns), and nobody can spoof it. The easiest way to find your own userid is to go to your profile page -- it's at the end of the URL to your profile. If you only want to discover the GM(s) for the purpose of whispers, you can use "/w gm text ." That will send whispers to the GM(s) regardless of who's sending the whisper and who the GM(s) is/are. Yea... I think I am going to leverage your suggest for languages. Right now the GM(s) get translated whispers because they are entitled to see it (GM speaks all languages.) The trouble is, GMs also get a second whisper (gibberish if they don't have a character or gibberish if they do have a character that doesn't' speaks the language or a second translated whisper if they have a character that speaks the language.) Its just a double whisper, but still.... So if I leverage your suggestion and make a "activeGMs" sheet and give the GM(s) "control" that way I can ensure they get only one whisper stating: (From Stephen in kender): Do all humans look so stupid? or (From Stephen in kender): ss s?l noapduloal ohDmuitk o? (GM Translation: Do all humans look so stupid?) (the second version serves as a reminder their character doesn't speak kender.
The reason that information isn't stored as part of the player's object is because a player can join a game either as a GM or as a player...so just because someone "could" be a GM doesn't mean that's their *current* role in the game. I'll see if there's a way I can have some sort of temporary state object that gives that information, as I can see how it would be useful.
1384397817
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Many thanks!
Stephen S. said: Dwarf (based on "dwarven") says: the quick brown fox jumped over the lazy dog [Γ⌈Ξ⌈Π∫⌈M⌈⌈∫⌈iΛMΞ⌋¦⌈¬nΞf⌈ΞΞ|¦VV⌈Ξ⌈|¦Ξ[ΓΞ⌉⌈ΠΠ⌈Ξ⌈⌊ Gnome (based on "dwarven") says: the quick brown fox jumped over the lazy dog [¦⌈Λ|⌈⌈ΓVVΛ⌊¬⌈⌋ΠΛM⌈ΛΛ]⌈¦ΠΠ⌈‡Λ⌈|⌈¬Λ[¦⌈Λ‡⌈||⌈Λd⌈⌉ Elf (based on "elven") says: the quick brown fox jumped over the lazy dog ∪ξí~çíí∫Ψ~Þríq∈~ϒí~~⊇írun∋ífiní∋íd~íφer~∪ξe~çí∂í~díþ Drow (based on "evil") says: the quick brown fox jumped over the lazy dog '∪∋ô∪ξôô∋ç∪∫ςôς⊆∪þô∪∪Ψô∈çô⊇∪ôqôς∪'∪∋ô ξôϖô ⊇ôς Where can I find the code that produces this beautiful result? This is outstanding work, guys! I love it!
1384660559
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
I will post the updated code tomorrow
Outstanding, thank you!
Just checking, but this is meant to work for NPCs as well right? As in, GM says something "as" an NPC and it should come out as that character speaking language "x", correct? Having issues with that working but I wanted to make sure that I wasn't assuming too much.
1385232053
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
The ability to speak a language is keyed off the "can be controlled by" field which only allows players, not characters... ..so you would have to put the GM in each language.... and just speak as GM. Its a good thought... might be a way to improve it.