DROP ALL/TAKE ALL

Anonymous
10 Sept 2004, 13:40
You guys are going to get tired of all these questions.

I have seen in older Inform text games where you can type "take all" and every item in the room that is readily takeable will go into your inventory. I don't mean the items that are part of a puzzle (e.g. a hidden needle in a haystack that you have to search through first). I just mean objects that are right there. Let's say in a game, someone pushes you down and your whole inventory spills onto the floor. What if your holding a huge lot of items, it'd be annoying to the player to make them say "take wallet, take keys, take hair piece, take tarantula, take mother-in-law, etc..."
You get my drift.

A reason for "dropping all" would be a scenario where you have to squeeze through a small opening and you can't be carrying anything with you but you want to be able to pick them all up when you return.

steve

Alex
10 Sept 2004, 14:12
I can't test this right now (I'm at work..) but something like this should work:


command <take all> for each object in <#quest.currentroom#> give <#quest.thing#>


You should be able to see the idea anyway, and you can extend that to print a message for each item taken, check for a certain property etc.

Anonymous
10 Sept 2004, 18:44
Can this be used in the game properties so no matter what room you're in, you can drop all or take all?

steve :P

Alex
10 Sept 2004, 19:55
Yes :D

007bond
10 Sept 2004, 23:14
That's handy to know. I defenitely could of used that in some of the games I tried to create and never finished.

Anonymous
14 Sept 2004, 13:27
I think that this script should still check if the #quest.thing# is, say visible, cause you may have an invisible item in there and the script command would still yield you the item, even invisible. Or am I wrong?

007bond
16 Sept 2004, 06:27
That's a good point. Is there a script command that will let you check for that?

Alex
16 Sept 2004, 08:55
You could check for the "invisible" property e.g.


if not property <#quest.thing#; invisible> then .... (take the object)


Actually I have a niggling feeling that there is a bug in setting an object as "invisible" not showing up as a property if you set the invisibility using a tag. It works when you do it with the "conceal" script command though. Something like that anyway - I could be confusing it with something else - again I'm at work at the moment so can't check. Try it out!

Elexxorine
28 Oct 2004, 14:38
do you put it in misc. asl codes in properties or somewhere else?

I think Im Dead
28 Oct 2004, 20:13
The code Alex posted you would insert into a command, specifically your TAKE ALL command.

In QDK you would simply create a new command, call it TAKE ALL, then press the edit button. After that you basically read that script of code, and select from the menu the option that seems most like the code.

For this one you would...
add a FOR EACH OBJECT IN with the string #quest.currentroom#

then press the edit script button

add a conditional, in the IF section select if the object does NOT have a property(you check a little box for not), then the object is #quest.thing#, the property is invisible,

then you specify the THEN script, which would be, give #quest.thing#.

Basically as simple as it reads in the code, just stepped it out for the QDK users. You can basically do this exact same thing with any code pasted here, just gotta read, then pick the right options and enter the right information.

paul_one
29 Oct 2004, 10:49
Alex - I remember that bug.
Testing for invisibility didn't work (or it didn't show in the properties window - or both) until you actually used conceal. Then it worked.
I did do a test file on that once but haven't used it since.

steve the gaming guy
26 Nov 2007, 16:58
I think Im Dead wrote:In QDK you would simply create a new command, call it TAKE ALL, then press the edit button. After that you basically read that script of code, and select from the menu the option that seems most like the code.

For this one you would...
add a FOR EACH OBJECT IN with the string #quest.currentroom#


then press the edit script button

add a conditional, in the IF section select if the object does NOT have a property(you check a little box for not), then the object is #quest.thing#, the property is invisible,

then you specify the THEN script, which would be, give #quest.thing#.

Basically as simple as it reads in the code, just stepped it out for the QDK users. You can basically do this exact same thing with any code pasted here, just gotta read, then pick the right options and enter the right information.


...and 3 years later

I think I dropped this idea because it looked to be too complicated. I remember starting this thread to ask a question but I don't remember implementing it.

