CallTryPickup

From ZDoom Wiki
Jump to navigation Jump to search


Inventory

bool, Actor CallTryPickup(Actor toucher)

Usage

Called by Inventory items to enter another actor's inventory. In contrast to TryPickup, this function is not virtual and cannot be overridden. It's designed to handle all the necessary checks before the item can be picked up, such as:

and others.

If there's a need to move an item into another actor's inventory, this function should be called (such as <toucherpointer.CalltryPickup(<itempointer>)) instead of trying to call TryPickup directly.

Note: This function does not handle the printing of the item's PickupMessage or the playing of its PickupSound, it only handles the giving of the item. Messages and sounds are handled in the Touch virtual function.

Parameters

  • Actor toucher
The actor who is attempting to receive this item.

Return values

  • bool
Returns true if the item was successfully received. Note, this doesn't guarantee that the item itself keep existing. Many classes, such as Health, perform their function (such as healing the toucher) and then disappear. TryPickup still returns true in this case, because technically the item was sucecssfully received.
  • Actor
A pointer to the actor who received the item.

Examples

This version of Doom's HealthBonus will be instantly received by any player who enters the 256 radius around it:

class HealthBonus_AutoPickup : HealthBonus
{
	override void Tick()
	{
		super.Tick();
		// Do nothing if this item is frozen or has the NOSECTOR flag
		// (is in the process of being respawned):
		if (isFrozen() || bNOSECTOR)
		{
			return;
		}

		double dist = 256;
		let bti = BlockThingsIterator.Create(self, dist);
		while (bti.Next())
		{
			let act = bti.thing;
			if (act.player && act.health > 0 && Distance3D(act) <= dist)
			{
				CallTryPickup(act);
				break;
			}
		}
	}
}

As mentioned above, this item will not print its pickupmessage or play its pickupsound, those are handled in the Touch virtual.

ZScript definition

Note: The ZScript definition below is for reference and may be different in the current version of GZDoom.The most up-to-date version of this code can be found on GZDoom GitHub.
	bool, Actor CallTryPickup(Actor toucher)
	{
		let saved_toucher = toucher;
		let Invstack = Inv; // A pointer of the inventories item stack.

		// unmorphed versions of a currently morphed actor cannot pick up anything. 
		if (bUnmorphed) return false, null;

		//[AA] starting with true, so that CanReceive can unset it,
		// if necessary:
		bool res = true;
		// [AA] CanReceive lets the actor receiving the item process it first.
		if (!toucher.CanReceive(self))
		{
			res = false;
		}
		// CanPickup processes restrictions by player class.
		else if (CanPickup(toucher))
		{
			res = TryPickup(toucher);
		}
		else if (!bRestrictAbsolutely)
		{
			// let an item decide for itself how it will handle this
			res = TryPickupRestricted(toucher);
		}
		else
			return false, null;


		if (!res && (bAlwaysPickup) && !ShouldStay())
		{
			res = true;
			GoAwayAndDie();
		}

		if (res)
		{
			GiveQuestItem(toucher);

			// Transfer all inventory across that the old object had, if requested.
			if (bTransfer)
			{
				while (Invstack)
				{
					let titem = Invstack;
					Invstack = titem.Inv;
					if (titem.Owner == self)
					{
						if (!titem.CallTryPickup(toucher)) // The object no longer can exist
						{
							titem.Destroy();
						}
					}
				}
			}
			// [AA] Let the toucher do something with the item they've just received:
			toucher.HasReceived(self);

			// If the item can be shared, make sure every player gets a copy.
			if (multiplayer && !deathmatch && sv_coopsharekeys && bIsKeyItem)
				ShareItemWithPlayers(toucher);
		}
		return res, toucher;
	}

See also