Question about containers and ScopeInventory

Mareus
Well, my game is certainly progressing nicely, but I am stuck on one tiny problem. Basically, I made a bag that can be picked up and is also a container. The idea is to make this bag my inventory. I also have a few items in the bag. These items get added to my inventory once I open the bag. The problem is that these items don't show when I type: Inventory. I can see them in my Inventory panel, but when I type: Inventory I get this reply: You are not carrying anything. That is the first thing that makes me stumped. The second problem is that if the bag is going to serve as my Inventory, I want to type something like: "search bag" and I want to call function to list all items currently in my inventory. I think one has to use the ScopeInventory function, but I do not know how.

PS. I do not know if this is relevant, but the empty square under container tab where I check/uncheck "can be opened" option is grayed out.

Here is my failed attempt at doing what I described:
if (GetBoolean(school bag, "opened")) {
ScopeInventory
}
else if (ListContains(ScopeVisible(), school bag)) {
msg ("Upon searching the bag you find some <font color=\"#00FFFF\">books</font>, a <font color=\"#00FFFF\">pencil</font> and a <font color=\"#00FFFF\">calculator</font>.")
AddToInventory (pencil)
AddToInventory (books)
AddToInventory (calculator)
MakeObjectVisible (books)
MakeObjectVisible (calculator)
MakeObjectVisible (pencil)
SetObjectFlagOn (school bag, "opened")
}
else {
msg ("What are you talking about?")
}


As always, I am grateful for any help.

jaynabonne
You can directly invoke the inventory command's script:

invoke (inventory.script)

If you wish to output it yourself in some other way, then you need to take the list returned by ScopeInventory and format it for output yourself.

As far as items being added to the inventory, I can't imagine how they could be in the inventory panel and not available via the command, and I'm really curious how it happens! Unfortunately, I can't work it out from the small snippet you've provided. If you could provide some complete working game (either yours or a test that shows the problem), then it will be much easier to get to the heart of the problem.

Mareus
jaynabonne wrote:You can directly invoke the inventory command's script:

invoke (inventory.script)

If you wish to output it yourself in some other way, then you need to take the list returned by ScopeInventory and format it for output yourself.

As far as items being added to the inventory, I can't imagine how they could be in the inventory panel and not available via the command, and I'm really curious how it happens! Unfortunately, I can't work it out from the small snippet you've provided. If you could provide some complete working game (either yours or a test that shows the problem), then it will be much easier to get to the heart of the problem.


Sure thing. I made a copy over my testing game, so take a look. I hope you can get to the bottom of it. I also noticed that when I type in close bag, I get the response that the bag is already closed, although I opened it before.

jaynabonne
They don't show up in your inventory because you've marked them all as "scenery" for some reason. And, for some reason, scenery objects don't show up in the inventory command's list but they do in the inventory pane.

Silver
I would mark an object as scenery if I didn't want it to appear in the generated object list on entering the room, something to be discovered by examining places in the room. Is there another way of doing that instead of marking them as scenery (and not putting them in containers)?

jaynabonne
You already have things like the bag and pencil invisible until discovered anyway.

Scenery is meant for objects that people are meant to interact with (e.g. a window in a room that you look at or open) but which aren't meant to be in the "You can see..." objects list in the room description. It's not a way to hide things. (For example, if you had an object as scenery, people could still interact with it if they knew it was there although "hidden" from the room description.)

Mareus
jaynabonne wrote:They don't show up in your inventory because you've marked them all as "scenery" for some reason. And, for some reason, scenery objects don't show up in the inventory command's list but they do in the inventory pane.


By George, this absoluetely worked! How did you figure this out? I mean, my alarm clock is set to scenery as well, but it shows up when I type inventory. This is why it never even occurred to me that the problem could be connected with scenery. You really are a genius!

Silver
jaynabonne wrote:You already have things like the bag and pencil invisible until discovered anyway.

Scenery is meant for objects that people are meant to interact with (e.g. a window in a room that you look at or open) but which aren't meant to be in the "You can see..." objects list in the room description. It's not a way to hide things. (For example, if you had an object as scenery, people could still interact with it if they knew it was there although "hidden" from the room description.)


