Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Alen101 on Fri 04/12/2015 16:32:54

Title: give object to another character
Post by: Alen101 on Fri 04/12/2015 16:32:54
                                :confused:???
is there some easy way to make a player give an item to another player?
my game is maniac mansion style, im trying to make the same, as the characters in that game can pass items from one to another.
Title: Re: give object to another character
Post by: Snarky on Fri 04/12/2015 17:49:33
Yes, you just add it to their inventory and remove it from your own.

Code (ags) Select
// Helper function
void giveInventory(this Character*, InventoryItem* item, Character* recipient)
{
  if(this.HasInventory(item))
  {
    this.LoseInventory(item);
    recipient.AddInventory(item);
  }
}

// And you call it like:
  player.giveInventory(iDentures, cBernard);


Instead of writing a hundred functions, one for each inventory item, you probably want to use player.ActiveInventory, though.
Title: Re: give object to another character
Post by: Alen101 on Thu 17/12/2015 01:54:44
Thank you very much Snarky, this works fine,

Yes i really want and need desperately to do this:

"Instead of writing a hundred functions, one for each inventory item, you probably want to use player.ActiveInventory, though."

But i dont know how !
Title: Re: give object to another character
Post by: Snarky on Thu 17/12/2015 03:38:14
The sample I gave you works when you're handing over a specific inventory item. But in MM/DOTT you can hand over pretty much any item in your inventory, and you don't want to have to write separate lines of code that all do the same thing only with different items:

Code (ags) Select
  // THIS IS SO BAD!
  player.giveInventory(iDentures, cBernard);
  // ...
  player.giveInventory(iZombieWig, cBernard);
  // ...
  player.giveInventory(iGuanaGum, cBernard);
  // ...
  player.giveInventory(iStolenEnvelope, cBernard);
  // ...
  player.giveInventory(iNuclearRod, cBernard);
  // ...


player.ActiveInventory is whatever inventory item is currently active. So you can select an item from your inventory, and then just call player.giveInventory(player.ActiveInventory, cBernard). Probably this goes in the "use inventory item on" handler for the character.
Title: Re: give object to another character
Post by: Alen101 on Thu 17/12/2015 03:45:25
Thank you very much Snarky you are the best!
This works awesome!!!! Thanks!!!!::-D
Title: Re: give object to another character
Post by: AndreasBlack on Fri 07/10/2022 19:59:13
Instead of starting a new thread. I'm using Thumbleweed template 1.4 and giving an item with a character with these instructions only seems to work the second time. This is the code that do not work at first click. Oh, and maybe i should add. Not all items should be able to be given away, so that's why i use the "giveInventory(iPizza) one

  if (Verbs.UsedAction(eGA_GiveTo) && player.ActiveInventory==iPizza)

{
  Verbs.GoToCharacter(cRain, eDirectionNone, true, eBlock);  //he walks up to the character then nothing happens..Click the Verb "Give Pizza to",
                                                   //and he gives it the second time. since the gotocharacter is e-blocked i would imagine that it would work in theory.
player.giveInventory(iPizza, cRain);
aPickupsound.Play();
}
Title: Re: give object to another character
Post by: Khris on Fri 07/10/2022 21:47:21
The proper use is

  if (Verbs.UsedAction(eGA_GiveTo) && player.ActiveInventory==iPizza)
  {
    if (Verbs.GoToCharacter(cRain, eDirectionNone, true, eBlock))
    {
      player.giveInventory(iPizza, cRain);
      aPickupsound.Play();
    }
  }

Although I'm not really sure why your version fails the way it fails tbh.
Title: Re: give object to another character
Post by: AndreasBlack on Fri 07/10/2022 23:06:06
It didn't work either! 8-0 Just to make sure. Selecting > Character > cRain > anyclick elipse button, perhaps it's wrong place to put the code in? But looking in the manual it seems about right?! and then i have this code on the top of the globalscript.  Tried with    player.LoseInventory(iPizza); & cRain.AddInventory(iPizza); same issue. Characters walk up, then nothing.

Edit: If i choose UseInv instead of anyclick elipse button it seems to work better, but i'm not sure that's the right way to do it. By better i mean, he gives the item, but instead doesn't walk up.



void giveInventory(this Character*, InventoryItem* item, Character* recipient)
{
  if(this.HasInventory(item))
  {
    this.LoseInventory(item);
    recipient.AddInventory(item);
  }
}

import InventoryItem*ItemGiven;
Title: Re: give object to another character
Post by: Khris on Sat 08/10/2022 00:26:59
You're right; I tried several variations and nothing worked. I'll debug this, maybe we're just missing something.

