Skip to content

Items - Active

Author(s): benevolusgoat
Tags:

Crash course table of contents

The crash course is still a work in progress!

  1. Creating a mod.
    1. Creating the mod.
    2. Uploading a mod.
  2. Creating a passive item.
  3. Creating an active item.
  4. Adding to item pools.
  5. Making costumes.
  6. Making a new character.
  7. Creating entities.
    1. Creating effects.
    2. Creating enemies.
    3. Creating a familiar.
    4. Creating a projectile variant.
    5. Creating a tear variant.
  8. Adding sounds.
  9. Adding music.
  10. Making pocket items.
    1. Creating custom pills.
    2. Creating custom cards.
    3. Creating custom runes.
    4. Creating custom objects.
  11. Creating challenges.
  12. Creating new curses.
  13. Structuring your mod.
  14. Conclusion.

Active items are items held in the active slot and usually require charge to be used. This tutorial will branch off of the passive items page, so be sure to read that first.

Video tutorial⚓︎

(This tutorial covers both Item Pools and Active Items) Active Items and Item Pools | Youtube Tutorial

Creating your active item⚓︎

The process of creating an active item is identical to that of a passive item, replacing the passive tag with active. However, there are a few unique attributes exclusive to active items.

1
2
3
<items gfxroot="gfx/items/" version="1">
    <active id="1" name="Big Red Button" gfx="big_red_button_item.png" description="It's a big red button" quality="4" maxcharges="6" chargetype="normal"/>
</items>
active-exclusive tag variables
Note

All tags are optional.

Variable Name Possible Values Description
maxcharges int 0 by default. When chargetype is set to timed, this attribute is used to define the cooldown of the item in game ticks. 30 = 1 second.
chargetype string normal by default. Possible values: [normal, timed, special].
passivecache bool false by default. Calls a cache evaluation when picked up similar to passive items, as typically the cache flag for active items will only trigger upon item activation.

Explaining charge types⚓︎

There are three charge types an active item can have that affect its charging behavior.

  • normal: The standard, default method of charging. Charges through room clears, battery pickups, and other conventional methods. Vanilla only uses max charges of [0, 1, 2, 3, 4, 6, 8, 12], but there is support for any number from 0 to 12.
    normal active
  • timed: Can charge all the same ways normal charge type items do. Will automatically fill its chargebar over time.
    timed active
  • special: Cannot be charged through any conventional means, and must be charged manually with Lua code.
    special active

Coding the active item⚓︎

The active item now exists, but does not do anything on its own upon activation. This will require Lua code in order to give it an effect when used. The crucial callback for active items is ModCallbacks.MC_USE_ITEM.

Inside your main.lua, get your active item's ID and create a function attached to the MC_USE_ITEM callback.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
local mod = RegisterMod("My Mod", 1)

local bigRedButton = Isaac.GetItemIdByName("Big Red Button")

function mod:RedButtonUse(item)

end

--Will call the mod:RedButtonUse function upon activating our active item.
--Our item's ID is inserted at the end of the AddCallback function, as this callback accepts an optional argument
--to specify which active item should trigger our code.
mod:AddCallback(ModCallbacks.MC_USE_ITEM, mod.RedButtonUse, bigRedButton)

For this example, this item will kill every enemy in the room upon use.

 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
local mod = RegisterMod("My Mod", 1)

local bigRedButton = Isaac.GetItemIdByName("Big Red Button")

function mod:RedButtonUse(item)
    --Gets every entity in the room, as there are no specialized methods of getting only enemies.
    local roomEntities = Isaac.GetRoomEntities()
    --Loop through the list of entities.
    for _, entity in ipairs(roomEntities) do
        --Will check if it is an enemy and is susceptible to damage.
        if entity:IsActiveEnemy() and entity:IsVulnerableEnemy() then
            --Kill it.
            entity:Kill()
        end
    end

    --Returns a table of variables that dictate the behavior of the active item once it's been used.
    return {
        Discharge = true,
        Remove = false,
        ShowAnim = true
    }
    --The Afterbirth+ method of only returning `true` will also replicate the return behavior seen above.
    --return true
end

mod:AddCallback(ModCallbacks.MC_USE_ITEM, mod.RedButtonUse, bigRedButton)

Adding charges manually⚓︎

If you have a chargetype of special, you will require the use of EntityPlayer:SetActiveCharge. If you have REPENTOGON, you can also use EntityPlayer:AddActiveCharge and set the Force argument to true.

This snippet of code will loop through the player's inventory of active items (active items can appear in multiple different slots) and increase each item's charge by 1 every 10 seconds.

 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
34
35
36
37
local mod = RegisterMod("My Mod", 1)

local game = Game()

local bigRedButton = Isaac.GetItemIdByName("Big Red Button")

local ONE_SECOND = 30
local TEN_SECONDS = ONE_SECOND * 10
--Will need to compare against the maximum amount of charges later to see if the active needs to be charged.
local MAX_CHARGE = Isaac.GetItemConfig():GetCollectible(bigRedButton).MaxCharges

function mod:ChargeActiveItem(player)
    --Only run this code if we have our active item and that the game's timer has hit an interval of ten seconds.
    if player:HasCollectible(bigRedButton) and game:GetFrameCount() % TEN_SECONDS == 0 then
        --Will loop through the primary, secondary (from Schoolbag), and pocket item slot for active items.
        for slot = ActiveSlot.SLOT_PRIMARY, ActiveSlot.SLOT_POCKET do
            local maxCharge = MAX_CHARGE
            local charge = player:GetActiveCharge(slot)
            --Important to remember that The Battery will double the maximum charge of all actives.
            if player:HasCollectible(CollectibleType.COLLECTIBLE_BATTERY) then
                maxCharge = maxCharge * 2
            end
            --Check that it's our active item and it needs to be charged.
            --There is an EntityPlayer:NeedsCharge() function, but it will always return `false` for `special` chargetype actives.
            if player:GetActiveItem(slot) == bigRedButton and player:GetActiveCharge(slot) < maxCharge then
                --Will use the REPENTOGON-exclusive method of adding charges to the item, if available. Otherwise, uses the traditional method.
                if REPENTOGON then
                    player:AddActiveCharge(1, slot, true, false, true)
                else
                    player:SetActiveCharge(charge + 1, slot)
                end
            end
        end
    end
end

mod:AddCallback(ModCallbacks.MC_POST_PEFFECT_UPDATE, mod.ChargeActiveItem)