Library: Three pages of questions

The Pixie
EDIT 1: I have updated the library so it now works on integer values, rather than strings, which makes it much easier to increase and decrease the attributes.

EDIT 2: The second update allows you to have any number of pages of questions. You can download the library and demo in this zip file:



So you have a character creation process like a questionaire. You could give a menu of choices, then another men, then another and another and...

Or you could put say six questions, each with their own options on a page, and another six on another page, and another six of a third page. This library lets you do just that. You can see the principle here, in the demo:
http://textadventures.co.uk/games/view/ ... r-neonayon

For each list of options, a random option is also provided to the player, and if chosen, a value is automatically assigned from the appropriate options.

Setting Up

Once you have added the library to your game, to use it, just create each list of options as a string list on the game object. Then set up the menus in the start script of the game object. There are four functions required.

AddCreationNewPage (string title): Start a new page of options, with the given title. You need to call this before any of the other functions, and in total you need to call it once for each page you want.

AddCreationList (string listname, string name, string title): Adds a menu to the current page. The first attribute is the name of the string list attribute on the game object (and not the attribute itself). You can use the same attribute more than once. The name parameter is what the attribute on the player will be called. It must be unique. The title is what the player will see at the top of the options.

AddCreationListSubset (string listname, string name, string title, int from, int to): Adds a menu to the current page, as AddCreationList, but only displays a subset of the list as options. Options are added from the from item in the list; 0 is the first element, so a value of 2 will skip the first two entries, a value of 0 will not skip any. Options are added up to (and excluding) the to item in the list. Alternatively, you can give a minus number to count back for the to value. For example, a value of 7 will skip item 7 (remember that they count from zero) and onwards; a value of 0 will skip none and a value of -1 will skip the last entry. To illustrate, given this list, with 8 entries (numbered from 0 to 7):
game.heights = Split("Tiny|Small|Below average|Average|Above average|Tall|Very tall|Freakishly tall", "|")
These two will both miss the first and last entries
AddCreationListSubset ("heights", "height", "Height", 1, 7)
AddCreationListSubset ("heights", "height", "Height", 1, -1)

AddCreationNewLine: Call this to have the next menu go into a new row. It looks best if you have three menus across and two high, in my opinion, but if you have more scroll bars will appear to fit them.

CreationGo: Call this to have the dialogs display. You should call this only once, and once you have do not call any of the above.

Here is an example:
// First page, two menus on top row, one on bottom row.
AddCreationNewPage ("What are your strengths?")
AddCreationList ("atts", "pri_att", "Primary Attribute")
AddCreationList ("atts", "sec_att", "Secondary Attribute")
AddCreationNewLine
AddCreationList ("advs", "advantage", "Special advantage")

// Second page
AddCreationNewPage ("What are your weaknesses?")
AddCreationList ("atts", "pri_neg", "Primary Weakness")
AddCreationList ("atts", "sec_neg", "Secondary Weakness")
AddCreationNewLine
AddCreationList ("dbs", "drawback", "Drawback")

// Third page
AddCreationNewPage ("What is your background")
AddCreationList ("bgds", "background", "Background")
AddCreationListSubset ("heights", "height", "Height", 1, -1)
AddCreationListSubset ("builds", "build", "Build", 1, 8)
CreationGo


Changing Values

There are also two new functions to change attributes

Increase(string attname): Increases the named attribute by one. Return true if successful, and false if not (the attribute is already at the limit for the list).

Decrease(string attname): Decreases the named attribute by one. Return true if successful, and false if not (the attribute is already at zero).

If you have an attribute called "height", then this will store the height as a string. The system will also generate another attribute "height_as_int", where the value is stored as an integer. You can modify "height_as_int", and "height" ill get updated automatically (and "height_as_int" will get reset to be in range if you try to set it too high or too low).

In the demo game, the BIGGER command changes the value of "height_as_int", while SMALLER calls the function Decrease.

The Code

