Random Object Hyperlinks?

InsertCoin25
04 Jan 2014, 01:19
I looked through the forums for this answer, but I might have missed it. Is it possible to have random object/item hyperlinks? For example: You enter a room and each time you enter the room (for instance...you died and have to re-enter room) it displays different objects/items you can interact with using hyperlinks. I tried the random text, but that only generates random text that you can't interact with. Basically, all I need is random objects/items I can interact with each time a room is loaded.

Thank You
InsertCoin25

jaynabonne
04 Jan 2014, 10:05
Quest automatically supports hyperlinks for objects existing in a room, so the question is really one of creating random objects in a room - you get the hyperlinks for free. Unfortunately, that's a fairly broad topic depending on what you want. Can you provide some examples of what you're looking for? For example, when you "respawn" in the room, are the objects you find there taken from a pool of existing objects (e.g. you find a sword, but there is only one sword ever) or do they need to be created dynamically (e.g. you have a healing potion, and in the room you can find another)?

If it's the former, then you can just have a list of possible objects that can appear in the room, and then randomly select from that list, moving the desired objects into the room. If you need to create new objects dynamically, then there are different ways to go depending on how many possible objects you can dynamically create - a list of objects to clone, a switch statement based on a random number selection with each case creating a different object, etc.

InsertCoin25
04 Jan 2014, 19:36
Basically what I need is that every time a player dies in the game and a new game restarts objects/items are randomly placed in the room. For example: There are items in a drawer in a desk (a container) that you can look at or take, items on a desk, on a bookshelf, etc., etc..., and then if the player dies and has to restart the level/room there are different (random) items in the drawer, on the desk, and on the bookshelf. I hope that clears it up somewhat. If not, I will try another example. Thank you for the response, I greatly appreciate the help.

Thank You
InsertCoin25

jaynabonne
04 Jan 2014, 23:47
It confirms what I was suspecting, but it leaves unanswered the main question which is: are these going to be static objects that you choose from (reusing them next time as needed), or will you need to dynamically create new objects? That might be too subtle a question. Perhaps if you could give examples of the kinds of objects, it might help.

I gave simple examples in my previous post about what I mean.

HegemonKhan
05 Jan 2014, 00:06
I'll leave jayna to help you with the randomizing of Objects, I think I could figure out the coding for this, but he can do it much faster, easier, globally-efficiently-fancier'ly (applies to or effecting all Objects), and cleaner~simpler, than I could.

but here's possibly how to script for restarting the game:

<object name="player">
-> <inherit name="editor_object" />
-> <inherit name="editor_player" />
-> <current_hit_points type="int">999</current_hit_points>
-> <maximum_hit_points type="int">999</maximum_hit_points>
-> <hit_points type="string">HP: 999/999</hit_points>
-> <changedcurrent_hit_points type="script"><![CDATA[
->-> hit_points = "HP: " + player.current_hit_points +"/"+ player.maximum_hit_points
->-> if (player.current_hit_points <= 0) {
->->-> show menu ("You have died, would you like to start over, or end the game?", split ("start over;end game",";"), false) {
->->->-> if (result = "start over") {
->->->->-> // is there a built-in script to reset~restart the game? if not, we'd need a bunch of coding... (and the randomizing of the objects coding too)... lol
->->->-> } else if (result = "end game") {
->->->->-> finish
->->->-> }
->->-> }
->-> }
-> ]]></changedcurrent_hit_points>
-> <changedmaximum_hit_points type="script">
->-> hit_points = "HP: " + player.current_hit_points +"/"+ player.maximum_hit_points
-> </changedmaximum_hit_points>
-> <statusattributes type="simplestringdictionary">hit_points = !</statusattributes>
</object>

InsertCoin25
05 Jan 2014, 21:53
jaynabonne wrote:It confirms what I was suspecting, but it leaves unanswered the main question which is: are these going to be static objects that you choose from (reusing them next time as needed), or will you need to dynamically create new objects? That might be too subtle a question. Perhaps if you could give examples of the kinds of objects, it might help.

I gave simple examples in my previous post about what I mean.


