Triggering an effect upon item pickup
Author(s): benevolusgoatTags:
Having something happen when you finish picking up a collectible is a common yet unsupported feature in the Isaac modding API.
Introduction⚓︎
Many items have some kind of effect upon picking it up from a pedestal for the first time. These items will typically either grant health, coins, keys, or bombs directly, or spawn a pickup on the ground next to Isaac. Some of this may be achieved through variables in the items.xml
, but others require Lua code. The vanilla Isaac modding API has no support for naturally triggering an effect upon the first pickup of a collectible from an item pedestal, but this tutorial will help cover a workaround to get as close to vanilla behavior as possible.
Granting health or pickups through XML⚓︎
If you're not looking to add any complex effect to your item on first pickup, you can make your item grant health or pickups through XML. Below is an example of a passive item that grants 5 bombs. You can find a list of attributes you can add here.
1 |
|
Detecting item pickup with Lua⚓︎
Without REPENTOGON⚓︎
The main goal of this tutorial is to assist with non-REPENTOGON users, given the lack of convenient tools to work with. Thankfully, there is a variable that can be accessed on players to see what item they're holding before it's put into their inventory. This variable is called QueuedItem
, which gives access to a QueuedItemData
object. Utilizing this variable, we can know when we've picked up a specific item, and when the animation has finished so that we can trigger our desired effect.
Firstly, you'll need your item's ID:
1 2 3 |
|
Next, create the function you'll be nesting your code in and the callback to run it on. We'll be using MC_POST_PEFFECT_UPDATE
, which is an "update callback" that runs for every player. All entities have a callback that runs every time the entity is updated, which is 30 times every second. It is recommended to use this over MC_POST_PLAYER_UPDATE
for most situations, as MC_POST_PLAYER_UPDATE
runs 60 times per second.
1 2 3 4 5 6 7 8 9 |
|
Now we'll use QueuedItem
to read what item the player is holding above their head, and if they're holding any item at all. QueuedItem
has three variables: Charge
, Item
, and Touched
.
Charge
is only relevant to active items. It gives you the current charge of the active item.Item
is the ItemConfigItem object that stores every piece of information on an item you could ask for, and as such is important for identifying what item it is.QueuedItem
will always be available, butItem
can returnnil
if Isaac is not holding any items above his head. Remember that this can also have information on trinkets, not just collectibles.Touched
is the key to accomplishing the goal of this tutorial, indicating if this particular copy of the item has been picked up before or not. It will returnfalse
if not, andtrue
otherwise.
Additionally, we will make use of GetData()
. This is a function available for every entity in the game which returns a table that's unique to that entity that can be used to store arbitrary data. It's recommended to read the article on Entity Data for detailed information about its many drawbacks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Finally, we will spawn a random heart on first-time pickup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Note
This method will only cover if Isaac has an item queued to be put into his inventory, such as collecting them from pedestals, and not from any methods that involve directly adding the item into Isaac's inventory such as the debug console.
Using REPENTOGON⚓︎
REPENTOGON adds a new callback named MC_POST_ADD_COLLECTIBLE
. It will trigger whenever an item is added to Isaac's inventory through any means, with a parameter to see if it's a first-time pickup or not. This is the perfect callback for the purposes of this tutorial and simplifies our code tremendously.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|