But if you walk into a room and there's shelves filled with books and other objects, you would say there are shelves filled with books and other objects in the description, you wouldn't list every takeable object on these shelves as takeable objects from the off. Otherwise why would they bother to explore?

I'd been setting objects such as those as scene objects. I can't think of another way of doing it without adding a zillion scripts for every eventuality.

jaynabonne
Perhaps it would be easier to simply turn off the "You can see" line in the room description! I notice as well that you're auto-taking objects, which confused me at first (e.g. when I opened the wardrobe, it said there was a bag there, and when I went to take the bag, it said I already had it). Since you seem to bypassing a lot of the normal "give and take" (so to speak) anyway, you could just customize it all.

Another thought: when you do take an object that is scenery normally (with the "take" command), Quest seems to automatically remove the "scenery" state from the object. So it shows up properly in your inventory, and if you drop it, it shows up in the "You can see" list. Perhaps you could do the same: simply set the scenery attribute to false when moving it to inventory. (You could make a function that does that. Saves you from setting the state everywhere. Just call your own function to do the move.)

Mareus
jaynabonne wrote:Perhaps it would be easier to simply turn off the "You can see" line in the room description! I notice as well that you're auto-taking objects, which confused me at first (e.g. when I opened the wardrobe, it said there was a bag there, and when I went to take the bag, it said I already had it). Since you seem to bypassing a lot of the normal "give and take" (so to speak) anyway, you could just customize it all.

Another thought: when you do take an object that is scenery normally (with the "take" command), Quest seems to automatically remove the "scenery" state from the object. So it shows up properly in your inventory, and if you drop it, it shows up in the "You can see" list. Perhaps you could do the same: simply set the scenery attribute to false when moving it to inventory. (You could make a function that does that. Saves you from setting the state everywhere. Just call your own function to do the move.)

Well, I took to heart some of your advice and I actually removed the "automatic take" when opening containers. The problem that I am now struggling with is following. Opening containers works like a charm, but what if I want to type search container instead of opening it? Namely if I search the container, you do not get the list of items that are still inside. Is there a function I can call to list all the items inside the container. Here I am talking about wardrobe, since I won't be doing the same thing for the bag which serves as an inventory anyway.

HegemonKhan
there's this function:

http://docs.textadventures.co.uk/quest/ ... ylist.html

or, you can create your own:

<function name="display_list_items_function">
x = 0
foreach (item_x, Object_name.list_Attribute_name) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>