I bolded a line in the quote above that I don't understand. I can't find a place to choose anything like "FOR EACH OBJECT IN".
I'm kind of back to where I was before and other people posted similar responses in here.
I haven't gotten to the point to decide whether something is invisible or not.

What I've tried [in QDK] is 'If #quest.thing# is available for interaction, then give #quest.thing# to the player.' This does nothing. I also substituted with #quest.objects#. Nothing.

paul_one
26 Nov 2007, 18:02
Steve.

I think the idea is a bit more sound with the "execute command as player [ get #quest.thing#]".
Still, the visible property is very important (don't want to give away important hidden objects do we).

Try the if [property]
#quest.thing# ; invisible
??

Dr.Froth
26 Nov 2007, 18:16
Instead of worrying about hidden objects, make the objects that you want to be hidden also inaccessible.

When the player "finds" the object, you can run a script to make it accessible.

I am pretty sure that you will then only pick up the accessible objects with your script.

Of course, you would need to find a way to not pick up Scenery items. Otherwise, how can you describe the walls, floor, doors, ceiling, etc. Surely you would not leave those things out for further examination.

I suppose that you could make custom commands for each item, but that seems like a lot of extra work.

That is a good thought for Quest 5. Provide a setting in the if/than scripts to stipulate between the different object sets.

steve the gaming guy
26 Nov 2007, 18:19
Thanks!
Are you saying when the player types "take all", that the script will use the "execute command as player" command? Are you saying that I will just have a bunch of take commands in the script? Like the player types "take all" and I have "take apple, take pencil, take stapler" in the script?
And out of curiosity, is #quest.thing# a built in command in the game? I don't understand how to use it properly.

After playing around with the Excecute thing...

Player types <take all>, "Execute command..." "take #quest.thing#"
returns
"I can't see that here"

also tried with #quest.objects#

I want to get the take all feature to work for me before adding the invisible item bit.

EDIT
I did find that #quest.thing# is mentioned in the help file but I still don't understand how to use it.

Dr.Froth
26 Nov 2007, 18:58
Here you go Steve. Compile this game and check it out:




' "take test"
' Created with QDK Pro 4.02

!include <stdverbs.lib>

define game <take test>
asl-version <400>
gametype singleplayer
start <The Moon>
game author <froth>
game info <Created with QDK Pro 4.02>
command <drop all> for each object in <inventory> lose <#quest.thing#>
end define

define options
debug on
panes on
end define

define room <The Moon>
look <Welcome to the Moon. Try to take all of these objects.|n|nNow type: jump>
east <Moon Base>
command <take all> for each object in <The Moon> if exists <#quest.thing#> then give <#quest.thing#>
command <jump> {
if flag <jumpdone> then msg <You leap about like a moron.> else {
msg <You jump up and discover that you were standing on a lemon.>
show <Lemon>
flag on <jumpdone> }
}

define object <Severed Head>
take
displaytype <Object>
article <it>
gender <it>
end define

define object <Fetus>
take
displaytype <Object>
article <it>
gender <it>
end define

define object <Lemon>
take
displaytype <Object>
article <it>
gender <it>
hidden
end define

end define

define room <Moon Base>
look <Wow... now take all of this crap.|n|nNow type: drop all|n|n|nAmazing.>
west <The Moon>
command <take all> for each object in <Moon Base> if exists <#quest.thing#> then give <#quest.thing#>

define object <key>
take
displaytype <Object>
article <it>
gender <it>
end define

define object <bass guitar>
take
displaytype <Object>
article <it>
gender <it>
end define

define object <Satan's Codpiece>
take
displaytype <Object>
article <it>
gender <it>
end define

end define



The room descriptions will walk you through it. But if you check this out in QDK you can see exactly how I did it. Notice that my hidden object (the lemon) was not taken by the take all command until it was revealed (by jumping). Notice also that jump only works once. The drop all command works great too.

Hope this helps you out.

steve the gaming guy
26 Nov 2007, 19:28
Well how 'bout them apples. It works.

And I see how you did it in QDK. That's interesting. Thanks a lot!

I think Im Dead
26 Nov 2007, 19:48
I'm not totally sure what this is about but #quest.thing# is a built in string variable only used with the FOR EACH OBJECT IN GAME/ROOM, it's just what Quest calls the objects it is recursively going through as it goes through them. But for shits and giggles, here's a conditional take all command.


command <take all> {
for each object in <#quest.currentroom#> {
if property <#quest.thing#; WHATEVERYOUWANT> then {
give <#quest.thing#>
}
}

}


