Collapsibles in Gamebook mode!

Zesc
09 Sept 2019, 09:39Greetings fellow Quest users!
I recently attempted (unsucesfully) to transplant the text processor function of parser-games to create collapsibles into my gamebook. Since i am having no clue what i'm doing whilst messing with the libraries, i decided to stop before my PC inexplicably catches fire from my incompetence.
Yet trying to use {popup:}
without any modification, i found it throws up some really odd error messages, transcribed here in full:
Error running script: Error compiling expression 'JSSafe(s1) + GetRandomInt(0, 999999999)': FunctionCallElement: Could find not function 'JSSafe(String)'
I honestly have lost track of what could possibly cause this (why a Random Integer?) and what i should do.
I am banging my head against a wall, and the wall is proving sturdier. Any suggestions? Help is as always highly appreciated!
mrangel
09 Sept 2019, 10:12{popup:
uses random integers to identify each popup, so that the link knows which one to show/hide. This is a pretty weird way of doing it, but shouldn't be a problem.
The function JSSafe
is in CoreFunctions.aslx
, and it just removes any characters that would be a problem in a javascript identifier. The function used in the Text Adventure mode looks like:
<function name="JSSafe" parameters="s" type="string"><![CDATA[
s = Replace(s, "\"", "")
s = Replace(s, "\'", "")
s = Replace(s, " ", "")
s = Replace(s, ".", "")
s = Replace(s, ",", "")
s = Replace(s, "!", "")
s = Replace(s, "?", "")
s = Replace(s, "-", "")
s = Replace(s, "/", "")
s = Replace(s, "(", "")
s = Replace(s, ")", "")
s = Replace(s, "$", "")
s = Replace(s, "%", "")
s = Replace(s, "&", "")
s = Replace(s, "*", "")
s = Replace(s, "@", "")
return (s)
]]></function>
You should be able to include that function, and your popups will work.
I'm a little curious about that function, though. It seems inefficient to me; I would be more inclined to use something like:
<function name="JSSafe" parameters="s" type="string"><![CDATA[
output = ""
for (i, 1, LengthOf(s)) {
c = Mid (s, i, 1)
if (Instr ("\"\'\\ .,!?-/()$%&*@", c) = 0) output = output + c
}
return (output)
]]></function>
or even
<function name="JSSafe" parameters="s" type="string"><![CDATA[
while (IsRegexMatch ("^(?<before>\\w*)\\W+(?<after>.*)$", s)) {
parts = Populate ("^(?<before>\\w*)\\W+(?<after>.*)$", s)
s = DictionaryItem(parts, "before") + DictionaryItem(parts, "after")
}
return (s)
]]></function>
(the regular expression engine is optimised to be very efficient at finding blocks of characters; but I'm not sure if the overhead of Quest's dictionaries would make that slower overall)

Zesc
09 Sept 2019, 20:49...why would anyone ever do this with random integers?
Anyway, thanks for your help. In the end, it was really as simple as adding CoreFunctions.aslx
, and all my attempts of specifically adding {popup:}
were ludicrously convoluted. Talking about missing the obvious.
The random Integer still baffles me.
mrangel
09 Sept 2019, 21:26The random Integer still baffles me.
The popup needs an ID that isn't shared with any other popup.
Quest doesn't have a list of the IDs it's already used.
Sticking a large random number on the end of the ID makes it unlikely to collide with anything.
A better approach might have been using a javascript function to generate the ID; but a lot of the text processor stuff seems to be written with an absolute minimum of JS for no obvious reason.

Zesc
10 Sept 2019, 20:55Oh, i get why there is an ID needed. But as a mathematician, i don't see why you would use a random int for this. Picking an element from any finite set has the chance of hitting a previously used one... Especially since we're only talking of a billion here. I haven't done the Gaußian distribution, but if your games uses enough popups, you're in peril.
Hmm, if i ever find the time and motivation (read: never) i might actually look into the code behind {popup:}
and get it working properly (the lack of background transparency annoys me, for example).