give object to another character

Started by Alen101, Fri 04/12/2015 16:32:54

Previous topic - Next topic

Alen101

                                :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.

Snarky

Yes, you just add it to their inventory and remove it from your own.

Code: ags
// 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.

Alen101

#2
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 !

Snarky

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
  // 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.

Alen101

Thank you very much Snarky you are the best!
This works awesome!!!! Thanks!!!!::-D

AndreasBlack

#5
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

Code: ags
  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();
}

Khris

The proper use is

Code: ags
  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.

AndreasBlack

#7
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.



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

import InventoryItem*ItemGiven; 

Khris

#8
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).

AndreasBlack

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:


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) 


Khris

#10
Is cRain moving around? Because if not you can use hard-coded coordinates, like
Code: ags
    if (Verbs.MovePlayer(123, 456)) {
      player.giveInventory(iPizza, cRain);
      aPickupsound.Play();
    }

Edit: nevermind, it still fails

AndreasBlack

#11
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

Khris

#12
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

AndreasBlack

Ahh! Good to know  (nod) Thanks! I'll keep working on other stuff then! Let's hope Abstauber see's this

Nahuel

#14
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()

Code: ags
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.
Life isn't a game. Let's develop a life-like-game.

AndreasBlack

#15
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.

Code: ags
  
  
  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.

Code: ags
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();
    }
  
   

}
}

SMF spam blocked by CleanTalk