With Less Brackets


command <take all> {
for each object in <#quest.currentroom#> if property <#quest.thing#; WHATEVERYOUWANT> then give <#quest.thing#>
}

paul_one
26 Nov 2007, 23:11
Are you sure that it didn't give it to the player?
I would have expected the player to get it - BUT IT STILL BE INVISIBLE.

http://www.axeuk.com/quest/developer/documentation/script-object.htm

Hidden actually doesn't let the loop interact with it.
Invisible still means the user can interact (say - flowers perhaps) but you may not want that object to be given to the player when he types "take all".

The if should still be included..

Dr.Froth
27 Nov 2007, 05:39
Are you asking me or Dead?

If you are asking me than my answer is:

Yes the player did not get it. Why? Because it was not hidden it was inaccessible, which works a little different. You can tell after you jump and the lemon is revealed (after typing take all once) and it is in the room, not your inventory. Compile my example and see.

If you were talking to Dead, than pardon me.

paul_one
27 Nov 2007, 19:13
Nah - you're right Froth.. I wouldn't have expected the object to be inaccessible to the "for every object in room <>" command..

Actually I think I better go over my common library and make sure that I've put stuff in for this in the description tag - I think I did because I use invisible objects.

AAANYWAY, yeah - I think invisibility should still be checked for because you shouldn't be able to (really) pick up an object which isn't really visible.

I think you're doing a good job though guys - replying to Steve's queries.

insidethecircle
03 Oct 2009, 09:31
ok

ive been trying to make this work for me- how do i insert the code practically?

- For each object in "#quest.currentroom#" Give "#quest.thing#" to the player
this code picks up every object in the room.
how do literally code the line so that the #quest.currentroom# specifies the non invisible items?

this isnt a deal breaker- its just nice to have the option.

Freak
03 Oct 2009, 11:01
Question: How does your version of GET ALL / DROP ALL handle it if the object has a script that fires when the object is taken or dropped?

