Files
oracle-of-secrets/Docs/Sprites/NPCs/Followers.md
scawful aede7551a3 Add new sprite documentation for Minecart, Pedestal, Portal, and Switch Track
- 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.
2025-10-03 01:52:48 -04:00

9.4 KiB

Followers

Overview

The followers.asm file is a comprehensive collection of routines and data structures that implement a sophisticated follower system within Oracle of Secrets. It manages various NPC types, including the Zora Baby, Old Man, Kiki, and a Minecart, each with unique behaviors, interactions, and integration into the game world. This file heavily utilizes vanilla overrides to inject custom logic and expand upon existing game mechanics.

Follower Data Memory Locations

This section defines various WRAM addresses used to store and cache follower-related data, enabling complex interactions and animations:

  • FollowerYL, FollowerYH, FollowerXL, FollowerXH, FollowerZ, FollowerLayer: Stores position (Y, X, Z coordinates) and layer information for followers, with a cache for 20 steps of animation and movement.
  • FollowerHeadOffset, FollowerHeadOffsetH, FollowerBodyOffset, FollowerBodyOffsetH: Stores offsets for follower head and body graphics, used to adjust their appearance based on direction (e.g., facing Link).
  • Flwhgfxt, Flwhgfxth, Flwhgfxb, Flwhgfxbh, Flwbgfxt, Flwbgfxth, Flwbgfxb, Flwbgfxbh: Graphics data for follower head and body.
  • Flwanimir: Index for reading follower animation steps.
  • FollowerHook: Flag indicating when a follower is being used with the Hookshot.
  • FollowerHookI: Caches FLWANIMIW when Hookshotting is finished.
  • FLWGRABTIME: Countdown timer preventing followers from being immediately regrabbed after being dropped.
  • FLWANIMIW: Index for writing follower animation steps.
  • FollowCacheYL, FollowCacheYH, FollowCacheXL, FollowCacheXH: Cache of follower properties in SRAM.

This routine adjusts a follower's head and body graphics offsets to make them turn and face Link, providing a more interactive and responsive NPC presence.

Zora Baby Follower

The Zora Baby follower is a key NPC involved in specific puzzles and interactions, particularly with water switches.

  • ZoraBaby_RevertToSprite: This routine spawns a Sprite 0x39 Locksmith (which is the Zora Baby sprite) and initializes its properties based on the follower's cached data. It sets SprBulletproof, SprAction, and SprTimerB, and clears relevant follower flags.
  • CheckForZoraBabyTransitionToSprite: Checks if the Zora Baby is currently a follower ($7EF3CC = $09). If Link is standing on a star tile ($0114 = $3B), it calls ZoraBaby_RevertToSprite to transition the follower back into a regular sprite. If Link is outdoors, it clears the follower flag.
  • CheckForZoraBabyFollower: A utility routine to check if the Zora Baby is currently a follower.
  • UploadZoraBabyGraphicsPrep: Prepares the graphics for the Zora Baby, setting $7EF3CC to $09 and calling LoadFollowerGraphics.
  • ZoraBaby_CheckForWaterSwitchSprite: Checks for the presence of a Sprite 0x21 (Water Gate Switch) and determines if the Zora Baby is positioned on top of it.
  • ZoraBaby_CheckForWaterGateSwitch: Checks for a Sprite 0x04 (Water Gate Switch) and performs a precise coordinate check to see if the Zora Baby is on top of it.
  • ZoraBaby_GlobalBehavior: This is the main behavior routine for the Zora Baby. It makes the Zora Baby act as a barrier (Sprite_BehaveAsBarrier), makes it watch Link (Follower_WatchLink), and handles interactions like being lifted (Sprite_CheckIfLifted) and thrown (ThrownSprite_TileAndSpriteInteraction_long). Crucially, it detects if the Zora Baby is on a water switch and triggers the ZoraBaby_PullSwitch state.

Zora Baby Vanilla Overrides

  • org $09AA5E: Injects JSL CheckForZoraBabyFollower to enable the Zora Baby's swaying animation.
  • org $09A19C: Injects JSL CheckForZoraBabyTransitionToSprite for follower basic movement.
  • org $09A902: Sets the Zora Baby follower's palette to blue.
  • org $09A8CF: Sets the Zora Baby character data offset.
  • org $06BD9C: Defines the Zora Baby Sprite Idle OAM data.
  • org $068D59 (SpritePrep_Locksmith): Overrides the SpritePrep_Locksmith routine. It makes the Zora Baby bulletproof, prevents spawning if already following, and calls UploadZoraBabyGraphicsPrep.
  • org $06BCAC (Sprite_39_ZoraBaby): Overrides Sprite_39_Locksmith. This is the main state machine for the Zora Baby, including states like LockSmith_Chillin (idle), ZoraBaby_FollowLink, ZoraBaby_OfferService, ZoraBaby_RespondToAnswer, ZoraBaby_AgreeToWait, ZoraBaby_PullSwitch, and ZoraBaby_PostSwitch. These states manage dialogue, following behavior, and interaction with switches.