<library>
<object name="creation_dialogue_object">
<script_prototype type="script">
UpdateAllAttributes
</script_prototype>

<window><![CDATA[
<div id="dialog_window_###WINDOW###" class="dialog_window" title="###TITLE###" style="display:none;">
<table width="100%" style="-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none;">
<tr class="details">
###CONTENT###
</tr>
</table>
</div>
]]></window>
<firstWindow><![CDATA[
$(document).ready(function () {
$('.ui-dialog-titlebar-close').css('visibility', 'hidden');
$('#dialog_window_1').dialog({
height: 520,
width: 640,
buttons: {
###BUTTON###
}
});
});
]]></firstWindow>
<secondWindow><![CDATA[
function window###WINDOW###() {
$('#dialog_window_###PREVIOUS###').dialog("close");
if ($("input:radio[name='race_input']:checked").val() == '4') {
$('#skintonetd').css('display', 'none');
$('#scalestd').css('display', 'block');
}
$('#dialog_window_###WINDOW###').dialog({
height: 520,
width: 640,
buttons: {
###BUTTON###
}
});
}
]]></secondWindow>
<setValues><![CDATA[
function setValues() {
answer = "answers";
###VALUES_SCRIPT###
ASLEvent("HandleDialogue", answer);
$('#dialog_window_###WINDOW###').dialog("close");
}
]]></setValues>
<author>The Pixie</author>
</object>


<function name="HandleDialogue" parameters="answer">
//msg(answer)
l = Split(answer, "|")
for (i, 0, ListCount(creation_dialogue_object.creation_name_list) - 1) {
lst = GetAttribute(game, StringListItem(creation_dialogue_object.creation_lists_list, i))
if (StringListItem(l, i + 1) = "random") {
index = GetRandomInt(0, ListCount(lst) - 1)
//set (player, StringListItem(creation_dialogue_object.creation_name_list, i), StringListItem(lst, index))
}
else {
//msg ("Looking for " + StringListItem(l, i + 1) + " in ")
index = IndexOf(StringListItem(l, i + 1), lst)
//set (player, StringListItem(creation_dialogue_object.creation_name_list, i), StringListItem(l, i + 1))
}
set (player, StringListItem(creation_dialogue_object.creation_name_list, i) + "_as_int", index)
//msg (StringListItem(creation_dialogue_object.creation_name_list, i) + ": " + GetString(player, StringListItem(creation_dialogue_object.creation_name_list, i)))
set (player, "changed" + StringListItem(creation_dialogue_object.creation_name_list, i) + "_as_int", creation_dialogue_object.script_prototype)
}
UpdateAllAttributes
</function>


<!--

from: Options are added from this item in the list; 0 is the first element, so a value of 2 will skip the first two entries
to: Options are added to (and exclding) this item in the list

For example, given this list, with 7 entries:
game.heights = Split("Tiny|Small|Below average|Average|Above average|Tall|Very tall|Freakishly tall", "|")
These two will both miss the first and last entries
AddCreationListSubset ("heights", "height", "Height", 1, 7)
AddCreationListSubset ("heights", "height", "Height", 1, -1)

-->