(Also, Quest's concept of invisibility doesn't make sense to me. If you don't want the object to be listed in the room, or for the player to be able to refer to it, why even put the object in the room in the first place?)

Overcat
03 Oct 2009, 12:02

Question: How does your version of GET ALL / DROP ALL handle it if the object has a script that fires when the object is taken or dropped?



That is a telling question. What if taking an object triggers some effect, or one of the objects cannot be taken for some reason? GET/DROP ALL both need to fire the rules you've defined for your objects. You cannot simply bypass all your normal logic and do a blind exchange. Preferably, one would do this:

pseudo-code:
for each object in the room
execute "get obj"
next


But even so, there's this:

> get all
You take it.
You take it.
You take them.
You can't take it - it's attached to the wall.
You take it.

So what exactly did I (and couldn't I) take?

> drop all
You drop it.
You drop it.
You drop them.
You drop it.
You wouldn't dare part with it.

Same question.

These issues are solvable, but it takes some planning.

(Also, Quest's concept of invisibility doesn't make sense to me. If you don't want the object to be listed in the room, or for the player to be able to refer to it, why even put the object in the room in the first place?)



An object can either be "invisible" (in which case - if I remember correctly - it doesn't show up in the object pane, but can still be referred to) or "hidden" (in which case it cannot be interacted with). I think hiding an object is equivalent to moving the object to an inaccessible room. It's redundant, but redundancy is good (IMO). One can either move the object away, or hide it. Then they can either move it back, or unhide it.

insidethecircle
05 Oct 2009, 10:47
yeah
i'd figured that if i made the all the objects that i didn't want to pick up inaccessible than i wouldn't be able to interact with any objects acting as scenery.
is there a way to set a 'property' to certain objects that could separate the objects you can take and the ones you can't with the 'take all objects in current room ' command?

Overcat
05 Oct 2009, 16:55

> get all
You take it.
You take it.
You take them.
You can't take it - it's attached to the wall.
You take it.



The fourth item that could not be taken may be something you can actually take if you do something else first. Like a hook on a wall. Perhaps you need to unscrew it, then take it. Regardless, the hook is still a viable item that can be referenced with "get all".

is there a way to set a 'property' to certain objects that could separate the objects you can take and the ones you can't with the 'take all objects in current room ' command?



Indeed!

command <get all> {
for each object in <#quest.currentroom#> {
if property <#quest.thing#; item> and not hidden <#quest.thing#> then {
exec <get #quest.thing#>
}
}
}


Then, in the definitions for your objects, just specify as so:

define object <couch>

...

end define

define object <apple>

properties <item>
...

end define


The couch isn't an object, but the apple is. Still, if you have several items in the room, you're going to get the ugly message block full of useless pronouns (ie. 'it'):

You take it.
You take it.
You take them.
etc.

A possibility is to define an item type and a game property to handle 'get/drop all'.

define type <item>

action <OnGet> {

set string <this; $thisobject$>
if property <game; noPronoun> then msg <You take the #@this#.> else msg <You take #(this):article#.>
give <$thisobject$>
}

action <OnDrop> {

set string <this; $thisobject$>
if property <game; noPronoun> then msg <You drop the #@this#.> else msg <You drop #(this):article#.>
lose <$thisobject$>
}


end define


Define your item objects thusly:

define object <apple>

type <item>
...

end define


Create the 'all' commands as so:

command <get all> {

'put the noPronoun property on the game object
property <game; noPronoun>

'cycle through the items
set numeric <i; 0>
for each object in <#quest.currentroom#> {
if type <#quest.thing#; item> then {
exec <get #quest.thing#>
inc <i>
}
}

if (%i% = 0) then msg <There is nothing to take here.>

'remove the noPronoun property from the game object
property <game; not noPronoun>
}

command <drop all> {

'put the noPronoun property on the game object
property <game; noPronoun>

'cycle through the items
set numeric <i; 0>
for each object in <inventory> {
exec <drop #quest.thing#>
inc <i>
}

if (%i% = 0) then msg <You have nothing to drop.>

'remove the noPronoun property from the game object
property <game; not noPronoun>
}


The last step is to write your own 'get' and 'drop' commands, overriding the built-in functionality:

command <get #@item#> {

if not got <#item#> then {
if action <#item#; OnGet> then doaction <#item#; OnGet> else msg <You cannot take that.>
}
else {
msg <You already have that.>
}
}

command <drop #@item#> {

if got <#item#> then {
if action <#item#; OnDrop> then doaction <#item#; OnDrop> else msg <You cannot drop that.>
}
else {
msg <You don't have that to drop.>
}
}


WARNING: I hand-typed all of the above, with no check in the Quest runner, so there may be typos.

UPDATE: Created and checked a demo file, which is attached. Use this over the above example.

steve the gaming guy
05 Oct 2009, 19:17
If you need my final version of the game, check out Christmakwanzakkuh in the game archives. I'd post the link but I can no longer access the game page from work. The command comes into play in the second room after you've looked at everything and make the weapons all available. Then say "take all"... and it works. I got the code from this thread so you should be able to see how it blends into the rest of the game coding if you open it up in notepad.

insidethecircle
07 Oct 2009, 09:08
thanks overcat thats really great.i'll give it a real look over in a bit and see what youp did.
i had a go at doing it myself after copying previous code found on this topic and tweaking it bit by painful pit

as i spent time on it - and for my ego's sake i'll add what i did - as i was impressed with my own coding efforts (i am no programmer!!)

