Community

SCI Programming => SCI Community How To's & Tutorials => Topic started by: Cloudee1 on December 27, 2006, 02:32:26 AM

Title: Taking an Inventory Item away from character
Post 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

Code: [Select]
(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.

Code: [Select]
(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.
Title: Re: Taking an Inventory Item away from character
Post by: lskovlun on December 27, 2006, 07:19:53 AM
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:
Code: [Select]
(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
Code: [Select]
(send gEgo:put(anItem gRoomNumber))too.

Lars
Title: Re: Taking an Inventory Item away from character
Post by: Cloudee1 on December 27, 2006, 10:52:25 PM
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.
Title: Re: Taking an Inventory Item away from character
Post by: jtyler125 on March 05, 2007, 08:48:50 PM
Ok Will it make it appear on the screen and take it out of my inventory?

JT
Title: Re: Taking an Inventory Item away from character
Post by: troflip on March 05, 2007, 09:35:41 PM
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?
Title: Re: Taking an Inventory Item away from character
Post by: troflip on March 06, 2007, 02:24:12 AM
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.

Code: [Select]
(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
    )
)

Title: Re: Taking an Inventory Item away from character
Post by: gumby on June 30, 2010, 09:53:32 PM
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?
Title: Re: Taking an Inventory Item away from character
Post by: Cloudee1 on July 02, 2010, 12:39:06 AM
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.
Title: Re: Taking an Inventory Item away from character
Post by: Collector on January 17, 2011, 02:06:05 AM
Gumby, were you going to try to do anything more with this?
Title: Re: Taking an Inventory Item away from character
Post by: gumby on January 17, 2011, 09:10:52 AM
Yeah, I haven't circled back around it yet though.  Maybe in a few more months.
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on August 29, 2011, 06:50:06 PM
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:
Code: [Select]
(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.
Title: Re: Taking an Inventory Item away from character
Post by: lskovlun on August 30, 2011, 01:41:18 AM
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.
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on August 30, 2011, 02:20:15 PM
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.
Title: Re: Taking an Inventory Item away from character
Post by: Collector on August 30, 2011, 03:34:36 PM
Once you get it sorted out it would be nice to have the Wiki updated.
Title: Re: Taking an Inventory Item away from character
Post by: lskovlun on August 30, 2011, 03:41:06 PM
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.
Code: [Select]
(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
Code: [Select]
(if (IsOwnedBy INV_ITEM ego) ... or
Code: [Select]
(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.
Title: Re: Taking an Inventory Item away from character
Post by: gumby on August 30, 2011, 04:40:56 PM
This makes perfect sense - I'll have to give this a shot when I get a chance.  Thanks!
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on August 30, 2011, 06:48:11 PM
Thank you! I'll try this out later tonight and report back. Makes more sense now. Looks like it should work.
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on September 01, 2011, 05:48:49 PM
This works wonderfully! The only problem was that the procedure was called incorrectly. It should instead read:

Code: [Select]
(if (== IsOwnedBy(INV_ITEM gRoomNumber) TRUE)
    ...
)

or for Ego:

Code: [Select]
(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:

Code: [Select]
(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.
Title: Re: Taking an Inventory Item away from character
Post by: Collector on September 01, 2011, 06:35:28 PM
Would you mind adding it to the Wiki?
Title: Re: Taking an Inventory Item away from character
Post by: gumby on September 01, 2011, 08:28:28 PM
Nice!  I'm glad you got it working.
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on September 01, 2011, 08:38:16 PM
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?
Title: Re: Taking an Inventory Item away from character
Post by: Collector on September 02, 2011, 12:30:43 AM
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)
Code: [Select]
[[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

Title: Re: Taking an Inventory Item away from character
Post by: gumby on September 03, 2011, 10:50:18 AM
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.
Title: Re: Taking an Inventory Item away from character
Post by: MusicallyInspired on September 03, 2011, 01:50:19 PM
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.