Random Object Movement

venzen2K
Hi all. I've been working with Quest for about a week now, and am curious about a couple things that I would like to make random. Any help or suggestions would be appreciated.

1. At the start of the game I would like to run a script that selects 3 random objects and moves them to a specified room. //edit: Okay, I figured out how to select my three objects and move them to the room I want. Now on to question 2...

2. During the game I would like to randomly select an object that will move to a random room every certain number of turns (I have the turn script set up, but I am not sure if/how to select a random object and move it to a random room - i.e. a poltergeist is stealing something random and moving it someplace random.)

I have a hunch that it will have something to do with lists, but I can't seem to make heads nor tails of what I'm reading about creating lists on the Wikis and tutorials.

Any help i could get would be much appreciated. The past week I have just been toying with the tutorial game, trying to gain as deep an understanding as I can get of Quest (I love it so far!). I've been testing the opening script part just using object1, object2, object3, object4, object5 and object6 and room1, room2, room3, and lockedroom (where I want my 3 random objects selected at the beginning of the game to go). The rest of the game is still blank, so I don't really have anything workable to give you.

Thanks again!

HegemonKhan
I know this is code stuff, and being a new person you're probably using the GUI~Editor, but it's easier for me to try to explain stuff this way, hopefully, you can figure out how to do this stuff in the GUI~Editor on your own, but if not I can help you, but it takes a lot longer (more work) to explain how to do things via the GUI~Editor, than it does with code.

http://quest5.net/wiki/Category:All_Fun ... t_Commands (page 1, range: A-S)

http://quest5.net/w/index.php?title=Cat ... h#mw-pages (page 2, range: S-Z)

-----------

I'm still trying to learn how Object Lists work... (Jayna explained it to me), but I'm not able to get them to work, I don't know if you have to actually have the Objects within the same place as your Object List or not, I haven't had much time to work on figuring out how Object Lists work yet.