Old Man Follower

This section includes logic for the Old Man follower, particularly concerning his spawning conditions and item interactions.

  • OldMan_ExpandedPrep: Prevents the Old Man sprite from spawning in his home room if Link already has him as a follower.

Old Man Vanilla Overrides

  • org $1EE9FF: Modifies the item given by the Old Man to be the Goldstar Hookshot upgrade.
  • org $1BBD3C: Modifies FindEntrance for the Old Man.
  • org $02D98B: Modifies Underworld_LoadEntrance for the Old Man.
  • org $1EE8F1 (SpritePrep_OldMan): Overrides SpritePrep_OldMan. It makes the Old Man bulletproof, uses OldMan_ExpandedPrep, checks for the Lv2 Hookshot, and sets $7EF3CC to $04 (Old Man follower) before calling LoadFollowerGraphics.
  • org $09A4C8 (Follower_HandleTriggerData): This is a large data block defining trigger coordinates and messages for various followers, including the Old Man, Zelda, and Blind Maiden.

Kiki Follower

This section contains logic for the Kiki follower, focusing on her reaction to Link's health.

  • Kiki_CheckIfScared: If Link's health is low and Kiki is flashing, she will run away from him.

Kiki Vanilla Overrides

  • org $09A1C6: Injects JSL Kiki_CheckIfScared to implement Kiki's fear behavior.
  • org $1EE2E9 (Kiki_WalkOnRoof): Defines speed data for Kiki walking on a roof.
  • org $1EE576 (Kiki_HopToSpot): Defines target coordinates for Kiki to hop to a spot.
  • org $1EE5E9 (Kiki_WalkOnRoof_Ext): Defines step and timer data for Kiki's extended roof walk.

Minecart Follower

This section details the implementation of the Minecart follower, including its drawing, transition, and Link's interaction with it.

  • FollowerDraw_CalculateOAMCoords: A helper routine to calculate OAM coordinates for followers.
  • MinecartFollower_Top / MinecartFollower_Bottom: Drawing routines for the top and bottom halves of the Minecart follower.
  • Minecart_AnimDirection: Data for Minecart animation direction.
  • MinecartFollower_TransitionToSprite: Transitions the Minecart follower back into a regular sprite.
  • DrawMinecartFollower: The main drawing routine for the Minecart follower, which also handles its transition to a sprite if Link is in the cart and not in a submodule.
  • FollowerDraw_CachePosition: Caches the follower's position for drawing, adjusting coordinates relative to Link.
  • CheckForMinecartFollowerDraw: Checks if the Minecart follower should be drawn.
  • CheckForFollowerInterroomTransition / CheckForFollowerIntraroomTransition: Handles transitions for followers between rooms and within rooms.
  • LinkState_Minecart: Defines Link's behavior when he is in a Minecart, including movement, collision, and animation.
  • TileBehavior_TL_Long / TileBehavior_StopLeft_Long: Tile behaviors for Minecart tracks.

Minecart Vanilla Overrides

  • org $07A5F7: Injects JSL LinkState_Minecart to control Link's state when in a Minecart.
  • org $07D938: Defines Minecart Track tile types.
  • org $09A41F: Injects JSL CheckForMinecartFollowerDraw.
  • org $028A5B: Injects JSL CheckForFollowerInterroomTransition.
  • org $0289BF: Injects JSL CheckForFollowerIntraroomTransition.

Design Patterns

  • Multi-Purpose File: This file serves as a central repository for various follower-related logic, demonstrating how to manage diverse NPC behaviors within a single module.
  • Follower System: Implements a robust and flexible follower system with features like position caching, animation, and complex interaction logic.
  • Vanilla Overrides: Extensive use of org directives to modify vanilla sprite behaviors and integrate custom follower logic, showcasing advanced ROM hacking techniques.
  • Context-Sensitive Behavior: Follower behavior dynamically changes based on game state, player actions, and environmental factors (e.g., Zora Baby on water switch, Old Man's spawning conditions, Kiki's fear of low-health Link).
  • Cutscene Integration: Some followers (like the Zora Baby) are involved in cutscene-like sequences, demonstrating how to choreograph NPC actions within narrative events.
  • Item Gating/Progression: The Old Man's appearance and item offerings are tied to the player's possession of specific items (e.g., Lv2 Hookshot), integrating followers into the game's progression system.
  • Player State Manipulation: Routines like LinkState_Minecart directly control Link's movement and animation when interacting with followers, providing a seamless player experience.
  • 16-bit OAM Calculations: Explicitly uses REP #$20 and SEP #$20 for precise 16-bit OAM calculations in drawing routines, ensuring accurate sprite rendering.