TypeLib - Containables, Containers and Closable

EagleWing
28 Sept 2004, 15:43
:? It's Frank again. I'm sure the answer is obvious - it's just eluding me!

I have a desk, which is a container and it's closeable.
I have a manual which is containable and readable and starts the game in the closed desk.
I can open the desk and see the manual but, as it's in the desk rather than in the room I cannot take it. I've tried a variety of things but still get the "I can't see that here" message.

Here's the desk
define object <desk>
alt <drawer>
examine <A good solid wooden desk - none of your Ikea stuff!!>
prefix <the>
article <it>
gender <it>
type <TLTcontainer>
type <TLTcontainer>
type <TLTclosable>
properties <listHeader=In the drawer you find; closedDesc=The desk drawer is closed; isOpenDesc=The desk drawer is open.>
action <desk_open> if not property <desk; #&closed#> then msg <In the desk drawer you see a tattered and rather mildewed copy of a computer manual.>
end define


and the manual is

define object <manual>
take {
msg <You now possess a tattered and rather mildewed copy of a computer manual.>
give <manual>
}
type <TLTreadable>
type <TLTcontainable>
properties <isIn=desk>
end define


It ought to be fairly simple but I'm not getting there.

Any help etc .....

Frank

Anonymous
28 Sept 2004, 20:43
Hi Frank

This is one of those 'not very obvious' issues introduced by typelib.qlb, (but fixed in the version under test now) - the normal 'take' commands in QDK are completely hi-jacked by typelib.

To get a normally takeable object you just need to click the 'regular object' check box under typelib's 'Basics' tab. If however you want to do something else (like print your custom message) the trick is to write a replacement 'take' action for the object - and thus override typelib's default take action.

Sounds complicated but it is actually easy... here's the code you offered re-written as an action - try it and you'll see it works as required.

' "Game Name"
' Created with QDK Pro 3.52

!include <Typelib.qlb>

define game <Game Name>
asl-version <350>
gametype singleplayer
start <Start Room>
game author <Your Name>
game version <1.0>
game copyright <© 2004 ...>
game info <Enter any additional information about this game here.>
end define

define synonyms
end define

define room <Start Room>
look <Description Goes Here>

define object <desk>
alt <drawer>
examine <A good solid wooden desk - none of your Ikea stuff!!>
prefix <the>
article <it>
gender <it>
type <TLTcontainer>
type <TLTclosable>
properties <listHeader=In the drawer you find; closedDesc=The desk drawer is closed; isOpenDesc=The desk drawer is open.>
action <desk_open> if not property <desk; #&closed#> then msg <In the desk drawer you see a tattered and rather mildewed copy of a computer manual.>
end define

define object <manual>
type <TLTobject>
type <TLTreadable>
type <TLTcontainable>
properties <isIn=desk>
action <take> {
msg <You now posess a rather tattered and mildewed copy of a computer manual.>
give <manual>
}
end define

end define

define text <intro>
Enter intro text here
end define

define text <win>
Enter win text here
end define

define text <lose>
Enter lose text here
end define


Al (MaDbRiT)

007bond
28 Sept 2004, 22:28
I've had the same problem in my first game that I'm currently writing (and planning to release). Why should we have to write a custom command just to pick up objects that we want to have other scripts with. That's pointless. I know how to write a custom command, but I don't think that we should have to!

Anonymous
29 Sept 2004, 08:22

I've had the same problem in my first game that I'm currently writing (and planning to release). Why should we have to write a custom command just to pick up objects that we want to have other scripts with. That's pointless. I know how to write a custom command, but I don't think that we should have to!



You don't have to do that at all - so it isn't pointless, you are just missing the point!

1: The issue applies only if you use typelib and you want to do something other than pick up an object and add it to the inventory- (which is all the Quest 'normal' take will do without some additional coding work anyway). Typelib has to intercept that 'normal take' in some way to deal with objects in containers, closed things etc. and this causes some minor issues that I think are worth putting up with for the benefits - if you don't think so - don't use it. :-)

