Game Development Community

Items disapearing when thrown or on death

by Lucus · in Technical Issues · 12/13/2008 (3:31 pm) · 2 replies

I am working on a level involving capture the flag. When the player is killed I would like the flag to drop where he was killed but the flag disappears with the player body!

I tried %obj.unmountImage(%image.item);
The flag is not mounted anymore but it disappears


I also tried %obj.throw(%flagslot); this did not work also.



I am writing the code in player.cs / function Armor::damage


I have an idea which is unmount the flag and then create a new instance were the old flag was, but I would rather just use the same flag without it disappearing.


Does anyone have any suggestions how I can keep a item from disappearing when its thrown or on death?

Thanks much

Lucus

#1
12/13/2008 (4:33 pm)
Short Answer: You won't be able to use the same flag since the flag the player is carrying is not a real item, it's a ShapeBaseImage. What you'll need to do is create a new Item object and spawn this at the players location.

Long Answer: If you're using the "Item" class for spawning the flag into the game, with a corresponding "ItemData" datablock then onPickup you'll use the item's .image field (which is a ShapeBaseImageData datablock) to mount an "image" to the player. By the sounds of it, you already have this much functioning, if there's any doubt however, check out crossbow.cs which shows how the crossbow item can be picked up and cause the "image" to mount correctly.

Assuming the above is working, your next step is to allow the image to be unmounted and a new item spawned at the appropriate location. You need to spawn a new !Item" because Images and Items are two different things. Images can only exist as part of the player, they're a visual representation (plus a few other handy things such as states) of "things" mounted to a player. Where as "items" can exist in the world independently of any players.

Rather than just unmount the image and spawn a new Item though, you can make use of the throw function as you mentioned in your post. There's a few reasons why it may not be working for you, hopefully the following will help you resolve the problem.

Take a look in inventory.cs you'll see

function ShapeBase::throw(%this,%data,%amount)
{
   // Throw objects from inventory. The onThrow method is
   // responsible for decrementing the inventory.
   if (%this.getInventory(%data) > 0) {
      %obj = %data.onThrow(%this,%amount);
      if (%obj) {
         %this.throwObject(%obj);
         return true;
      }
   }
   return false;
}

There's two important aspects to this code. %data will be the ItemData block for the object you're wanting to throw. so if your flag ItemData was called "CTFBlueItem" then during onPickup the players inventory for "CTFBlueItem" will have been incremented by 1. Use the debugger in torsion to verify you are increase the players inventory when the flag is initially picked up. Again reference the way crossbow works to see if you've missed anything. If the players inventory does not contain at least one flag, then throw will not do anything.

The second important part is that the onThrow method is called on datablock, if you follow the code you'll see it ends up calling ItemData::onThrow which will decrease the player's inventory and create a new Item of the appropriate type for you. The important part here is that when the inventory is decreased, you'll get a onInventory call on the datablock i.e CTFBlueItem::onInventory( ... ). It's inside this method that you can check if the inventory is 0 for this particular item type and if so, unmount the item's image. Again refer to the crossbow implementation of this in weapon.cs. Note the crossbow method uses a className "weapon" rather than a datablock name, both methods are valid, you may want to read up on namespaces to understand when to use one over the other.

If you follow through the above, you should be able to allow players to throw the flag when they want and also force a throw on death.

One other pointer if you're still stuck after working through the above, use torsion to step through the onPickup code and pay particular attention to the incInventory call, step into it and see if the code reaches setInventory or not.
#2
12/13/2008 (7:39 pm)
Gary,

Thanks for pointing me in the right direction.

LOL

The problem was I had maxInv[flag] and it should have been maxInv[flag2].
flag2 = enemy flag

I created two different players datablocks for the teams and gave them different flags. I just got them mixed up so they were never making it to the inventory. I put in a couple echo()'s in the pick up function and throw function and found the problem.

thanks for you help.