Spoiler: show





With the Beta 5 Update (hurrah, X2 Devs!), vanilla heart characters now work! Here's two GIFs showcasing vanilla heart compatibility vs. heartsForAll compatibility:


Load in your luna.lua with something like local lr = require("lovelyReserves"). Here's the settings if you wanna mess with those:
Spoiler: show
*playerObject.data.itemCoords - A table assigned to a player in onHUDDraw with the item's X, the item's Y, and the camera index of the player
(will be 1 for both when the camera ISN'T split). Used in lr.dropReserveVanilla to properly drop the item basegame-style
*SaveData.lovelyReserves - The bread and butter of the library. It's indexed per player ID and per character.
It contains these fields (cause it's a table) afterwards:
- canUseReserve, which determines if that player/character can use their reserve
- reserveID, which is their current reserve NPC id
- stateNPC, which is the NPC id used to reach the current powerup
*lr.SD - Shorthand for the above
*lr.enabled - Set to false to disable everything
*lr.useDefaultInitialization - Set to false if you want to initialize players/characters on your own
*lr.powerupDefaults - Table that's indexed per powerup. Each indexed powerup has it's own mapped table
with all the NPCs that correspond with it
*lr.emptyReserveItems - Mapped table with powerup NPCs that only go into the reserve if it's empty
*lr.mainReserveItems - Mapped table with powerup NPCs that typically affect...everything lol. These are your flowers, super leafs, etc
*lr.dupeReserveItems - Mapped table with powerup NPCs that will typically dupe your stateNPC into the reserve.
This is one is setup slightly different, as each dupeItem is tied to another NPC ID that your stateNPC
is set to when you collect said dupeItem (for example, the SMAS2 Mushroom is [249] = 9)
*lr.straightToReserveItems - Mapped table with item NPCs that go straight into your reserve box. These NPCs will ONLY drop down from the box
vanilla style, even if you're using modernReserveItems or the discount lovelyReserves MRI.
*lr.poweringStates - Mapped table with forcedStates that prevent onTick/onTickEnd code from running
*lr.lockedBoxStates - Mapped table with forcedStates that prevent the player from dropping their reserve
*lr.useDefaultDrawing - Set to false to stop the default box/item drawing
*lr.boxCoords - Vector that has the x and y offsets for the box drawing
*lr.boxYbombOffset - How much the box is pushed down by if your character has bombs
*lr.boxXoffset - How much the boxes are offset from each other horizontally
*lr.priority - The priority the box stuff is drawn at
*lr.linkItems - Specific powerup IDs that look different for Link
*lr.linkCharacters - Mapped table with characters that behave like Link (and should use the above)
*lr.useDefaultDrop - Set to false to disable ALL types of item-dropping in this library
*lr.useMRItypeDrop - Set to true to use what is essetially a worse version of modernReserveItems' drop lol
(just go use MRI, I only have really kept this for legacy reasons)
*lr.npcCoords - Vector that has the x and y offsets for when the reserve is spawned
*lr.npcSpeedStats - Vector that has the x and y speeds for when the reserve is spawned
*lr.npcSpawnLayer - I'm not gonna continue to support the worse MRI drop this library has, but I'll add this as a last thing
*lr.dropSound - The sound that plays when the reserve is dropped
*lr.clearAllBlocks - Mapped table with block IDs that will clear your powerup and reserve
*lr.mushroomBlocks - Mapped table with block IDs that'll give you your state NPC as your reserve under certain circumstances
*lr.setReserveBlocks - Mapped table with block IDs that'll change your reserve to whatever's in these blocks
*lr.notAheartCharacter(i, c) - Checks if the passed character (c) with the given index (i) is ANY kind of heart character
*lr.figureOutHealthChecks(i, c) - Checks which health systems should be checked for the indexed character (i and c).
Returns a table with two fields: toCheck and max. Will give you an error if you aren't a
heartsForAll character OR a vanilla heart character. Use like:
local h = lr.figureOutHealthChecks(p.idx,p.character)
if h.toCheck < h.max then...
*lr.dropReserve(p, itemID, clearReserve) - Spawns an NPC of the given itemID for the player (p) if the below checks out.
You can pass false for the clearReserve part to NOT clear the reserve if you want.
This is the offbrand modernReserveItems one that uses all the lr.npcCoords and lr.npcSpeedStats stuff lol
*lr.dropReserveVanilla(p, itemID, clearReserve) - Spawns an NPC of the given itemID for the player (p) if the below checks out.
You can pass false for the clearReserve part to NOT clear the reserve if you want.
This is the vanilla drop-item recreation one
*lr.canDropReserve(p) - Checks if the passed player (p) can drop their reserve item
*lr.callCustomEvents(p, itemID) - Calls the custom library events (as well as the dropping-item functions) using the passed player (p) and the given itemID
*lr.setBothTypedReserves(itemID, p) - Using the passed itemID, set both types of reserves (vanilla and LR ones) for the passed player (p)
*lr.getDefaultPowerupItem(powerID) - Function that returns the basic powerup ID associated with the given powerID using lr.powerupDefaults
(so, if you put 5 for powerID, this function will return 169, which is the Tanooki Suit NPC)
*lr.runDefaultReserveHandling(itemID, p, sfx) - Runs the default reserve/stateNPC handling for the passed player (p) using the itemID.
If you so choose, you can use sfx to play a sound effect, since calling this on your own most likely won't play one
*lr.isDataInitialized(i, c) - Checks if the player with an index of i and a character of c has their data setup
*lr.initializeData(i, c, canUseBoxItem, startingReserve, startingStateNPC) - Sets up data for the player with an index of i and a character of c.
Optionally, you can decided if they can use the reserve, what reserve item they start with, and what their stateNPC should be.
Will NOT run if lovelyReserves data is already setup OR if the player isn't some kind of heart-based character
*lr.onLovelyDrop(eventToken, p, itemID) - Happens right before the library's default drop. eventToken.cancelled can be set to true to prevent the item from dropping,
otherwise p is the player dropping the item, and itemID is typically used to check the player's reserve powerup.
*lr.onPostLovelyDrop(p, droppedItem) - Happens after the library's default drop AND if lr.onLovelyDrop WASN'T cancelled. p is the player dropping the item, and droppedItem is, y'know...
This is good for modifying the dropping player or the dropped item afterwards, I guess? Hopefully these work okay, I've never tried this before,
I just looked at modernReserveItems and got MDA's help to see what to do LOL
(will be 1 for both when the camera ISN'T split). Used in lr.dropReserveVanilla to properly drop the item basegame-style
*SaveData.lovelyReserves - The bread and butter of the library. It's indexed per player ID and per character.
It contains these fields (cause it's a table) afterwards:
- canUseReserve, which determines if that player/character can use their reserve
- reserveID, which is their current reserve NPC id
- stateNPC, which is the NPC id used to reach the current powerup
*lr.SD - Shorthand for the above
*lr.enabled - Set to false to disable everything
*lr.useDefaultInitialization - Set to false if you want to initialize players/characters on your own
*lr.powerupDefaults - Table that's indexed per powerup. Each indexed powerup has it's own mapped table
with all the NPCs that correspond with it
*lr.emptyReserveItems - Mapped table with powerup NPCs that only go into the reserve if it's empty
*lr.mainReserveItems - Mapped table with powerup NPCs that typically affect...everything lol. These are your flowers, super leafs, etc
*lr.dupeReserveItems - Mapped table with powerup NPCs that will typically dupe your stateNPC into the reserve.
This is one is setup slightly different, as each dupeItem is tied to another NPC ID that your stateNPC
is set to when you collect said dupeItem (for example, the SMAS2 Mushroom is [249] = 9)
*lr.straightToReserveItems - Mapped table with item NPCs that go straight into your reserve box. These NPCs will ONLY drop down from the box
vanilla style, even if you're using modernReserveItems or the discount lovelyReserves MRI.
*lr.poweringStates - Mapped table with forcedStates that prevent onTick/onTickEnd code from running
*lr.lockedBoxStates - Mapped table with forcedStates that prevent the player from dropping their reserve
*lr.useDefaultDrawing - Set to false to stop the default box/item drawing
*lr.boxCoords - Vector that has the x and y offsets for the box drawing
*lr.boxYbombOffset - How much the box is pushed down by if your character has bombs
*lr.boxXoffset - How much the boxes are offset from each other horizontally
*lr.priority - The priority the box stuff is drawn at
*lr.linkItems - Specific powerup IDs that look different for Link
*lr.linkCharacters - Mapped table with characters that behave like Link (and should use the above)
*lr.useDefaultDrop - Set to false to disable ALL types of item-dropping in this library
*lr.useMRItypeDrop - Set to true to use what is essetially a worse version of modernReserveItems' drop lol
(just go use MRI, I only have really kept this for legacy reasons)
*lr.npcCoords - Vector that has the x and y offsets for when the reserve is spawned
*lr.npcSpeedStats - Vector that has the x and y speeds for when the reserve is spawned
*lr.npcSpawnLayer - I'm not gonna continue to support the worse MRI drop this library has, but I'll add this as a last thing
*lr.dropSound - The sound that plays when the reserve is dropped
*lr.clearAllBlocks - Mapped table with block IDs that will clear your powerup and reserve
*lr.mushroomBlocks - Mapped table with block IDs that'll give you your state NPC as your reserve under certain circumstances
*lr.setReserveBlocks - Mapped table with block IDs that'll change your reserve to whatever's in these blocks
*lr.notAheartCharacter(i, c) - Checks if the passed character (c) with the given index (i) is ANY kind of heart character
*lr.figureOutHealthChecks(i, c) - Checks which health systems should be checked for the indexed character (i and c).
Returns a table with two fields: toCheck and max. Will give you an error if you aren't a
heartsForAll character OR a vanilla heart character. Use like:
local h = lr.figureOutHealthChecks(p.idx,p.character)
if h.toCheck < h.max then...
*lr.dropReserve(p, itemID, clearReserve) - Spawns an NPC of the given itemID for the player (p) if the below checks out.
You can pass false for the clearReserve part to NOT clear the reserve if you want.
This is the offbrand modernReserveItems one that uses all the lr.npcCoords and lr.npcSpeedStats stuff lol
*lr.dropReserveVanilla(p, itemID, clearReserve) - Spawns an NPC of the given itemID for the player (p) if the below checks out.
You can pass false for the clearReserve part to NOT clear the reserve if you want.
This is the vanilla drop-item recreation one
*lr.canDropReserve(p) - Checks if the passed player (p) can drop their reserve item
*lr.callCustomEvents(p, itemID) - Calls the custom library events (as well as the dropping-item functions) using the passed player (p) and the given itemID
*lr.setBothTypedReserves(itemID, p) - Using the passed itemID, set both types of reserves (vanilla and LR ones) for the passed player (p)
*lr.getDefaultPowerupItem(powerID) - Function that returns the basic powerup ID associated with the given powerID using lr.powerupDefaults
(so, if you put 5 for powerID, this function will return 169, which is the Tanooki Suit NPC)
*lr.runDefaultReserveHandling(itemID, p, sfx) - Runs the default reserve/stateNPC handling for the passed player (p) using the itemID.
If you so choose, you can use sfx to play a sound effect, since calling this on your own most likely won't play one
*lr.isDataInitialized(i, c) - Checks if the player with an index of i and a character of c has their data setup
*lr.initializeData(i, c, canUseBoxItem, startingReserve, startingStateNPC) - Sets up data for the player with an index of i and a character of c.
Optionally, you can decided if they can use the reserve, what reserve item they start with, and what their stateNPC should be.
Will NOT run if lovelyReserves data is already setup OR if the player isn't some kind of heart-based character
*lr.onLovelyDrop(eventToken, p, itemID) - Happens right before the library's default drop. eventToken.cancelled can be set to true to prevent the item from dropping,
otherwise p is the player dropping the item, and itemID is typically used to check the player's reserve powerup.
*lr.onPostLovelyDrop(p, droppedItem) - Happens after the library's default drop AND if lr.onLovelyDrop WASN'T cancelled. p is the player dropping the item, and droppedItem is, y'know...
This is good for modifying the dropping player or the dropped item afterwards, I guess? Hopefully these work okay, I've never tried this before,
I just looked at modernReserveItems and got MDA's help to see what to do LOL
viewtopic.php?t=26306
viewtopic.php?t=28409
Please credit me if you use this, and have a great day!