B: When using Typelib. you don't have to write custom 'take' commands at all - you're (plain and simply) wrong on this. You just have to provide an alternative action for the inbuilt take command instead of writing an alternative script / custom take command.

As this alternative take action is called by the typelib custom 'take' command you don't have to do any checks re the object, the take action will only be called if the object ought to be allowed to be taken. So writing a custom take command is completely the wrong approach, you'd have to re-do all the checks for object location, takeability, containment and so on - that's a helluva lot of duplicated work and hardly the sensible way to approach it.

I agree that it's a workaround in so much as you have to put your custom message into an action and have that action move the object to the inventory, rather than use the slightly easier QDK take tag & script box, but that's hardly a major hardship.

I realise this does 'break' QDK's take tag & script function, which is not an ideal situation, so in my under test new typelib I've re-coded to avoid the problem. For now though you have 'Hobsons choice' - use the workaround or don't... :-)

Al (MaDbRiT)

EagleWing
29 Sept 2004, 18:05
:P Al said

here's the code you offered re-written as an action - try it and you'll see it works as required.



You've done it again Al. That code worked a treat.

Thanks again.

While on the subject of closeables, I was wondering how to deal with a door. I assume the same door has to be defined in both rooms since it exists in both so if it's opened in one room it has to be opened in the other etc.?

Frank
:P

Anonymous
29 Sept 2004, 18:54
Frank asked

While on the subject of closeables, I was wondering how to deal with a door. I assume the same door has to be defined in both rooms since it exists in both so if it's opened in one room it has to be opened in the other etc.?



Although typelib's closable type wasn't really intended for doors between rooms, you can use it to do this in a number of ways, using one door object, two synchronised door objects or even use no door objects at all.

Here's a demo of how to do it using typelib with the 'two synchronised doors' method (a method I quite like :-) ). Basically this means each room has its own door object (aliased to just 'door') and any open/close action you perform on one door is also applied by way of the open/close actions to the other door too. i.e. open the door in the lounge and the other door in the hall is also opened. This gives the effect of a single door between the rooms.

The open/close actions are also used to create and destroy exits between the two rooms as required. I'm relying on typelib's default open, close, already open, already closed messages here, but you can tailor those individually for either door - which looks to the player like either side of the same door - as required.

Here's the code.

' "door example"
' Created with QDK Pro 3.52

!include <Typelib.qlb>

define game <door example>
asl-version <350>
gametype singleplayer
start <hallway>
game author <Al (MaDbRiT)>
game info <Created with QDK Pro 3.52>
end define

define synonyms
end define

define room <hallway>
prefix <the>

define object <halldoor>
alias <door>
alt <door>
type <TLTclosable>
action <opened> {
create exit north <hallway; lounge>
create exit south <lounge; hallway>
property <loungedoor; not closed>
}
action <closed> {
create exit north <hallway; >
create exit south <lounge; >
property <loungedoor; closed>
}
end define

end define

define room <lounge>
prefix <the>

define object <loungedoor>
alias <door>
alt <door>
type <TLTclosable>
action <opened> {
create exit north <hallway; lounge>
create exit south <lounge; hallway>
property <halldoor; not closed>
}
action <closed> {
create exit north <hallway; >
create exit south <lounge; >
property <halldoor; closed>
}
end define

end define

define text <intro>

end define

define text <win>

end define

define text <lose>

end define



Al (MaDbRiT)

EagleWing
29 Sept 2004, 20:04
Al said

Here's a demo of how to do it using typelib with the 'two synchronised doors' method



Thanks yet again, Al. I look forward to trying that out as soon as I have time.

:P

Frank

007bond
29 Sept 2004, 22:00
That's all well and fine Al, but how to write an alternitive script?

Anonymous
30 Sept 2004, 08:27

That's all well and fine Al, but how to write an alternitive script?



An alternative script to do what exactly?

If you just want the typelib take to do something else instead of (or in addition to) the normal 'move to inventory', you just have to replace the object's take action with one of your own as shown in the example above. If you don't want the object to be takeable at all then you could either not make it a TLTobject or make it a not takeable TLTobject. The thing to remember here is that the core typelib 'take' only does the checking, if the object is available for the player to take it calls an inherited 'take' action that does the actual taking - and you can replace that take action very easily.

Example: if you don't want the object actually taken normally (i.e. in attempting to pick up a booby trapped treasure you might want the player killed by a volley of poisoned arrows or whatever) you can still put the neccessary scripting into a replacement 'take' action for the object and let typelib deal with checking that the treasure object is available to be taken etc.

An absolute last resort (as always) with Quest is to code your own custom command for a particularly troublesome object to override the typelib "take" construct completely (all the typelib checks would be bypassed too of course, which could make this a pretty shaky piece of code) but I have to say that I can't think of a situation in which that would be needed - which is exactly how I intended it to be. :-)

Al (MaDbRiT)

EagleWing
30 Sept 2004, 09:50
Things are going really weird on me at the moment!! The code Al gave me seemed to be working fine - but now it doesn't! :evil:

I get the desk drawer open OK. I'm told there's a manual there. But any attempt to take the manual gets the response "I can't see that anywhere!"

I'm sure I haven't changed any code - this is the complete description of the room, objects and actions.


define room <East End of Corridor>
west <Long Corridor>
description <You are at the east end of the long corridor.|nThere is a desk here.>

define object <desk>
alt <drawer; desk drawer>
look <A good solid wooden desk - none of your Ikea stuff!!>
examine <A good solid wooden desk - none of your Ikea stuff!!>
prefix <the>
article <it>
gender <it>
type <TLTcontainer>
type <TLTclosable>
properties <listHeader=In the drawer you find; closedDesc=The desk drawer is closed; isOpenDesc=The desk drawer is open.>
action <desk_open> if not property <desk; #&closed#> then msg <In the desk drawer you see a tattered and rather mildewed copy of a computer manual.>
end define

define object <manual>
type <TLTobject>
type <TLTreadable>
type <TLTcontainable>
properties <isIn=desk>
action <take> {
msg <You now posess a rather tattered and mildewed copy of a computer manual.>
give <manual>
}
end define

end define


Sorry to be a nuisance but I'm about ready for the men in the white coats!

Frank