Edit: I'm reasonably sure I figured out the problem: first of all, the blocking parameter is supposed to be a number, not the enum AGS uses. You need to pass 1 for a blocking walk, 2 for a semi-blocking (cancelable) walk instead of eBlock (which has a value of 919).
Next you need to make sure there's enough walkable area surrounding the cRain character; GoToCharacter calculates approach coordinates, and if these are outside a reachable walkable area, the character won't arrive at the target coordinates and the GoToCharacter function considers the approach as failed (this is most likely why my code didn't work).
Title: Re: give object to another character
Post by: AndreasBlack on Sat 08/10/2022 08:08:27
Quote from: Khris on Sat 08/10/2022 00:26:59You're right; I tried several variations and nothing worked. I'll debug this, maybe we're just missing something.

Edit: I'm reasonably sure I figured out the problem: first of all, the blocking parameter is supposed to be a number, not the enum AGS uses. You need to pass 1 for a blocking walk, 2 for a semi-blocking (cancelable) walk instead of eBlock (which has a value of 919).
Next you need to make sure there's enough walkable area surrounding the cRain character; GoToCharacter calculates approach coordinates, and if these are outside a reachable walkable area, the character won't arrive at the target coordinates and the GoToCharacter function considers the approach as failed (this is most likely why my code didn't work).

Interesting. I did add your suggestions increasing the walkingarea, block number. It is a pretty thin walking area actually. Look here: (https://i.imgur.com/JjXqJYY.png)


do you think it matters for the walkingarea that the pixels under the character are wider? Cause if so i have to make the street they walk on a bit wider, perhaps raise the whole BG Room image upwards, but that sucks, cause then i have to re-do everything in the room, i believe.........Since deleting parts of the image doesn't feel like an option, and i have to increase the height of the BG art. I did increase the walkarea above the characters tho. I also tried erasing the blocking height/width syntax for characters, since well obviously they don't walk into each other 100%, but it had no effect either.

Thanks for your help as always! This is not in anyway an emergency, the game is in no means near completion, but it's getting better and better. Better move onto other things then! Please update if you find out a workaround for thinner walkareas, since probably what's causing it. I mean i guess it's possible with teleporting items, worst case scenarium. (laugh) 

Title: Re: give object to another character
Post by: Khris on Sat 08/10/2022 08:11:04
Is cRain moving around? Because if not you can use hard-coded coordinates, like
    if (Verbs.MovePlayer(123, 456)) {
      player.giveInventory(iPizza, cRain);
      aPickupsound.Play();
    }

Edit: nevermind, it still fails
Title: Re: give object to another character
Post by: AndreasBlack on Sat 08/10/2022 08:13:46
Yes unfortunaly, playable Characters. Think the template name "Tumbleweed". I should try in another room just to confirm that this is actually the issue, i'll edit this post.

Edit: It doesn't work in a larger walkable room areas either, Please don't say i messed up some important script, but i didn't touch much stuff all i did was add some int or bool for the running mechanism and also i imported the scripts from 1.4 into my project, i hope that didn't break anything.

@abstauber
Title: Re: give object to another character
Post by: Khris on Sat 08/10/2022 08:33:23
Don't worry, something is wrong here that's not your fault at all. Create a new Tumbleweed game and try to give something to cHologram. It sometimes reproduces the issue, depending on the player's position in relation to the hologram. Which means there's definitely a bug on of the template's movement functions.

Edit: as far as I can tell this is all about the calculated target coordinates and whether the player reaches them. I'm also not sure why the player approaches the other character with some verbs and not with others but I haven't had my first coffee yet and the idea of debugging this makes my head spin :P
Title: Re: give object to another character
Post by: AndreasBlack on Sat 08/10/2022 08:36:56
Ahh! Good to know  (nod) Thanks! I'll keep working on other stuff then! Let's hope Abstauber see's this
Title: Re: give object to another character
Post by: Nahuel on Wed 12/10/2022 20:18:10
Hi there @AndreasBlack I was facing the same issue with the item giving. Researching I found that there's a function that is not documented with the new changes, and it's not working with the doc example. I found researching the code that the function is Verbs.GetItemGiven()

Because I like the action eGA_GiveTo as much as eGA_UseInv I use either one or the other, but it's only my preference.
The idea is that you need to use the comparison agains Verbs.GetItemGiven()

if ( ( UsedAction(eGA_GiveTo) || UsedAction(eGA_UseInv) ) )
{
  if ( Verbs.GetItemGiven() == iLetter || player.ActiveInventory == iLetter )
  {
    // bla
   }
}

eGA_GiveTo  will work with Verbs.GetItemGiven()

But

eGA_UseInv of course with player.ActiveInventory

Hope that helps.
Title: Re: give object to another character
Post by: AndreasBlack on Thu 13/10/2022 06:44:41
Edit: Wohoo! It works now! Well, almost. Your code got me thinking a bit about a previous code example @Khris gave me in another topic, and this works now!
It can probably be cleaned up, but this is what it is atm. Edit 2: Actually sometimes it bugs a little, but it's way better then before!  Because the character walks closely most of the time and gives the item no matter what everytime, instead of having to click twice. Edit 3: Arrgghh, Tried "walkstraight" thought that would solve it, it didn't. Well they line up their x's now at least.

 
 
  if (Verbs.UsedAction(eGA_UseInv) && cTucker.ActiveInventory==iPizza)
 
  {

  if (Verbs.GetItemGiven() == iPizza || player.ActiveInventory == iPizza)
  {
   
   
    cTucker.Walk(cRain.x, cTucker.x, eBlock);
    player.giveInventory(iPizza, cRain);

   

 
}
  }


Your code doesn't work unfortunately for me. Or rewrite it, maybe i misunderstood it.


I am guessing this is what you've meant to write, but it's the same, it doesn't work. Sometimes he gives items, but most times not, you have to click twice.

function cTucker_AnyClick()  //GIVE ITEMS TO TUCKER
{
 
if (Verbs.UsedAction(eGA_GiveTo) || (Verbs.UsedAction(eGA_UseInv)))
{

  if (Verbs.GetItemGiven() == iPizza || player.ActiveInventory == iPizza)
{
    player.giveInventory(iPizza, cTucker); //or     player.LoseInventory(iPizza); & cTucker.AddInventory(iPizza); same results, unfortunaly

   
}
 
}

  //This could also have been what you've meant, but it's the same, sometimes it doesn't give the item.

  if (Verbs.UsedAction(eGA_GiveTo) && Verbs.GetItemGiven() == iPizza)
 
  {
   player.LoseInventory(iPizza);
   cTucker.AddInventory(iPizza);
      aPickupsound.Play();
    }
 
   

}
}