- 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.
228 lines
7.8 KiB
Markdown
228 lines
7.8 KiB
Markdown
# Maple
|
|
|
|
## Overview
|
|
The `maple.asm` file defines the behavior for the NPC "Maple," a significant character involved in a branching "Dream" questline. Maple interacts with Link through extensive dialogue, offers explanations about game mechanics, and possesses the unique ability to put Link to sleep, triggering special dream sequences that advance the narrative and potentially grant rewards.
|
|
|
|
## Main Logic (`MapleHandler`)
|
|
This routine orchestrates Maple's complex interactions with Link, managing dialogue, quest progression, and the initiation of dream sequences.
|
|
|
|
* **Player Collision**: Prevents Link from passing through Maple (`JSL Sprite_PlayerCantPassThrough`).
|
|
* **`Maple_Idle`**: Displays a solicited message (`%ShowSolicitedMessage($01B3)`). Upon dismissal, it transitions to `Maple_HandleFirstResponse`. It also includes logic to set a flag (`$7EF351`) and a timer (`$012F`) for a specific event.
|
|
* **`Maple_HandleFirstResponse`**: Processes Link's initial dialogue response (`$1CE8`), leading to different branches: `Maple_Idle`, `Maple_ExplainHut`, or `Maple_DreamOrExplain`.
|
|
* **`Maple_DreamOrExplain`**: Displays an unconditional message (`%ShowUnconditionalMessage($01B4)`) and, based on Link's response, transitions to `Maple_ExplainPendants`, `Maple_CheckForPendant`, or back to `Maple_Idle`.
|
|
* **`Maple_ExplainHut`**: Displays an unconditional message (`%ShowUnconditionalMessage($01B5)`) and returns to `Maple_Idle`.
|
|
* **`Maple_ExplainPendants`**: Displays an unconditional message (`%ShowUnconditionalMessage($01B8)`) and returns to `Maple_Idle`.
|
|
* **`Maple_CheckForPendant`**: Checks Link's collected Pendants (`Pendants` SRAM flag) and Dreams (`Dreams` SRAM flag) to determine if a new Dream is available. If so, it sets `CurrentDream`, displays a message (`%ShowUnconditionalMessage($01B6)`), and transitions to `Maple_PutLinkToSleep`. Otherwise, it transitions to `Maple_NoNewPendant`.
|
|
* **`Maple_NoNewPendant`**: Displays an unconditional message (`%ShowUnconditionalMessage($01B7)`) and returns to `Maple_Idle`.
|
|
* **`Maple_PutLinkToSleep`**: Calls `Sprite_PutLinkToSleep` to initiate the sleep sequence and then transitions to `Maple_HandleDreams`.
|
|
* **`Maple_HandleDreams`**: After a timer (`SprTimerA, X`), calls `Link_HandleDreams` to process the dream sequence.
|
|
|
|
```asm
|
|
MapleHandler:
|
|
{
|
|
%PlayAnimation(0,1,16)
|
|
JSL Sprite_PlayerCantPassThrough
|
|
|
|
LDA.w SprAction, X
|
|
JSL JumpTableLocal
|
|
|
|
dw Maple_Idle
|
|
dw Maple_HandleFirstResponse
|
|
dw Maple_DreamOrExplain
|
|
dw Maple_ExplainHut
|
|
dw Maple_ExplainPendants
|
|
dw Maple_CheckForPendant
|
|
dw Maple_NoNewPendant
|
|
dw Maple_PutLinkToSleep
|
|
dw Maple_HandleDreams
|
|
|
|
|
|
Maple_Idle:
|
|
{
|
|
%ShowSolicitedMessage($01B3) : BCC +
|
|
INC.w SprAction, X
|
|
+
|
|
LDA.l $7EF351 : BEQ +
|
|
LDA.b #$02 : STA.l $7EF351
|
|
LDA.b #$1B : STA.w $012F
|
|
+
|
|
RTS
|
|
}
|
|
|
|
Maple_HandleFirstResponse:
|
|
{
|
|
LDA.w $1CE8 : CMP.b #$02 : BNE +
|
|
STZ.w SprAction, X
|
|
RTS
|
|
+
|
|
CMP.b #$01 : BNE .next_response
|
|
LDA.b #$03 : STA.w SprAction, X
|
|
RTS
|
|
.next_response
|
|
INC.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_DreamOrExplain:
|
|
{
|
|
%ShowUnconditionalMessage($01B4)
|
|
LDA.w $1CE8 : BEQ .check_for_pendant
|
|
CMP.b #$01 : BNE .another_time
|
|
LDA.b #$04 : STA.w SprAction, X
|
|
RTS
|
|
.check_for_pendant
|
|
LDA.b #$05 : STA.w SprAction, X
|
|
RTS
|
|
|
|
.another_time
|
|
STZ.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_ExplainHut:
|
|
{
|
|
%ShowUnconditionalMessage($01B5)
|
|
STZ.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_ExplainPendants:
|
|
{
|
|
%ShowUnconditionalMessage($01B8)
|
|
STZ.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_CheckForPendant:
|
|
{
|
|
; Check for pendant
|
|
LDA.l Pendants : AND.b #$04 : BNE .courage
|
|
LDA.l Pendants : AND.b #$02 : BNE .power
|
|
LDA.l Pendants : AND.b #$01 : BNE .wisdom
|
|
JMP .none
|
|
.courage
|
|
LDA.l Dreams : AND.b #$04 : BNE .power
|
|
LDA.b #$02 : STA.w CurrentDream : BRA +
|
|
.power
|
|
LDA.l Dreams : AND.b #$02 : BNE .wisdom
|
|
LDA.b #$01 : STA.w CurrentDream : BRA +
|
|
.wisdom
|
|
LDA.l Dreams : AND.b #$01 : BNE .none
|
|
STZ.w CurrentDream
|
|
+
|
|
%ShowUnconditionalMessage($01B6)
|
|
LDA.b #$07 : STA.w SprAction, X
|
|
LDA.b #$40 : STA.w SprTimerA, X
|
|
RTS
|
|
.none
|
|
INC.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_NoNewPendant:
|
|
{
|
|
%ShowUnconditionalMessage($01B7)
|
|
STZ.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_PutLinkToSleep:
|
|
{
|
|
JSR Sprite_PutLinkToSleep
|
|
INC.w SprAction, X
|
|
RTS
|
|
}
|
|
|
|
Maple_HandleDreams:
|
|
{
|
|
LDA.w SprTimerA, X : BNE +
|
|
JSR Link_HandleDreams
|
|
+
|
|
RTS
|
|
}
|
|
}
|
|
```
|
|
|
|
## `Sprite_PutLinkToSleep`
|
|
This routine initiates a cinematic sleep sequence for Link. It adjusts Link's coordinates, sets his state to sleeping (`$5D = $16`), spawns a blanket ancilla, adjusts Link's OAM coordinates, and applies a blinding white palette filter to transition into a dream sequence.
|
|
|
|
```asm
|
|
Sprite_PutLinkToSleep:
|
|
{
|
|
PHX
|
|
LDA.b $20 : SEC : SBC.b #$14 : STA.b $20
|
|
LDA.b $22 : CLC : ADC.b #$18 : STA.b $22
|
|
|
|
LDA.b #$16 : STA.b $5D ; Set Link to sleeping
|
|
LDA.b #$20 : JSL AncillaAdd_Blanket
|
|
LDA.b $20 : CLC : ADC.b #$04 : STA.w $0BFA,X
|
|
LDA.b $21 : STA.w $0C0E,X
|
|
LDA.b $22 : SEC : SBC.b #$08 : STA.w $0C04,X
|
|
LDA.b $23 : STA.w $0C18,X
|
|
JSL PaletteFilter_StartBlindingWhite
|
|
JSL ApplyPaletteFilter
|
|
PLX
|
|
RTS
|
|
}
|
|
```
|
|
|
|
## `Link_HandleDreams`
|
|
This routine manages the different dream sequences based on the `CurrentDream` variable. It sets specific bits in the `Dreams` SRAM flag and warps Link to a designated room using `Link_WarpToRoom`.
|
|
|
|
* **`Dream_Wisdom`**: Sets bit `0` in `Dreams`, warps Link to a room, and sets `$EE` to `$01`.
|
|
* **`Dream_Power`**: Sets bit `1` in `Dreams` and warps Link to a room.
|
|
* **`Dream_Courage`**: Sets bit `2` in `Dreams` and warps Link to a room.
|
|
|
|
```asm
|
|
Link_HandleDreams:
|
|
{
|
|
LDA.w CurrentDream
|
|
JSL JumpTableLocal
|
|
|
|
dw Dream_Wisdom
|
|
dw Dream_Power
|
|
dw Dream_Courage
|
|
|
|
Dream_Wisdom:
|
|
{
|
|
LDA.l Dreams : ORA.b #%00000001 : STA.l Dreams
|
|
LDX.b #$00
|
|
JSR Link_WarpToRoom
|
|
LDA.b #$01 : STA.b $EE
|
|
RTS
|
|
}
|
|
|
|
Dream_Power:
|
|
{
|
|
LDA.l Dreams : ORA.b #%00000010 : STA.l Dreams
|
|
LDX.b #$01
|
|
JSR Link_WarpToRoom
|
|
RTS
|
|
}
|
|
|
|
Dream_Courage:
|
|
{
|
|
LDA.l Dreams : ORA.b #%00000100 : STA.l Dreams
|
|
LDX.b #$02
|
|
JSR Link_WarpToRoom
|
|
RTS
|
|
}
|
|
}
|
|
```
|
|
|
|
## `Link_WarpToRoom`
|
|
This routine sets Link's state for warping, including setting his `LinkState` and room coordinates, and uses a `.room` data table to determine the target room for the warp.
|
|
|
|
## `Link_FallIntoDungeon`
|
|
This routine sets Link's state for falling into a dungeon, including setting the entrance ID and various state flags. It uses an `.entrance` data table to determine the target entrance.
|
|
|
|
## Vanilla Override
|
|
* **`org $068C9C`**: Sets a byte to `$0F`, likely a minor adjustment to vanilla code.
|
|
|
|
## Design Patterns
|
|
* **Complex Dialogue System**: Maple's interactions feature a highly branching and conditional dialogue system, where player choices and game progression influence the conversation flow and subsequent events.
|
|
* **Quest Gating/Progression**: Maple is a central figure in a "Dream" questline, with her dialogue and actions dynamically adapting based on Link's collected Pendants and Dreams, guiding the player through a significant narrative arc.
|
|
* **Player State Manipulation**: Maple possesses the unique ability to put Link to sleep, which triggers special dream sequences and warps him to different locations, creating immersive and story-rich transitions.
|
|
* **Cinematic Sequences**: The `Sprite_PutLinkToSleep` routine orchestrates a cinematic effect, incorporating screen transitions, visual filters, and the spawning of ancillae to enhance the player's experience during dream initiations.
|
|
* **Global State Management**: The sprite extensively modifies `Pendants`, `Dreams`, `CurrentDream`, and other global variables to meticulously track and influence quest progress, ensuring a consistent and evolving game world.
|