summaryrefslogtreecommitdiff
path: root/home/pokemon.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home/pokemon.asm')
-rw-r--r--home/pokemon.asm464
1 files changed, 464 insertions, 0 deletions
diff --git a/home/pokemon.asm b/home/pokemon.asm
new file mode 100644
index 00000000..141baa65
--- /dev/null
+++ b/home/pokemon.asm
@@ -0,0 +1,464 @@
+DrawHPBar::
+; Draw an HP bar d tiles long, and fill it to e pixels.
+; If c is nonzero, show at least a sliver regardless.
+; The right end of the bar changes with [wHPBarType].
+
+ push hl
+ push de
+ push bc
+
+ ; Left
+ ld a, $71 ; "HP:"
+ ld [hli], a
+ ld a, $62
+ ld [hli], a
+
+ push hl
+
+ ; Middle
+ ld a, $63 ; empty
+.draw
+ ld [hli], a
+ dec d
+ jr nz, .draw
+
+ ; Right
+ ld a, [wHPBarType]
+ dec a
+ ld a, $6d ; status screen and battle
+ jr z, .ok
+ dec a ; pokemon menu
+.ok
+ ld [hl], a
+
+ pop hl
+
+ ld a, e
+ and a
+ jr nz, .fill
+
+ ; If c is nonzero, draw a pixel anyway.
+ ld a, c
+ and a
+ jr z, .done
+ ld e, 1
+
+.fill
+ ld a, e
+ sub 8
+ jr c, .partial
+ ld e, a
+ ld a, $6b ; full
+ ld [hli], a
+ ld a, e
+ and a
+ jr z, .done
+ jr .fill
+
+.partial
+ ; Fill remaining pixels at the end if necessary.
+ ld a, $63 ; empty
+ add e
+ ld [hl], a
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+; loads pokemon data from one of multiple sources to wLoadedMon
+; loads base stats to wMonHeader
+; INPUT:
+; [wWhichPokemon] = index of pokemon within party/box
+; [wMonDataLocation] = source
+; 00: player's party
+; 01: enemy's party
+; 02: current box
+; 03: daycare
+; OUTPUT:
+; [wcf91] = pokemon ID
+; wLoadedMon = base address of pokemon data
+; wMonHeader = base address of base stats
+LoadMonData::
+ jpab LoadMonData_
+
+OverwritewMoves::
+; Write c to [wMoves + b]. Unused.
+ ld hl, wMoves
+ ld e, b
+ ld d, 0
+ add hl, de
+ ld a, c
+ ld [hl], a
+ ret
+
+LoadFlippedFrontSpriteByMonIndex::
+ ld a, 1
+ ld [wSpriteFlipped], a
+
+LoadFrontSpriteByMonIndex::
+ push hl
+ ld a, [wd11e]
+ push af
+ ld a, [wcf91]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld hl, wd11e
+ ld a, [hl]
+ pop bc
+ ld [hl], b
+ and a
+ pop hl
+ jr z, .invalidDexNumber ; dex #0 invalid
+ cp NUM_POKEMON + 1
+ jr c, .validDexNumber ; dex >#151 invalid
+.invalidDexNumber
+ ld a, RHYDON ; $1
+ ld [wcf91], a
+ ret
+.validDexNumber
+ push hl
+ ld de, vFrontPic
+ call LoadMonFrontSprite
+ pop hl
+ ld a, [hLoadedROMBank]
+ push af
+ ld a, BANK(CopyUncompressedPicToHL)
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ xor a
+ ld [hStartTileID], a
+ call CopyUncompressedPicToHL
+ xor a
+ ld [wSpriteFlipped], a
+ pop af
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ ret
+
+
+PlayCry::
+; Play monster a's cry.
+ call GetCryData
+ call PlaySound
+ jp WaitForSoundToFinish
+
+GetCryData::
+; Load cry data for monster a.
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, CryData
+ add hl, bc
+ add hl, bc
+ add hl, bc
+
+ ld a, BANK(CryData)
+ call BankswitchHome
+ ld a, [hli]
+ ld b, a ; cry id
+ ld a, [hli]
+ ld [wFrequencyModifier], a
+ ld a, [hl]
+ ld [wTempoModifier], a
+ call BankswitchBack
+
+ ; Cry headers have 3 channels,
+ ; and start from index CRY_SFX_START,
+ ; so add 3 times the cry id.
+ ld a, b
+ ld c, CRY_SFX_START
+ rlca ; * 2
+ add b
+ add c
+ ret
+
+DisplayPartyMenu::
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ call PartyMenuInit
+ call DrawPartyMenu
+ jp HandlePartyMenuInput
+
+GoBackToPartyMenu::
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ call PartyMenuInit
+ call RedrawPartyMenu
+ jp HandlePartyMenuInput
+
+PartyMenuInit::
+ ld a, 1 ; hardcoded bank
+ call BankswitchHome
+ call LoadHpBarAndStatusTilePatterns
+ ld hl, wd730
+ set 6, [hl] ; turn off letter printing delay
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld hl, wTopMenuItemY
+ inc a
+ ld [hli], a ; top menu item Y
+ xor a
+ ld [hli], a ; top menu item X
+ ld a, [wPartyAndBillsPCSavedMenuItem]
+ push af
+ ld [hli], a ; current menu item ID
+ inc hl
+ ld a, [wPartyCount]
+ and a ; are there more than 0 pokemon in the party?
+ jr z, .storeMaxMenuItemID
+ dec a
+; if party is not empty, the max menu item ID is ([wPartyCount] - 1)
+; otherwise, it is 0
+.storeMaxMenuItemID
+ ld [hli], a ; max menu item ID
+ ld a, [wForcePlayerToChooseMon]
+ and a
+ ld a, A_BUTTON | B_BUTTON
+ jr z, .next
+ xor a
+ ld [wForcePlayerToChooseMon], a
+ inc a ; a = A_BUTTON
+.next
+ ld [hli], a ; menu watched keys
+ pop af
+ ld [hl], a ; old menu item ID
+ ret
+
+HandlePartyMenuInput::
+ ld a, 1
+ ld [wMenuWrappingEnabled], a
+ ld a, $40
+ ld [wPartyMenuAnimMonEnabled], a
+ call HandleMenuInput_
+ call PlaceUnfilledArrowMenuCursor
+ ld b, a
+ xor a
+ ld [wPartyMenuAnimMonEnabled], a
+ ld a, [wCurrentMenuItem]
+ ld [wPartyAndBillsPCSavedMenuItem], a
+ ld hl, wd730
+ res 6, [hl] ; turn on letter printing delay
+ ld a, [wMenuItemToSwap]
+ and a
+ jp nz, .swappingPokemon
+ pop af
+ ld [hTilesetType], a
+ bit 1, b
+ jr nz, .noPokemonChosen
+ ld a, [wPartyCount]
+ and a
+ jr z, .noPokemonChosen
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPokemon], a
+ ld hl, wPartySpecies
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wcf91], a
+ ld [wBattleMonSpecies2], a
+ call BankswitchBack
+ and a
+ ret
+.noPokemonChosen
+ call BankswitchBack
+ scf
+ ret
+.swappingPokemon
+ bit 1, b ; was the B button pressed?
+ jr z, .handleSwap ; if not, handle swapping the pokemon
+.cancelSwap ; if the B button was pressed
+ callba ErasePartyMenuCursors
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ call RedrawPartyMenu
+ jr HandlePartyMenuInput
+.handleSwap
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPokemon], a
+ callba SwitchPartyMon
+ jr HandlePartyMenuInput
+
+DrawPartyMenu::
+ ld hl, DrawPartyMenu_
+ jr DrawPartyMenuCommon
+
+RedrawPartyMenu::
+ ld hl, RedrawPartyMenu_
+
+DrawPartyMenuCommon::
+ ld b, BANK(RedrawPartyMenu_)
+ jp Bankswitch
+
+; prints a pokemon's status condition
+; INPUT:
+; de = address of status condition
+; hl = destination address
+PrintStatusCondition::
+ push de
+ dec de
+ dec de ; de = address of current HP
+ ld a, [de]
+ ld b, a
+ dec de
+ ld a, [de]
+ or b ; is the pokemon's HP zero?
+ pop de
+ jr nz, PrintStatusConditionNotFainted
+; if the pokemon's HP is 0, print "FNT"
+ ld a, "F"
+ ld [hli], a
+ ld a, "N"
+ ld [hli], a
+ ld [hl], "T"
+ and a
+ ret
+
+PrintStatusConditionNotFainted::
+ ld a, [hLoadedROMBank]
+ push af
+ ld a, BANK(PrintStatusAilment)
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ call PrintStatusAilment ; print status condition
+ pop bc
+ ld a, b
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ ret
+
+; function to print pokemon level, leaving off the ":L" if the level is at least 100
+; INPUT:
+; hl = destination address
+; [wLoadedMonLevel] = level
+PrintLevel::
+ ld a, $6e ; ":L" tile ID
+ ld [hli], a
+ ld c, 2 ; number of digits
+ ld a, [wLoadedMonLevel] ; level
+ cp 100
+ jr c, PrintLevelCommon
+; if level at least 100, write over the ":L" tile
+ dec hl
+ inc c ; increment number of digits to 3
+ jr PrintLevelCommon
+
+; prints the level without leaving off ":L" regardless of level
+; INPUT:
+; hl = destination address
+; [wLoadedMonLevel] = level
+PrintLevelFull::
+ ld a, $6e ; ":L" tile ID
+ ld [hli], a
+ ld c, 3 ; number of digits
+ ld a, [wLoadedMonLevel] ; level
+
+PrintLevelCommon::
+ ld [wd11e], a
+ ld de, wd11e
+ ld b, LEFT_ALIGN | 1 ; 1 byte
+ jp PrintNumber
+
+GetwMoves::
+; Unused. Returns the move at index a from wMoves in a
+ ld hl, wMoves
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ret
+
+; copies the base stat data of a pokemon to wMonHeader
+; INPUT:
+; [wd0b5] = pokemon ID
+GetMonHeader::
+ ld a, [hLoadedROMBank]
+ push af
+ ld a, BANK(BaseStats)
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ push bc
+ push de
+ push hl
+ ld a, [wd11e]
+ push af
+ ld a, [wd0b5]
+ ld [wd11e], a
+ ld de, FossilKabutopsPic
+ ld b, $66 ; size of Kabutops fossil and Ghost sprites
+ cp FOSSIL_KABUTOPS ; Kabutops fossil
+ jr z, .specialID
+ ld de, GhostPic
+ cp MON_GHOST ; Ghost
+ jr z, .specialID
+ ld de, FossilAerodactylPic
+ ld b, $77 ; size of Aerodactyl fossil sprite
+ cp FOSSIL_AERODACTYL ; Aerodactyl fossil
+ jr z, .specialID
+ cp MEW
+ jr z, .mew
+ predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
+ ld a, [wd11e]
+ dec a
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ ld hl, BaseStats
+ call AddNTimes
+ ld de, wMonHeader
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ call CopyData
+ jr .done
+.specialID
+ ld hl, wMonHSpriteDim
+ ld [hl], b ; write sprite dimensions
+ inc hl
+ ld [hl], e ; write front sprite pointer
+ inc hl
+ ld [hl], d
+ jr .done
+.mew
+ ld hl, MewBaseStats
+ ld de, wMonHeader
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ ld a, BANK(MewBaseStats)
+ call FarCopyData
+.done
+ ld a, [wd0b5]
+ ld [wMonHIndex], a
+ pop af
+ ld [wd11e], a
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ld [hLoadedROMBank], a
+ ld [MBC1RomBank], a
+ ret
+
+; copy party pokemon's name to wcd6d
+GetPartyMonName2::
+ ld a, [wWhichPokemon] ; index within party
+ ld hl, wPartyMonNicks
+
+; this is called more often
+GetPartyMonName::
+ push hl
+ push bc
+ call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times
+ ld de, wcd6d
+ push de
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop de
+ pop bc
+ pop hl
+ ret