Checking if reachable objects have attribute
Tibor
30 Jun 2018, 18:25Hi guys, how are you all?
I'm a bit new on quest, and for my first game i was creating a system where you can smoke cigarettes from a pack (yeah yeah I know :p). So far I created one object called Pack of Cigarettes, that has an atributte that counts how many cigarettes are in it, and everytime you take one, I clone the object Cigarette from outside the game (my "limbo" room) and put it in the inventory, and decrease one in the cigarrete from the pack. I wanted to make it as realistic as possible, because that's the goal of my game, but I though that it was better doing like this, instead of making the pack a mini container that holds twenty one separate cigarette objects.. I didn't have any other idea about this, so any opinions are welcome.
The real issue is, now I want the player to light the cigarette, and for this he needs a source of fire. I created one object "Lighter" and set an atribute "sourceoffire" in it. I plan to make everything that has fire , like a fireplace, a candle, etc, to have this atributte, so i can use it in other ways later.
Now for the player to light his cigarette he needs to have in reach some object that has this atributte "sourceoffire", be it in his inventory or in the same room, and if so, he can light his cigarette (and an apropriate msg appears), so I need to check if all the reachable objects have this atributte, and I don't have any Idea how to do that.
I dont want to use "if player has object lighter" i want "if player have in inventory or in the same room an object with the atributte sourceoffire"
I was trying to understand the ScopeReachable function, if it has something to do with my issue, but I don't know.
Maybe I'm trying too hard, and I could just make the lighter the only source of fire and check if I have one in inventory, but like I said, i want it to be realistic, and do something like that.
Any ideas how i can check if reachable objects have atributte? Or any workarounds or other ideas?
thanks in advance, and sorry for my english, i'm brazilian :)

Richard Headkid
30 Jun 2018, 19:18container that holds twenty one separate cigarette objects
21? American packs only contain 20. (I feel cheated!)
Assuming you set the boolean attribute "sourceoffire" to true
on the lighter (and other fire sources):
// First, assume we have no fire source.
hasfire = false
// Iterate through all reachable objects.
foreach (obj, ScopeReachable()){
// Check if object has the boolean attribute "sourceoffire" set to true
if (GetBoolean (obj, "sourceoffire")){
// If even one object that is reachable has "sourceoffire" set to true, we have fire!
hasfire = true
}
}
if (hasfire){
msg ("You light it.")
// Maybe do more stuff here.
}
else {
msg ("You have no fire source.")
// Maybe do more stuff here.
}
hegemonkhan
30 Jun 2018, 19:28you've actually got everything right (might be able to do a bit more efficient system/design, but that's not that important)!
I'll use 'ScopeReachable()' as it returns an Object List of all Objects you can directly/immediately (it's not within some other Object for example, which you would have to open up, and/or unlock and then open up, first) interact with: objects within the room you can directly interact with and/or Objects within your inventory (contained within/on you, usually the default 'player' Player Object) that you can directly/immediately interact with:
http://docs.textadventures.co.uk/quest/functions/corelibrary/scopereachable.html
also, I show a few methods/designs/concepts/ideas for you to know about and use if you want to for this or for later other stuff you want/need to do within your game, so you don't need all of them, as they do the same thing, or they're ideas for other uses within your game
Also, the above makes it a bit messy, and not the most efficient, and confusing too, so...
if you need help understanding any of it, let me know
<object name="room">
<inherit name="editor_room" />
</object>
<object name="limbo">
<inherit name="editor_room" />
</object>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<attr name="parent" type="object">room</attr>
</object>
<object name="lighter">
<inherit name="lightable_type" />
<inherit name="source_of_fire" />
<attr name="parent" type="object">player</attr>
</object>
<object name="pack_of_cigarettes">
<inherit name="editor_object" />
<attr name="parent" type="object">player</attr>
<attr name="quantity" type="int">10</attr>
<attr name="take" type="script">
if (this.quantity = 0) {
msg ("You're out of cigarettes")
} else {
this.quantity = this.quantity - 1
object_variable = CloneObject (this)
object_variable.prototype = this // http://docs.textadventures.co.uk/quest/functions/corelibrary/cloneobject.html
object_variable.parent = player
}
</attr>
</object>
<object name="cigarette">
<inherit name="editor_object" />
<inherit name="flammable_type" />
<attr name="parent" type="object">limbo</attr>
<attr name="alias" type="string">cigarette</attr>
<attr name="example_script_attribute" type="script">
msg ("You light your cigarette, and start smoking it")
</attr>
</object>
<type name="source_of_fire">
<attr name="light" type="script">
if (DoesInherit (this, "lightable_type") or GetString (this, "type_string") = "lightable") {
foreach (object_variable, ScopeReachable ()) {
if (DoesInherit (object_variable, "flammable_type") or GetString (object_variable, "type_string") = "flammable") {
do (object_variable, "example_script_attribute")
}
}
}
</attr>
</type>
<type name="lightable_type">
<attr name="type_string" type="string">lightable</attr>
</type>
<type name="flammable_type">
<attr name="type_string" type="string">flammable</attr>
</type>
mrangel
30 Jun 2018, 19:31Richard has the right answer :)
If you want, you could do the check on a single line (if you don't mind it being a little less intuitive)
ScopeReachable()
is a list of everything the player can reachFilterByAttribute (ScopeReachable(), "sourceoffire", true)
is a list of all reachable objects which have the "sourceoffire" attribute set to trueListCount (FilterByAttribute (ScopeReachable(), "sourceoffire", true))
counts the objects in that list
So you can do:
if (ListCount (FilterByAttribute (ScopeReachable(), "sourceoffire", true)) > 0) {
msg ("You light it.")
}
else {
msg ("You have no fire source.")
}

Doctor Agon
01 Jul 2018, 07:03Have you seen Pixies guide to handling water
http://docs.textadventures.co.uk/quest/handling_water.html
The same structure of coding used to handle water, could be used to handle fire.
Equally, a similar 'look at' code, could be used to 'look at pack of cigarettes' or 'look at matchbox'.
Verb: Light (match)
if (matchbox.matchlit = 0) {
msg ("the matchbox is empty.")
}
else {
msg ("You light a match.")
matchbox.matchlit = matchbox.matchlit - 1
}
Look at Description:
if (this.matchlit = 0) {
msg ("It's an empty matchbox.")
}
else if (this.matchlit = 1) {
msg ("It is a matchbox containing 1 match.")
}
else {
msg ("It is a matchbox containing " + matchbox.matchlit + " matches.")
}
This is what I've used in my text adventure to enable a turnscript as well.
Verbs - Light Candle
if (Got(matchbox)) {
if (matchbox.matchlit = 0) {
msg ("There are no matches left to light the candle.")
}
else {
msg ("You light the candle.")
matchbox.matchlit = matchbox.matchlit - 1
candle.moves = 3
this.lightsource = true
SetObjectFlagOn (candle, "lit")
EnableTurnScript (candlelight)
}
}
else {
msg ("You have nothing to light the candle with.")
}
Tibor
02 Jul 2018, 19:03Thank You for all the answers, it was actually very simple to do what I wanted, and now I have some new ideas to work with too... and sorry Richard I mistyped lol, there's only 20 cigarretes in a pack here in Brazil too :) Thx guys