Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Carles on Tue 09/01/2024 11:23:39

Title: Give (inventory item) to (object) [SOLVED]
Post by: Carles on Tue 09/01/2024 11:23:39
Hi!

I have another question. I'm using the Tumbleweed template and I would like that when the player performs the action: "Give (inventory item) to (object)" a message will be displayed. The fact is that it only works if it is executed on a character, otherwise it does nothing.

Is there any way to do it?

Thank you!
Title: Re: Give (inventory item) to (object)
Post by: Khris on Tue 09/01/2024 15:39:05
This is handled in two places in VerbGui.asc.

line 811:

      cond =((Verbs.IsAction(eGA_TalkTo) || (Verbs.IsAction(eGA_GiveTo) && (Mouse.Mode == eModeUseinv))) && (GetLocationType(mouse.x, mouse.y) != eLocationCharacter));
Change to
      cond = Verbs.IsAction(eGA_TalkTo) && GetLocationType(mouse.x, mouse.y) != eLocationCharacter;
Next, go to the "giveto" section, it should be lines 2524 - 2549 (mind the proper closing curly brace).

Replace the block with:      // Giveto
      else if (( verbsData.AGSCursorMode == eModeUseinv)  && Verbs.IsAction(eGA_GiveTo)) {
        lblAction.TextColor = verbsData.actionLabelColorHighlighted;
        verbsData.ItemGiven=player.ActiveInventory;
        if (verbsData.location_type == eLocationCharacter) {
          if (!verbsData.approachCharInteract || Verbs.GoToCharacter(character[verbsData.location_id], 0, verbsData.NPCfacingPlayer, 2))
            if (IsInteractionAvailable(x, y, eModeUseinv)) {
              character[verbsData.location_id].RunInteraction(eModeInteract);
              Verbs.SetAction(eGA_Default);
            }
        }
        // give to object
        else {
          Room.ProcessClick(x, y, verbsData.AGSCursorMode);
          Verbs.SetAction(eGA_Default);
        }
      }

You should now be able to handle giving things to objects by simply adding the verb to the any_click handler like any other verb, i.e.

    else if (Verbs.UsedAction(eGA_GiveTo)) {
      if (Verbs.GetItemGiven() == iKeyCard) player.Say("Yes.");
      else player.Say("No.");
    }

edit: fixed code
Title: Re: Give (inventory item) to (object)
Post by: Carles on Tue 09/01/2024 18:04:29
Thanks a lot!

It has worked perfectly for me.

Just one more question. Could you tell me how to do the same with hotspots? That is, a message can be displayed when the player performs the action: "Give (inventory item) to (hotspot)".

Thank you very much again.
Title: Re: Give (inventory item) to (object)
Post by: Khris on Tue 09/01/2024 21:43:59
Great :)

This requires just a small change: you can shorten the first line of the new "giveto" block to:

      else if (( verbsData.AGSCursorMode == eModeUseinv)  && Verbs.IsAction(eGA_GiveTo)) {
(We basically skip the location type check completely.)
Title: Re: Give (inventory item) to (object)
Post by: Carles on Wed 10/01/2024 08:53:20
Thank you! It worked for me again.

But there's just one small problem.

What happens now after the player performs the action "Give (inventory item) to (anything)" is that the order does not automatically disappear. Keep pointing "Give (inventory item) to (anything)" continuously until you right click. It doesn't happen with the other actions, after executing them the order disappears without having to right click.
Title: Re: Give (inventory item) to (object)
Post by: Khris on Wed 10/01/2024 09:36:35
Find this part again, near line 2550

        // give to object
        else Room.ProcessClick(x, y, verbsData.AGSCursorMode);

Replace it with:
        // give to object
        else {
          Room.ProcessClick(x, y, verbsData.AGSCursorMode);
          Verbs.SetAction(eGA_Default);
        }

In theory one should also call verbsData.ItemGiven = null; however this would get called too early since Room.ProcessClick doesn't run immediately.

The special Give stuff is a remnant of the original Maniac Mansion Deluxe and has caused so much grief in the last 20 years  (roll)

I've been wanting to do a 9-verb GUI from scratch for years, maybe I'll get around to it at some point :-D
Title: Re: Give (inventory item) to (object)
Post by: Carles on Wed 10/01/2024 10:21:21
Surely you can get it, you know everything about this engine! (nod)  I only know how to use it superficially.

Once again what you have indicated has worked for me. But only when the GIVE action is on a hotspot or an object. If the GIVE action is on a character, the same problem still appears...

Thanks for helping me so much, these are some things I want to polish in the game.
Title: Re: Give (inventory item) to (object)
Post by: Khris on Wed 10/01/2024 10:41:12
True, here's the fixed version:

      // Giveto
      else if (( verbsData.AGSCursorMode == eModeUseinv)  && Verbs.IsAction(eGA_GiveTo)) {
        lblAction.TextColor = verbsData.actionLabelColorHighlighted;
        verbsData.ItemGiven=player.ActiveInventory;
        if (verbsData.location_type == eLocationCharacter) {
          if (!verbsData.approachCharInteract || Verbs.GoToCharacter(character[verbsData.location_id], 0, verbsData.NPCfacingPlayer, 2))
            if (IsInteractionAvailable(x, y, eModeUseinv)) {
              character[verbsData.location_id].RunInteraction(eModeInteract);
              Verbs.SetAction(eGA_Default); // reset action
            }
        }
        // give to object
        else {
          Room.ProcessClick(x, y, verbsData.AGSCursorMode);
          Verbs.SetAction(eGA_Default); // reset action
        }
      }
Title: Re: Give (inventory item) to (object)
Post by: Carles on Wed 10/01/2024 11:13:57
Brilliant! Thank you very much Khris. It works perfectly.

I consider the issue solved.