<function name="AddCreationListSubset" parameters="listname, name, title, from, to"><![CDATA[
// Check if stuff needs to be initialised first
if (not HasInt(creation_dialogue_object, "creation_page_count")) {
creation_dialogue_object.creation_page_count = 1
}
if (not HasString(creation_dialogue_object, "creation_values_script")) {
creation_dialogue_object.creation_values_script = ""
}
if (not HasAttribute(creation_dialogue_object, "creation_lists_list")) {
creation_dialogue_object.creation_lists_list = NewStringList()
}
if (not HasAttribute(creation_dialogue_object, "creation_name_list")) {
creation_dialogue_object.creation_name_list = NewStringList()
}

// Get the list from the game object
list = GetAttribute(game, listname)
// This is the name of the attribute that will store the HTML table string
att = "creation_table_" + creation_dialogue_object.creation_page_count
//name2 = LCase(Replace(name, " ", "_"))
if (not HasString(creation_dialogue_object, att)) {
set (creation_dialogue_object, att, "")
}
if (to <= 0) {
to = ListCount(list) + to
}
// Grab the string we already have
s = GetString(creation_dialogue_object, att)
// Add the new title
s = s + "<td>" + title + "<br/>\n"
// Add each option
for (i, from, to - 1) {
s = s + "<input type=\"radio\" name=\"" + name + "_input\" value=\"" + StringListItem(list, i) + "\"/>" + StringListItem(list, i) + "<br/>\n"
}
// Add the rtandom option
s = s + "<input type=\"radio\" name=\"" + name + "_input\" value=\"random\" checked=\"checked\"/>Random<br/>\n"
// Add the ending
s = s + "</td>\n"
// Save back to the attribute
set (creation_dialogue_object, att, s)

// This will update the JavaScript function that is called when the last dialog is closed so we collect this value
creation_dialogue_object.creation_values_script = creation_dialogue_object.creation_values_script + " answer += \"|\" + $(\"input:radio[name='" + name + "_input']:checked\").val();\n"
// Finally add the attribute name and its list to the lists
list add (creation_dialogue_object.creation_lists_list, listname)
list add (creation_dialogue_object.creation_name_list, name)
]]></function>



<function name="AddCreationList" parameters="listname, name, title">
AddCreationListSubset(listname, name, title, 0, 0)
</function>



<function name="AddCreationNewLine"><![CDATA[
if (not HasInt(creation_dialogue_object, "creation_page_count")) {
creation_dialogue_object.creation_page_count = 1
}
att = "creation_table_" + creation_dialogue_object.creation_page_count
if (not HasString(creation_dialogue_object, att)) {
set (creation_dialogue_object, att, "")
}
s = GetString(creation_dialogue_object, att)
s = s + "</tr>\n<tr>\n"
set (creation_dialogue_object, att, s)
]]></function>


<function name="AddCreationNewPage" parameters="title">
if (not HasInt(creation_dialogue_object, "creation_page_count")) {
creation_dialogue_object.creation_page_count = 1
}
else {
creation_dialogue_object.creation_page_count = creation_dialogue_object.creation_page_count + 1
}
set (creation_dialogue_object, "creation_page_" + creation_dialogue_object.creation_page_count, title)
</function>



<function name="CreationGo"><![CDATA[
// create some windows
for (i, 1, creation_dialogue_object.creation_page_count) {
s = creation_dialogue_object.window
s = Replace(s, "###WINDOW###", "" + i)
s = Replace(s, "###TITLE###", GetString(creation_dialogue_object, "creation_page_" + i))
s = Replace(s, "###CONTENT###", GetString(creation_dialogue_object, "creation_table_" + i))
OutputTextNoBr(s)
}

//s = creation_dialogue_object.stuff
s = creation_dialogue_object.firstWindow
s = Replace(s, "###BUTTON###", CreationGetJSButton(1))

for (i, 2, creation_dialogue_object.creation_page_count) {
s = s + creation_dialogue_object.secondWindow
s = Replace(s, "###WINDOW###", "" + i)
s = Replace(s, "###PREVIOUS###", "" + (i - 1))
s = Replace(s, "###BUTTON###", CreationGetJSButton(i))
}



// create function to collect data
s = s + creation_dialogue_object.setValues
s = Replace(s, "###WINDOW###", "" + creation_dialogue_object.creation_page_count)
s = Replace(s, "###VALUES_SCRIPT###", creation_dialogue_object.creation_values_script)

OutputTextNoBr ("<script>" + s + "</script>")
]]></function>






<function name="CreationGetJSButton" type="string" parameters="n"><![CDATA[
if (creation_dialogue_object.creation_page_count = n) {
return ("\"Done\": function() { setValues();}")
}
else {
return ("\"Next\": function() { window" + (n + 1) + "();}")
}
]]></function>






