- Created detailed documentation for the Minecart sprite, outlining its properties, constants, collision setup, main logic, and design patterns. - Added documentation for the Pedestal sprite, including its vanilla overrides, custom logic for item interaction, and event triggering based on area context. - Introduced documentation for the Portal sprite, detailing its two-way warping system, initialization, main logic, and helper routines for seamless transitions. - Documented the Switch Track sprite, explaining its interactive behavior, state-based animation, and integration with external switches for dynamic track manipulation.
148 lines
5.4 KiB
Markdown
148 lines
5.4 KiB
Markdown
# Deku Leaf / Whirlpool
|
|
|
|
## Overview
|
|
The `deku_leaf.asm` file defines a versatile sprite (`!SPRID = Sprite_DekuLeaf`) that can function as two distinct in-game objects: the "Deku Leaf" and a "Whirlpool." Its specific behavior and visual representation are dynamically determined by the current `AreaIndex`, allowing it to serve different purposes in various locations.
|
|
|
|
## Sprite Properties
|
|
* **`!SPRID`**: `Sprite_DekuLeaf` (Custom symbol, likely a remapped vanilla ID)
|
|
* **`!NbrTiles`**: `00` (Graphics are handled externally or as a background)
|
|
* **`!Harmless`**: `01`
|
|
* **`!HVelocity`**: `00`
|
|
* **`!Health`**: `00`
|
|
* **`!Damage`**: `00`
|
|
* **`!DeathAnimation`**: `00`
|
|
* **`!ImperviousAll`**: `00`
|
|
* **`!SmallShadow`**: `00`
|
|
* **`!Shadow`**: `00`
|
|
* **`!Palette`**: `00`
|
|
* **`!Hitbox`**: `$0D`
|
|
* **`!Persist`**: `01` (Continues to live off-screen)
|
|
* **`!Statis`**: `00`
|
|
* **`!CollisionLayer`**: `00`
|
|
* **`!CanFall`**: `00`
|
|
* **`!DeflectArrow`**: `00`
|
|
* **`!WaterSprite`**: `00`
|
|
* **`!Blockable`**: `00`
|
|
* **`!Prize`**: `00`
|
|
* **`!Sound`**: `00`
|
|
* **`!Interaction`**: `00`
|
|
* **`!Statue`**: `00`
|
|
* **`!DeflectProjectiles`**: `00`
|
|
* **`!ImperviousArrow`**: `00`
|
|
* **`!ImpervSwordHammer`**: `00`
|
|
* **`!Boss`**: `00`
|
|
|
|
## Main Structure (`Sprite_DekuLeaf_Long`)
|
|
This routine acts as a dispatcher for drawing, selecting `Sprite_Whirlpool_Draw` if `AreaIndex` is `$3D` (Whirlpool area), and `Sprite_DekuLeaf_Draw` otherwise. It also dispatches to the main logic if the sprite is active.
|
|
|
|
```asm
|
|
Sprite_DekuLeaf_Long:
|
|
{
|
|
PHB : PHK : PLB
|
|
LDA $8A : CMP.b #$3D : BEQ .whirlpool
|
|
JSR Sprite_DekuLeaf_Draw
|
|
JMP +
|
|
.whirlpool
|
|
JSR Sprite_Whirlpool_Draw
|
|
+
|
|
JSL Sprite_CheckActive : BCC .SpriteIsNotActive
|
|
JSR Sprite_DekuLeaf_Main
|
|
.SpriteIsNotActive
|
|
PLB
|
|
RTL
|
|
}
|
|
```
|
|
|
|
## Initialization (`Sprite_DekuLeaf_Prep`)
|
|
This routine initializes the sprite upon spawning. If `AreaIndex` is `$3D` (Whirlpool area), it sets `SprAction, X` to `$01` (`Whirlpool_Main`), indicating its role as a whirlpool.
|
|
|
|
```asm
|
|
Sprite_DekuLeaf_Prep:
|
|
{
|
|
PHB : PHK : PLB
|
|
LDA $8A : CMP.b #$3D : BNE .not_whirlpool
|
|
LDA.b #$01 : STA.w SprAction, X
|
|
.not_whirlpool
|
|
PLB
|
|
RTL
|
|
}
|
|
```
|
|
|
|
## Main Logic & State Machine (`Sprite_DekuLeaf_Main`)
|
|
This routine manages the behavior of both the Deku Leaf and the Whirlpool through a jump table based on `SprAction, X`:
|
|
|
|
* **`WaitForPlayer` (Deku Leaf)**: Plays an idle animation. It checks if Link is on the leaf (`JSR CheckIfPlayerIsOn`). If so, it sets a flag (`$71`) and, if Link is in Minish form, spawns a poof garnish. Otherwise, it clears the flag.
|
|
* **`Whirlpool_Main`**: Plays an animation. If Link is on the whirlpool and the underwater flag (`$0AAB`) is set, it resets various Link state flags (`$55`, `$0AAB`, `$0351`, `$037B`, `$02B2`). If Link's state is not `$0B` (Mirror), it saves Link's coordinates and sets `GameMode` to `$23` to initiate a warp, similar to the Mirror effect.
|
|
|
|
```asm
|
|
Sprite_DekuLeaf_Main:
|
|
{
|
|
LDA.w SprAction, X
|
|
JSL JumpTableLocal
|
|
|
|
dw WaitForPlayer
|
|
dw Whirlpool_Main
|
|
|
|
WaitForPlayer:
|
|
{
|
|
%StartOnFrame(0)
|
|
%PlayAnimation(0, 0, 10)
|
|
|
|
JSR CheckIfPlayerIsOn : BCC +
|
|
LDA.b #$01 : STA.b $71
|
|
LDA.w $02B2 : CMP.b #$01 : BNE ++
|
|
JSL Sprite_SpawnPoofGarnish
|
|
++
|
|
RTS
|
|
+
|
|
STZ.b $71
|
|
RTS
|
|
}
|
|
|
|
Whirlpool_Main:
|
|
{
|
|
%PlayAnimation(0, 2, 10)
|
|
JSR CheckIfPlayerIsOn : BCC .not_on
|
|
|
|
LDA $0AAB : BEQ .not_on
|
|
|
|
STZ $55 ; Reset cape flag
|
|
STZ $0AAB ; Reset underwater flag
|
|
STZ $0351 ; Reset ripple flag
|
|
STZ $037B ; Reset invincibility flag
|
|
STZ $02B2 ; Reset mask flag
|
|
|
|
LDA.b $10 : CMP.b #$0B : BEQ .exit
|
|
LDA.b $8A : AND.b #$40 : STA.b $7B : BEQ .no_mirror_portal
|
|
LDA.b $20 : STA.w $1ADF
|
|
LDA.b $21 : STA.w $1AEF
|
|
LDA.b $22 : STA.w $1ABF
|
|
LDA.b $23 : STA.w $1ACF
|
|
.no_mirror_portal
|
|
LDA.b #$23
|
|
|
|
#SetGameModeLikeMirror:
|
|
STA.b $11
|
|
STZ.w $03F8
|
|
LDA.b #$01 : STA.w $02DB
|
|
STZ.b $B0
|
|
STZ.b $27 : STZ.b $28
|
|
LDA.b #$14 : STA.b $5D
|
|
|
|
.not_on
|
|
.exit
|
|
RTS
|
|
}
|
|
}
|
|
```
|
|
|
|
## Drawing (`Sprite_DekuLeaf_Draw` and `Sprite_Whirlpool_Draw`)
|
|
Each object type has its own dedicated drawing routine. These routines handle OAM allocation and animation, and explicitly use `REP #$20` and `SEP #$20` for 16-bit coordinate calculations. Each routine contains its own specific OAM data for rendering the respective object.
|
|
|
|
## Design Patterns
|
|
* **Multi-Object Sprite (Conditional Drawing/Logic)**: A single sprite definition (`Sprite_DekuLeaf`) is used to represent two distinct objects (Deku Leaf and Whirlpool) based on `AreaIndex`, showcasing efficient resource utilization and varied functionality.
|
|
* **Context-Sensitive Behavior**: The sprite's behavior changes entirely based on the `AreaIndex`, allowing it to function as a traversal item (Deku Leaf) or a warp point (Whirlpool), adapting to different game contexts.
|
|
* **Player Interaction**: The Deku Leaf allows Link to stand on it for traversal, while the Whirlpool provides a warp mechanism, both offering unique forms of player interaction.
|
|
* **Game State Manipulation**: The Whirlpool modifies various Link state flags to initiate a warp, demonstrating direct control over the player's game state during transitions.
|
|
* **16-bit OAM Calculations**: Demonstrates explicit use of `REP #$20` and `SEP #$20` for precise 16-bit OAM coordinate calculations, crucial for accurate sprite rendering.
|