if you want me to create a Command of this (if you're interested in using~doing this, of course), let me know, and I'll write~code it for you.

Mareus
HegemonKhan wrote:there's this function:

http://docs.textadventures.co.uk/quest/ ... ylist.html

or, you can create your own:

<function name="display_list_items_function">
x = 0
foreach (item_x, Object_name.list_Attribute_name) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>


if you want me to create a Command of this (if you're interested in using~doing this, of course), let me know, and I'll write~code it for you.


Well, that would be awfully nice of you and I would really appreciate it, because I can't make sense of this.

HegemonKhan
no problem, and I'll try to explain how the scripting works too (HK crosses his fingers at his attempt to explain how it works, lol):

explanation of this previous posted function:

<function name="display_list_items_function">
x = 0
foreach (item_x, Object_name.list_Attribute_name) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>


let's say we've got an Object, and it has~holds an Objectlist of it's paint colors:

paint_box.paint_color_list = split ("red;blue;yellow", ",")

what the 'foreach' Function does is: it 'Gets' all the stuff (Objectlist:Objects or Stringlist:Strings~text) in the list, and represents them via a custom variable (in my above 'display_list_items_function' Function, I label the variable as 'item_x'.

conceptually what it is doing:
item_x = red
(does scripts within the 'foreach' script block again, aka 'loops', for the next thing in the list)
item_x = blue
(does scripts within the 'foreach' script block again, aka 'loops', for the next thing in the list)
item_x = yellow

then we got the message script (which is done for each thing, red + blue + yellow, in the list:

msg (item_x.alias)

conceptually what it'll do, outputs:

red
blue
yellow

now, the:

x = 0
and then
x = x + 1
msg (x + ". " + item_x)

is just to do the numbering, it'll output:

1. red
2. blue
3. yellow

conceptually, how the math function works:

x = 0
------------------------------
x = x + 1
------------------------------
x = (old x:0) + 1
x = 1
x = (old x:1) + 1
x = 2
x = (old x:2) + 1
x = 3

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

and before I forget (lol), here's the function as a Command:

<command name="showlist_command">
<pattern>showlist #object# #text#</pattern>
<script>
if (HasAttribute (object, text)) {
ClearScreen
showlist_function (object, text)
on ready {
wait {
ClearScreen
}
}
} else {
msg ("This object, " + object + " does not have this list, " + text + ".")
}
</script>
</command>

<function name="showlist_function" parameters="object_x,text_x">
x = 0
foreach (item_x, object_x.text_x) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>

jaynabonne
If you just want the search verb to act the same as open, then make your "search" verb attribute be this:

do(this, "open")


Then "search" will act identically to "open".

Mareus
jaynabonne wrote:If you just want the search verb to act the same as open, then make your "search" verb attribute be this:

do(this, "open")


Then "search" will act identically to "open".

Any way to isolate this so it works only in a very particular scenario? For example just on the wardrobe and not any other object? And btw, I can't make it work. Can you provide a few more details? Perhaps I am putting in the code in the wrong place. I basically created a new verb called search and I added the code under attribute. Perhaps I didn't get your insturctions.

Mareus
HegemonKhan wrote:no problem, and I'll try to explain how the scripting works too (HK crosses his fingers at his attempt to explain how it works, lol):

explanation of this previous posted function:

<function name="display_list_items_function">
x = 0
foreach (item_x, Object_name.list_Attribute_name) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>


let's say we've got an Object, and it has~holds an Objectlist of it's paint colors:

paint_box.paint_color_list = split ("red;blue;yellow", ",")

what the 'foreach' Function does is: it 'Gets' all the stuff (Objectlist:Objects or Stringlist:Strings~text) in the list, and represents them via a custom variable (in my above 'display_list_items_function' Function, I label the variable as 'item_x'.

conceptually what it is doing:
item_x = red
(does scripts within the 'foreach' script block again, aka 'loops', for the next thing in the list)
item_x = blue
(does scripts within the 'foreach' script block again, aka 'loops', for the next thing in the list)
item_x = yellow

then we got the message script (which is done for each thing, red + blue + yellow, in the list:

msg (item_x.alias)

conceptually what it'll do, outputs:

red
blue
yellow

now, the:

x = 0
and then
x = x + 1
msg (x + ". " + item_x)

is just to do the numbering, it'll output:

1. red
2. blue
3. yellow

conceptually, how the math function works:

x = 0
------------------------------
x = x + 1
------------------------------
x = (old x:0) + 1
x = 1
x = (old x:1) + 1
x = 2
x = (old x:2) + 1
x = 3

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

and before I forget (lol), here's the function as a Command:

<command name="showlist_command">
<pattern>showlist #object# #text#</pattern>
<script>
if (HasAttribute (object, text)) {
ClearScreen
showlist_function (object, text)
on ready {
wait {
ClearScreen
}
}
} else {
msg ("This object, " + object + " does not have this list, " + text + ".")
}
</script>
</command>

<function name="showlist_function" parameters="object_x,text_x">
x = 0
foreach (item_x, object_x.text_x) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>


I am sorry, but I don't know what to do with this line of code. Where do I put it? Its like rocket science to me.

jaynabonne
Mareus wrote:

"jaynabonne"

If you just want the search verb to act the same as open, then make your "search" verb attribute be this:

do(this, "open")


Then "search" will act identically to "open".

Any way to isolate this so it works only in a very particular scenario? For example just on the wardrobe and not any other object? And btw, I can't make it work. Can you provide a few more details? Perhaps I am putting in the code in the wrong place. I basically created a new verb called search and I added the code under attribute. Perhaps I didn't get your insturctions.



It is per-object. Right now, you have a "search" attribute on the wardrobe that duplicates your "open" one. Just set your "search" attribute on the wardrobe object to that one line.

Mareus
jaynabonne wrote:

"Mareus"

[quote="jaynabonne"]If you just want the search verb to act the same as open, then make your "search" verb attribute be this:

do(this, "open")


Then "search" will act identically to "open".

Any way to isolate this so it works only in a very particular scenario? For example just on the wardrobe and not any other object? And btw, I can't make it work. Can you provide a few more details? Perhaps I am putting in the code in the wrong place. I basically created a new verb called search and I added the code under attribute. Perhaps I didn't get your insturctions.



It is per-object. Right now, you have a "search" attribute on the wardrobe that duplicates your "open" one. Just set your "search" attribute on the wardrobe object to that one line.[/quote]
Sorry Jay, I am not getting it. Are you telling me to go to attributes tab when I click on wardrobe and then change the value to that one line? Or do I have to change the attribute so that it doesn't say search anymore? Or is it something entirely different? I am trying this out as I write this and so far I keep failing. I have tried changing value to your line, without any luck and I am still trying to figure out how to exactly change search to your line.

jaynabonne
Keep the "search" attribute and make its script be that one line.

        <search type="script">do(this, "open")</search>

Screenshot 2014-08-24 20.18.15.png

Mareus
jaynabonne wrote:Keep the "search" attribute and make its script be that one line.

        <search type="script">do(this, "open")</search>

Ok! I tried doing it, but its not working. I get this error:
Error running script: Object reference not set to an instance of an object.

PS. I made some more changes to my original script, so perhaps that is causing it.

jaynabonne
Actually here is the modified file... :)

Mareus
jaynabonne wrote:Actually here is the modified file... :)

Thanks, but its not working on the modified script. I will be posting the modified version where I made changes so that you have to pick up stuff manually. Just give me a sec and please dont go anywhere.

Mareus
Mareus wrote:

"jaynabonne"

Actually here is the modified file... :)


Thanks, but its not working on the modified script. I will be posting the modified version where I made changes so that you have to pick up stuff manually. Just give me a sec and please dont go anywhere.


One more slight change. Here is the final version, and as you can see I get the error.

jaynabonne
Not sure why, but make it:

do(this, "openscript")


instead of "open".

Mareus
jaynabonne wrote:Not sure why, but make it:

do(this, "openscript")


instead of "open".

Well it works, but not exactly what I had in mind unfortunately. You see, I am still not getting "It contains.." part. The whole point why I want search to behave like open is because I want to be able to see what is inside the wardrobe with search command. At least the error is gone.

HegemonKhan
you can put this anywhere, so long as it's at the same indenting as your 'game' Object, for example:

<asl version="540">
<ref name="English.aslx" />
<ref name="Core.aslx" />
<game name="blah">
// blah code lines
</game>
// blah code lines~tags
<command name="showlist_command">
<pattern>showlist #object# #text#</pattern>
<script>
if (HasAttribute (object, text)) {
ClearScreen
showlist_function (object, text)
on ready {
wait {
ClearScreen
}
}
} else {
msg ("This object, " + object + " does not have this list, " + text + ".")
}
</script>
</command>
<function name="showlist_function" parameters="object_x,text_x">
x = 0
foreach (item_x, object_x.text_x) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>
// blah code lines~tags
</asl>


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

let me try to explain how quest's code structure works:

coding can be written horizontally and~or vertically, professional coders write horizontally, but for us noobs, vertically is much easier for us to see, read, understand, write, and troubleshoot. So, let's do this explanation of mine, vertically, obviously.

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

<XXX> ~~~ is the beginning 'tag'
// it's contents
</XXX> ~~~ is the ending 'tag'

think of these 'tag' blocks (think of these 'tag' blocks as a bag~container holding stuff), as your physical things (ELEMENTS) in coding. Like 'matter' if you're into physics, or 'nouns' if you're into english grammer~language.

now, you'll actually see this, for example:

<asl version="550">
// mass of code lines
<object name="XXX">
<attr name="XXX" type="string">XXX</attr>
</object>
<function name="XXX" parameters="XXX">
msg ("hi")
</function>
</asl>


the, version="550" or name="blah" or type="string" or parameters="XXX" or etc XXX="XXX", are special attributes for the 'tag' blocks themselves.

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

whereas, scripting, is your actions in coding. Like 'forces~energy~waves~work' if you're into physics, or 'verbs' if you're into english grammer-language:

(the code lines or blocks with *NO* tags being used)

examples:

1. player.strength = player.strength + 5
2. Do (this.open)
3. if (orc.dead = true) { msg ("The orc is already dead, silly.") } else { msg ("You attack the orc, killing it.") } // wrote this horizontally, but you usually see it written vertically
4. // etc etc etc

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

The Elements:

1A. Your Game File (*.aslx); your game's coding; your entire game:

<asl>
// mass of code lines
</asl>

tells quest that this is, and contains, your entire (coded) game file

1B. if you want to make a library file (*.aslx), instead of a game file:

<library>
// mass of code lines
</library>

tells quest that this is, and contains, a library file. (think of a library file as a 'patch', 'expansion pack', an 'add-on', a 'mod', and etc gaming terms, that you can add to game files)

2. your library files added to your game, example, the default library files (which is how quest works, hehe):

<ref name="English.aslx" />
<ref name="Core.aslx" />

3. your game's settings:

<game>
// your game's settings and game info stuff
</game>

4. Objects:

<object>
// it's contents
</object>

5. Templates (shown horizontally, as it's short):

<template>it's contents</template>

6. Verbs

<verb>
// it's contents
</verb>

7+. I think you get the idea now... (Commands, Timers, Turnscripts, Object Types, Functions, and etc)

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

Sub-Elements (they must be inside the correct Element tag block, aka the Element which can hold them):

1. Attributes (shown horizontally):

<attr>it's contents</attr>

2. Exits

(too lazy, you know what the Exits are and how they look in code)

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

does this help you understand quest's code structure better, or has it just confused you more?

Mareus
HegemonKhan wrote:you can put this anywhere, so long as it's at the same indenting as your 'game' Object, for example:

<asl version="540">
<ref name="English.aslx" />
<ref name="Core.aslx" />
<game name="blah">
// blah code lines
</game>
// blah code lines~tags
<command name="showlist_command">
<pattern>showlist #object# #text#</pattern>
<script>
if (HasAttribute (object, text)) {
ClearScreen
showlist_function (object, text)
on ready {
wait {
ClearScreen
}
}
} else {
msg ("This object, " + object + " does not have this list, " + text + ".")
}
</script>
</command>
<function name="showlist_function" parameters="object_x,text_x">
x = 0
foreach (item_x, object_x.text_x) {
x = x + 1
msg (x + ". " + item_x.alias)
}
</function>
// blah code lines~tags
</asl>


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

let me try to explain how quest's code structure works:

coding can be written horizontally and~or vertically, professional coders write horizontally, but for us noobs, vertically is much easier for us to see, read, understand, write, and troubleshoot. So, let's do this explanation of mine, vertically, obviously.

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

<XXX> ~~~ is the beginning 'tag'
// it's contents
</XXX> ~~~ is the ending 'tag'

think of these 'tag' blocks (think of these 'tag' blocks as a bag~container holding stuff), as your physical things (ELEMENTS) in coding. Like 'matter' if you're into physics, or 'nouns' if you're into english grammer~language.

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

whereas, scripting, is your actions in coding. Like 'forces~energy~waves~work' if you're into physics, or 'verbs' if you're into english grammer-language:

(the code lines or blocks with *NO* tags being used)

examples:

player.strength = player.strength + 5
Do (this.open)
// etc etc etc

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

The Elements:

1A. Your Game File (*.aslx); your game's coding; your entire game:

<asl>
// mass of code lines
</asl>

tells quest that this is, and contains, your entire (coded) game file

1B. if you want to make a library file (*.aslx), instead of a game file:

<library>
// mass of code lines
</library>

tells quest that this is, and contains, a library file. (think of a library file as a 'patch', 'expansion pack', an 'add-on', a 'mod', and etc gaming terms, that you can add to game files)

2. your library files added to your game, example, the default library files (which is how quest works, hehe):

<ref name="English.aslx" />
<ref name="Core.aslx" />

3. your game's settings:

<game>
// your game's settings and game info stuff
</game>

4. Objects:

<object>
// it's contents
</object>

5. Templates (shown horizontally, as it's short):

<template>it's contents</template>

6. Verbs

<verb>
// it's contents
</verb>

7+. I think you get the idea now... (Commands, Timers, Turnscripts, Object Types, Functions, and etc)

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

Sub-Elements (they must be inside the correct Element tag block, aka the Element which can hold them):

1. Attributes (shown horizontally):

<attr>it's contents</attr>

2. Exits

(too lazy, you know what the Exits are and how they look in code)

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

does this help you understand quest's code structure better, or has it just confused you more?


I tried for almost an hour to make sense of this, experimenting and failing constantly. So quite honestly, you seem to be speaking with a language I do not understand. But thanks for trying to help me. It would help me a lot if you just downloaded the modified version I posted and made the necessary changes. Then I could see what you did and perhaps make sense out of this wall of alien text.

HegemonKhan
can you post (copy and paste) your entire game code, so I can paste my code into it, so you can see~have it done?

use the posting code tags:

[code.]your pasted game code[/code.]

but without the dots~periods in it, as it should look like this:

your pasted game code


-----------

back to trying to explain the code structure:

you are familiar with outlines, right?

I. earth
A. continents
1. europe
a. countries
i. Germany
2. africa


quest's code structure is the same way...

outline's 'I. earth' tag block holds: A. continents, 1. europe, a. countries, i. Germany, 2. africa

just as quest's '<asl version="550"></asl>' tag block holds it's entire game code contents

outline's '1. europe' tag block holds: a. countries, i. germany ~~~ BUT NOT: 2. africa

just as quest's '<game name="XXX"></game>' tag block holds '<author>XXX</author>' ~~~ BUT NOT: <object name="room">XXX</object>

Mareus
HegemonKhan wrote:can you post (copy and paste) your entire game code, so I can paste my code into it, so you can see~have it done?

use the posting code tags:

[code.]your pasted game code[/code.]

but without the dots~periods in it, as it should look like this:

your pasted game code


-----------

back to trying to explain the code structure:

you are familiar with outlines, right?

I. earth
A. continents
1. europe
a. countries
i. Germany
2. africa


quest's code structure is the same way...

outline's 'I. earth' tag block holds: A. continents, 1. europe, a. countries, i. Germany, 2. africa

just as quest's '<asl version="550"></asl>' tag block holds it's entire game code contents

outline's '1. europe' tag block holds: a. countries, i. germany ~~~ BUT NOT: 2. africa

just as quest's '<game name="XXX"></game>' tag block holds '<author>XXX</author>' ~~~ BUT NOT: <object name="room">XXX</object>


I already posted the whole game. Here it is again.

jaynabonne
If you want to list the contents, add this to your open script:

ListObjectContents (this)


That will list the contents of the object you pass. (That's what the standard "open" handler does after opening.)

jaynabonne
Actually, I probably mean your "search" script :)

Mareus
jaynabonne wrote:If you want to list the contents, add this to your open script:

ListObjectContents (this)


That will list the contents of the object you pass. (That's what the standard "open" handler does after opening.)

YES! Finally! Thank you sooooooo much Jay. I was struggling with this for a couple of hours already and I was slowly becoming desperate. Thank you and thank you. This is exactly what I needed. A small code to list objects. Perhaps my explanations are to blame, but I was getting dead tired.

jaynabonne
I just had to go look at how "open" worked. Sorry for the long path getting there. :)

Mareus
jaynabonne wrote:I just had to go look at how "open" worked. Sorry for the long path getting there. :)

You have nothing to be sorry, Jay. You are the most awesome of the awesomost persons :) I am just happy we finally found a way to fix my problem. And damn, my wife will probably kill me for playing with this awesome program so much :D

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

Support

Forums