<function name="UpdateAllAttributes"><![CDATA[
for (i, 0, ListCount(creation_dialogue_object.creation_name_list) - 1) {
att = StringListItem(creation_dialogue_object.creation_name_list, i)
index = GetInt (player, att + "_as_int")
if (index < 0) {
index = 0
set (player, att + "_as_int", index)
}
lst = GetAttribute(game, StringListItem(creation_dialogue_object.creation_lists_list, i))
if (index >= ListCount(lst)) {
index = ListCount(lst) - 1
set (player, att + "_as_int", index)
}
set (player, StringListItem(creation_dialogue_object.creation_name_list, i), StringListItem(lst, index))
}
]]></function>


<function name="Increase" type="boolean" parameters="att">
index = GetInt (player, att + "_as_int")
lst = GetAttribute(game, StringListItem(creation_dialogue_object.creation_lists_list, i))
if (index >= ListCount(lst)) {
return (false)
}
set (player, att + "_as_int", index + 1)
return (true)
</function>


<function name="Decrease" type="boolean" parameters="att"><![CDATA[
index = GetInt (player, att + "_as_int")
if (index < 0) {
return (false)
}
set (player, att + "_as_int", index - 1)
return (true)
]]></function>


<function name="IndexOf" type="int" parameters="item, lst">
for (i, 0, ListCount(lst) - 1) {
if (StringListItem(lst, i) = item) {
return (i)
}
}
return (-1)
</function>
</library>


Here is a full demo. Type the command TEST to see three of your choices. Type BIGGER or SMALLER to change your size.
<!--Saved by Quest 5.6.5621.18142-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<include ref="ThreePageDialogLib.aslx" />
<game name="UI Test for Neonayon">
<gameid>34419325-ce15-4906-ae0e-2fd8ce8f6373</gameid>
<version>1.0</version>
<firstpublished>2015</firstpublished>
<author>The Pixie</author>
<atts type="stringlist">
<value>Sport</value>
<value>Puzzles</value>
<value>Sneaking</value>
<value>Persuasion</value>
<value>Creativity</value>
</atts>
<start type="script">
game.advs = Split("Chameleon|Techie|Motor-bike|X-ray eyes|Super strength|Mind reader|Lucky", "|")
game.dbs = Split("Stupid|Pig-ugly|Lazy|Slow|Technophobe", "|")
game.bgds = Split("Astronaut|Janitor|Paperboy|Mad scientist|Mutant|Raised by prairie dogs", "|")
game.heights = Split("Tiny|Small|Below average|Average|Above average|Tall|Very tall|Freakishly tall", "|")
game.builds = Split("Starvation thin|Sleight|Slim|Average|Chunky|Chubby|Fat|Obese|Morbidly obese", "|")
AddCreationNewPage ("What are your strengths?")
AddCreationList ("atts", "pri_att", "Primary Attribute")
AddCreationList ("atts", "sec_att", "Secondary Attribute")
AddCreationNewLine
AddCreationList ("advs", "advantage", "Special advantage")
AddCreationNewPage ("What are your weaknesses?")
AddCreationList ("atts", "pri_neg", "Primary Weakness")
AddCreationList ("atts", "sec_neg", "Secondary Weakness")
AddCreationNewLine
AddCreationList ("dbs", "drawback", "Drawback")
AddCreationNewPage ("What is your background")
AddCreationList ("bgds", "background", "Background")
AddCreationListSubset ("heights", "height", "Height", 1, -1)
AddCreationListSubset ("builds", "build", "Build", 1, 8)
CreationGo
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
<command name="test">
<pattern>test</pattern>
<script>
msg (player.name)
msg (player.advantage)
msg (player.drawback)
msg (player.height)
msg (player.height_as_int)
</script>
</command>
<command name="bigger">
<pattern>bigger</pattern>
<script>
player.height_as_int = player.height_as_int + 1
</script>
</command>
<command name="smaller">
<pattern>smaller</pattern>
<script>
Decrease ("height")
</script>
</command>
</asl>

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums