Community
SCI Programming => SCI Community How To's & Tutorials => Topic started by: Cloudee1 on December 27, 2006, 02:32:26 AM
-
This is a pretty basic need, perhaps you have given the golden ring to the potion maker or say you eat the spinach dip, either way your character will need to "lose" the inventory item.
This is not covered in any of the tutorials, but has been covered enough at our old home that we all know how to do it, but any new members won't. I figured I had better stick this up here so anyone new to sci won't have to ask. I remember I asked when I first started out.
Anyway, if you have done the tutorial, which if you haven't you should, then you will remember that in order for you character to get an item you needed to use the code
(send gEgo:get(INV_KEY))
Now to drop an item either when your character uses it, gives it away, or simply drops it, it is simply a matter of using put instead of get.
(send gEgo:put(INV_KEY))
And that is it. One thing to remember though, in whatever room your character got the item, if you checked to see whether or not gEgo had it before initing it, then the item will reappear there since your character no longer has the item. This may seem strange if the person used the item, or gave it to someone else. Handling these type of instances will require using global variables.
-
One thing to remember though, in whatever room your character got the item, if you checked to see whether or not gEgo had it before initing it, then the item will reappear there since your character no longer has the item.
That would be because this is the wrong way of doing that. In these cases, you really want to test whether an object is in the room or not. An inventory object has an owner property and an ownedBy() method. The way Sierra used to do things was set the owner field to the number of the room the object is in. The (ego get:), (ego put:) and (ego has:) methods simply use this property. You can then test for ownership by doing:
(if (send anItem:ownedBy(gRoomNumber)) ...)This allows items to move around in the game. You can also use objects as owners, if you prefer; indeed, this is already done when an item is in the player's inventory.
Oh, and you'd want to know about
(send gEgo:put(anItem gRoomNumber))too.
Lars
-
Lars, never before has the ownedby or really any of the inventory items other parameters really been discussed. I personally had no idea how to do it, even though, it makes since that ownedBy would be a room number. I assume that by getting the item the ownedby attribute is changed automatically, or do we need to make a call to change it when the ego gets the item?
That will be great to get rid of some of those redundant global variables in the main script. Every byte counts afterall. ;)
Who'd have thought that I would have learned something from my own tutorial.
-
Ok Will it make it appear on the screen and take it out of my inventory?
JT
-
Ok Will it make it appear on the screen and take it out of my inventory?
JT
Nope... the concept of an inventory item is completely different than the visual representation of it that you might see in the room.
So I think what Lars is saying, is that you would check to see if the room "owns" the inventory object prior to going ahead and initializing the Prop instance (or whatever) that represents that object in the room.
I suppose it might have been possible for Sierra to bring these two concepts together (since they really are conceptually the same thing), but you have the problem that you want the image of the object as seen in your inventory to be different from the image of it showing up in the room. And also, there is a position associated with it when it's in the room, but not in your inventory.
Question for Lars: did Sierra then, usually set the initial owner room of each inventory object that is declared in the main script?
-
Question for Lars: did Sierra then, usually set the initial owner room of each inventory object that is declared in the main script?
Ok, looking at the space quest disassembly, it looks like the initial "owner" room is indeed specified in the inventory object.
(instance {Thermal Detonator} of InvI
(properties
said '/detonator'
description "Used for blowing stuff to little bits. It has an impact switch, so in other words...DON'T DROP IT!"
owner 69
view 242
loop 0
cel 12
)
)
-
So... has anyone put together a script which cleanly allows adding and dropping objects from inventory? I ask because if nobody has, I will. I am new to developing SCI games, but am becoming quickly entrenched in the process - I was thinking of putting together a boilerplate script that would be called upon initialization of the room that would go through all the objects in the game and display any that were currently in the room. This would involve tracking all objects at the game level, i.e. a script that would maintain the location/state of objects throughout during gameplay. A 'drop object' action would have to be implemented so that the actor would be able to drop the object without colliding with other props/resources on the screen (basically the reverse of the 'take object' functionality). A binding of views between the 'room' view and the 'inventory' view for a single object would also be necessary.
Am I on the right track here? Any suggestions?
-
If I'm picturing this right, then the scripts almost take care of everything for you. Almost anyway. You are going to need a butt ton of global variables, an x and y for each item representing wherever it gets dropped. Setting the x y dropped position would simply be a matter of setting its position variables as egos position, maybe - a couple of ys. Setting the room that the item is in is a matter of changing it's owner variable to the room number. Basicly it sounds to me that your extra script would really only need to handle the initalisation, something like if == currentroom item:owner then init at x y and also all the get and drop said statements. At least how I'm picturing it, it would be interesting to see what you come up with though.
-
Gumby, were you going to try to do anything more with this?
-
Yeah, I haven't circled back around it yet though. Maybe in a few more months.
-
That would be because this is the wrong way of doing that. In these cases, you really want to test whether an object is in the room or not. An inventory object has an owner property and an ownedBy() method. The way Sierra used to do things was set the owner field to the number of the room the object is in. The (ego get:), (ego put:) and (ego has:) methods simply use this property. You can then test for ownership by doing:
(if (send anItem:ownedBy(gRoomNumber)) ...)
I've been trying to implement this code but I'm not sure what to replace "anItem" with. If I try the inventory item's macro (INV_ITEM, for example) the compiler says it can't send to it...which makes sense because it's just a number. Can someone shed some light on this? I'm just not sure how to call it.
-
You need a pointer to the object you want to ask first. Try gInv:at(INV_ITEM), that should give you a pointer.
EDIT: Oh, and remember to check whether the return value is NULL before you use it. I forgot to do that in the other thread, as you pointed out there.
-
I'm afraid I'll need a little more instruction on how to implement this into an if statement to check whether the current room owns it. Everything I've tried so far with that line of code doesn't compile.
-
Once you get it sorted out it would be nice to have the Wiki updated.
-
The structure here is basically analogous to the other thread. We get a result back from a standard function (= gInv:at, in the other case this was gInv:firstTrue),
check that the result is actually a valid object, then get some value of out that object (= checkObject:ownedBy, in the other case it was lookObject:saidMe).
It's probably best to make it a global procedure.
(procedure public (IsOwnedBy invItem roomOrActor)
(var checkObject)
= checkObject (send gInv:at(invItem))
(if(IsObject(checkObject))
return (send checkObject:ownedBy(roomOrActor)
)
(else
return(0)
)
)
You use it like (if (IsOwnedBy INV_ITEM ego) ... or (if (IsOwnedBy INV_ITEM gCurrentRoom) ...Two points of note: You only need to do the null check if you're worried you may pass something other than a valid inventory number to this code. And this code supports checking both whether an object is in a room or in ego's possession. In fact, there is a third use: You can see whether an inventory object is irretrievably gone from the game (if you call gEgo:put with just one parameter, this is what will happen) - and you can check by passing the number -1 for roomOrActor.
And finally, this code is untested for compilation issues.
-
This makes perfect sense - I'll have to give this a shot when I get a chance. Thanks!
-
Thank you! I'll try this out later tonight and report back. Makes more sense now. Looks like it should work.
-
This works wonderfully! The only problem was that the procedure was called incorrectly. It should instead read:
(if (== IsOwnedBy(INV_ITEM gRoomNumber) TRUE)
...
)
or for Ego:
(if (== IsOwnedBy(INV_ITEM ego) TRUE)
...
)
There were also some bracket issues with the actual procedure declaration, but it's simple enough to sort out. Here's the code again for those who just want to copy and paste:
(procedure public (IsOwnedBy invItem roomOrActor)
(var checkObject)
= checkObject (send gInv:at(invItem))
(if(IsObject(checkObject))
return (send checkObject:ownedBy(roomOrActor))
)(else
return(0)
)
)
Thank you so much, Lars! Truly invaluable! Now I don't have to make several if cases for what objects ego is carrying! All I have to do is make the script check whether the room owns it or not. I'm sure this will save on memory and size.
-
Would you mind adding it to the Wiki?
-
Nice! I'm glad you got it working.
-
Sure, I can. Just tell me how lol. I'm logged in. I don't really see where to add a page. Also, what would be the best spot to put it in? Examples?
-
Just do a search for the title you want to give your page and if there no such page it will give you the opportunity to create it. You can add it to all of the appropriate categories by adding (at the bottom of the page)
[[Category:Examples]]
[[Category:Scripting]]
[[Category:Syntax]]This will add it to the Examples, Scripting and Syntax categories. This page will give you more info on the formatting, etc.
http://sierrahelp.com/SCI/Wiki/index.php?title=Help:Contents
-
This really helps with my understanding of the inventory. I always conceived it as 'what is the player holding', however it encompasses all 'takeable' objects within a game, whether they are currently in your inventory or not.
-
Indeed. We've been surviving thus far on little tricks, hacks, and workarounds when we didn't understand the proper concepts of the template game specifics.