so hopefully someone else can help you, who knows exactly how to do this for you, but I can still offer some help (even if it doesn't exactly work correctly)

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

Lists (String Lists and Object Lists) and Dictionaries (String Dictionaries, Object Dictionaries, and Script Dictionaries) are not easy for new people to understand. And, what you're asking for, is pretty complicated too.

think of a list as a 'pot or basket' which holds options~choices of "Strings" or "Objects", which you can grab-n-use: all of them, some of them specifically, some of them randomly, or all of them randomly.

A 'String' is a collection of characters (not all though), for examples:

a
1
abc
3716
a_3jn_3d8_redblueyellow

A 'String List' is a collection of choices~options (strings), for example:

1, 2, 3
a, b, c
red, blue, yellow

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

conceptually about "Spliting" and "Joining", for example:

http://quest5.net/wiki/Split
http://quest5.net/wiki/Join

String: redblueyellow
String List: (1) red, (2) blue, or (3) yellow

a "String" is "split (apart)" into multiple separate strings to make a "String List"
a "String List" (multiple separated strings) is "joined (together)" to make a single (long) "String"

(You shouldn't be using "Join" much, as it doesn't have much use for basic stuff, unless you're doing much more complex code stuff, lol)

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

for yourself to do this later on, I'd first work on learning to use lists and dictionaries as basic and simple as you can, for example:

try to do the character creation as it uses lists:

http://quest5.net/wiki/Character_Creation
http://quest5.net/wiki/Showing_a_menu
http://quest5.net/wiki/Using_Lists

there's 3 ways to create a String List or Object List:

split ("option_1;option_2;option_3;etc" , ";")

split ("object_1;object_2;object_3;etc" , ";")

~or~

my_string_list = NewStringList ()
list add (my_string_list, option_1)
list add (my_string_list, option_2)
list add (my_string_list, option_3)
etc list add (my_string_list, etc)

my_object_list = NewObjectList ()
list add (my_object_list, object_1)
list add (my_object_list, object_2)
list add (my_object_list, object_3)
etc list add (my_object_list, etc)

~or~

(for objects, you can also get them from a room, other objects, or entire game, and put them into your list, for example...)my_object_list = ScopeInventory () // or 'AllObjects ()', or 'ScopeVisibleNotHeld ()', or etc Scopes

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

"foreach" and "for"

http://quest5.net/wiki/Foreach

foreach (team_member_x, team_members_string_list) {
-> team_member_x.run_laps
}

Every~All~(*Each*) team member ("team_member_x"), on the team ("team_members_string_list), is to run laps.

http://quest5.net/wiki/For

it's basically the same thing, except you can specify which 'team members', to do the action ('run laps') upon~with.

so for example:

team_members_string_list: (0) john, (1) jim; (2) jeff; (3) jake; (4) julius
(String List items start their counting~listing with 0, not 1, and starts from left to right as seen above)

foreach (all~every~*each*): john.run_laps, jim.run_laps, jeff.run_laps, jake.run_laps, and julius.run_laps
for (2,2): jeff.run_laps
for (1,3): jim.run_laps, jeff.run_laps, and jake.run_laps
for (1,3,2): jim.run_laps and jake.run_laps
for (0,4,2): john.run_laps, jeff.run_laps, and julius.run_laps
for (0,4,3): john.run_laps and jake.run_laps
for (0,4,4): john.run_laps and julis.run_laps
(I think you get the idea now)

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

dictionaries are a bit more complicated to understand than lists.

think of dictionaries as 'tables' (or whatever you call it, lol):

(pretend that there's an expedition and there's only so much food, that to feed everyone ~keep everyone alive, food must be properly rations and divided, as an example)

(pretend that I made a table~grid~spread sheet ~ whatever you call it, lol)

family size: 1 ~ 2 ~ 3 ~~ 4
fish given: 5 ~ 10~ 15 ~ 20

1 = 5
2 = 10
3 = 15
4 = 20

(input) families of 1, (output) get 5 fish
(input) families of 2, (output) get 10 fish
(input) families of 3, (output) get 15 fish
(input) families of 4, (output) get 20 fish

A String Dictionary is literally: string_1 = string_2

an example of it's application:

1 = hi
2 = bye

1 ---> hi
2 ---> bye

if input is "1", then output is "hi"
if input is "2", then output is "bye"

a useful application of this is in a game with magic elements (doing more damage against opposite element, and less damage or no damage or damage gets absorbs or reflected ~lol~ against same element), though it's full scripting is a bit more complex.

fire = water
water = fire

fire ---> water
water ---> fire

monster.elemental = water
spell.elemental = fire

if cast fire spell (spell.elemental), fire -> water, if (water=monster.elemental), then you do x2 damage, else if (spell.elemental = monster.elemental), then do zero damage, else do x1 damage

Object Dictionary is the same thing, but it's equal to an object:

string_1 = object_1

1 = soccer ball
2 = baseball ball
red = apple
yellow = lemon

Script Dictionary is the same thing, but it's equal to a script:

string_1 = script_1

1 = msg ("hi")
2 = msg ("bye")

red = msg ("apple")
yellow = msg ("lemon")

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

if you want to take a look at a "game" that uses lists and dictionaries, though it's not exactly for what you need as it deals with traveling, it's got many of the same aspects:

<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>eef801a1-4e6b-4b0a-bdbf-8f3ecfa8389c</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<turns type="int">0</turns>
<statusattributes type="simplestringdictionary">turns=</statusattributes>
<start type="script">
msg ("Important Note:")
msg ("Type in: help")
</start>
</game>
<object name="homeland">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
<object name="grassland">
<inherit name="editor_room" />
</object>
<object name="plains">
<inherit name="editor_room" />
</object>
<object name="desert">
<inherit name="editor_room" />
</object>
<object name="tundra">
<inherit name="editor_room" />
</object>
<object name="swampland">
<inherit name="editor_room" />
</object>
<object name="mountains">
<inherit name="editor_room" />
</object>
<object name="forest">
<inherit name="editor_room" />
</object>
<object name="wasteland">
<inherit name="editor_room" />
</object>
<object name="coastland">
<inherit name="editor_room" />
</object>
<object name="hills">
<inherit name="editor_room" />
</object>
<command name="help_command">
<pattern>help</pattern>
<script>
help_function
</script>
</command>
<command name="explore_command">
<pattern>explore</pattern>
<script>
explore_function
</script>
</command>
<command name="travel_command">
<pattern>travel</pattern>
<script>
travel_function
</script>
</command>
<object name="data_object">
<inherit name="editor_object" />
<travel_string_list type="simplestringlist">homeland</travel_string_list>
<homeland_events_string_list type="simplestringlist">grassland_discovery;plains_discovery;desert_discovery;tundra_discovery;swampland_discovery;forest_discovery;mountains_discovery;hills_discovery;wasteland_discovery;coastland_discovery</homeland_events_string_list>
<homeland_events_script_dictionary type="scriptdictionary">
<item key="grassland_discovery">
list add (data_object.travel_string_list, "grassland")
msg ("You've discovered the grassland! Now, you can travel to the grassland and explore it!")
</item>
<item key="plains_discovery">
list add (data_object.travel_string_list, "plains")
msg ("You've discovered the plains! Now, you can travel to the plains and explore it!")
</item>
<item key="desert_discovery">
list add (data_object.travel_string_list, "desert")
msg ("You've discovered the desert! Now, you can travel to the desert and explore it!")
</item>
<item key="tundra_discovery">
list add (data_object.travel_string_list, "tundra")
msg ("You've discovered the tundra! Now, you can travel to the tundra and explore it!")
</item>
<item key="swampland_discovery">
list add (data_object.travel_string_list, "swampland")
msg ("You've discovered the swampland! Now, you can travel to the swampland and explore it!")
</item>
<item key="forest_discovery">
list add (data_object.travel_string_list, "forest")
msg ("You've discovered the forest! Now, you can travel to the forest and explore it!")
</item>
<item key="mountains_discovery">
list add (data_object.travel_string_list, "mountains")
msg ("You've discovered the mountains! Now, you can travel to the mountains and explore it!")
</item>
<item key="hills_discovery">
list add (data_object.travel_string_list, "hills")
msg ("You've discovered the hills! Now, you can travel to the hills and explore it!")
</item>
<item key="wasteland_discovery">
list add (data_object.travel_string_list, "wasteland")
msg ("You've discovered the wasteland! Now, you can travel to the wasteland and explore it!")
</item>
<item key="coastland_discovery">
list add (data_object.travel_string_list, "coastland")
msg ("You've discovered the coastland! Now, you can travel to the coastland and explore it!")
</item>
</homeland_events_script_dictionary>
</object>
<turnscript name="global_turnscript">
<enabled />
<script>
game.turns = game.turns + 1
</script>
</turnscript>
<function name="help_function">
msg ("Type 'explore' to explore your area.")
msg ("Type 'travel' to travel to different areas.")
</function>
<function name="explore_function"><![CDATA[
switch (game.pov.parent) {
case (homeland) {
result_1 = ListCount (data_object.homeland_events_string_list) - 1
if (result_1 >= 0) {
result_2 = StringListItem (data_object.homeland_events_string_list,GetRandomInt(0,result_1))
invoke (ScriptDictionaryItem (data_object.homeland_events_script_dictionary,result_2))
on ready {
foreach (item_x, split ("grassland_discovery;plains_discovery;desert_discovery;tundra_discovery;swampland_discovery;forest_discovery;mountains_discovery;hills_discovery;wasteland_discovery;coastland_discovery",";")) {
if (result_2 = item_x) {
list remove (data_object.homeland_events_string_list, result_2)
}
}
}
} else {
msg ("There seemingly is nothing left to explore in this area.")
}
}
}
]]></function>
<function name="travel_function">
show menu ("Where do you wish to travel?",data_object.travel_string_list,false) {
if (not game.pov.parent = GetObject (result)) {
game.pov.parent = GetObject (result)
} else {
msg ("You are already at this area.")
ask ("Try again?") {
if (result=true) {
travel_function
} else {
msg ("You realize that you need to discover a new area to travel to first, before you can travel to that place.")
}
}
}
}
</function>
</asl>


or, the game file is an attachment at the bottom, you can download.

-----------

conceptually what you want~need~are to do~doing is this:

have a Non-Room (and Non-Player) Object existing by itself like it's a room (the Object isn't within a room). This will be our secret 'storage' (or 'data object') object that the game player doesn't know about. We use this secret Object to hold our needed Attributes and (the will be randomly selected) Objects. So, put~create~add your random objects into this secret Object, and then we'll need to make~add the Attributes needed as well.

If you want your "turns" Attribute to be shown in the right pane during game play, then you'll to create~add it to either the "game" Object or to a Player Object, such as your default "player" Player Object. Or, we can still display the "turns" via a similar effect of like a "stats screen", which we can do with a Command (you type in something to see your turns and~or other info) or via buttons~hyperlinks. I don't know how you want it done, lol.

As for 'after x turns move object here', this is achieved either via a Turnscript or the special 'changed' Script, and our 'turns' Attribute (and a turns increasing script). Also, in the scripting, we'll use the % sign to achieve the 'after x turns'.

I know you said this already, but for completeness, to randomly select three objects to move to 3 specific rooms:

you need an Object List Attribute, and the 'GetRandomInt' Script, and a 'moving' Script. You'll also need 'list remove' script too, so for the 2nd and 3rd time the 'GetRanomInt' script is run, you're not selecting the same object that you already selected and moved. And, you'll need to re-add the objects back to the object list too with 'list add' script.

as for moving random objects to random rooms (can you specify whether its the same objects and rooms that you acted upon at the start of the game, or are you talknig about after x turns moving randomly new objects to new rooms), you're basically using 'GetRandomInt' Script with: an Object List Script for the Objects and also an Object List Script for the Rooms.

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

if you still need help, let me know, and I can try to craft coding for you ~ what you want, but it'd take me some time to do so.

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

Liam315
Yes, you will need to create object lists in order to make this work. You will need an object list for the potential items that can be moved, and another for the rooms they can be moved to. Here is a script that can be used to select objects and move them.

moveable = NewObjectList()
list add (moveable, object1)
list add (moveable, object2)
list add (moveable, object3)
list add (moveable, object4)
moveable = ListExclude(moveable,ScopeInventory())
rooms = NewObjectList()
list add (rooms, room1)
list add (rooms, room2)
list add (rooms, room3)
pickobject = GetRandomInt(0,ListCount(moveable) - 1)
pickroom = GetRandomInt(0,2)
MoveObject (ObjectListItem(moveable,pickobject), ObjectListItem(rooms,pickroom))


So to explain what happens:
The first part makes a new object list, and adds all of the objects that can potentially be moved to it. Because I'm assuming that some of these objects may be able to be picked up by the player, I've put in a line that will stop anything the player has from being the object selected to be moved. If you wanted the theft from the player to be a part of it though, you'd just have to remove this line. (There are many techniques to have certain objects only able to be moved under different circumstances.)

The next part adds all the potential rooms, which is quite straightforward. Obviously you'd have to replace object1, room1, etc. with the actual object and room names.

After that, 2 random numbers are selected based on the number of objects or rooms in each list. Note that it's important to use 0 as a potential number due to the way the ObjectListItem function works. The upper limit of the random number to be picked should be the number of items in the list minus 1. These numbers are represented by the variables "pickobject" and "pickroom".

Finally, these numbers are used to pluck an object and room from the list and perform the move. The reason the random number must be 0 to (1 less than the total number of items in the list) is to do with the way the ObjectListItem function operates.

Paste that script into whatever turn script you have and see how you get on, any further questions feel free to ask.

EDIT: I've also assumed that the number of objects that are able to be moved around is fairly small, so I've used the "list add" method to select all of the appropriate objects and rooms. If the number of objects and/or rooms is quite large, there are more elegant ways of creating those object lists. If you post the specifics (or a copy of your game file) I can provide a more tailored script.

venzen2K
Perfect. Both those posts helped. I think I got it licked. The actual list will be between 8 and 15 objects/rooms. Figuring out object lists was a big help.

I do have one other question though. Do the lists not save for later use? Or at least is there a way to do that b/c if i create the list in a function early in the game, then try to call another object from the list later in the game, it says the list variable is unknown. I would like to be able to create the lists at the beginning of the game, and then call it up for various situations, like having a NPC move away after being spoken to, or something like that, but what I am running into is that if in the NPCs "Speak to/ask scripts if I just try to call from a list I made earlier in the game a random room that the NPC should move to, i get an error saying the roomlist is and unknown variable.

Thanks again! I can see many uses for learning the NewObjectList and NewStringList.

jaynabonne
(Just a guess here...)

The only way to persist variables is to attach them to objects. Any bare variables in scripts exist only within those scripts. So if you do:

list = NewObjectList()

then the list will disappear when the script exits. If you want to have it persist and be available later, you need to attach it to an object. The game object is a good one:

game.list = NewObjectList()

Then you can access wherever you like.

Hope that helps.

HegemonKhan
as I forgot to explain in my post, jayna has done so for you, hehe.

so, as jayna said already (just further explanation~commentary by me):

Variable (local, temporary, non-saved ~ non-load'able, only usable within its scripting, NOT attached to an Object):

Variable = Expression_or_Value

custom example ("you_go_first"):

you_go_first = false
if (self.speed > enemy.speed) {
-> you_go_first = true
}
if (you_go_first = true) {
-> enemy.hp = enemy.hp - self.damage
-> msg ("You get to go first, and damage the enemy.")
} else if (you_go_first = false) {
-> self.hp = self.hp - enemy.damage
-> msg ("The enemy got to go first and damaged you.,")
}

// notice that "enemy.hp", "self.hp", "self.damage", "enemy.damage", "self.speed", and "enemy.speed" are Attributes, NOT Variables. They can be used in other scripts, but "you_go_first" can not: ~ "ERROR, missing or unknown variable"

a built-in example ("result"):

show menu ("What is your gender?", split ("male;female",";"), false) {
-> // you choose "male"
-> // quest automatically sets: result = "male"
-> msg ("You are a " + result + ".")
-> // outputs: You are a male.
}

// by the way: ' split (male;female",";") ' is also a variable too, as it also is not attached to an Object

--------

if you want to use "male" elsewhere (in other scripts), then you have to do this (an example):

show menu ("What is your gender?", split ("male;female",";"), false) {
-> // you choose "male"
-> // quest automatically sets: result = "male"
-> player.gender_string = result
-> msg ("You are a " + result + ".")
-> // outputs: You are a male.
}

in your (for example) "look at ~ look ~ pov_description ~ whatever it called" other script:

msg ("Gender: " + player.gender_string)
// outputs: Gender: male

----------

Attributes (global, permanent, saved ~ load'able, usable in any script within the game, attached to an Object):

(so long as the object, that the attribute is attached to, still exists, of course, lol)

Object.Attribute = Expression_or_Value

custom examples:

HK.strength_integer = 100
HK.clothes_object_list = split ("shirt;pants;shoes;socks",";")
HK.gender_string = "male"
HK.damage_double = 593.72
HK.dead_boolean = false
HK.favorite_colors_string_list = split ("black;red",";")
HK.fight_script = (see below)
etc...

<object name="HK">
-> <inherit name="editor_object">
-> <attr name="strength_integer" type="int">100</attr>
-> <attr name="clothes_object_list" type="simpleobjectlist">shirt;pants;socks;shoes</attr>
-> <attr name="gender_string" type="string">male</attr>
-> <attr name="damage_double" type="double">593.72</attr>
-> <attr name="dead_boolean" type="boolean">false</attr>
-> <attr name="favorite_colors_string_list" type="simplestringlist">black;red</attr>
-> <attr name="fight_script" type="script"><![CDATA[
->-> if (HK.dead=true) {
->->-> msg ("HK is already dead, silly.")
->-> } else if (HK.dead=false) {
->->-> HK.hp_integer = HK.hp_integer - venzen.damage_integer
->->-> if (HK.hp <= 0) {
->->->-> HK.dead_boolean = true
->->->-> msg ("You killed HK")
->->-> }
->-> }
-> </attr>
</object>

an "Analyze" Spell's Verb's partial and quasi Script:

(it's able to 'call upon ~ load' "HK's" attributes, even though it's a different script from a different source)

msg ("Dead: " + HK.dead_boolean)
msg ("Gender: " + HK.gender_string)
msg ("Damage: " + HK.damage_integer)
etc etc etc

// outputs:
// Dead: false_or_true (depending whether you already killed HK or not, lol)
// Gender: male
// Damage: 593.72
// etc etc etc

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

in the GUI~Editor:

just "add" the attributes to an Object

"whatever" Object -> Attributes (Tab) -> Attributes -> Add -> (set it up)

and~or within the scripting, for making~using Attributes:

"whatever" Object -> Verb (Tab) -> Add a script -> variables -> set a variable or attribute -> Object.Attribute = Expression_or_Value

as for variables, they can only be created within~via the scripting, for example:

"whatever" Object -> Verb (Tab) -> Add a script -> variables -> set a variable or attribute -> Variable = Expression_or_Value

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

if you want to display the attributes during game play on the pane on the right side, then you must create~add~attach the Attributes to the "game" Object or the Player Objects, such as the default "player" Player Object, or your own custom (such as "HK" and "venzen") Player Objects, as these are the only Objects that the built-in special "statusattributes" (string dictionary) Attributes are attached to, which causes the Attributes' displayment during game play on the right pane.

"game" Object -> Attributes (Tab) -> Attributes -> Add ->

Attribute Name: turns
Attribute Type: int (integer)
Attribute Value: 0

"game" Object -> Attributes (Tab) -> Status Attributes -> Add ->

Name: turns
Field...whatever it is called (Value): Turns: !

// ouputs in the right pane, during game play: Turns: 0

or

replace the "game" Object with the default "player" Player Object, or a custom Player Object, such as "HK" or "venzen".

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

Support

Forums