Newbie question: Adventure and Gamebook?

gernotg
03 Jan 2014, 20:20
Hi everyone,

I'm still trying to get started, but I'm stuck at the most basic level. I want to create a game that has rooms and objects with properties, but I want the interface to look like a game book. Or, at least in certain cases, I would like to be able to switch to a game book interface.

For example, let's say I am in a room with a particular object or person, when the character interacts with that object or has a conversation with that person, I want a series of game-book-style menus such as "person says xyz, respond a) b), or c)", and at the end of the conversation or interaction, return to normal adventure mode.

When I start my game as a text adventure, I can't figure out how to create the game-book-style interaction sequences, and when I start it as a game book, I can't figure out how to add rooms and objects with properties... Please help!

Thanks,

Gernot

tbritton
04 Jan 2014, 00:23
First link below shows how to create a menu for use with objects. For interaction with characters use ask, tell or talk. Ask and tell can be set up with the gui, not sure about talk. These would all be done in adventure mode.

http://quest5.net/wiki/Showing_a_menu

http://quest5.net/wiki/Dynamic_Menus_for_Conversations

HegemonKhan
04 Jan 2014, 06:20
here's a start of trying to make a hybrid of TA (Text Adventure) and GB (Game Book):

viewtopic.php?f=18&t=4025

I'm not sure if this will be of any help to you, as I haven't looked at it myself yet, but it's worth a look.

--------------

also, here's a Journal Library, I haven't looked at this yet, but it might be the closest thing in the TA to the pages in a GB:

viewtopic.php?f=18&t=2610

otherwise, maybe one of the good programmers~coders here can craft a GB pages feature in the TA for you.

-------------

I can't help you with GB stuff, but if you want or need any help with the TA stuff, I'd be glad to try to help you with anything.

gernotg
04 Jan 2014, 09:14
Thank you very much for the pointers. It seems clear that the correct way to go is to use menus from the TA setup.
One simple way I see to implement menus is to print statements with links to commands, like
Would you like to {command:open box:open} the box?

But is there a way to create a link that calls a script or function, without creating a command? Something along the lines of:
By the way, do you have {script:player.hairlength="long":long} or {script:player.hairlength="short":short} hair?

jaynabonne
04 Jan 2014, 09:46
I don't know of a way to do it without any commands at all, but in my own work, I created a single command as a gateway to scripts. Its code is here:

  <command name="Dungeons_DoScriptCmd">
<pattern>DoScript #text1# #text2#;DoScript #text1#</pattern>
<script>
<![CDATA[
// text = object.attribute parameters
// text2 = parameter string (param1,param2,...)
source = Split(text1, ".")
object = StringListItem(source, 0)
attribute = StringListItem(source, 1)
if (not IsDefined("text2")) {
text2 = ""
}
args = Split(text2, ",")
params = NewDictionary()
argnum = 1
foreach (arg, args) {
dictionary add(params, "arg"+argnum, arg)
argnum = argnum + 1
}
//msg("object = " + object + ", attribute = " + attribute + ", params = " + params)
do (GetObject(object), attribute, params)
]]>
</script>
</command>

You could use this as is or make your own variant. It doesn't allow direct inline script, but it does allow a script to be called on an object. You specify the object and script attribute to be called as "object.script". You an also pass an additional string, which is a comma-separated list of arguments (e.g. "foo,bar,3,5"), and they appear to the script as variables arg1, arg2, etc.

Your example would then be:

By the way, do you have {command:DoScript player.sethairlength long:long} or {command:DoScript player.sethairlength short:short} hair?


where you'd have a script attribute on the player like to handle setting the hair length:

<sethairlength type="script">
this.hairlength = arg1
</sethairlength>

Hope that helps.

gernotg
04 Jan 2014, 20:56
Thanks, jaynabonne!

I was not able to get the script to work quite as is. For some reason, it did not consider "player.hairlength" as one string, but instead used the dot to separate my line into several commands, so I modified your command to use spaces instead:

<command name="DoScriptCmd">
<pattern>DoScript #text#</pattern>
<script><![CDATA[
args = Split(text," ")
count = ListCount( args )
if ( count < 2 ) {
msg ("Usage: DoScript object script [parms]")
}
else {
object = StringListItem(args, 0)
attribute = StringListItem(args, 1)
params = NewDictionary()
if ( count > 2 ) {
for (idx, 2, count - 1) {
dictionary add (params, "arg"+(idx-1), StringListItem(args, idx))
}
}
obj = GetObject(object)
if ( obj = null ) {
msg (object + " does not specify a valid object.")
}
else if ( not HasScript( obj, attribute ) ) {
msg (object + " does not have a script " + attribute + ".")
}
else {
do (obj, attribute, params)
}
}
]]></script>
</command>

This now works, and I can use it to call scripts. The one qualm I still have is that the "DoScript xxx yyy" is still displayed as a command when the user clicks on the link. Is there any way around that?

jaynabonne
04 Jan 2014, 21:24
You have to override some default Quest behavior to get rid of that (ah yes, the bane of customization). The place to look is in HandleCommand. The easiest way to modify it is to:

1) In the Quest editor, click the Filter dropdown below the left pane and check "Show Library Elements". Then
2) Look for the function "HandleCommand" in the Functions area.
3) Click on it. It will appear in the script editor on the right.
4) Click the Copy button at the top right of the screen. That will pull the script up into your game file.
5) In Script view (since I think you are comfortable with script!), find this text and get rid of it:

          if (not shownlink) {
msg ("")
OutputTextRaw ("&gt; " + SafeXML(command))
}


That should do it.

gernotg
04 Jan 2014, 21:56
Thanks!!

gernotg
21 Jan 2014, 06:47
When you leave a room, quest disables some hyperlinks, for example to objects that are no longer available. Can I somehow tap into that same mechanism and disable command links that are not available anymore?

For example, I would like to disable a previous printed "{command:open box:open}" link when the player leaves the room, or for example if the box is now open. Or, since keeping track of all previously printed links seems like a big task, it would be nice to have a way to specify an expression to say whether the link should be active or not, i.e. {command : open box : open : ( box.parent = game.pov.parent ) and ( not box.is_open ) }.

Any ideas?