007bond
30 Sept 2004, 10:05
OK, I think I get it. I just write a custom take command, and everything works fine, including TypeLib, right? (Al's posts are always long and complicated)

Anonymous
30 Sept 2004, 15:22
Frank

I've tried c&p'ng the drawer & manual code you posted here into a test piece and can confirm it still works properly - which means that somehow, somewhere something else is causing the problem you are experiencing. :-(

So one way or another it seems you've changed 'something' inadvertently and broken the code.

If you want to, e-mail me your asl file and I'll see if I can spot the bug for you.

Al (MaDbRiT)

(check the memberlist profiles to get my e-mail address)

007bond
30 Sept 2004, 21:04
Just on your email address I you told me to email you about something a week ago. I did, and got no reply!

Anonymous
01 Oct 2004, 07:43
007Bond wrote:

Just on your email address -you told me to email you about something a week ago. I did, and got no reply!



That's because I've not received an e-mail... did it bounce? was it mis-directed? I'm not the sort of person to ignore e-mails (unless they are obvious spam)

Al (MaDbRiT)

007bond
02 Oct 2004, 03:52
I'll send you another one...I just can't remember what is was about! Once I've digged up the post and found out what it was for, I'll email you.

EagleWing
02 Oct 2004, 15:11
Al said (to Frank)

If you want to, e-mail me your asl file and I'll see if I can spot the bug for you.



So I've sent my short adventure to you, Al. Thanks!! :D :P :D

Frank

Anonymous
02 Oct 2004, 20:35
Hi Frank

"Small Adventure" received, several bugs splatted, adventure returned... :-)

Al (MaDbRiT)

steve the gaming guy
05 Oct 2004, 16:35
to AL!

Anonymous wrote:To get a normally takeable object you just need to click the 'regular object' check box under typelib's 'Basics' tab. If however you want to do something else (like print your custom message) the trick is to write a replacement 'take' action for the object - and thus override typelib's default take action.


I finally got started messing around with containables and containers and I too, am having the problem where the game does not see the object once it's placed in something else. I clicked the 'regular object' box but there seems to be no change.

I'm practicing in a test game format where it's not really a game. I have a room full of scripts and objects that are there for practice purposes only. In this room, I have a containable car and a frog. I can put the frog in the car. I can see the frog in the car but even after the 'regular object' box is checked, I continue to get the same response that the game cannot see it anywhere.

Do I have to break down and actually do some coding or can I manipulate it in QDK?

steve the gaming guy :?:

Anonymous
05 Oct 2004, 17:50
Steve wrote


I finally got started messing around with containables and containers and I too, am having the problem where the game does not see the object once it's placed in something else. I clicked the 'regular object' box but there seems to be no change.



When you say the 'game does not see' the object, do you mean it is no longer listed as visible in the room in the available objects box - or that the game cannot interact with the object.?

If it is the former, well that is entirely intentional on my part. If something is inside another thing the immediately visible object in the room is the container, not the containable inside it. You see what's inside something by examining it - that's the way I coded typelib to work.

If the latter - then something is broken because unless the container is closed, you should be able to interact with containables inside it.


I'm practicing in a test game format where it's not really a game. I have a room full of scripts and objects that are there for practice purposes only. In this room, I have a containable car and a frog. I can put the frog in the car. I can see the frog in the car but even after the 'regular object' box is checked, I continue to get the same response that the game cannot see it anywhere.

Do I have to break down and actually do some coding or can I manipulate it in QDK?



You shouldn't need to leave QDK for this, I'll sign off & knock out a frog & car scenario you can try and then post it here...

Al (MaDbRiT)

Anonymous
05 Oct 2004, 17:58
As promised - frog and car demo (done from QDK in about 40 seconds - excuse lack of finesse!)


' Created with QDK Pro 3.52

!include <Typelib.qlb>

define game <>
asl-version <350>
gametype singleplayer
start <start>
game info <Created with QDK Pro 3.52>
end define

define synonyms
end define

define room <start>
look <start room>

define object <car>
type <TLTcontainer>
properties <not takeable>
end define

define object <frog>
type <TLTobject>
type <TLTcontainable>
end define

end define

define text <intro>

end define

define text <win>

end define

define text <lose>

end define


Absolutely nothing but a few clicks required...

Al (MaDbRiT)

steve the gaming guy
05 Oct 2004, 18:32
Ok, thanks. I'll work with it and see if I can get it to work. I'm probably going to end up in the same point I was with the hamster and microwave as far as where to paste your code. But I'll give it a shot.

thanks a lot!
steve the gaming guy :lol:

steve the gaming guy
05 Oct 2004, 18:46
Good grief. I saw what I was doing wrong. My original code probably DID work. I normally type 'get object' as opposed to take object. When you initially pick up an item 'get' works. But when it is in a container, you must say 'take' or it won't work.

Thanks Al

steve the gaming guy :shock:

Anonymous
05 Oct 2004, 18:58
Hi Steve

'Get' ought to work too - but as Frank has also discovered there is a little oversight in my typelib that means it wont!

Easy fix - put a synonym of 'get = take' into your ASL file and both get and take (from container) will work fine

Al (MaDbRiT)

EagleWing
05 Oct 2004, 19:59
Al said

Easy fix - put a synonym of 'get = take' into your ASL file and both get and take (from container) will work fine



:D Certainly did for me! :P

Frank

steve the gaming guy
05 Oct 2004, 20:06
sweet! Thanks for the help!

steve the gaming guy :o