Built off of Coldcolor's
inventory.lua, this library adds a highly customizable inventory to your game! It requires
modernReserveItems.lua by KBM-Quine, which is included in the download below!
Gameplay Features:
The inventory is pretty simple- collected powerups are added to it instead of going to your reserve itembox! You can press the "drop item" key to open the inventory and select a powerup, which will spawn it directly in front of you! Any powerup from
customPowerups.lua will be detected by this library and have an additional slot created for it! As far as I've tested, all custom powerups should work, though a few (like the Penguin Suit and Frog Suit) might act a bit funky when released from the inventory.
As far as I'm aware, this library should work perfectly fine with any player character (including X2 playables like Megaman or Rosalina), though I haven't tested any characters besides Mario and Luigi (and most custom powerups only support Mario and Luigi, and occasionally Peach, Toad, and/or Link anyhow). Please let me know if you run into any issues with this library!
This library also comes with a small handful of its own cheats:
"emptypockets" - Clears the player's inventory
"stockpile" - Adds one copy of every loaded powerup to the player's inventory
"imgreedy"/"fullpockets" - Maxes out the storage space of every loaded powerup in the player's inventory
"creativemode" - Gives the player an infinite supply of every item for as long as they have the cheat enabled. When the cheat is disabled, the player's inventory is returned to its state before creativemode was activated
Here are a few screenshots (and one gif) showing off the inventory! Note that although I downloaded customPowerups.lua for these showcases, it is not included in the download below, nor are any of the custom powerups you see here! (everything on the green sizeable) You'll have to download those yourself. The test level itself is also not included, though a sample luna.lua file is!
Showcase Screenshots: show
Finally, here's the download link for the library!
How to Use:
- Download the files from the link above (which includes the library itself and the required assets, modernReserveItems.lua, and an example luna.lua file)
- Copy "simpleInventory.lua", "modernReserveItems.lua", and the "inventory" folder into your episode's folder (SMBX2/data/worlds/Your Episode Name)
- Add the following code to a luna.lua file in your episode:
Code: Select all
local inventory = require("simpleInventory")
- You should be good to go! If you want to tweak some of the settings in the library, you'll want to add a bit more code to your luna.lua file. You can find several examples in the example luna.lua file in the download above, but here's some basic examples too:
Customization Example: show Code: Select all
local inventory = require("simpleInventory")
-- This will make it so that the inventory doesn't close when the player selects a powerup
inventory.settings.closeOnSpawn = false
-- This will increase the maximum amount of Super Mushrooms that can be held at once from 99 to 999
inventory.settings.maxStorage["mushroom"] = 999
-- This will allow the player to pocket any Starman they touch instead of becoming invulnerable immediately,
-- but they can only store one at a time
inventory.settings.starmanSlot = true
inventory.settings.collectableStarmans = true
inventory.settings.maxStorage["starman"] = 1
Changelogs
v1.0 - Initial public release! Since there aren't any changes to list from prior versions of this library, I'll instead go over what I've changed from Coldcolor's inventory.lua:
- Reworked how the inventory detects when an item enters the reserve itembox, so that anything that adds an item to the reserve itembox automatically sends it to the inventory! (This includes vanilla cheats like "needaflower", lakitu shops configured to put items in the reserve itembox, and of course, powerups that are stored there because you collected another one)
- Made the library use modernReserveItems.lua to spawn powerups, rather than having the player's state automatically change
- Increased the default maximum supply of all powerups from 5-10 to 99
- Tweaked how the quantity text is drawn, so that it can support numbers up to three digits, instead of only one or two
- Changed how each slot is drawn- the panel is now a separate image, and powerup icons are loaded dynamically from their NPC textures. This means any powerup graphics replacements will be automatically applied to the inventory HUD!
- Added support to automatically load powerups from customPowerups.lua! (Also added special behavior for the Cloud Flower to make it not add to the inventory if it should be consumed)
- Added tons of settings, some of which include toggling features that were present in the original library (such as the feature that stopped the player from spawning powerups for the state they were in) and others are entirely new options (such as repositioning the HUD, replacing the HUD textures and sounds, adding a Starman and/or Mega Mushroom slot, and more!). See the "settings" spoiler below for a full list
- Due to the fact that the inventory can have a dynamic number of powerup slots, it is now paginated; you can use the up/down arrows to cycle through the pages if more than a configurable number of powerups are loaded!
- Added several functions and events for other coders to use, ranging from adding/setting item quantities to detecting when the inventory is opened or closed! See the sections on those for more details
- Added four cheats- "emptypockets" (clears the inventory), "stockpile" (adds one item to every slot), "imgreedy"/"fullpockets" (maxes out every slot), and "creativemode" (gives infinite items)
- Added custom drawing behavior for Yoshis; so long as their modernReserveItems configs are set up properly, any slot containing a Yoshi will display them in their colored egg! In fact, any NPC with a specified "idOverwrite" in modernReserveItems will display the container NPC instead of the actual NPC
Functions, Events, Settings, and SaveData:
For anyone looking to make more advanced use of this library, a large amount of settings and a few custom functions and events have been added! Starting with the events, they're accessed the same way as any other event, like so:
Code: Select all
-- Triggers when the inventory is opened, and allows you to cancel opening the inventory with eventObj.cancelled = true
function onInventoryOpen(eventObj)
-- Your code goes here
--eventObj.cancelled = true -- This would prevent the inventory from opening
end
-- Triggers when the inventory is closed, and allows you to cancel closing the inventory with eventObj.cancelled = true
function onInventoryClose(eventObj)
-- Your code goes here
--eventObj.cancelled = true -- This would prevent the inventory from closing
end
-- Triggers immediately after the inventory has opened, only if it successfully opened (so if you set eventObj.cancelled = true in onInventoryOpen, this would not run)
function onPostInventoryOpen()
-- Your code goes here
end
-- Triggers immediately after the inventory has closed, only if it successfully closed (so if you set eventObj.cancelled = true in onInventoryClose, this would not run)
function onPostInventoryClose()
-- Your code goes here
end
-- Triggers when an item is slated to be added to the inventory, passing in a token to cancel the addition ("eventObj"), the name of the powerup added ("slot"), and the number of items added ("quantity")
-- Note that this is called by both inventory.addItem() and inventory.setItemCount()! In both cases, the net change in item quantity is passed in to the "quantity" argument, and there's no distinction between the two
function onInventoryItemAdded(eventObj, slot, quantity)
-- Your code goes here
end
-- Triggers immediately after any item is added to the inventory, only if it was successfully added (same logic as onPostInventoryOpen/Close)
-- Passes in the name of the powerup added ("slot") and the number of items added ("quantity")
-- Note that this is called by both inventory.addItem() and inventory.setItemCount()! In both cases, the net change in item quantity is passed in to the "quantity" argument, and there's no distinction between the two
function onPostInventoryItemAdded(slot, quantity)
-- Your code goes here
end
-- Triggers any time inventory slots are being generated (namely in onStart() and whenever inventory.regenerateSaveData() is called)
-- The purpose of this event is for other libraries to generate their slots here to ensure consistency with what order things generate in
-- If you generate your slots here, they will always be placed after the Starman and Mega Mushroom slots (if those are enabled) but before any customPowerups slots
-- Note that this consistency is not guaranteed if customPowerups slots already exist before you generate your slots
function onInventorySlotsGenerate()
-- Your code goes here
end
As for functions, there's quite a few of those as well! They're documented in great detail in the code itself (including support for the
Visual Studio lua addon), but I'll list all of them here too:
Code: Select all
-- Returns the name of a powerup slot given an alias
-- For example, "Super Mushroom", "SuperShroom", "shroom", etc. would all return "mushroom"
-- This method is automatically called by most functions that call for a slot name (such as addItem and getSlot)
-- This method also automatically removes capitalization, spaces, hyphens, and underscores from input aliases, so it's quite flexible with what is a valid alias!
-- (i.e, you don't have to specifically add "Super Mushroom" as an alias, it'll automatically work as an alias if "supermushroom" is an alias, which it is by default)
inventory.getAlias(name)
-- Given a name (or existing alias) and either a new alias or a list of new aliases, adds them to the internal alias map, allowing them to be returned by getAlias()
-- This is mostly useful for custom powerups, since by default they don't have any aliases (aside from accounting for capitalization/spaces/etc.)
-- Example: inventory.addAlias("Bee Mushroom", { "bee", "beeShroom" })
-- Assuming you kept the default internal name of the Bee Mushroom custom powerup, this would create two new valid aliases, so you could call inventory.getSlot("bee") instead of having to type out "beemushroom" or "Bee Mushroom" every time
inventory.addAlias(name, newAlias)
-- Given the name (or alias) of a slot, returns its numerical index
-- This is needed to access the inventory list in SaveData (SaveData.inventory[inventory.getSlot("Super Mushroom")] for example)
inventory.getSlot(name)
-- Creates a new slot and returns its index (or, if a slot with this name already exists, returns that slot's numerical index)
-- Newly-created slots are always appended at the end of the list in SaveData
-- Unlike the other functions, this one uses named args (similar to, say, textplus.print). The valid arguments for this method are as follows:
-- "name": The name of the new slot (required)
-- "defaultPowerup": The NPC ID to use as the slot's icon, and to spawn when the player takes an item from this slot (required)
-- "givenState": The powerup state the player enters upon consuming a powerup associated with this slot
-- "minStorage", "maxStorage", and "quantity": Numbers defining the corresponding values for this slot
-- "aliases": A table of strings defining the aliases for this slot
-- "linkedPowerups": A table of NPC IDs defining the non-default powerups linked to this slot
-- "overwriteMRI": A boolean specifying whether or not to replace modernReserveItem's default configs for the provided NPC ID
-- "mriSettings": A table containing config data for modernReserveItems (see that library's post for more details). Only used if "overwriteMRI" is also true, and if not specified while "overwriteMRI" is true, a default set of configs will be applied that ensures consistent behavior for all spawned powerups
inventory.newSlot(args)
-- Removes the specified slot from SaveData.inventory
-- As with most methods, you can input an alias and it will be automatically accounted for
inventory.removeSlot(name)
-- Basically nukes the entire SaveData.inventory table and recreates it from scratch
-- I don't see this being too useful, but maybe it could be useful if you remove a bunch of custom powerups and don't want to manually remove each slot? Or maybe if you enable the Starman/Mega Mushroom slots late and don't like them being at the end of the list?
-- Do keep in mind, however, that inventory data obviously does not transfer across saves! So anyone who plays your episode should see the inventory generate with the "proper" order, assuming they're booting up your episode for the first time
inventory.regenerateSaveData()
-- Adds items to a slot in the inventory. "num" is a number specifying the amount. If not specified, num is automatically inferred as 1 (so you can just do inventory.addItem("mushroom") to add one Super Mushroom to the inventory)
-- "slot" can either be a string for the type of item you want to add (aliases are supported), or an index number for the slot (obtained from inventory.getSlot())
inventory.addItem(slot, num)
-- Sets the amount of items in a given slot to the specified number. "slot" and "num" are the same as in addItem, except that "num" is required here.
-- The difference between addItem and setItemCount can be visualized like so:
-- inventory.addItem("mushroom", 10): 5 -> 15
-- inventory.setItemCount("mushroom", 10): 5 -> 10
inventory.setItemCount(slot, num)
-- Clears every slot in the player's inventory, setting their quantities to the minimum value. Same functionality as the "emptypockets" cheat
inventory.clear()
-- Opens and closes the inventory respectively!
inventory.open()
inventory.close()
In addition to events and methods, simpleInventory.lua has a whole host of settings you can mess with! Here's those if you want to take a look:
Code: Select all
-- If true, prevents the player from selecting powerups if they are already in the corresponding state. Defaults to false
inventory.settings.disableRepeatSpawning = false
-- If true, closes the inventory automatically when the player selects a powerup to spawn. Defaults to true
inventory.settings.closeOnSpawn = true
-- Controls the number of powerup slots displayed on a single page. I don't recommend going over 12, because the 13th slot onwards will render offscreen while the inventory is opened. It still functions fine, but you won't be able to see what you have selected
-- Defaults to 10
inventory.settings.powerupsPerPage = 10
-- If true, shows 2 x powerupsPerPage inventory slots while the inventory is closed. Defaults to true
inventory.settings.showTwoPagesWhenClosed = true
-- If true, displays the quantities of items while the inventory is closed. Defaults to true
inventory.settings.showCountsWhenClosed = true
-- Controls the position at which the inventory HUD is displayed. vector(0, 0) is the top-left corner of the screen. Defaults to vector(20, 536)
-- The height of the HUD controls whether it expands up, down, or centered when opened
inventory.settings.hudPosition = vector(20, 536)
-- If true, adds an inventory slot for the Starman or Mega Mushroom, respectively. If collectableStarmans/collectableMegas is false, you will need to do some lua coding to add either item to the player's inventory yourself (such as setting up a Lakitu Shop to send items to the player's reserve itembox). Both default to false
inventory.settings.starmanSlot = false
inventory.settings.megaSlot = false
-- If true (and starmanSlot/megaSlot is true), collecting a Starman or Mega Mushroom respectively through any means adds it to your inventory instead of providing their default effects. Probably not a good idea to enable this unless you account for players being able to use these items at any time in any level. Defaults to false
inventory.settings.collectableStarmans = false
inventory.settings.collectableMegas = false
-- If false, entering any of the cheats from this library will not do anything. "emptypockets" is not considered a cheat, and is not affected by this config option. Defaults to true
inventory.settings.enableCheats = true
-- Controls which image files are loaded for the background panels and selector. Powerup images are loaded automatically, and are not included here. Defaults to the following files:
inventory.settings.images.panel = Graphics.loadImage(Misc.resolveFile("inventory/panel.png"))
inventory.settings.images.selector = Graphics.loadImage(Misc.resolveFile("inventory/selector.png"))
-- Controls which audio files are loaded for the five custom sound effects. If you want to use a vanilla sound, you can set these variables to the sound ID of whatever sound you want (see SMBX2/data/_templates/sounds.ini for a list of all the sound IDs) Defaults to the following files:
inventory.settings.sounds.errorSFX = Misc.resolveFile("inventory/error.wav")
--inventory.settings.sounds.errorSFX = 9 -- Vanilla sound ID example, this one points to the "Shell Kick" sound
inventory.settings.sounds.closeSFX = Misc.resolveFile("inventory/invclose.wav")
inventory.settings.sounds.openSFX = Misc.resolveFile("inventory/invopen.wav")
inventory.settings.sounds.menuSFX = Misc.resolveFile("inventory/menuselect.wav")
inventory.settings.sounds.selectSFX = Misc.resolveFile("inventory/powerupselect.wav")
Finally, I may as well explain how the inventory data is stored in SaveData, since it's accessible to any lua file:
Code: Select all
-- Each powerup type has its own numerical index, which you can access with inventory.getSlot() like so:
local idx = inventory.getSlot("Super Mushroom")
-- This will allow you to access SaveData.inventory like so:
SaveData.inventory[idx] --[[ Returns a table that looks like this: {
name="mushroom",
defaultPowerup=9, -- SMB3 Super Mushroom
givenState=PLAYER_BIG, -- Will be nil for Starman, Mega Mushroom, and custom powerups
minStorage=0,
maxStorage=99,
quantity=0
}]]--
-- If you want to set the min/max storage of an item, you can do so like this:
SaveData.inventory[idx].minStorage = 10
SaveData.inventory[idx].maxStorage = 999 -- Note: Numbers above 999 are allowed, but may look funny in the HUD
-- Another useful table you have access to is inventory.itemMap, which lets you take any NPC ID and figure out what slot it corresponds to!
inventory.itemMap[183] -- npc-183 is the SMW Fire Flower, so this would return "fire"