Sorry I missed your previous post. The objects are going to be static, so they can be reused. So..static random objects. An example of a random object in the game would be a hammer that can be used to break a mirror, but that hammer won't be in the same place each time the game or room restarts. I think that covers it. Thank you for the help jaynabonne and HegemonKhan.


InsertCoin25

InsertCoin25
08 Jan 2014, 18:23
Just wondering if you have had a chance to look into this? Please let me know.

Thank You
InsertCoin25

jaynabonne
08 Jan 2014, 19:48
Sorry. I was back to work on Monday, and I haven't mentally recovered yet... :)

Since the objects are static, you just need to create a list attribute somewhere that lists them. You can either use an object list (which directly references the objects), or you can use a string list that contains the names of the objects. The latter requires you to use GetObject to get the actual object from the name. The only advantage to the string list is that you can create and edit it in the Quest editor. The editor doesn't know how to deal with object list attributes.

I decided to punt and not use a static list but rather generate the list by which objects were in a source room. Some code to examine is follows. Note that I have Quest 5.5 installed, so if you have 5.4, you'll have to change the asl version or dump the code into your own game.

<!--Saved by Quest 5.5.5101.21548-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="objlist_text">
<gameid>cd9e7a8a-fb1a-4bb3-8c90-cc19b37793aa</gameid>
<version>1.0</version>
<firstpublished>2014</firstpublished>
<objects type="objectlist"></objects>
</game>
<object name="room">
<inherit name="editor_room" />
<beforeenter type="script">
MoveRandomObjects (limbo, this, 3)
</beforeenter>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="south" to="otherroom">
<inherit name="southdirection" />
</exit>
</object>
<object name="limbo">
<inherit name="editor_room" />
<object name="apple">
<inherit name="editor_object" />
<take />
</object>
<object name="banana">
<inherit name="editor_object" />
<take />
</object>
<object name="monkey">
<inherit name="editor_object" />
<take />
</object>
<object name="drum">
<inherit name="editor_object" />
<take />
</object>
<object name="stick">
<inherit name="editor_object" />
<take />
</object>
<object name="doll">
<inherit name="editor_object" />
<take />
</object>
</object>
<object name="otherroom">
<inherit name="editor_room" />
<exit alias="north" to="room">
<inherit name="northdirection" />
</exit>
</object>
<function name="MoveRandomObjects" parameters="source, destination, count">
if (not HasAttribute(source, "objects")) {
set (source, "objects", GetDirectChildren(source))
}
objects = GetAttribute(source, "objects")
foreach (object, objects) {
object.parent = source
}
set (source, "tempobjects", objects)
tempobjects = GetAttribute(source, "tempobjects")
for (i, 1, count) {
index = GetRandomInt(0, ListCount(tempobjects)-1)
object = ListItem(tempobjects, index)
list remove (tempobjects, object)
object.parent = destination
}
</function>
</asl>

The basic idea behind this is that there is a room that holds the objects you want. I called it "limbo" in the example. Then there is a function called MoveRandomObjects that moves the specified number of objects from the source room to the target room. In order to know what the objects are, the function assumes that the first time it's called, the objects are all in the source room. It captures that list for later use. It also resets all the objects back into the source room before selection. You can see this if you go south in the example and then back north again. Every time you enter the room, a new selection of objects will be there. If you had any of the objects in your possession, they will be moved back to limbo and selected a new.

This may be more complicated than you wanted. In order to pick "n" objects, I had to create a temporary list to pluck objects from. I use that fact that when you assign a list to an object attribute, it copies the list. So when I set the "tempobjects" attribute from "objects", it makes a copy of objects we can remove objects from.

I couldn't put comments in the source that would stick, so it's a bit "self documenting". If you have any questions about how any of it works, I'll be happy to explain.

Hope that gets you at least part way on your way! (And sorry again for the delay getting back to you.)

InsertCoin25
09 Jan 2014, 18:02
Thanks jaynabonne. I am going to try and wrap my head around this process and if I have any questions (which I sure I am :D ) I will post here. Thanks again.

InsertCoin25