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 .
×
May your rolls be merry + bright! ๐ŸŽ„
Create a free account

I'm looking for someone to make an API for this YouTube video that I really want to do

<a href="https://www.youtube.com/watch?v=Q6Z0a3eb-8c" rel="nofollow">https://www.youtube.com/watch?v=Q6Z0a3eb-8c</a> &nbsp; &nbsp; I &nbsp; want to create a conversation where the screen comes up like this. The character image
<a href="https://github.com/kibkibe/roll20-api-scripts/blob/master/visual_dialogue/README.md" rel="nofollow">https://github.com/kibkibe/roll20-api-scripts/blob/master/visual_dialogue/README.md</a> based on the YT video - web tabs, found this link also, it seems the OP has messaged the YT creator who recently replied and posted this link <a href="https://www.postype.com/@rnfckck/post/14493705" rel="nofollow">https://www.postype.com/@rnfckck/post/14493705</a> for non Koreans, get your google translate ready.
1757817286

Edited 1757817317
Here is the code for any of the scripter writers to review and understand what he/she did and maybe improve on it skip the first several lines that are in korean but the code itself is not. /* <a href="https://github.com/kibkibe/roll20-api-scripts/tree/master/visual_dialogue" rel="nofollow">https://github.com/kibkibe/roll20-api-scripts/tree/master/visual_dialogue</a> */ /* (visual_dialogue.js) 220118 ์ฝ”๋“œ ์‹œ์ž‘ */ // define: global constant state.api_tag = "&lt;a href=\"#vd-permitted-api-chat\"&gt;&lt;/a&gt;"; state.vd_divider = "โ„"; state.last_displayed_time = 0; // /define: global constant // define: option const vd_setting = { // option: ํ•œ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. // ์ด ์ˆซ์ž๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์—‘์ŠคํŠธ๋ผ, ํ˜น์€ ์ฑ„ํŒ…๊ธฐ๋ก์ด ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์บ๋ฆญํ„ฐ์˜ ์Šคํƒ ๋”ฉ์ด ์‚ญ์ œ๋˜๊ณ  ๊ทธ ์œ„์น˜์— ์ƒˆ ์Šคํƒ ๋”ฉ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. max_number: 5, // option: ํ‘œ์‹œํ•  ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€๋“ค์˜ ๊ฐ€๋กœ ์‚ฌ์ด์ฆˆ์ž…๋‹ˆ๋‹ค. width: 420, // option: ํ‘œ์‹œํ•  ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€๋“ค์˜ ์„ธ๋กœ ์‚ฌ์ด์ฆˆ์ž…๋‹ˆ๋‹ค. height: 420, // option: ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€์˜ ๊ฐ€๋กœ ๋„ˆ๋น„ ์ค‘ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋น ์ ธ๋‚˜๊ฐ€์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•  ๊ฐ€๋กœ ์‚ฌ์ด์ฆˆ์ž…๋‹ˆ๋‹ค. fit_width: 200, // option: ์บ๋ฆญํ„ฐ๋“ค์ด ์—ฌ๋Ÿฌ ๊ฐ์ •ํ‘œํ˜„์„ ์‚ฌ์šฉํ• ์ง€(true) ๋Œ€ํ‘œ ์Šคํƒ ๋”ฉ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ• ์ง€(false) ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. // false์ผ ๊ฒฝ์šฐ deck_name์— ์„ค์ •ํ•œ ์นด๋“œ ๋ฑ์—์„œ ๋ชจ๋“  ์บ๋ฆญํ„ฐ์˜ ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. use_emotion: true, // option: /as๋ฅผ ์ด์šฉํ•ด ์ €๋„์— ์—†๋Š” ์บ๋ฆญํ„ฐ๋กœ ์ฑ„ํŒ…ํ•  ๊ฒฝ์šฐ ์—‘์ŠคํŠธ๋ผ ์ „์šฉ ์Šคํƒ ๋”ฉ์„ ํ‘œ์‹œํ• ์ง€ (true) ์Šคํƒ ๋”ฉ์„ ์ƒ๋žตํ• ์ง€(false) ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. // true์ผ ๊ฒฝ์šฐ extra_name์— ์„ค์ •ํ•œ ์ด๋ฆ„์— ๋”ฐ๋ผ ์—‘์ŠคํŠธ๋ผ์šฉ ์Šคํƒ ๋”ฉ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. show_extra_standing: true, // option: use_emotion๊ฐ€ false์ผ ๊ฒฝ์šฐ์— ์บ๋ฆญํ„ฐ์˜ ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ ์นด๋“œ๋ฑ์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. deck_name: "standings", // option: use_emotion์ด true์ผ ๊ฒฝ์šฐ์— ์—‘์ŠคํŠธ๋ผ์šฉ ์Šคํƒ ๋”ฉ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ ์นด๋“œ๋ฑ์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. extra_name: "extra", // option: show_extra_standing ์˜ต์…˜๊ณผ ๋ณ„๊ฐœ๋กœ ์Šคํƒ ๋”ฉ์„ ํ‘œ์‹œํ•˜์ง€ ์•Š์„ ์บ๋ฆญํ„ฐ์˜ ์ด๋ฆ„์„ ๊ธฐ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๊ฐœ์ผ ๊ฒฝ์šฐ ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ignore_list: "GM", // option: ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•  ํŽ˜์ด์ง€์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๊ฐœ์ผ ๊ฒฝ์šฐ ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. // ํŽ˜์ด์ง€๊ฐ€ ์—ฌ๋Ÿฟ์ผ ๊ฒฝ์šฐ Player ๋ถ๋งˆํฌ๊ฐ€ ์„ค์ •๋œ ํŽ˜์ด์ง€์— ์šฐ์„ ์ ์œผ๋กœ ๋Œ€์‚ฌ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. page_list: "conversation,intro", // option: ์บ๋ฆญํ„ฐ์˜ ์ด๋ฆ„์ด ํ‘œ์‹œ๋˜๋Š” ํ…์ŠคํŠธ ๋ฐ•์Šค์˜ ํฐํŠธ ์‚ฌ์ด์ฆˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. name_font_size: 18, // option: ์บ๋ฆญํ„ฐ ์ด๋ฆ„์˜ ๊ธ€์”จ์ƒ‰์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. name_font_color: "rgb(255, 255, 255)", // option: ๋Œ€์‚ฌ ๋‚ด์šฉ์ด ํ‘œ์‹œ๋˜๋Š” ํ…์ŠคํŠธ ๋ฐ•์Šค์˜ ํฐํŠธ ์‚ฌ์ด์ฆˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. dialogue_font_size: 16, // option: ๋Œ€์‚ฌ ๋‚ด์šฉ์˜ ๊ธ€์”จ์ƒ‰์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. dialogue_font_color: "rgb(255, 255, 255)", // option: /desc๋‚˜ /em์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฐ•์กฐ๋œ ํ…์ŠคํŠธ ๋ฐ•์Šค์˜ ํฐํŠธ ์‚ฌ์ด์ฆˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. desc_font_size: 20, // option: /desc, /em์˜ ๊ธ€์”จ์ƒ‰์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. desc_font_color: "rgb(255, 255, 255)", // option: ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ ์ฑ„ํŒ…์ด ๋ชฐ๋ ค์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ์ฑ„ํŒ…๋‹น ์ตœ์†Œ ๋…ธ์ถœ์‹œ๊ฐ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. (1000=1์ดˆ) min_showtime: 1000, // option: ์ฑ„ํŒ… 1๊ธ€์ž๋‹น ํ‘œ์‹œ ์‹œ๊ฐ„. ์ˆซ์ž๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๊ธ€์ž์ˆ˜ ๋Œ€๋น„ ๋Œ€์‚ฌ์˜ ํ‘œ์‹œ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง‘๋‹ˆ๋‹ค. showtime_ratio: 20, // option: (๊ณ ๊ธ‰์„ค์ •) ๊ฐ ์—ด์ด ๊ฐ„๊ฒฉ์ด font_size ๋Œ€๋น„ ์–ผ๋งˆ๋งŒํผ์˜ ํ”ฝ์…€์„ ์ฐจ์ง€ํ•˜๋Š”์ง€์˜ ๋น„์œจ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. line_height: 1.7, // option: (๊ณ ๊ธ‰์„ค์ •) ๊ฐ ๊ธ€์ž๊ฐ€ font_size ๋Œ€๋น„ ์–ผ๋งˆ๋งŒํผ์˜ ํ”ฝ์…€์„ ์ฐจ์ง€ํ•˜๋Š”์ง€์˜ ๋น„์œจ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. letter_spacing: 0.85 }; // /define: option on('ready', function() { // on.ready state.vd_stock = []; // /on.ready on("add:card", function(obj) { updateMacro(obj); }); }); on("change:card", function(obj,prev) { // on.change:card updateMacro(obj); // /on.change:card }); on("destroy:card", function(obj) { // on.destroy:card updateMacro(obj); // /on.destroy:card }); on("destroy:graphic", function(obj) { // on.destroy:graphic if (obj.get('name') == "vd_standing") { arrangeStandings(false); } // /on.destroy:graphic }); on("chat:message", function(msg) { // on.chat:message if ((msg.type == "general" || msg.type == "desc" || msg.type == "emote") &amp;&amp; (msg.playerid != 'API' || msg.content.includes(state.api_tag)) &amp;&amp; !msg.rolltemplate){ if (findCharacterWithName(msg.who) || findObjs({_type:'player',_displayname:msg.who.replace(' (GM)','')}).length == 0) { if (msg.content.length &gt; 0) { msg.content = msg.content.replace(state.api_tag,'').replace(/&lt;br&gt;/g,state.vd_divider); msg.time = new Date().getTime(); state.vd_stock.push(msg); if (state.vd_stock.length == 1 || (state.vd_stock.length &gt; 1 &amp;&amp; state.last_displayed_time + 5000 &lt; msg.time)) { setTimeout(showDialogue, 100); } } } } // /on.chat:message // on.chat:message:api if (msg.type == "api" &amp;&amp; msg.content.indexOf("!@") === 0) { const current_page_id = vdGetCurrentPage(); if (!current_page_id) { return; } if (msg.content == '!@์ˆจ๊น€' || msg.content == '!@hide') { showHideDecorations('vd_deco',false); showHideDecorations('vd_panel',false); let bg_name = findObjs({ _type: 'graphic', name:'vd_name', _pageid:current_page_id}); let bg_dialogue = findObjs({ _type: 'graphic', name:'vd_dialogue', _pageid:current_page_id}); if (bg_name.length &gt; 0) { bg_name = bg_name[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_name ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } if (bg_dialogue.length &gt; 0) { bg_dialogue = bg_dialogue[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_dialogue ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } let text_name = getObj('text', bg_name.get('gmnotes')); let text_dialogue = getObj('text', bg_dialogue.get('gmnotes')); text_name.remove(); text_dialogue.remove(); sendChat('vd-api-wildcard','!@ํ‡ด์žฅ:์ „์›'); } else if (msg.content.indexOf("!@ํ‡ด์žฅ") == 0 || msg.content.indexOf("!@exit") == 0) { const keyword = msg.content.replace("!@ํ‡ด์žฅ","").replace("!@exit","").replace(state.api_tag,''); if (keyword.length == 0) { removeStanding(msg); } else if (playerIsGM(msg.playerid) || msg.playerid == 'API' || msg.who == 'vd-api-wildcard') { if (keyword == ":์ „์›" || keyword == ":์ „์ฒด" || keyword == ":all") { let tokens = findObjs({ _type: 'graphic', name: 'vd_standing', _pageid: current_page_id}); tokens.forEach(token =&gt; { token.remove(); }); } else if (keyword == ":์—‘์ŠคํŠธ๋ผ" || keyword == ":extra") { let tokens = findObjs({ _type: 'graphic', name: 'vd_standing', represents: '', _pageid: current_page_id}); tokens.forEach(token =&gt; { token.remove(); }); } else { msg.who = keyword.replace(":",""); removeStanding(msg); } } } else if (playerIsGM(msg.playerid) &amp;&amp; (msg.content == "!@๋ฆฌ์…‹" || msg.content == "!@reset")) { state.vd_stock = []; sendChat("error","/w gm ํ‘œ์‹œ ๋Œ€๊ธฐ์—ด์— ์Œ“์—ฌ์žˆ๋˜ ๋Œ€์‚ฌ๋“ค์„ ์ดˆ๊ธฐํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); } else if (playerIsGM(msg.playerid) &amp;&amp; (msg.content == "!@๊ฐ•์ œ์ง„ํ–‰" || msg.content == "!@force-progress")) { showNextDialogue(); } else if (playerIsGM(msg.playerid) &amp;&amp; (msg.content.indexOf("!@๋ฐฐ๊ฒฝ ") == 0 || msg.content.indexOf("!@background ") == 0)) { let bg_background = findObjs({ _type: 'graphic', name:'vd_background', _pageid:current_page_id}); let bg_deck = findObjs({_type: 'deck', name:'background'}); if (bg_background.length == 0) { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_background ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } bg_background = bg_background[0]; const current_url = bg_background.get('imgsrc'); const new_bg = msg.content.replace('!@๋ฐฐ๊ฒฝ ','').replace('!@background ',''); let is_url_input = (msg.content.indexOf('https://') &gt; -1); if (is_url_input) { bg_background.set('imgsrc',new_bg.replace('med','thumb').replace('max','thumb').replace(' ','')); if (current_url == bg_background.get('imgsrc')) { sendChat("error","/w gm ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฃผ์†Œ๋‚˜ ๋ช…๋ น์–ด ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•ด์ฃผ์„ธ์š”. (ex: !@๋ฐฐ๊ฒฝ https://์ด๋ฏธ์ง€์ฃผ์†Œ...)",null,{noarchive:true}); } } else { if (bg_deck.length == 0) { sendChat("error","/w gm **background** ๋ฑ์ด ์ฝœ๋ ‰์…˜์— ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€๋ฅผ background ๋ฑ์— ๋„ฃ๊ฑฐ๋‚˜ !@๋ฐฐ๊ฒฝ https://์ด๋ฏธ์ง€์ฃผ์†Œ... ํ˜•์‹์œผ๋กœ ์ด๋ฏธ์ง€ ์ฃผ์†Œ๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•˜์„ธ์š”.",null,{noarchive:true}); return; } else { let bg_cards = findObjs({_type:'card', _deckid: bg_deck[0].get('_id'), name: new_bg}); if (bg_cards.length == 0) { sendChat("error","/w gm ์ด๋ฆ„์ด '**" + new_bg + "'**์ธ ๋ฐฐ๊ฒฝ ์นด๋“œ๊ฐ€ **background** ๋ฑ์— ์—†์Šต๋‹ˆ๋‹ค.", null,{noarchive:true}); return; } else { bg_background.set('imgsrc',bg_cards[0].get('avatar').replace('med','thumb').replace('max','thumb')); } } } } else if (vd_setting.use_emotion) { let cha_name = msg.who; let content_str = msg.content.replace(state.api_tag,'').replace('!@',''); let emot = content_str; if (content_str.lastIndexOf(':') &gt; -1 &amp;&amp; (playerIsGM(msg.playerid) || msg.playerid == 'API')) { cha_name = content_str.substring(0,content_str.lastIndexOf(':')); emot = content_str.substring(content_str.lastIndexOf(':')+1,content_str.length); } let chat_cha = findCharacterWithName(cha_name); let current_token = null; if (chat_cha || vd_setting.show_extra_standing) { current_token = findTokenWithCharacter(chat_cha?chat_cha.get('_id'):'', cha_name); } if (current_token) { let rt = findObjs({ _type: 'deck', name: vd_setting.deck_name}); if (rt.length == 0) { sendChat("error","/w gm ์ด๋ฆ„์ด **" + vd_setting.deck_name +"**์ธ ์นด๋“œ ๋ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } else { let opt = { name: 'vd_standing', _subtype: 'card', _pageid: current_token.get('_pageid'), width: vd_setting.width, height: vd_setting.height, bar1_value: cha_name, left:current_token.get('left'), top:current_token.get('top'), layer: 'map', represents: chat_cha? chat_cha.get('_id'): '', tint_color: current_token.get('tint_color') }; let search_opt = { _type: 'card', _deckid: rt[0].get('_id')}; if (!vd_setting.use_emotion) { search_opt.name = chat_cha ? cha_name : vd_setting.extra_name; } else if (emot.length &gt; 0) { search_opt.name = cha_name + "-" + emot; } else { search_opt.name = cha_name; } let rt_items = findObjs(search_opt); if (rt_items.length &gt; 0) { opt.imgsrc = rt_items[0].get('avatar').replace('med','thumb').replace('max','thumb'); } else { sendChat("error","/w gm **"+ vd_setting.deck_name + "** ์นด๋“œ ๋ฑ์— ์ด๋ฆ„์ด **" + search_opt.name + "**์ธ ์นด๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } current_token.set(opt); } } else { sendChat("error","/w \"" + msg.who + "\" ์ด๋ฆ„์ด **" + cha_name +"**์ธ ์บ๋ฆญํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); } } } // /on.chat:message:api }); // define: global function const vdGetCurrentPage = function() { const page_list = vd_setting.page_list.replace(/, /g,',').replace(/ ,/g,',').split(','); if (page_list.indexOf(getObj('page',Campaign().get("playerpageid")).get('name')) &gt; -1) { return Campaign().get("playerpageid"); } else { const page = findObjs({type:'page',name:page_list[0]}); if (page.length &gt; 0) { return page[0].get('_id'); } else { sendChat("error","/w gm ์ด๋ฆ„์ด **" + page_list[0] + "**์ธ ํŽ˜์ด์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); } } } const showDialogue = function() { let msg = state.vd_stock[0]; for (let index = 1; index &lt; state.vd_stock.length; index++) { const element = state.vd_stock[index]; if (element.who == msg.who &amp;&amp; Math.abs(element.time - msg.time) &lt; 100) { msg.content = msg.content + state.vd_divider + element.content; state.vd_stock.splice(index,1); index--; } else { break; } } const current_page_id = vdGetCurrentPage(); if (!current_page_id) { return; } let is_general = msg.type == "general"; const font_color = vd_setting[is_general?'dialogue_font_color':'desc_font_color']; let font_size = vd_setting[is_general ? 'dialogue_font_size' : 'desc_font_size']; let bg_area = findObjs({ _type: 'graphic', name:'vd_area', _pageid:current_page_id}); let bg_name = findObjs({ _type: 'graphic', name:'vd_name', _pageid:current_page_id}); let bg_dialogue = findObjs({ _type: 'graphic', name:'vd_dialogue', _pageid:current_page_id}); let bg_panel = findObjs({ _type: 'graphic', name:'vd_panel', _pageid:current_page_id}); let split = []; if (bg_area.length &gt; 0) { bg_area = bg_area[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_area ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); showNextDialogue(); return; } if (bg_name.length &gt; 0) { bg_name = bg_name[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_name ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); showNextDialogue(); return; } if (bg_dialogue.length &gt; 0) { bg_dialogue = bg_dialogue[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_dialogue ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); showNextDialogue(); return; } if (bg_panel.length &gt; 0) { bg_panel = bg_panel[0]; } else { sendChat("error","/w gm **" + getObj('page',current_page_id).get('name') + "** ํŽ˜์ด์ง€์— vd_panel ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); showNextDialogue(); return; } const width = bg_dialogue.get('width'); const name_width = bg_name.get('width'); let blank_name = ''; let blank_dialogue = ''; let text_name = getObj('text', bg_name.get('gmnotes')); let text_dialogue = getObj('text', bg_dialogue.get('gmnotes')); while (name_width &gt; blank_name.length*vd_setting['name_font_size']*vd_setting['letter_spacing']*1.2) { blank_name += "โ€ƒ"; } while (width&gt;blank_dialogue.length*font_size*vd_setting['letter_spacing']*1.15) { blank_dialogue += "โ€ƒ"; } if (text_name &amp;&amp; text_name.get('_pageid') != current_page_id) { text_name.remove(); text_name = null; } if (text_dialogue &amp;&amp; text_dialogue.get('_pageid') != current_page_id) { text_dialogue.remove(); text_dialogue = null; } if (!text_name) { text_name = createObj('text', { _pageid: bg_area.get('_pageid'), left: bg_name.get('left'), top: bg_name.get('top'), width: bg_name.get('width'), height: bg_name.get('height'), layer: 'objects', font_family: 'Arial', text: '', font_size: vd_setting['name_font_size'], color: vd_setting['name_font_color'] }); bg_name.set({'gmnotes':text_name.get('_id')}); } if (!text_dialogue) { text_dialogue = createObj('text', { _pageid: bg_dialogue.get('_pageid'), left: bg_dialogue.get('left'), top: bg_dialogue.get('top'), width: width, height: bg_dialogue.get('height'), layer: 'objects', font_family: 'Arial', text: '', font_size: font_size, color: font_color }); bg_dialogue.set({'gmnotes':text_dialogue.get('_id')}); } // ์˜ˆ์™ธ์ฒ˜๋ฆฌํ•  ํ…์ŠคํŠธ ์ œ์™ธ let name = msg.who + '\n' + blank_name; let filtered = msg.content; let filter_word = [ {regex:/\*.+\*/g,replace:/\*/g}, // *, **, *** {regex:/``.+``/g,replace:/``/g}, // `` {regex:/\[[^\(\)\[\]]*\]\(http[^\(\)\[\]]+\)/g,replace:/\[[^\(\)\[\]]*\]\(http[^\(\)\[\]]+\)/g}, // [](http...) {regex:/&lt;[^&gt;]*&gt;/g,replace:/&lt;[^&gt;]*&gt;/g}, // &lt;html&gt; {regex:/\(.{1}\" style=\"[^\)]+\)/g,replace:/\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/g}, // [](#" style="...) {regex:/\$\[\[.+\]\]/g,replace:/\$\[\[.+\]\]/g}]; // [[]] for (let i=0;i&lt;filter_word.length;i++) { let match = filtered.match(filter_word[i].regex); if (match) { for (let j=0;j&lt;match.length;j++) { filtered = filtered.replace(match[j], match[j].replace(filter_word[i].replace,'')); } } } let ruby_match = filtered.match(/\([^\(\)\[\]]+\)\[[^\(\)\[\]]*\]/g); if (ruby_match) { for (let j=0;j&lt;ruby_match.length;j++) { let rubystr_split = ruby_match[j].substring(1,ruby_match[j].length-1).split(')['); filtered = filtered.replace(ruby_match[j], rubystr_split[1]+"("+rubystr_split[0]+")"); } } if (filtered.length == 0){ showNextDialogue(); return; } let str = filtered; let desc_ratio = is_general ? 1 : 0.8; let amount = Math.ceil(width/font_size/vd_setting['letter_spacing']*3) -3; let idx = 0; let length = 0; const thirdchar = ['\'',' ',',','.','!',':',';','"']; const halfchar = ['[',']','(',')','*','^','-','~','&lt;','&gt;','+','l','i','1']; const arr = thirdchar.concat(halfchar); let divided = false; for (let i=0;i&lt;str.length;i++){ let c = str[i]; length += 3; for (let j=0;j&lt;arr.length;j++) { if (c==arr[j]) { length -= (j&lt;thirdchar.length ? 2 : 1); break; } } if (length &gt;= amount * desc_ratio || c == state.vd_divider) { let substr = str.substring(idx,i+1).replace(state.vd_divider,''); split.push(is_general || msg.who.length &gt; 0 ? substr:getStringWithMargin(amount,length,desc_ratio,substr)); idx = i+1; length = 0; if ((split.length+1) * font_size * vd_setting['letter_spacing']*3 &gt; bg_dialogue.get('height')) { state.vd_stock.splice(1,0,{content:filtered.substring(idx,str.length),time:msg.time,playerid:msg.playerid,type:msg.type,who:msg.who}); divided = true; break; } } } if (idx &lt; str.length &amp;&amp; !divided) { let substr = str.substring(idx,str.length); split.push(is_general || msg.who.length &gt; 0 ? substr:getStringWithMargin(amount,length,desc_ratio,substr)); } if (is_general || msg.who.length &gt; 0) { while ((split.length+1) * font_size * vd_setting['line_height'] &lt; bg_dialogue.get('height')) { split.push(' '); } } else { split.splice(0,0,' '); } split.push(blank_dialogue); text_name.set({text:name,left:bg_name.get('left'),font_size: vd_setting['name_font_size'],color: vd_setting['name_font_color'], top:bg_name.get('top')+vd_setting['name_font_size']*vd_setting['line_height']/2}); text_dialogue.set({text:split.join('\n'),font_size: font_size, color: font_color, left: msg.type == 'desc' ? bg_panel.get('left'):bg_dialogue.get('left'), top: msg.type == 'desc'? bg_panel.get('top'):bg_dialogue.get('top')}); toFront(text_name); toFront(text_dialogue); setTimeout(() =&gt; { showHideDecorations('vd_panel',true); showHideDecorations('vd_deco',msg.type != 'desc'); toFront(text_name); toFront(text_dialogue); }, 100); clearTextWithout(text_name, text_dialogue); const ignore_list = vd_setting.ignore_list.replace(/, /g,',').replace(/ ,/g,',').split(','); if (msg.type != "desc" &amp;&amp; ignore_list.indexOf(msg.who) &lt; 0) { let chat_cha = findCharacterWithName(msg.who); let current_token = null; if (chat_cha || vd_setting.show_extra_standing) { current_token = findTokenWithCharacter(chat_cha?chat_cha.get('_id'):'', msg.who); } let tokens = findObjs({ _type: 'graphic', name: 'vd_standing', _pageid: current_page_id}); let lowest_priority = tokens[0]; for (var i=0;i&lt;tokens.length;i++) { var token = tokens[i]; token.set('tint_color','#000000'); if (parseInt(token.get('gmnotes')) &lt; parseInt(lowest_priority.get('gmnotes'))) { lowest_priority = token; } } if (current_token == null &amp;&amp; (chat_cha || vd_setting.show_extra_standing)) { let nm = chat_cha?msg.who:vd_setting.extra_name; let rt = findObjs({ _type: 'deck', name: vd_setting.deck_name}); if (rt.length == 0) { sendChat("error","/w gm ์ด๋ฆ„์ด **"+ vd_setting.deck_name + "**์ธ ์นด๋“œ ๋ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); showNextDialogue(); return; } else { let opt = { name: 'vd_standing', _pageid: bg_area.get('_pageid'), width: vd_setting.width, height: vd_setting.height, bar1_value: msg.who, layer: 'gmlayer', imgsrc: rt[0].get('avatar').replace('med','thumb').replace('max','thumb'), represents: chat_cha? chat_cha.get('_id'): '' }; const std = findObjs({ _type: 'card', _deckid: rt[0].get('_id'), name: msg.who}); if (std.length &gt; 0) { opt.imgsrc = std[0].get('avatar').replace('med','thumb').replace('max','thumb'); } if (tokens.length &gt;= vd_setting.max_number) { opt.left = lowest_priority.get('left'); } else { opt.left = arrangeStandings(true); } opt.top = bg_area.get('top'); if (tokens.length &gt;= vd_setting.max_number) { lowest_priority.set(opt); current_token = lowest_priority; } else { current_token = createObj('graphic', opt); } toFront(current_token); setTimeout(() =&gt; { current_token.set({tint_color:'transparent',gmnotes:Date.now(),layer:"map"}); }, 100); } } else if (current_token) { toFront(current_token); current_token.set({tint_color:'transparent',gmnotes:Date.now()}); } } state.last_displayed_time = new Date().getTime(); setTimeout(showNextDialogue, Math.max(vd_setting.min_showtime, str.length * vd_setting.showtime_ratio)); } const clearTextWithout = function(name_txt, dial_txt) { let filtered_txt = filterObjs(function(obj) { return (obj.get('_type') == 'text' &amp;&amp; obj.get("_pageid") == name_txt.get('_pageid') &amp;&amp; obj.get("_id") != name_txt.get('_id') &amp;&amp; obj.get("_id") != dial_txt.get('_id') &amp;&amp; ((Math.abs(obj.get("left") - name_txt.get('left')) &lt; 100 &amp;&amp; Math.abs(obj.get("top") - name_txt.get('top')) &lt; 100) || (Math.abs(obj.get("left") - dial_txt.get('left')) &lt; 100 &amp;&amp; Math.abs(obj.get("top") - dial_txt.get('top')) &lt; 100))); }); filtered_txt.forEach(txt =&gt; { txt.remove(); }); } const updateMacro = function(obj) { let background_deck = findObjs({type:'deck',name:'background'}); if (background_deck.length &gt; 0 &amp;&amp; obj.get('deckid') == background_deck[0].get('id')) { if (background_deck.length &gt; 1) { sendChat("error","/w gm **background** ๋ฑ์ด **" + background_deck.length + "**๊ฐœ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ƒ์„ฑ๋œ 1๊ฐœ ๋ฑ์„ ๊ธฐ์ค€์œผ๋กœ ๋งคํฌ๋กœ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.",null,{noarchive:true}); } let players = findObjs({type:'player'}); let bg_images = findObjs({_type:'card',_deckid:background_deck[0].get('id')}); let bg_macro = findObjs({_type:'macro',name:"๋ฐฐ๊ฒฝ์ „ํ™˜"}); let action_str = "!@๋ฐฐ๊ฒฝ ?{๋ฐฐ๊ฒฝ์„ ์„ ํƒํ•˜์„ธ์š”"; let gm_list = ""; for (let index = 0; index &lt; bg_images.length; index++) { const card = bg_images[index]; action_str += "|" + card.get('name'); } for (let index = 0; index &lt; players.length; index++) { const player = players[index]; if (playerIsGM(player.id)) { gm_list += player.id + ","; } } gm_list = gm_list.substring(0,gm_list.length - 1); action_str += "}"; let options = {name:"๋ฐฐ๊ฒฝ์ „ํ™˜",action:action_str,visibleto:gm_list}; if (bg_macro.length &gt; 0) { bg_macro = bg_macro[0]; bg_macro.set(options); } else { options.playerid = players[0].get('id'); bg_macro = createObj('macro',options); } } } const showHideDecorations = function(name, show) { const text_deco = findObjs({name: name, _type: 'graphic'}); for (let index = 0; index &lt; text_deco.length; index++) { const itm = text_deco[index]; if (show) { if (itm.get('gmnotes').includes('/')) { const wh = itm.get('gmnotes').split('/'); itm.set({width:parseInt(wh[0]),height:parseInt(wh[1]),layer:'objects'}); } toFront(itm); } else { if (itm.get('gmnotes').length == 0) { itm.set({gmnotes:itm.get('width')+"/"+itm.get('height')}); } itm.set({width:1,height:1,layer:'gmlayer'}); } } } const showNextDialogue = function() { state.vd_stock.splice(0,1); if (state.vd_stock.length &gt; 0) { showDialogue(); } } const getStringWithMargin = function(amount, length, ratio, str) { let margin = Math.round((amount - length)/4*ratio); for (var j=0;j&lt;margin;j++){ str = "ใ…ค" + str + "ใ…ค"; } return str; } const findCharacterWithName = function(who) { let chat_cha = findObjs({ _type: 'character', name: who}); if (chat_cha.length &gt; 0) { return chat_cha[0]; } else { return null; } } const findTokenWithCharacter = function(id, who) { let arr = findObjs({ _type: 'graphic', name: 'vd_standing', represents: id, _pageid: vdGetCurrentPage(), bar1_value: who}); if (arr.length &gt; 0) { return arr[0]; } return null; } const removeStanding = function(msg) { let character = findCharacterWithName(msg.who); let token = findTokenWithCharacter(character?character.get('_id'):'', msg.who); if (token) { token.remove(); arrangeStandings(false); } } const arrangeStandings = function(addNew) { const currernt_page_id = vdGetCurrentPage(); let tokens = findObjs({ _type: 'graphic', name: 'vd_standing', _pageid: currernt_page_id}); if (tokens.length &gt; 0 || addNew) { let bg_area = findObjs({ _type: 'graphic', name:'vd_area', _pageid:currernt_page_id}); if (bg_area.length &gt; 0) { bg_area = bg_area[0]; } else { sendChat("error1","/w gm vd_area ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค.",null,{noarchive:true}); return; } let tokens_position = []; const compare = function( a, b ) { if ( a.left &lt; b.left ){ return -1; } if ( a.left &gt; b.left ){ return 1; } return 0; } for (var i=0;i&lt;tokens.length;i++) { tokens_position.push({idx:i,left:tokens[i].get('left')}); } tokens_position.sort(compare); let final_count = tokens.length + (addNew?1:0); final_count = final_count&lt;2? 2: final_count; let space = Math.floor(bg_area.get('width')/final_count); let left = bg_area.get('left') - Math.floor(bg_area.get('width')/2); if (space &lt; vd_setting.fit_width) { left += vd_setting.fit_width/2; space = Math.floor((bg_area.get('width')-vd_setting.fit_width)/(final_count-1)); } else { left += space/2 } let rand = addNew ? Math.floor(Math.random()*(tokens_position.length-1))+1 : Infinity; rand = rand &lt; 0 ? 0 : rand; for (var i=0;i&lt;tokens_position.length;i++) { let token = tokens[tokens_position[i].idx]; token.set('left',left + space * (i + (i&gt;=rand?1:0))); } return addNew ? left + space * (rand == Infinity ? 0 : rand) : false; } } // /define: global function /* (visual_dialogue.js) 220118 ์ฝ”๋“œ ์ข…๋ฃŒ */