Add sprite analysis documentation for various bosses and mini-bosses

- Created detailed documentation for the Kydrog Boss sprite, outlining its phases, behaviors, and mechanics.
- Added analysis for the Manhandla sprite, including its transformation into Big Chuchu and phase management.
- Documented the Octoboss sprite, highlighting its unique mechanics and interactions with a "brother" Octoboss.
- Provided an overview of the Twinrova boss sprite, detailing its transformation and phase-based attacks.
- Included analysis for the Vampire Bat mini-boss, emphasizing its enhanced behavior compared to standard Keese.
- Documented the Wolfos mini-boss, focusing on its integration into a mask quest and unique pacification mechanics.
This commit is contained in:
scawful
2025-10-02 21:24:44 -04:00
parent 0f1e0a8c75
commit 6780dd0d45
14 changed files with 771 additions and 26 deletions

31
Docs/Sprites/DarkLink.md Normal file
View File

@@ -0,0 +1,31 @@
# Dark Link Sprite Analysis
## Overview
Dark Link (Sprite ID: `$C1`) is a boss sprite known for its dynamic and challenging combat. It features a variety of attacks, including sword slashes, jump attacks, and projectile spawning. A notable aspect of this sprite is its ability to transform into a Ganon-like entity via a subtype, suggesting a multi-phase boss encounter.
## Key Properties:
* **Sprite ID:** `$C1`
* **Number of Tiles:** 4
* **Health:** 34 (decimal)
* **Damage:** 0 (Damage is handled by spawned attacks or direct contact logic, not directly by the sprite's `!Damage` property.)
* **Special Properties:**
* `!DeflectProjectiles = 01` (Deflects all projectiles)
* `!ImperviousArrow = 01` (Impervious to arrows)
* `!Boss = 00` (Despite being a boss, this flag is not set, indicating custom boss logic rather than reliance on vanilla boss flags.)
## Subtypes:
* **Subtype `$05` (Ganon):** This subtype completely alters Dark Link's behavior to that of a Ganon boss, executing `Sprite_Ganon_Main` and `Sprite_Ganon_Draw`. This mechanism allows for a multi-stage boss fight or an entirely different boss using the same sprite slot.
* **Subtype `$01` (Sword Damage):** This subtype is used for a temporary sprite spawned during Dark Link's sword attacks to handle collision and damage detection.
## In-Game Behavior:
Dark Link is an active and engaging boss. It moves strategically towards Link, performs various sword attacks (including a jump attack with screen shake), can utilize a cape for evasion, and throws bombs. It reacts to damage with visual recoil and flashing, and enters an "enraging" state (indicated by a red palette change) which likely alters its attack patterns or aggression. The Ganon subtype suggests a significant shift in combat during the fight.
## Original Sprite Replaced:
The code does not explicitly state which vanilla sprite `dark_link` replaces. However, the integration of `GanonInit` and Ganon-related logic strongly suggests it either heavily modifies an existing Ganon boss fight or is a completely new boss utilizing a custom sprite ID.
## Development Goals for Oracle of Secrets:
* **Variety in Attacks:** Introduce more diverse attack patterns and abilities to enhance the fight's complexity and challenge.
* **Unique Oracle of Secrets Attacks:** Implement attacks that are thematic and unique to the Oracle of Secrets project, moving beyond standard ALTTP boss mechanics.
## Code Quality Notes:
The code, while functional and effective in creating a competent boss, is noted to be somewhat "messy" due to its origin from Zarby89's ZScream project. This implies that while it works, future modifications might require careful navigation through its structure.

65
Docs/Sprites/Kydreeok.md Normal file
View File

@@ -0,0 +1,65 @@
# Kydreeok Sprite Analysis
## Overview
The `kydreeok` sprite (ID: `Sprite_Kydreeok`, which is `$7A`) represents the main Kydreeok boss. It orchestrates the entire boss fight, including spawning and managing its child head sprites (`kydreeok_head`), controlling its own movement phases, and handling its overall defeat. This is a multi-headed boss where the heads are separate sprites.
## Key Properties:
* **Sprite ID:** `Sprite_Kydreeok` (`$7A`)
* **Description:** The main Kydreeok boss, controlling the overall fight and its child heads.
* **Number of Tiles:** 8
* **Health:** `00` (The boss's health is managed through its child heads and custom logic, not directly by this sprite's `!Health` property.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its heads or custom logic.)
* **Special Properties:**
* `!Boss = 01` (This sprite is correctly identified as a boss.)
* `!Hitbox = $07`
## Main States/Actions (`Sprite_Kydreeok_Main` Jump Table):
The boss's behavior is divided into several phases:
* **`Kydreeok_Start` (0x00):** Initial state. Applies graphics and palette, prevents Link from passing through, and transitions to `Kydreeok_StageControl` after a timer. Stores its own sprite index in `Kydreeok_Id`.
* **`Kydreeok_StageControl` (0x01):** Manages the boss's movement stage, setting velocities and checking boundaries.
* **`Kydreeok_MoveXandY` (0x02):** Moves the boss in both X and Y directions towards Link, checking boundaries and handling damage.
* **`Kydreeok_MoveXorY` (0x03):** Moves the boss in either X or Y direction towards Link, checking boundaries and handling damage.
* **`Kydreeok_KeepWalking` (0x04):** Continues walking, with a random chance to transition to a flying state.
* **`Kydreeok_Dead` (0x05):** Handles the boss's death sequence, including visual effects (flickering, explosions) and eventually despawning the sprite.
* **`Kydreeok_Flying` (0x06):** The boss enters a flying state, moving towards Link at a set height, checking boundaries and handling damage.
## Initialization (`Sprite_Kydreeok_Prep`):
* Sets initial timers and movement speeds.
* Caches its own origin position.
* **Spawns its child heads:** Calls `JSR SpawnLeftHead` and `JSR SpawnRightHead`. A `SpawnCenterHead` routine is commented out, suggesting a potential for a three-headed boss.
* Initializes neck offsets to zero.
* Applies a custom palette (`JSR ApplyPalette`).
* Sets the boss theme music.
## Death and Respawn Logic (`Sprite_Kydreeok_CheckIfDead`, `MaybeRespawnHead`):
* **`Sprite_Kydreeok_CheckIfDead`:** This crucial routine checks the state of its child heads (`Offspring1_Id`, `Offspring2_Id`). If both heads are defeated, it triggers a "dead" phase, changes its graphics, respawns both heads, and then transitions to the `Kydreeok_Dead` state. This indicates a multi-phase boss where heads can be temporarily defeated.
* **`MaybeRespawnHead`:** Randomly respawns a head if its corresponding child sprite is dead, adding a dynamic challenge to the fight.
## Head Spawning (`SpawnLeftHead`, `SpawnRightHead`):
* These routines spawn `Sprite_KydreeokHead` (`$CF`) sprites.
* They assign `SprSubtype` to the spawned heads (`$00` for left, `$01` for right), allowing the child sprites to differentiate their behavior.
* They store the IDs of the spawned heads in global variables (`Offspring1_Id`, `Offspring2_Id`).
* They set the initial position of the heads relative to the main boss and initialize neck segment coordinates.
## Movement (`MoveBody`, `StopIfOutOfBounds`):
* **`MoveBody`:** Manages the main body's movement, calling `JSL Sprite_Move` and updating background scrolling based on its movement. It reuses logic from `Trinexx_MoveBody`.
* **`StopIfOutOfBounds`:** Prevents the boss from moving beyond screen boundaries. It also subtly adjusts the neck positions when hitting a boundary, creating a visual "pushing" effect.
## Palette Management (`ApplyPalette`, `ApplyEndPalette`):
* **`ApplyPalette`:** Sets the initial palette for the boss.
* **`ApplyEndPalette`:** Sets a different palette, likely for a defeated state or phase change.
## Graphics Transfer (`ApplyKydreeokGraphics`):
* Handles DMA transfer of graphics data (`kydreeok.bin`, `kydreeok_phase2.bin`) to VRAM, allowing for different graphical appearances across phases.
## Global Variables for Neck Control:
* `LeftNeck1_X` to `LeftNeck3_Y`, `RightNeck1_X` to `RightNeck3_Y`: Global RAM addresses used to store the coordinates of the neck segments, enabling the heads to track them.
* `Kydreeok_Id`: Stores the sprite index of the main Kydreeok boss.
* `Offspring1_Id`, `Offspring2_Id`: Store the sprite indices of the spawned heads.
## Discrepancies/Notes:
* The `!Health` and `!Damage` properties are `00`, confirming that the boss's health and damage are managed through its heads (`Sprite_KydreeokHead`) and custom logic within `Sprite_Kydreeok_CheckIfDead`.
* The `Sprite_Kydreeok_CheckIfDead` routine clearly defines a multi-phase fight where the heads can be defeated, respawned, and ultimately lead to the main boss's defeat.
* The commented-out `SpawnCenterHead` suggests a potential for a three-headed Kydreeok that was either removed or is an unimplemented feature.
* Reusing movement logic from `Trinexx_MoveBody` is efficient but should be considered for unique boss feel.
* Hardcoded addresses for `JSL` calls could be replaced with named labels for better maintainability.

View File

@@ -0,0 +1,68 @@
# Kydreeok Head Sprite Analysis
## Overview
The `kydreeok_head` sprite (ID: `Sprite_KydreeokHead`, which is `$CF`) is a child sprite of the main `Kydreeok` boss. It represents one of the multi-headed boss's individual heads, possessing independent movement, attack patterns, and damage handling. Its primary role is to move, rotate, and attack Link, contributing to the overall boss encounter.
## Key Properties:
* **Sprite ID:** `Sprite_KydreeokHead` (`$CF`)
* **Description:** Child sprite of the Kydreeok boss, responsible for individual head behavior.
* **Number of Tiles:** 7
* **Health:** `$C8` (200 decimal) - This high health value indicates it's a significant component of the boss fight.
* **Damage:** `00` (Damage is likely applied through its spawned attacks.)
* **Special Properties:**
* `!Boss = 00` (Not marked as a boss itself, as it's a component of a larger boss.)
* `!Hitbox = 09`
## Subtypes:
The `SprSubtype, X` register is crucial for differentiating the heads and their behavior:
* **Subtype `$00`:** Controls the "Left Head" via `Neck1_Control`.
* **Subtype `$01`:** Controls the "Right Head" via `Neck2_Control`.
This allows the same sprite ID to manage multiple distinct heads.
## Main States/Actions (`Sprite_KydreeokHead_Main` Jump Table):
The head's behavior is governed by a state machine:
* **`KydreeokHead_ForwardAnim` (0x00):** Default state, plays forward animation, handles damage, performs rotational movement, and randomly attacks. Transitions to other directional states based on Link's position.
* **`KydreeokHead_RightAnim` (0x01):** Plays right-facing animation, handles damage, rotation, and attacks.
* **`KydreeokHead_LeftAnim` (0x02):** Plays left-facing animation, handles damage, rotation, and attacks.
* **`KydreeokHead_FarRight` (0x03):** Plays far-right animation, moves towards Link, handles damage, rotation, and attacks.
* **`KydreeokHead_FarLeft` (0x04):** Plays far-left animation, moves towards Link, handles damage, rotation, and attacks.
* **`KydreeokHead_SummonFire` (0x05):** Moves towards Link, checks damage, and utilizes `JSL Sprite_Twinrova_FireAttack` to deal damage. The head sprite is then killed after a timer.
## Initialization (`Sprite_KydreeokHead_Prep`):
* Sets initial health to `$FF` (255 decimal), though the `!Health` property is `$C8`. This discrepancy might be overridden by the parent `Kydreeok` sprite or is a temporary value.
* Sets `SprBump = $09` (bump damage type).
* Initializes `SprMiscE, X` to `0`.
## Drawing (`Sprite_KydreeokHead_Draw`):
* Uses standard OAM allocation routines.
* The main drawing routine calls `JMP Sprite_KydreeokHead_DrawNeck`, indicating that the neck segments are drawn after the head.
* Includes logic for flashing when damaged.
## Neck Control (`KydreeokHead_NeckControl`, `Neck1_Control`, `Neck2_Control`, `Sprite_KydreeokHead_DrawNeck`, `DrawNeckPart`):
This is a sophisticated system for managing the multi-segmented neck:
* `KydreeokHead_NeckControl` dispatches to `Neck1_Control` (for the left head) or `Neck2_Control` (for the right head) based on `SprSubtype, X`.
* `Neck1_Control` and `Neck2_Control` manage the movement and positioning of three neck segments, ensuring they follow the head while maintaining specific distances.
* `Sprite_KydreeokHead_DrawNeck` and `DrawNeckPart` handle the rendering of these segments.
## Movement and Rotation (`KydreeokHead_RotationMove`, `RotateHeadUsingSpeedValues`, `MoveWithBody`):
* **`KydreeokHead_RotationMove`:** Generates random speeds, dispatches to neck control, moves with the main body, and applies rotational movement.
* **`RotateHeadUsingSpeedValues`:** Uses sine/cosine tables (`XSpeedSin`, `YSpeedSin`) to apply smooth rotational movement.
* **`MoveWithBody`:** Ensures the head's position is correctly offset and relative to the main `Kydreeok` boss, adjusting for left or right heads.
## Attacks (`RandomlyAttack`, `KydreeokHead_SummonFire`):
* **`RandomlyAttack`:** Randomly spawns a fire-based projectile (which is actually the `Sprite_KydreeokHead` itself entering the `SummonFire` state).
* **`KydreeokHead_SummonFire`:** This state is entered when a fire projectile is spawned. It moves towards Link and uses `JSL Sprite_Twinrova_FireAttack` to deal damage, after which the head sprite is killed.
## Key Macros/Functions Used:
* `%Set_Sprite_Properties`, `%GotoAction`, `%StartOnFrame`, `%PlayAnimation`, `%MoveTowardPlayer`
* `JSL JumpTableLocal`, `JSL Sprite_CheckDamageFromPlayer`, `JSL Sprite_CheckDamageToPlayer`, `JSL Sprite_DamageFlash_Long`
* `JSL GetRandomInt`, `JSL Sprite_MoveLong`, `JSL Sprite_IsToRightOfPlayer`
* `JSL Sprite_SpawnDynamically`, `JSL Sprite_SetSpawnedCoords`
* `JSL Sprite_Twinrova_FireAttack`, `JSL Fireball_SpawnTrailGarnish`
* `JSR GetDistance8bit`
## Discrepancies/Notes:
* The `!Health` property is `$C8`, but `Sprite_KydreeokHead_Prep` sets `SprHealth, X` to `$FF`. This needs clarification.
* The reuse of `JSL Sprite_Twinrova_FireAttack` for Kydreeok's head is an example of code reuse, but it's important to ensure it fits the thematic design of Kydreeok.
* The neck control system is quite intricate, highlighting advanced sprite design.
* Several hardcoded addresses for `JSL` calls could be replaced with named labels for better maintainability.

View File

@@ -0,0 +1,90 @@
# Kydrog Boss Sprite Analysis
## Overview
The `kydrog_boss` sprite (ID: `Sprite_KydrogBoss`, which is `$CB`) represents the main Kydrog boss. This boss features multiple phases, dynamic movement, and the ability to summon stalfos offspring. It's a complex encounter designed to challenge the player through varied attack patterns and phase transitions.
## Key Properties:
* **Sprite ID:** `Sprite_KydrogBoss` (`$CB`)
* **Description:** The main Kydrog boss, controlling its own movement, phases, and spawning stalfos offspring.
* **Number of Tiles:** 11
* **Health:** `00` (The boss's health is managed through `CheckForNextPhase` and `Sprite_KydrogBoss_CheckIfDead`, not directly by this property.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its attacks or spawned offspring.)
* **Special Properties:**
* `!Boss = $01` (Correctly identified as a boss.)
* `!Shadow = 01` (Draws a shadow.)
* `!Hitbox = 03`
## Custom Variables:
* `!ConsecutiveHits = $AC`: Tracks consecutive hits on the boss, influencing its behavior.
* `!KydrogPhase = $7A`: Manages the current phase of the boss fight.
* `!WalkSpeed = 10`: Defines the boss's walking speed.
## Main States/Actions (`Sprite_KydrogBoss_Main` Jump Table):
The boss's behavior is governed by a detailed state machine:
* **`KydrogBoss_Init` (0x00):** Initial state, plays an "Arms Crossed" animation, and transitions to `KydrogBoss_WalkState` after an intro timer.
* **`KydrogBoss_WalkState` (0x01):** The primary walking state. Manages phase transitions, handles damage, taunting, and determines the next walking direction (forward, backward, left, right) based on Link's position and proximity.
* **`KydrogBoss_WalkForward` (0x02), `KydrogBoss_WalkLeft` (0x03), `KydrogBoss_WalkRight` (0x04), `KydrogBoss_WalkBackward` (0x05):** These states handle movement in specific directions, playing corresponding animations and executing core movement logic.
* **`KydrogBoss_TakeDamage` (0x06):** Manages the boss taking damage. Increments `!ConsecutiveHits`, plays a damage animation, spawns stalfos offspring, and can trigger an ascend action.
* **`KydrogBoss_TauntPlayer` (0x07):** Plays a taunting animation, handles damage, and transitions to `KydrogBoss_SummonStalfos`.
* **`KydrogBoss_SummonStalfos` (0x08):** Plays a summoning animation, handles damage, spawns stalfos offspring, and can throw a bone projectile at Link.
* **`KydrogBoss_Death` (0x09):** Handles the boss's death sequence, including killing spawned friends, playing a flickering animation, and despawning.
* **`KydrogBoss_Ascend` (0x0A):** The boss ascends off-screen, increasing its `SprHeight` and spawning stalfos offspring. Transitions to `KydrogBoss_Descend`.
* **`KydrogBoss_Descend` (0x0B):** The boss descends, tracking Link's position, decreasing its `SprHeight`, and spawning stalfos offspring. Transitions back to `KydrogBoss_WalkState`.
* **`KydrogBoss_Abscond` (0x0C):** The boss moves away from Link, increasing its speed, and transitions back to `KydrogBoss_WalkState`.
## Initialization (`Sprite_KydrogBoss_Prep`):
* Initializes `!KydrogPhase` to `00`.
* Sets initial health to `$A0` (160 decimal).
* Configures deflection (`SprDefl`), hitbox (`SprHitbox`), and bump damage (`SprBump`).
* Sets `SprGfxProps` to not invincible.
* Calls `JSR KydrogBoss_Set_Damage` to define its damage vulnerabilities.
* Sets initial sprite speeds and `!Harmless = 00`.
* Sets an intro timer (`SprTimerD = $80`).
## Death Check (`Sprite_KydrogBoss_CheckIfDead`):
* Monitors `SprHealth, X`. If health is zero or negative, it triggers the boss's death sequence, setting `SprState = $04` (kill sprite boss style) and `SprAction = $09` (KydrogBoss_Death stage).
## Phase Management (`CheckForNextPhase`):
This routine dynamically manages the boss's phases based on its current health:
* **Phase One (`!KydrogPhase = $00`):** Transitions to Phase Two when health drops below `$20`.
* **Phase Two (`!KydrogPhase = $01`):** Transitions to Phase Three when health drops below `$20`. Resets health to `$80`, sets action to `KydrogBoss_WalkState`, and increments `SprFlash, X`.
* **Phase Three (`!KydrogPhase = $02`):** Transitions to Phase Four when health drops below `$20`. Resets health to `$80`, sets action to `KydrogBoss_WalkState`.
* **Phase Four (`!KydrogPhase = $03`):** Sets action to `KydrogBoss_WalkState`.
## Damage Table (`KydrogBoss_Set_Damage`):
* Defines how KydrogBoss reacts to various attack types (Boomerang, Sword, Arrow, Bomb, etc.), stored in a damage properties table.
## Offspring Spawning (`RandomStalfosOffspring`, `Sprite_Offspring_Spawn`, `Sprite_Offspring_SpawnHead`):
* **`RandomStalfosOffspring`:** Randomly spawns either a normal stalfos offspring (`Sprite_Offspring_Spawn`) or a stalfos head offspring (`Sprite_Offspring_SpawnHead`), with a limit of 4 active stalfos.
* **`Sprite_Offspring_Spawn`:** Spawns a stalfos offspring (Sprite ID `$A7` or `$85`).
* **`Sprite_Offspring_SpawnHead`:** Spawns a stalfos head offspring (Sprite ID `$7C` or `$02`).
## Attacks (`Kydrog_ThrowBoneAtPlayer`):
* **`Kydrog_ThrowBoneAtPlayer`:** Spawns a bone projectile (Sprite ID `$A7`) that moves towards Link.
## Movement (`KydrogBoss_DoMovement`, `BounceBasedOnPhase`):
* **`KydrogBoss_DoMovement`:** Handles damage checks, applies damage to Link on contact, flashes when damaged, and incorporates phase-based bouncing and stalfos spawning.
* **`BounceBasedOnPhase`:** Adjusts the boss's bounce speed based on the current `!KydrogPhase`.
## Drawing (`Sprite_KydrogBoss_Draw`):
* Uses standard OAM allocation routines.
* Handles complex animation frames, x/y offsets, character data, properties, and sizes for drawing the boss.
* Utilizes 16-bit operations (`REP #$30`, `SEP #$30`) for precise drawing calculations.
## Other Routines:
* **`StopIfTooClose()` macro:** Prevents the boss from getting too close to Link.
* **`Sprite_CheckIfFrozen`:** Checks if the sprite is frozen and unfreezes it after a timer.
* **`GetNumberSpawnStalfos`:** Counts the number of active stalfos offspring.
* **`SpawnSplash`:** Spawns a splash effect.
* **`SpawnBossPoof`:** Spawns a boss poof effect.
* **`HandleMovingSplash`:** Handles splash effects during movement.
* **`SpawnMedallion` / `SpawnMedallionAlt`:** Spawns a medallion.
## Discrepancies/Notes:
* The main boss's health is intricately managed through `SprHealth, X` and `!KydrogPhase`, requiring a clear understanding of their interplay.
* The stalfos offspring are spawned using specific sprite IDs, which should be cross-referenced for full understanding.
* Many hardcoded values for timers, speeds, and offsets could be replaced with named constants for improved readability and maintainability.
* The code includes direct calls to sound effect functions (`JSL $0DBB8A`) and a commented-out call to `JSL $01F3EC` (Light Torch), which might be a leftover or an unimplemented feature.
## Hardcoded Activation Trigger:
* As noted by the user, the activation trigger for KydrogBoss is hardcoded. Specifically, in the `WaitForPlayerToApproach` routine, the boss checks `LDA.b $20 : CMP #$08C8`. `$20` represents Link's Y position, and `$08C8` is a hardcoded Y-coordinate. This means the boss will only activate when Link reaches this specific Y-coordinate, making it difficult to relocate the boss to other overworld maps without modifying this value.

79
Docs/Sprites/Manhandla.md Normal file
View File

@@ -0,0 +1,79 @@
# Manhandla / Big Chuchu Sprite Analysis
## Overview
The `manhandla` sprite (ID: `Sprite_Manhandla`, which is `$88`) is a multi-phase boss. It begins as Manhandla, a multi-headed plant-like enemy, and upon the defeat of its individual heads, it transforms into a Big Chuchu. This design creates a dynamic and evolving boss encounter.
## Key Properties:
* **Sprite ID:** `Sprite_Manhandla` (`$88`)
* **Description:** A multi-phase boss that transforms from Manhandla to Big Chuchu.
* **Number of Tiles:** 3
* **Health:** `00` (Health is managed by its spawned heads in the first phase and then by its own `SprHealth` in the second phase.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its heads or spawned projectiles.)
* **Special Properties:**
* `!Boss = 01` (Correctly identified as a boss.)
* `!DeathAnimation = 01` (Indicates custom death handling rather than a standard animation.)
* `!Hitbox = 00`
## Custom Variables:
* `Offspring1_Id`, `Offspring2_Id`, `Offspring3_Id`: Global variables used to track the sprite indices of the spawned Manhandla heads.
## Main States/Actions (`Sprite_Manhandla_Main` Jump Table):
The boss's behavior is governed by a detailed state machine across its phases:
* **`Manhandla_Intro` (0x00):** Initial state. Spawns the three Manhandla heads (`SpawnLeftManhandlaHead`, `SpawnRightManhandlaHead`, `SpawnCenterMandhandlaHead`) and transitions to `Manhandla_Body`.
* **`Manhandla_FrontHead` (0x01), `Manhandla_LeftHead` (0x02), `Manhandla_RightHead` (0x03):** These states are likely executed by the individual Manhandla head child sprites, managing their movement, damage, and contact with Link.
* **`BigChuchu_Main` (0x04):** The primary state for the Big Chuchu phase. Handles movement, damage, and can spawn Chuchu blasts.
* **`Flower_Flicker` (0x05):** A transitional state that flickers the background (BG2) and spawns a new `Sprite_Manhandla` (with `SprSubtype = $08`, representing the Big Chuchu head) after a timer, as part of the transformation.
* **`Manhandla_Body` (0x06):** The main state for the Manhandla body. Handles movement, damage, updates the positions of its spawned heads, and can spawn Mothula beams.
* **`BigChuchu_Emerge` (0x07):** Manages the emergence animation of the Big Chuchu.
* **`BigChuchu_Flower` (0x08):** A state for the Big Chuchu, possibly related to its visual appearance or an attack.
* **`BigChuchu_Dead` (0x09):** Handles the death sequence of the Big Chuchu.
* **`ChuchuBlast` (0x0A):** Manages the movement and damage of the spawned Chuchu blast projectile.
## Initialization (`Sprite_Manhandla_Prep`):
* Sets initial movement speeds and enables BG1 movement.
* Configures deflection properties (`SprDefl = $80`).
* Sets initial health to `$80`.
* Initializes `SprAction, X` based on `SprSubtype, X`.
## Phase Transition and Death Check (`Sprite_Manhandla_CheckForNextPhaseOrDeath`):
This critical routine orchestrates the boss's transformation:
* It checks if all three Manhandla heads (`Offspring1_Id`, `Offspring2_Id`, `Offspring3_Id`) are dead.
* If all heads are defeated, it triggers the transition to the Big Chuchu phase:
* Sets `SprMiscD, X = $01` (phase flag).
* Refills health (`SprHealth = $40`).
* Adjusts OAM entries (`SprNbrOAM = $08`).
* Sets `SprAction = $07` (BigChuchu_Emerge).
* It also manages the Big Chuchu's defeat, transitioning to `BigChuchu_Dead` when its health drops below `$04`.
## Head Spawning (`SpawnLeftManhandlaHead`, `SpawnRightManhandlaHead`, `SpawnCenterMandhandlaHead`):
* These routines spawn `Sprite_Manhandla` (`$88`) sprites as child heads.
* They assign specific `SprSubtype` values (`$03` for left, `$02` for right, `$01` for center) to differentiate the heads.
* They store the IDs of the spawned heads in global variables (`Offspring1_Id`, `Offspring2_Id`, `Offspring3_Id`).
* They set the initial position, health, and properties for each head.
## Head Positioning (`SetLeftHeadPos`, `SetRightHeadPos`, `SetCenterHeadPos`):
* These routines dynamically calculate and set the positions of the spawned heads relative to the main Manhandla body.
## Movement (`Sprite_Manhandla_Move`, `Manhandla_StopIfOutOfBounds`):
* **`Sprite_Manhandla_Move`:** The core movement logic for the Manhandla body, utilizing a jump table for `StageControl`, `MoveXandY`, `MoveXorY`, and `KeepWalking` states.
* **`Manhandla_StopIfOutOfBounds`:** Prevents the boss from moving beyond predefined screen boundaries.
## Attacks (`Chuchu_SpawnBlast`, `Mothula_SpawnBeams`):
* **`Chuchu_SpawnBlast`:** Spawns a Chuchu blast projectile (Sprite ID `$88` with `SprSubtype = $0A`).
* **`Mothula_SpawnBeams`:** Spawns beam projectiles (Sprite ID `$89`), called from `Manhandla_Body`.
## Drawing (`Sprite_Manhandla_Draw`, `Sprite_BigChuchu_Draw`):
* **`Sprite_Manhandla_Draw`:** Renders the Manhandla body and its heads.
* **`Sprite_BigChuchu_Draw`:** Renders the Big Chuchu form.
* Both utilize standard OAM allocation routines and handle animation frames, offsets, character data, properties, and sizes.
## Graphics and Palette (`ApplyManhandlaGraphics`, `ApplyManhandlaPalette`):
* **`ApplyManhandlaGraphics`:** Handles DMA transfer of graphics data (`manhandla.bin`) to VRAM.
* **`ApplyManhandlaPalette`:** Sets the custom palette for Manhandla.
## Discrepancies/Notes:
* The `!Health` property is `00`, indicating that the boss's health is managed by its heads in the first phase and then by its own `SprHealth` in the Big Chuchu phase.
* The `Sprite_Manhandla` ID (`$88`) is efficiently reused for the main boss, its heads, and the Chuchu blast projectile, with `SprSubtype` differentiating their roles.
* The reuse of `Mothula_SpawnBeams` for Manhandla is an example of code reuse.
* Hardcoded values for timers, speeds, and offsets could be replaced with named constants for improved readability and maintainability.
* A commented-out `org` for `Sprite_DoTheDeath#PrepareEnemyDrop.post_death_stuff` suggests potential modifications to the death routine.

79
Docs/Sprites/Octoboss.md Normal file
View File

@@ -0,0 +1,79 @@
# Octoboss Sprite Analysis
## Overview
The `octoboss` sprite (ID: `Sprite_Octoboss`, which is `$3C`) is a multi-phase boss, likely an octopus-like creature. It features a unique mechanic involving a "brother" Octoboss, and can summon stalfos offspring. The fight progresses through distinct phases including emergence, movement, taunting, ascending, submerging, and a surrender sequence.
## Key Properties:
* **Sprite ID:** `Sprite_Octoboss` (`$3C`)
* **Description:** A multi-phase boss with a "brother" Octoboss, capable of summoning stalfos and engaging in various movement and attack patterns.
* **Number of Tiles:** 11
* **Health:** `00` (Health is managed by `ReturnTotalHealth` and `CheckForNextPhase`, combining the health of both Octobosses.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its attacks or spawned offspring.)
* **Special Properties:**
* `!Boss = $01` (Correctly identified as a boss.)
* `!Shadow = 01` (Draws a shadow.)
* `!Hitbox = 03`
## Custom Variables:
* `!ConsecutiveHits = $AC`: Tracks consecutive hits on the boss.
* `!KydrogPhase = $7A`: Tracks the current phase of the boss fight. (Note: This variable name is `KydrogPhase`, suggesting shared logic or a copy-paste from the Kydrog boss.)
* `!WalkSpeed = 10`: Defines the boss's walking speed.
* `BrotherSpr = $0EB0`: Stores the sprite index of the "brother" Octoboss.
## Main Logic Flow (`Sprite_Octoboss_Main` and `Sprite_Octoboss_Secondary`):
The Octoboss has two primary main routines, `Sprite_Octoboss_Main` and `Sprite_Octoboss_Secondary`, which are called based on `SprMiscF, X`. This suggests different forms or behaviors for the two Octobosses.
**`Sprite_Octoboss_Main` Jump Table (for the primary Octoboss):**
* **`WaitForPlayerToApproach` (0x00):** Waits for Link to reach a specific Y-coordinate (`$08C8`) to trigger activation.
* **`Emerge` (0x01):** Emerges from the water, preventing Link's movement.
* **`EmergedShowMessage` (0x02):** Displays an introductory message.
* **`SpawnAndAwakeHisBrother` (0x03):** Spawns a "brother" Octoboss (`Sprite_Octoboss` with `SprMiscF = $01`) and stores its ID in `BrotherSpr`.
* **`WaitForBrotherEmerge` (0x04):** Waits for the brother to emerge and displays a message.
* **`SpawnPirateHats` (0x05):** Spawns "boss poof" effects for both Octobosses, changes their frames, and spawns walls using `Overworld_DrawMap16_Persist` macros.
* **`IdlePhase` (0x06):** Idles, can spawn fireballs, and checks total health (`ReturnTotalHealth`) to potentially trigger surrender.
* **`PickDirection` (0x07):** Picks a random direction and speed for movement.
* **`Moving` (0x08):** Moves around, handles boundary checks, spawns splash effects, and checks total health to potentially trigger surrender.
* **`WaitMessageBeforeSurrender` (0x09):** Displays a surrender message (`$004A`), sets the brother's action, and transitions to `RemoveHat`.
* **`RemoveHat` (0x0A):** Removes hats from both Octobosses with "boss poof" effects, displays a message (`$004B`), and transitions to `Submerge`.
* **`Submerge` (0x0B):** Submerges, playing an animation and spawning a splash effect.
* **`SubmergeWaitWall` (0x0C):** Submerges further, drawing walls using `Overworld_DrawMap16_Persist` macros.
* **`EmergeWaitGiveItem` (0x0D):** Emerges, spawns a medallion (`SpawnMedallion`), and sets an SRAM flag.
* **`SubmergeForeverKill` (0x0E):** Submerges completely, despawns, and allows Link to move again.
**`Sprite_Octoboss_Secondary` Jump Table (for the secondary/brother Octoboss, when `SprMiscF, X` is set):**
This routine largely mirrors `Sprite_Octoboss_Main` but includes specific states like `WaitDialog` and `Moving2`, suggesting slight behavioral differences.
## Initialization (`Sprite_Octoboss_Long` and `Sprite_Octoboss_Prep`):
* **`Sprite_Octoboss_Long`:** Main entry point. Handles sprite initialization, including setting OAM properties, bulletproofing, frame, and palette values. It also checks for boss defeat and medallion spawning.
* **`Sprite_Octoboss_Prep`:** Initializes `!KydrogPhase` to `00`, sets initial health (`$A0`), configures deflection, hitbox, bump damage, and calls `JSR KydrogBoss_Set_Damage` to set up the damage table. Sets initial sprite speeds and an intro timer.
## Health Management (`Sprite_Octoboss_CheckIfDead`, `ReturnTotalHealth`, `CheckForNextPhase`):
* **`Sprite_Octoboss_CheckIfDead`:** Monitors `SprHealth, X`. If health is zero or negative, it triggers the boss's death sequence.
* **`ReturnTotalHealth`:** Calculates the combined health of both Octobosses (`SprHealth, X` and `SprHealth, Y` of `BrotherSpr`).
* **`CheckForNextPhase`:** Manages the boss's phases based on health thresholds, similar to the Kydrog boss.
## Offspring Spawning (`RandomStalfosOffspring`, `Sprite_Offspring_Spawn`, `Sprite_Offspring_SpawnHead`):
* These routines are identical to those found in `kydrog_boss.asm`, spawning stalfos offspring.
## Attacks (`Chuchu_SpawnBlast`, `Mothula_SpawnBeams`, `Kydrog_ThrowBoneAtPlayer`):
* **`Chuchu_SpawnBlast`:** Spawns a Chuchu blast projectile.
* **`Mothula_SpawnBeams`:** Spawns beam projectiles.
* **`Kydrog_ThrowBoneAtPlayer`:** Spawns a bone projectile (reused from Kydrog).
## Drawing (`Sprite_Octoboss_Draw`, `Sprite_Octoboss_Draw2`):
* **`Sprite_Octoboss_Draw`:** Draws the primary Octoboss.
* **`Sprite_Octoboss_Draw2`:** Draws the secondary/brother Octoboss.
* Both use standard OAM allocation routines and handle complex animation frames, offsets, character data, properties, and sizes.
## Other Routines:
* **`SpawnSplash`:** Spawns a splash effect.
* **`SpawnBossPoof`:** Spawns a boss poof effect.
* **`HandleMovingSplash`:** Handles splash effects during movement.
* **`SpawnMedallion` / `SpawnMedallionAlt`:** Spawns a medallion.
## Discrepancies/Notes:
* **Shared Variables/Code with Kydrog:** The extensive use of `!KydrogPhase`, `KydrogBoss_Set_Damage`, and `Kydrog_ThrowBoneAtPlayer` suggests significant code reuse or copy-pasting from the Kydrog boss. This could lead to unexpected interactions or make maintenance challenging if changes are made to one boss but not the other. Refactoring shared logic into common functions or macros would be beneficial.
* **`Sprite_Octoboss_Secondary`:** The existence of a separate main routine for the "brother" Octoboss indicates that the two Octobosses might have slightly different behaviors or phases.
## Hardcoded Activation Trigger:
* As noted by the user, the activation trigger for Octoboss is hardcoded. In the `WaitForPlayerToApproach` routine, the boss checks `LDA.b $20 : CMP #$08C8`. `$20` represents Link's Y position, and `$08C8` is a hardcoded Y-coordinate. This means the boss will only activate when Link reaches this specific Y-coordinate, making it difficult to relocate the boss to other overworld maps without modifying this value. This hardcoded dependency needs to be addressed for improved reusability.

80
Docs/Sprites/Twinrova.md Normal file
View File

@@ -0,0 +1,80 @@
# Twinrova Boss Sprite Analysis
## Overview
The `twinrova` sprite (ID: `Sprite_Twinrova`, which is `$CE`) is a complex, multi-phase boss designed to override the vanilla Blind and Blind Maiden sprites. It features a dramatic transformation from Blind Maiden into Twinrova, followed by alternating phases where Twinrova switches between Koume (fire) and Kotake (ice) forms, each possessing distinct attacks and environmental interactions.
## Key Properties:
* **Sprite ID:** `Sprite_Twinrova` (`$CE`)
* **Description:** A multi-phase boss that transforms from Blind Maiden, then alternates between fire (Koume) and ice (Kotake) forms.
* **Number of Tiles:** 6
* **Health:** `00` (Health is managed by `Sprite_Twinrova_CheckIfDead` and phase transitions.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its attacks.)
* **Special Properties:**
* `!Boss = 01` (Correctly identified as a boss.)
* `!Shadow = 01` (Draws a shadow.)
* `!Hitbox = 03`
* `!CollisionLayer = 01` (Checks both layers for collision.)
## Custom Variables/Macros:
* `!AnimSpeed = 8`: Defines the animation speed for various states.
* `Twinrova_Front()`, `Twinrova_Back()`, `Twinrova_Ready()`, `Twinrova_Attack()`, `Show_Koume()`, `Show_Kotake()`, `Twinrova_Hurt()`: Macros for playing specific animations, enhancing code readability.
* `$AC`: A RAM address used to store the current attack type (Fire or Ice).
## Main Logic Flow (`Sprite_Twinrova_Main`):
The boss's behavior is governed by a detailed state machine:
* **`Twinrova_Init` (0x00):** Initial state. Displays an introductory message and transitions to `Twinrova_MoveState`.
* **`Twinrova_MoveState` (0x01):** The core movement and phase management state. It checks `SprHealth, X` to determine if Twinrova is in Phase 1 (single entity) or Phase 2 (alternating forms).
* **Phase 1:** Twinrova moves around, randomly spawning Fire/Ice Keese, or preparing Fire/Ice attacks.
* **Phase 2:** Twinrova alternates between `Twinrova_KoumeMode` (fire) and `Twinrova_KotakeMode` (ice) forms.
* **`Twinrova_MoveForwards` (0x02), `Twinrova_MoveBackwards` (0x03):** Handles movement using `Sprite_FloatTowardPlayer` and `Sprite_CheckTileCollision`.
* **`Twinrova_PrepareAttack` (0x04):** Prepares either a Fire or Ice attack based on the value in `$AC`.
* **`Twinrova_FireAttack` (0x05):** Executes a Fire attack. Restores floor tiles, uses `JSL Sprite_Twinrova_FireAttack` (a shared function for the actual attack), and randomly releases fireballs (`ReleaseFireballs`).
* **`Twinrova_IceAttack` (0x06):** Executes an Ice attack using `JSL Sprite_Twinrova_IceAttack` (a shared function).
* **`Twinrova_Hurt` (0x07):** Manages Twinrova taking damage. Plays a hurt animation and, after a timer, determines whether to dodge or retaliate with a fire or ice attack.
* **`Twinrova_KoumeMode` (0x08):** Koume (fire) form. Spawns pit hazards (`AddPitHazard`), falling tiles (`Ganon_SpawnFallingTilesOverlord`), and fireballs (`Sprite_SpawnFireball`). Uses `RageModeMove` for dynamic movement.
* **`Twinrova_KotakeMode` (0x09):** Kotake (ice) form. Can spawn lightning (`JSL $1DE612`) and uses `RageModeMove` for dynamic movement.
* **`Twinrova_Dead` (0x0A):** Handles Twinrova's death sequence, killing all spawned friends and playing a hurt animation.
## Initialization (`Sprite_Twinrova_Prep`):
* Checks for the presence of the Blind Maiden (`$7EF3CC = $06`). If the Maiden is present, Twinrova is killed, indicating that Twinrova spawns *from* the Blind Maiden.
* Sets initial health to `$5A` (90 decimal).
* Configures deflection (`SprDefl = $80`), bump damage (`SprBump = $04`), and ensures Twinrova is not invincible.
* Configures Blind Boss startup parameters and initializes various timers and `SprMisc` variables.
## Death Check (`Sprite_Twinrova_CheckIfDead`):
* Monitors `SprHealth, X`. If health is zero or negative, it triggers the boss's death sequence, setting `SprState = $04` (kill sprite boss style) and `SprAction = $0A` (Twinrova_Dead stage).
## Movement (`RageModeMove`, `DoRandomStrafe`, `VelocityOffsets`):
* **`RageModeMove`:** A sophisticated routine for dynamic, floaty movement. It randomly determines a movement mode (predictive movement towards player, random strafe, random dodge, stay in place) based on timers and probabilities. It also handles evasive actions.
* **`DoRandomStrafe`:** Generates random strafing movement.
* **`VelocityOffsets`:** A table defining X and Y speed offsets for movement.
## Environmental Interactions (`Twinrova_RestoreFloorTile`, `RestoreFloorTile`, `AddPitHazard`, `Ganon_SpawnFallingTilesOverlord`):
* **`Twinrova_RestoreFloorTile` / `RestoreFloorTile`:** Restores floor tiles, likely after they have been modified by an attack.
* **`AddPitHazard`:** Adds a pit hazard to the floor.
* **`Ganon_SpawnFallingTilesOverlord`:** Spawns falling tiles (reused from Ganon's mechanics).
## Drawing (`Sprite_Twinrova_Draw`):
* Uses standard OAM allocation routines.
* Handles complex animation frames, x/y offsets, character data, properties, and sizes for drawing Twinrova.
* Utilizes 16-bit operations for precise drawing calculations.
## Graphics Transfer (`ApplyTwinrovaGraphics`):
* Handles DMA transfer of graphics data (`twinrova.bin`) to VRAM.
## Attack Spawning (`Fireball_Configure`, `ReleaseFireballs`, `Sprite_SpawnFireKeese`, `Sprite_SpawnIceKeese`, `JSL Sprite_SpawnFireball`, `JSL $1DE612` (Sprite_SpawnLightning)):
* Twinrova can spawn various projectiles and enemies, including fireballs, Fire Keese, Ice Keese, and lightning.
## Blind Maiden Integration:
Twinrova's fight is deeply integrated with the Blind Maiden mechanics:
* **`Follower_BasicMover`:** This routine is hooked to check if the follower is the Blind Maiden, triggering the transformation to Twinrova.
* **`Follower_CheckBlindTrigger`:** Checks if the Blind Maiden follower is within a specific trigger area.
* **`Blind_SpawnFromMaiden`:** This is the core routine for the transformation. It applies Twinrova graphics, sets Twinrova's initial state and position based on the Maiden's, and sets various timers and properties.
* **`SpritePrep_Blind_PrepareBattle`:** This routine is overridden to handle Twinrova's prep or to despawn if a room flag is set.
## Discrepancies/Notes:
* **Health Management:** The `!Health` property is `00`. The boss's health is managed by `Sprite_Twinrova_CheckIfDead` and phase transitions.
* **Code Reuse:** There is extensive code reuse from other sprites/bosses (e.g., `Sprite_Twinrova_FireAttack` is also used by KydreeokHead, `Ganon_SpawnFallingTilesOverlord` in Koume mode, `Sprite_SpawnFireKeese`/`Sprite_SpawnIceKeese` in MoveState). This is an efficient practice but requires careful management to ensure thematic consistency and avoid unintended side effects.
* **Hardcoded Addresses:** Several `JSL` calls are to hardcoded addresses (e.g., `JSL $1DE612` for lightning). These should ideally be replaced with named labels for better maintainability.
* **Blind Maiden Overrides:** The boss heavily relies on overriding vanilla Blind Maiden behavior, which is a common ROM hacking technique but requires careful understanding of the original game's code.
* **`TargetPositions`:** This table is defined but appears unused in the provided code.

View File

@@ -0,0 +1,46 @@
# Vampire Bat Mini-Boss Sprite Analysis
## Overview
The `vampire_bat` sprite is a mini-boss, a specialized enemy that utilizes the generic Keese sprite ID (`$11`) but differentiates its behavior through `SprSubtype = 02`. It features more complex movement patterns and attacks compared to a standard Keese, including ascending, flying around, descending, and spawning other Keese.
## Key Properties:
* **Sprite ID:** `0x11` (Custom Keese Subtype 02)
* **Description:** A mini-boss variant of the Keese, with enhanced movement and attack capabilities.
* **Number of Tiles:** 8 (Inherited from the base Keese sprite.)
* **Health:** `32` (decimal, set in `Sprite_Keese_Prep` based on subtype.)
* **Damage:** `00` (Damage dealt to Link is likely handled by its attacks.)
* **Special Properties:**
* `!Boss = 00` (Not marked as a boss, but functions as a mini-boss/special enemy.)
* `!Shadow = 01` (Draws a shadow.)
## Main Logic Flow (`Sprite_VampireBat_Main`):
The Vampire Bat's behavior is governed by a state machine:
* **`VampireBat_Idle` (0x00):** Waits for Link to approach within a specified distance (`$24`). Transitions to `VampireBat_Ascend`.
* **`VampireBat_Ascend` (0x01):** Plays an ascending animation, increases its `SprHeight` to `$50`, and randomly spawns a Fire Keese (`Sprite_SpawnFireKeese`). Transitions to `VampireBat_FlyAround`.
* **`VampireBat_FlyAround` (0x02):** Plays a flying animation, moves towards Link (`Sprite_ProjectSpeedTowardsPlayer`), and randomly selects new directions (`Sprite_SelectNewDirection`). Transitions to `VampireBat_Descend` after a timer.
* **`VampireBat_Descend` (0x03):** Plays a descending animation, decreases its `SprHeight` until it's on the ground, and randomly uses `Sprite_Twinrova_FireAttack`. Transitions back to `VampireBat_Idle` after a timer.
## Initialization (from `Sprite_Keese_Prep` in `keese.asm`):
The Vampire Bat does not have its own `_Prep` routine and relies on the generic `Sprite_Keese_Prep` routine in `keese.asm`. When `SprSubtype = 02`:
* `SprHealth` is set to `$20` (32 decimal).
* `SprDefl` is set to `$80`.
* `SprTimerC` is set to `$30`.
## Drawing (`Sprite_VampireBat_Draw`):
* This routine is called from `Sprite_Keese_Long` in `keese.asm` when `SprSubtype = 02`.
* Uses standard OAM allocation routines.
* Handles animation frames, x/y offsets, character data, properties, and sizes specific to the Vampire Bat's appearance.
## Attack Spawning (`Sprite_SpawnFireKeese`, `Sprite_SpawnIceKeese`):
* **`Sprite_SpawnFireKeese`:** Spawns a Keese sprite (`$11`) with `SprSubtype = $01` (Fire Keese).
* **`Sprite_SpawnIceKeese`:** Spawns a Keese sprite (`$11`) with `SprSubtype = $00` (Ice Keese).
## Interactions:
* **Damage:** Responds to damage from Link, including flashing and bouncing from tile collisions.
* **Attacks:** Can spawn Fire Keese and utilize `Sprite_Twinrova_FireAttack` (a shared attack function).
## Discrepancies/Notes:
* **Shared Sprite ID:** The Vampire Bat efficiently reuses the generic Keese sprite ID (`$11`), with `SprSubtype = 02` serving as the primary differentiator for its unique behavior.
* **Health Management:** Its health is configured within the generic `Sprite_Keese_Prep` routine based on its subtype.
* **Code Reuse:** It reuses `Sprite_Twinrova_FireAttack`, demonstrating efficient code sharing across different boss/mini-boss sprites.
* **Hardcoded Values:** Many numerical values for timers, speeds, and offsets are hardcoded. Replacing these with named constants would improve readability and maintainability.

62
Docs/Sprites/Wolfos.md Normal file
View File

@@ -0,0 +1,62 @@
# Wolfos Mini-Boss Sprite Analysis
## Overview
The `wolfos` sprite (ID: `Sprite_Wolfos`, which is `$A9`) functions as a mini-boss or special enemy. It engages Link in combat with various movement and attack patterns. A key aspect of this sprite is its integration into a mask quest, where it can be subdued and, under specific conditions, grants Link the Wolf Mask.
## Key Properties:
* **Sprite ID:** `Sprite_Wolfos` (`$A9`)
* **Description:** A mini-boss/special enemy that fights Link and is part of a mask quest.
* **Number of Tiles:** 4
* **Health:** `30` (decimal)
* **Damage:** `00` (Damage dealt to Link is likely handled by its attacks.)
* **Special Properties:**
* `!Boss = 00` (Not marked as a boss, but functions as a mini-boss/special enemy.)
* `!ImperviousArrow = 01` (Impervious to arrows.)
## Custom Variables/Macros:
* `WolfosDialogue = SprMiscD`: Stores a flag to control Wolfos dialogue.
* `Wolfos_AnimateAction = SprMiscE`: Stores the current animation action.
* `AttackForward()`, `AttackBack()`, `WalkRight()`, `WalkLeft()`, `AttackRight()`, `AttackLeft()`, `Subdued()`, `GrantMask()`, `Dismiss()`: Macros for setting `SprAction` and `Wolfos_AnimateAction`, improving code clarity.
* `!NormalSpeed = $08`, `!AttackSpeed = $0F`: Constants for movement speeds.
## Main Logic Flow (`Sprite_Wolfos_Main`):
The Wolfos's behavior is governed by a state machine:
* **`Wolfos_AttackForward` (0x00), `Wolfos_AttackBack` (0x01), `Wolfos_WalkRight` (0x02), `Wolfos_WalkLeft` (0x03), `Wolfos_AttackRight` (0x04), `Wolfos_AttackLeft` (0x05):** These states manage the Wolfos's movement and attacks. They call `Wolfos_Move` and can randomly trigger attack actions with increased speed and temporary imperviousness.
* **`Wolfos_Subdued` (0x06):** In this state, the Wolfos stops moving, displays dialogue (`$23`), and waits for Link to play the Song of Healing (`SongFlag = $01`). If the song is played, it transitions to `Wolfos_GrantMask`.
* **`Wolfos_GrantMask` (0x07):** Displays the Wolfos mask graphic, shows a message (`$10F`), grants Link the `WolfMask` item, and transitions to `Wolfos_Dismiss`.
* **`Wolfos_Dismiss` (0x08):** Stops moving, kills the sprite, and clears Link's `BRANDISH` flag.
## Initialization (`Sprite_Wolfos_Prep`):
* Checks if Link is outdoors (`$1B`). If so, it further checks if the Wolfos has already been defeated (`$7EF303 = $01`). If defeated, the sprite is killed to prevent respawning.
* Sets initial timers (`SprTimerA = $40`, `SprTimerC = $40`).
* Configures deflection properties (`SprDefl = $82`, making it impervious to arrows).
* Sets `SprNbrOAM = $08` and initializes `SprMiscG, X` and `SprMiscE, X` to `0`.
## Defeat Check (`Sprite_Wolfos_CheckIfDefeated`):
* Checks if Link is outdoors. If `SprHealth, X` drops below `$04`, the Wolfos is considered "defeated."
* Upon defeat, it sets `SprAction = $06` (Wolfos_Subdued), `SprState = $09` (normal state, avoiding a full death animation), refills its health to `$40`, and clears `WolfosDialogue`. This indicates pacification rather than outright killing.
## Movement (`Wolfos_Move`, `Wolfos_DecideAction`, `Wolfos_MoveAction_Basic`, `Wolfos_MoveAction_CirclePlayer`, `Wolfos_MoveAction_Dodge`):
* **`Wolfos_Move`:** Handles damage flash, checks damage from player, prevents player from passing through, bounces from tile collision, checks for recoiling, moves the sprite, and calls `Wolfos_DecideAction`.
* **`Wolfos_DecideAction`:** Determines the Wolfos's next movement action based on timers and random chance. It uses a jump table to select between `Wolfos_MoveAction_Basic`, `Wolfos_MoveAction_CirclePlayer`, and `Wolfos_MoveAction_Dodge`.
* **`Wolfos_MoveAction_Basic`:** Basic movement towards or away from Link based on distance.
* **`Wolfos_MoveAction_CirclePlayer`:** Attempts to circle the player.
* **`Wolfos_MoveAction_Dodge`:** Dodges by applying speed towards the player.
## Animation (`Sprite_Wolfos_Animate`):
* This routine is called from `Sprite_Wolfos_Main`.
* It uses `Wolfos_AnimateAction` (stored in `SprMiscE, X`) to determine which animation to play.
* It has separate animation routines for `AttackForward`, `AttackBack`, `WalkRight`, `WalkLeft`, `AttackRight`, `AttackLeft`, and `Subdued`.
* It also spawns sparkle garnishes (`JSL Sprite_SpawnSparkleGarnish`).
## Drawing (`Sprite_Wolfos_Draw`):
* Uses standard OAM allocation routines.
* Handles animation frames, x/y offsets, character data, properties, and sizes for drawing the Wolfos.
* Includes a special frame for the Wolf Mask (`$CC`) when granting the item.
## Discrepancies/Notes:
* **Mask Quest Integration:** The Wolfos is directly integrated into a mask quest, where playing the Song of Healing subdues it and leads to receiving the Wolf Mask.
* **Health Refill on Defeat:** When defeated, its health is refilled to `$40`, and its state is set to `Wolfos_Subdued`, indicating it's not truly killed but rather pacified.
* **Hardcoded Values:** Many numerical values for timers, speeds, and offsets are hardcoded. Replacing these with named constants would improve readability and maintainability.
* **`JSL Link_ReceiveItem`:** This is a standard function for giving items to Link.
* **`JSL Sprite_SpawnSparkleGarnish`:** This is a generic garnish spawning function.