as you'd guess from the title, this aims to make the reserve box function like it does in SM3DL/SM3DW, with some added SMBX mannerisms.
such as:
- items default to being held (barring some already defined exceptions)
- auto held when first spawned (configurable)
- if riding yoshi, any holdable items are placed in yoshis mouth. (given yoshi can eat them in the first place)
- if in a clowncar, it spawns the npc on the players car on the side the player is facing.
- can spawn a holdable item while warping, only if the warp allows items.
- near every aspect is configurable. (see documentation for more)
scenarios: show
- in in the overworld.
- if in a launch barrel.
- all forced animation states. (aside from warping/using a clearpipe) all states can be found here.
- if a warp doesn't allow items or modernReserveItems.allowHeldItemsInWarps is false.
- is climbing on a vine. (held only)
- yoshi can't usually eat the item (held only)
- if yoshi's mouth is full. (held only)
- if mounted in a boot. (held only)
- if the player's hands are full. (held only)
- if using the tanooki statue. (held only)
- if currently dead.
- if the level is considered won.
- if any of the "modernReserveItems.allowX" options are false (per-case basis)
this mainly came about as a accessibility option for DA:E, but upon thinking about the best implementation, i figured others may also like said feature.
here's a showcase video for all the action:https://streamable.com/whte3v
documentation: show
this section assumes you have some knowledge of lunalua/lua. if not, then the only thing you need is the next two lines.
to start, use this to load it after which you can be on your way if your content with the default settings.
but if you'd rather do some tinkering, here's a breakdown of a function for that:
(not every value needs to be set here)
let's go over all that:
worth noting, overwriting the default pattern without filling all fields will more then likely error. if you want to redefine how an aspect of the default table works, use something similar to this:
available patterns:
to start, use this to load it
Code: Select all
local modernReserveItems = require("modernReserveItems")
but if you'd rather do some tinkering, here's a breakdown of a function for that:
Code: Select all
modernReserveItems.setThrowSettings(npcID, {speedX=number, speedY=number, isHeld=bool, isContained=bool, isThrown=bool, containedID=number, isMega=bool, doesntMove=bool, SFX=number or sound file, yoshiSFX=number or sound file, isEgg=bool, ai={ ai1=ai1, ect.}, data={variable=value}, pattern=modernReserveItems.patterns.pattern)
let's go over all that:
- npcID - fill this with the npc ID you want to change the settings for.
- speedX/speedY - sets the speedX/Y upon it's spawn.
- isHeld - is used to determine if the item should be held upon spawning it. set to false if you intend to use one of the two other flags to determine behavior.
- isContained - (currently only used by the reserve stopwatch) is used to determine misc behavior upon spawning it. set to false if you intend to use one of the two other flags to determine behavior.
- isThrown - is used to determine if the item should be thrown upon spawning it. set to false if you intend to use one of the two other flags to determine behavior.
- containedID - (currently only used by the reserve stopwatch) sets what the item is contained in. you can read more here under "State Related". (cannot be used with isHeld while riding yoshi.)
- isMega - (no longer used;left for others to do so) changes how the positioning of the npc is done upon spawning.
- doesntMove - (only applies to isThrown items.) if the item should not move upon spawning. sets the projectile flag for this to work properly, may lead to accidental npc kills. you have been warned.
- SFX - the sound played upon the npc's spawn. does not play if modernReserveItems.playSounds is false, also doesn't play a sound for isContained items.
- yoshiSFX - the sound played upon a held npc's spawn while riding yoshi. does not play if modernReserveItems.playSounds is false.
- isEgg - spawns an egg instead of the npc. to behave properly, it needs ai1 to be set along side it. (currently only used for proper yoshi spawning. lest we forget...)
- ai - the ai values to be set upon spawning. see this page for more information.
- data - variables to set in the npc's data fields upon spawn. (not used by anything predefined, mainly added for the neatness of the feature)
- pattern - settings to borrow from if a field is nil. read on for more on that.
Code: Select all
modernReserveItems.patterns.default = {speedX=number, speedY=number, ect.})
Code: Select all
modernReserveItems.patterns.default.doesntMove = true
modernReserveItems.patterns.default.data = {string = "text", var = 2, bool = true}
- modernReserveItems.patterns.default - the fall back pattern. used to either catch any undefined npcs or fill in missing essential fields. it defaults to held npcs.
- modernReserveItems.patterns.thrown - the thrown npc pattern. does as you'd expect.
- modernReserveItems.patterns.stationaryPowerup - the pattern used by power ups that don't move. (fire flower, hammer suit, tanooki suit, ice flower.)
- modernReserveItems.patterns.stationary - throws items above the player. used to get around some of the more annoying npc limitations. (racoon leaf's odd movement, the random smb3 powerup, smb3 fire flower #gdiredigit)
- modernReserveItems.patterns.mushroom - used solely by mushrooms.
- modernReserveItems.enabled - bool;whether or not the library is allowed to run. good for making it an optional setting. true by default.
- modernReserveItems.autoHold - bool;if the library is allowed to auto hold the run button for a short time after spawning isHeld npcs. true by default.
- modernReserveItems.timeAutoHeld- number;how long AutoHold will hold npcs in enabled. 32 by default.
- modernReserveItems.playSounds - bool;if the library should play sounds upon spawning npcs. true by default.
- modernReserveItems.playerXMomentum/modernReserveItems.playerYMomentum - number;how much to times the player's speedX/speedY by before adding it to the spawned npc's speedX/speedY. i recommend decimal numbers, such as 0.5 or so. 0 by default.
- modernReserveItems.allowThrownItems - bool;a flag to disable thrown items from being spawned. good for user edge cases. true by default.
- modernReserveItems.allowHeldItems - bool;a flag to disable held items from being spawned. good for user edge cases. true by default.
- modernReserveItems.allowHeldItemsInWarps- bool;a flag to disable held items from being spawned in warps/clearpipes. good for user edge cases. true by default.
- modernReserveItems.allowContainedItems - bool;a flag to disable isContained items from being spawned. good for user edge cases. true by default.
- modernReserveItems.allowAnyItems - bool;a flag to disable all items from being spawned. good for user edge cases. true by default.
- modernReserveItems.spawnLayer - string;determines what layer the npc is given on spawn. "Spawned NPCs" by default.
- modernReserveItems.useBuiltInDrop - bool;a third flag that gets checked alongside modernReserveItems.enabled and isOverworld. good for systems where you need to use modernReserveItems.drop without changing modernReserveItems.enabled. true by default.
- modernReserveItems.offScreenDespawn - number;determines how many ticks the npc can be offscreen before being despawned. 3600 (or 60 seconds) by default.
- modernReserveItems.drop(npcID, p) - function;used to resolve and spawn a reserve item. can be used to integrate modernReserveItems's system into external ones. returns the spawned NPC reference or nil if failed. will require modernReserveItems to be loaded in the same file to use.
- npcID - npc ID (intended for player.reservePowerup)
- p - player object. - modernReserveItems.validityCheck(npcID, p) - function;can be used to allow external libraries the freedom to use modernReserveItems.drop without it failing due to builtin checks or use it to abide by them. returns false upon meeting any criteria in it, otherwise returns true. see scenarios spoiler for details. will require modernReserveItems to be loaded in the same file to use.
- npcID - npc ID (intended for player.reservePowerup)
- p - player object. - modernReserveItems.onReserveUse(eventObj, npcID, p, throwSettings) - function; used to run code upon modernReserveItems.drop being called. will require modernReserveItems to be loaded in the same file to use.
- eventObj - used as any other lua event object. doing eventObj.cancelled = true will cause modernReserveItems.drop to abort and return nil.
- npcID - the current ID being used by modernReserveItems.drop
- p - the current player object being used by modernReserveItems.drop
- throwSettings - a resolved throw settings table currently being used by modernReserveItems.drop. includes: .speedX, .speedY, .isHeld, .isContained, .isThrown, .containedID, .isMega, .doesntMove, .isEgg, .data, .ai, .SFX, .yoshiSFX.
below is example code & a gif of that in action:example: showCode: Select all
local modernReserveItems = require("modernReserveItems") modernReserveItems.onReserveUse(eventObj, ID, p , throwSettings) if ID == 153 then eventObj.cancelled = true -- makes modernReserveItems.drop abort for i=0,5 do local n = NPC.spawn(10, p.x + p.width*0.5, p.y + p.height*0.5) n.speedY = -6 - (0.2*i) n.speedX = -1.3 + (0.3*i) Defines.earthquake = 20 n.ai1 = 1 -- gives coins gravity n:mem(0x136, FIELD_BOOL, true) -- thrown/projectile flag end p.reservePowerup = 0 p:kill() end end
- modernReserveItems.onPostReserveUse(npc, p) - function;runs after modernReserveItems.drop successfully executes. npc being the npc resulting from modernReserveItems.drop and p the player object it was using. will require modernReserveItems to be loaded in the same file to use.
- modernReserveItems.resolveThrowSettings(npcID, field) - function; returns the resolved setting specified. field being a string (so it'd be used like modernReserveItems.resolveThrowSettings(ID, "isContained"), ect.) intended to be used with modernReserveItems.onReserveUse or alike functions. will require modernReserveItems to be loaded in the same file to use.
known bugs: show
N/A
changelog: show
-- v1.2 (2/18/2023) --
- fixed a mass typo of "pattren".
- made it use onInputUpdate instead of onTick. preeettty sure that won't change anything...
- adjusted items being spawned whilst riding yoshi. fixing yoshi ducking/opening their mouth for a frame.
- renamed the npc variable for modernReserveItems.drop from "spawned" to "MRINPC". was having issues with other npc variables of the same name somehow referencing it.
- added modernReserveItems.spawnLayer (string). see the documentation for more info.
- moved all validity checking to modernReserveItems.validityCheck(ID, p). see the documentation for more info.
- now checks if the player's dead or if the game is in a winning state as well. - modernReserveItems.drop(ID, p) now returns nil on an event cancel from modernReserveItems.onReserveUse (see documentation) or the npc object it spawns.
- added modernReserveItems.onReserveUse(eventObj, ID, p, throwSettings). see the documentation for more info.
- added modernReserveItems.onPostReserveUse(npc, p). npc being the npc resulting from modernReserveItems.drop and p the player object. see the documentation for more info.
- modernReserveItems.resolveThrowSettings(npcID, field) is now usable by external sources. see the documentation for more info.
- added modernReserveItems.useBuiltInDrop (bool). see the documentation for more info.
- added modernReserveItems.offScreenDespawn (number). see the documentation for more info.
- adjusted item coordinates calulations, fixing a few oddities with using reserve items on mounts.
- this causes isMega to become unused. it is now left in for users instead. - added an entire system to handle projectile npcs killing other npcs, fixing powerups dying to what ever is in their way. (lightly tested;may have missed edge case.)
- fixed up original post and added more documentation.
feel free to suggest things, bug report, or what have you. have a nice day.