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

Loading Screen api - removing random to order, how?

So I know I need to edit this line (90):  var pickone = randomInteger(tips.length) - 1; But I know nothing about json. Trying to repurpose this and need it to go in order. Code: /* Roll 20 - Script Title: DnD 5e Tips Based Loading Page Author: Michael Nekrasov Description: Creates a page to drop players on to that gives helpful tips while DM sets up a map To use: 1. Create a page called "Loading" (you can change this in variables) 2. On the object layer create a textbox (will be auto created if none exists) Note: To optimize resources, the tooltips only change when the players (not GM) are viewing the page */ var displaySpeed = 15000; //Sets speed (in milleseconds) at which to cycle tips var numChars = 70; //Set maximum number of characters per line var targetPageName = "Loading"; //The name of the page you want to use for your loading screen var onlyChangeIfVisible = false; //Only rotates tips when players are on Loading screen var debug = true; //Enables debugging messages var tips = [ "In the quietude of their separate lives, five souls moved through mundane rhythms until an inexplicable event shattered their reality. A blinding light enveloped them, revealing forgotten memories and distant echoes. When their vision returned, they stood in a dimly lit chamber, strangers bound by shared bewilderment.", "Who were they? Why were they here? The questions echoed silently, etching themselves into their newfound reality. As their eyes adjusted to the gloom, they realized they were not alone.", "Five figures stood there, drawn together by an invisible thread. And so began their tale—the tale of five souls awakened, their destinies irrevocably intertwined, and the promise of a world beyond imagination awaiting them", ]; // // Don't edit bellow this line if you don't know what you are doing // ------------------------------------------------------ function fixNewObject(obj) { var p = obj.changed._fbpath; var new_p = p.replace(/([^\/]*\/){4}/, "/"); obj.fbpath = new_p; return obj; } on("ready", function(obj) { var loadingPage; // Warn user that there is no page if( findObjs({_type: "page",name: targetPageName}).length == 0){ log("Warning! No Page named '"+targetPageName+"' exists, create one for this script to work"); return; } else{ loadingPage = findObjs({_type: "page",name: targetPageName})[0]; } //Update the loading screen with a new tip (requires players to be viewing page) var UpdateWithNewTip = function() { //Change Tip only if Red player marker is on Loading Page if(onlyChangeIfVisible && getObj("page", Campaign().get("playerpageid")).get("name") != targetPageName) return; else if(debug) log("Players not on "+targetPageName); var textObjects = findObjs({ _type: "text", _pageid: loadingPage.get("_id"), layer: "objects" }); if(debug) log("Text Objects on page"); if(debug) log(textObjects); //Find First text field or create one if none exists var text; if(textObjects.length == 0){ if(debug) log("Create New Text Box"); text = createObj("text", { _pageid: loadingPage.get("_id"), left: 650, top: 255, width: 200, height: 200, font_size: 56, text: "Loading...", layer: "objects" }); text = fixNewObject(text); } else{ if(debug) log("Text Box Already Exists"); text = textObjects[0]; } var pickone = randomInteger(tips.length) - 1; var formattedText; var formattedLines = []; _.each(tips[pickone].split(/\n/),function(l){ formattedText = ''; _.each(l.split(''),function(c){ if(formattedText.length > numChars && ' ' === c) { formattedLines.push(formattedText); formattedText = ''; } else { formattedText += c; } }); formattedLines.push(formattedText); }); formattedText=formattedLines.join("\n"); text.set("text", formattedText); if(debug) log( "new tip: "+ text.get("text")); } UpdateWithNewTip(); setInterval( UpdateWithNewTip, displaySpeed); //take an action every ___ seconds });
1721429576
timmaugh
Pro
API Scripter
There are several things I'd like to do to that script (like housing all of its variables in the script closure to prevent namespace pollution... or telling it to get its tips from a character -- because editing tips in the GMNotes field of a character sheet would be a hell of a lot easier than having to open the code and edit it, there, if you needed to change... or having it create the Loading page automatically if it doesn't exist... or creating that character automatically if it doesn't exist... or... ) Lots of things. However, this is about the minimum you have to do to that script to make it work. Basically, you need to record somewhere what index of tip you are on so that you can reference it when you need to increment it and show the next one. You can do that with a closure in an IIFE (so that the variable sticks around from incrementation to incrementation)... or you can store it in the state. It's was a quicker edit to store it in the state, though not my preferred method of doing things. Anyway, this should work: /*   Roll 20 - Script       Title: DnD 5e Tips Based Loading Page   Author: Michael Nekrasov   Description: Creates a page to drop players on to that gives helpful tips while DM sets up a map      To use:   1. Create a page called "Loading" (you can change this in variables)   2. On the object layer create a textbox (will be auto created if none exists)      Note: To optimize resources, the tooltips only change when the players (not GM) are viewing the page */ var displaySpeed = 15000; //Sets speed (in milleseconds) at which to cycle tips var numChars = 70; //Set maximum number of characters per line var targetPageName = "Loading"; //The name of the page you want to use for your loading screen var onlyChangeIfVisible = false; //Only rotates tips when players are on Loading screen var debug = true; //Enables debugging messages var tips = [ "In the quietude of their separate lives, five souls moved through mundane rhythms until an inexplicable event shattered their reality. A blinding light enveloped them, revealing forgotten memories and distant echoes. When their vision returned, they stood in a dimly lit chamber, strangers bound by shared bewilderment.", "Who were they? Why were they here? The questions echoed silently, etching themselves into their newfound reality. As their eyes adjusted to the gloom, they realized they were not alone.", "Five figures stood there, drawn together by an invisible thread. And so began their tale—the tale of five souls awakened, their destinies irrevocably intertwined, and the promise of a world beyond imagination awaiting them", ]; //  // Don't edit bellow this line if you don't know what you are doing // ------------------------------------------------------ function fixNewObject(obj) { var p = obj.changed._fbpath; var new_p = p.replace(/([^\/]*\/){4}/, "/"); obj.fbpath = new_p; return obj; } on("ready", function (obj) { if (!state.LoadingScreen) state.LoadingScreen = { currentTip: 0 }; if (!state.LoadingScreen.hasOwnProperty("currentTip") || state.LoadingScreen.currentTip >= tips.length) state.LoadingScreen.currentTip = 0; var loadingPage; // Warn user that there is no page if (findObjs({ _type: "page", name: targetPageName }).length == 0) { log("Warning! No Page named '" + targetPageName + "' exists, create one for this script to work"); return; } else { loadingPage = findObjs({ _type: "page", name: targetPageName })[0]; } //Update the loading screen with a new tip (requires players to be viewing page) var UpdateWithNewTip = function () { //Change Tip only if Red player marker is on Loading Page if (onlyChangeIfVisible && getObj("page", Campaign().get("playerpageid")).get("name") != targetPageName) return; else if (debug) log("Players not on " + targetPageName); var textObjects = findObjs({ _type: "text", _pageid: loadingPage.get("_id"), layer: "objects" }); if (debug) log("Text Objects on page"); if (debug) log(textObjects); //Find First text field or create one if none exists var text; if (textObjects.length == 0) { if (debug) log("Create New Text Box"); text = createObj("text", { _pageid: loadingPage.get("_id"), left: 650, top: 255, width: 200, height: 200, font_size: 56, text: "Loading...", layer: "objects" }); text = fixNewObject(text); } else { if (debug) log("Text Box Already Exists"); text = textObjects[0]; } var formattedText; var formattedLines = []; _.each(tips[state.LoadingScreen.currentTip].split(/\n/), function (l) { formattedText = ''; _.each(l.split(''), function (c) { if (formattedText.length > numChars && ' ' === c) { formattedLines.push(formattedText); formattedText = ''; } else { formattedText += c; } }); formattedLines.push(formattedText); }); formattedText = formattedLines.join("\n"); text.set("text", formattedText); state.LoadingScreen.currentTip = state.LoadingScreen.currentTip >= tips.length ? 0 : state.LoadingScreen.currentTip + 1; if (debug) log("new tip: " + text.get("text")); } UpdateWithNewTip(); setInterval(UpdateWithNewTip, displaySpeed); //take an action every ___ seconds    });
1724402410

Edited 1724402449
hi, sorry for the late respond, totally forgot I asked about this. So I tried the new one out and after it finishes the first cycle, the script crashes Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your script's code and click the "Save Script" button. We will then attempt to start running the scripts again.  More info...  If this script was installed from the Mod Library, you might find help in the Community API Forum. For reference, the error message generated was:  TypeError: Cannot read properties of undefined (reading 'split') TypeError: Cannot read properties of undefined (reading 'split') at Timeout.UpdateWithNewTip [as _onTimeout] (apiscript.js:37637:47) at listOnTimeout (node:internal/timers:569:17) at process.processTimers (node:internal/timers:512:7)
1724441426
timmaugh
Pro
API Scripter
Sorry, I was a little sloppy with my incrementing, at the end.  Change line 97 (of my version) from this: state.LoadingScreen.currentTip = state.LoadingScreen.currentTip >= tips.length ? 0 : state.LoadingScreen.currentTip + 1; ...to state.LoadingScreen.currentTip = state.LoadingScreen.currentTip + 1 >= tips.length ? 0 : state.LoadingScreen.currentTip + 1; That should do it.