here it goes....
-this script takes everything in the room providing it is visible and not in closed containers and doesn't have a property called 'droppable' (so objects can act as scenery and items can be in closed containers without being picked up as well; the droppable property will allow specified visible objects to be immune to the #take all# command. The script also prints a list of what you have collected and adds a failsafe if nothing is in the area to pick up. WHEW!!
-this works great for me as i prefer writing my own descriptions for locations via the runscript button on quest's room page - but if you want to use the quest automatically generated location scripts then i guess all it means is applying a property tab to any item that you want (or alternatively not want) to pick up.


command <take all; get all; take everything ; get everything; pick up everything> {
for each object in <#quest.currentroom#> {
if not property <#quest.thing#; invisible> and not property <#quest.thing#; hidden> and not property <#quest.thing#; droppable> then {
give <#quest.thing#>
msg <|s00You pick up #(quest.thing):prefix# |b#@quest.thing#|xb.>
flag on <taken all> } }
if not property <#quest.objects#; invisible> and not property <#quest.objects#; hidden> and not flag <taken all> and not ( #(#quest.objects#):droppable# = 1 ) then msg <|s00There is nothing here to pick up.>
flag off <taken all>
}
command <drop all> {
for each object in <inventory> {
lose <#quest.thing#>
msg <|s00You drop #(quest.thing):prefix# |b#@quest.thing#|xb.> }
}

insidethecircle
07 Oct 2009, 09:09
-however how do you code for or express the script for stating a message like 'You aren't carrying anything.'if you try and use the drop all command without carrying anything.

Overcat
07 Oct 2009, 11:59
Does the above script work? I ask, because I notice some errors, I think.

For instance, the documentation for #quest.objects# states:

quest.objects
Returns a list of objects in the current room.



In which case, I don't think you can check for properties on that list. In fact, if you turn on the ASL debug window, I'm pretty sure you'll be getting error messages something like this:

ERROR: No such object 'your list of objects here' in condition 'property <your list of objects here; invisible>' ...
ERROR: No such object 'your list of objects here' in condition 'property <your list of objects here; hidden>' ...
etc.



Additionally, I think the snippet "#(#quest.objects#):droppable# = 1 )" is incorrect - it should be "#(quest.objects):droppable# = 1 )". You don't enclose the variable inside the round brackets with hashes (as you normally would), because this will confuse the interpreter. However, because #quest.objects# is a list (essentially just a string, but no object exists with the contents of this string), this won't work anyway.

-however how do you code for or express the script for stating a message like 'You aren't carrying anything.'if you try and use the drop all command without carrying anything.



If you've downloaded my demo GetAndDropAll.asl file, you can see how I've achieved this with a for-each loop of the inventory room, and a counter variable (i). The drop all command in the above post shows it too, I think. The counter (i) increments every time an object is found that will be dropped. Therefore, if the counter is 0 at the end of the for-each loop, then we know the player did not drop anything, and we can message the window accordingly.

as i spent time on it - and for my ego's sake i'll add what i did - as i was impressed with my own coding efforts (i am no programmer!!)



You're doing great! ASL is a very good language to learn the basics of programming (IMO, others may disagree). It is simple and allows one to step on up to more sophisticated languages later, having grasped a bit about program flow, user-defined typing, and inheritance.

insidethecircle
08 Oct 2009, 10:02
thanks overcat
(and thanks for the help from everybody here too)- otherwise i think id be halfway through pulling my hair out haha
ive copied the script for a game im putting together- and i works with out any errors but ill run through what you suggest and make sure that its all working properly.

is there any luck with how do you code for or express the script for stating a that the inventory is empty - i saw "i" on some script a page or so back - is that it?

Overcat
08 Oct 2009, 15:28

is there any luck with how do you code for or express the script for stating a that the inventory is empty - i saw "i" on some script a page or so back - is that it?



Yes - I used a numeric variable called 'i' (you can call it whatever you wish) to increment whenever an object is found that is actually dropped. It is set to 0 before the for-each loop. After the for-each loop is complete (after all the objects in the inventory have been checked), then I see whether this 'i' variable still equals 0. If it does, then I know the player did not drop anything.

insidethecircle
09 Oct 2009, 13:09
thanks
i realised that i was being a dumb ass when i looked through your previous script properly and saw the 'i'
have a great weekend!!