This code allows Mario to summon the closest carryable sprite, horizontally, into his hands. The closest sprite will be put into his hands instantly as long as he isn't already holding something, and it will also detect kicked sprites. Could be useful for puzzle levels, or Kaizo levels involving summoning sprites in a tight order to perform specific tricks.
Summon is performed by holding X, then tapping L or R.
Please give credit if used.
Usage note: If using in your hack, it may be wise to let the player know that it only measures horizontal distance, not vertical.
Update: Added spark and smoke effects.
This code is cool and this code is janky, and a lot of it is definitely good jank, but ultimately there are just too many little things that add up to a rejection. It's close though!
• The big one is Yoshi eggs. A Yoshi egg bumped out of a ?-block or laid by a Yoshi exists in the "stunned" state until it makes contact with the ground. In this brief window, the egg can be snapped to the player's hands and carried around, and even used to bump blocks. If it touches the ground, it'll hatch into a Yoshi/mushroom/coin game cloud like normal. If this egg is carried down a pipe, it'll hatch into a shelless green Koopa. But if this egg is carried around until after another Yoshi is discovered, hatching the egg will then produce a second Yoshi, which is a notoriously glitchy affair.
• Given the way sprite states work for the springboard, this code is unable to snap a springboard to the player's hands, which users may find counterintuitive.
• When snapping certain sprites (such as Koopa shells) to the player while riding Yoshi, Yoshi will run away.
• A sprite that is currently on Yoshi's tongue, when snapped to the player, will appear in the player's hands until Yoshi's tongue fully retracts, at which point the sprite will suddenly be in Yoshi's mouth.
• If the player is behind scenery (ex. behind the climbing net), a sprite in front snapped to the player will still be in front while the player carries it from the other side of the scenery.
Acceptably janky things:
• This code allows snapping an item to the player's hands during normally carry-forbidden actions such as when climbing, spin jumping, sliding, or riding Yoshi. I'm not strictly against this, but I'd like to at least see an option to disable this behavior if possible.
• Disco shells can be snapped to the player freely, becoming safely carryable in whatever color it happened to be when summoned. They resume normal disco shell behavior when kicked. I think this is cool, honestly, and definitely not a rejection reason by itself, but I'd rather see this behavior exist as a user-settable option if possible.
• Carryable sprites that have "process when offscreen" set can be snapped to the player from all the way on the other side of the level once encountered. I don't consider this a rejection reason.
• Sprites sinking in lava that are snapped to the player will generate lava splashes at the player's location.
• If a sprite is in water and the player is not (or vice versa), the sprite snapped to the player will generate splashes at the player's position.
LDX $02 ; Retrieve slot of sprite closest to Mario.
LDA !14C8,x ; If sprite is dead,
BEQ Return ; Return. This stops the SFX from playing if there are no carryable sprites spawned.
Why does this work? It seemed okay in testing, but I'm not confident there isn't a scenario that could break things. If every sprite slot is full with a non-stunned, non-kicked-state sprite, then $02 never gets set. As $02 is also never initialized, it's no guarantee the code won't snap a non-carryable sprite. Forgive me if I've overlooked the obvious.
• Scratch RAM addresses $00 and $01 are initialized to #$FFFF as a 16-bit value. This process could be optimized from this:
• The sprite loop portion of this code doesn't use the Y register at all. You could eliminate the usage of $02 altogether by using Y, which would allow you to get rid of an extra SEP #$20 as well.
• It would be nice if the snap sound effect were configurable as a define.
That's all! A couple options and checks and it'll be good to go.
Tested with Asar 1.71, Lunar Magic 3.11, SA-1 1.32, Snes9x 1.59.2, UberASM Tool 1.4.