ref: 10211cc461b35140c815e18e95f7070eb0dcc586
parent: 2fe782b11a039b52fd236da28fb2f1ae10cae7db
author: xCrystal <rgr.crystal@gmail.com>
date: Wed Apr 1 13:03:05 EDT 2015
Rename battle files and split move effects Part 5 15.asm, 16.asm, 1a.asm, 1c.asm
--- a/engine/battle/15.asm
+++ /dev/null
@@ -1,372 +1,0 @@
-GainExperience: ; 5524f (15:524f)
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- ret z ; return if link battle
- call DivideExpDataByNumMonsGainingExp
- ld hl, wPartyMon1
- xor a
- ld [wWhichPokemon], a
-.partyMonLoop ; loop over each mon and add gained exp
- inc hl
- ld a, [hli]
- or [hl] ; is mon's HP 0?
- jp z, .nextMon ; if so, go to next mon
- push hl
- ld hl, wPartyGainExpFlags
- ld a, [wWhichPokemon]
- ld c, a
- ld b, $2
- predef FlagActionPredef
- ld a, c
- and a ; is mon's gain exp flag set?
- pop hl
- jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
- ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
- add hl, de
- ld d, h
- ld e, l
- ld hl, wEnemyMonBaseStats
- ld c, $5
-.gainStatExpLoop
- ld a, [hli]
- ld b, a ; enemy mon base stat
- ld a, [de] ; stat exp
- add b ; add enemy mon base state to stat exp
- ld [de], a
- jr nc, .nextBaseStat
-; if there was a carry, increment the upper byte
- dec de
- ld a, [de]
- inc a
- jr z, .maxStatExp ; jump if the value overflowed
- ld [de], a
- inc de
- jr .nextBaseStat
-.maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
- ld a, $ff
- ld [de], a
- inc de
- ld [de], a
-.nextBaseStat
- dec c
- jr z, .asm_552a1
- inc de
- inc de
- jr .gainStatExpLoop
-.asm_552a1
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- ld a, [wEnemyMonBaseExp]
- ld [H_MULTIPLICAND + 2], a
- ld a, [wEnemyMonLevel]
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, 7
- ld [H_DIVISOR], a
- ld b, 4
- call Divide
- ld hl, -((wPartyMon1HPExp + 1) - wPartyMon1OTID + 4 * 2)
- add hl, de
- ld b, [hl] ; party mon OTID
- inc hl
- ld a, [wPlayerID]
- cp b
- jr nz, .tradedMon
- ld b, [hl]
- ld a, [wPlayerID + 1]
- cp b
- ld a, $0
- jr z, .next
-.tradedMon
- call BoostExp ; traded mon exp boost
- ld a, $1
-.next
- ld [wGainBoostedExp], a
- ld a, [W_ISINBATTLE]
- dec a ; is it a trainer battle?
- call nz, BoostExp ; if so, boost exp
- inc hl
- inc hl
- inc hl
-; add the gained exp to the party mon's exp
- ld b, [hl]
- ld a, [H_QUOTIENT + 3]
- ld [wcf4c], a
- add b
- ld [hld], a
- ld b, [hl]
- ld a, [H_QUOTIENT + 2]
- ld [wcf4b], a
- adc b
- ld [hl], a
- jr nc, .noCarry
- dec hl
- inc [hl]
- inc hl
-.noCarry
-; calculate exp for the mon at max level, and cap the exp at that value
- inc hl
- push hl
- ld a, [wWhichPokemon]
- ld c, a
- ld b, 0
- ld hl, wPartySpecies
- add hl, bc
- ld a, [hl] ; species
- ld [wd0b5], a
- call GetMonHeader
- ld d, MAX_LEVEL
- callab CalcExperience ; get max exp
-; compare max exp with current exp
- ld a, [$ff96]
- ld b, a
- ld a, [$ff97]
- ld c, a
- ld a, [$ff98]
- ld d, a
- pop hl
- ld a, [hld]
- sub d
- ld a, [hld]
- sbc c
- ld a, [hl]
- sbc b
- jr c, .next2
-; the mon's exp is greater than the max exp, so overwrite it with the max exp
- ld a, b
- ld [hli], a
- ld a, c
- ld [hli], a
- ld a, d
- ld [hld], a
- dec hl
-.next2
- push hl
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- ld hl, GainedText
- call PrintText
- xor a ; party mon data
- ld [wcc49], a
- call LoadMonData
- pop hl
- ld bc, wPartyMon1Level - wPartyMon1Exp
- add hl, bc
- push hl
- callba CalcLevelFromExperience
- pop hl
- ld a, [hl] ; current level
- cp d
- jp z, .nextMon ; if level didn't change, go to next mon
- ld a, [W_CURENEMYLVL]
- push af
- push hl
- ld a, d
- ld [W_CURENEMYLVL], a
- ld [hl], a
- ld bc, wPartyMon1Species - wPartyMon1Level
- add hl, bc
- ld a, [hl] ; species
- ld [wd0b5], a
- ld [wd11e], a
- call GetMonHeader
- ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
- add hl, bc
- push hl
- ld a, [hld]
- ld c, a
- ld b, [hl]
- push bc ; push max HP (from before levelling up)
- ld d, h
- ld e, l
- ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
- add hl, bc
- ld b, $1 ; consider stat exp when calculating stats
- call CalcStats
- pop bc ; pop max HP (from before levelling up)
- pop hl
- ld a, [hld]
- sub c
- ld c, a
- ld a, [hl]
- sbc b
- ld b, a ; bc = difference between old max HP and new max HP after levelling
- ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
- add hl, de
-; add to the current HP the amount of max HP gained when levelling
- ld a, [hl] ; wPartyMon1HP + 1
- add c
- ld [hld], a
- ld a, [hl] ; wPartyMon1HP + 1
- adc b
- ld [hl], a ; wPartyMon1HP
- ld a, [wPlayerMonNumber]
- ld b, a
- ld a, [wWhichPokemon]
- cp b ; is the current mon in battle?
- jr nz, .printGrewLevelText
-; current mon is in battle
- ld de, wBattleMonHP
-; copy party mon HP to battle mon HP
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hl]
- ld [de], a
-; copy other stats from party mon to battle mon
- ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
- add hl, bc
- push hl
- ld de, wBattleMonLevel
- ld bc, $b ; size of stats
- call CopyData
- pop hl
- ld a, [W_PLAYERBATTSTATUS3]
- bit 3, a ; is the mon transformed?
- jr nz, .recalcStatChanges
-; the mon is not transformed, so update the unmodified stats
- ld de, wPlayerMonUnmodifiedLevel
- ld bc, $b
- call CopyData
-.recalcStatChanges
- xor a
- ld [wd11e], a
- callab CalculateModifiedStats
- callab ApplyBurnAndParalysisPenaltiesToPlayer
- callab ApplyBadgeStatBoosts
- callab DrawPlayerHUDAndHPBar
- callab PrintEmptyString
- call SaveScreenTilesToBuffer1
-.printGrewLevelText
- ld hl, GrewLevelText
- call PrintText
- xor a ; party mon data
- ld [wcc49], a
- call LoadMonData
- ld d, $1
- callab PrintStatsBox
- call WaitForTextScrollButtonPress
- call LoadScreenTilesFromBuffer1
- xor a
- ld [wcc49], a
- ld a, [wd0b5]
- ld [wd11e], a
- predef LearnMoveFromLevelUp
- ld hl, wccd3
- ld a, [wWhichPokemon]
- ld c, a
- ld b, $1
- predef FlagActionPredef
- pop hl
- pop af
- ld [W_CURENEMYLVL], a
-
-.nextMon
- ld a, [wPartyCount]
- ld b, a
- ld a, [wWhichPokemon]
- inc a
- cp b
- jr z, .done
- ld [wWhichPokemon], a
- ld bc, wPartyMon2 - wPartyMon1
- ld hl, wPartyMon1
- call AddNTimes
- jp .partyMonLoop
-.done
- ld hl, wPartyGainExpFlags
- xor a
- ld [hl], a ; clear gain exp flags
- ld a, [wPlayerMonNumber]
- ld c, a
- ld b, $1
- push bc
- predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
- ld hl, wPartyFoughtCurrentEnemyFlags
- xor a
- ld [hl], a
- pop bc
- predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
-
-; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
-DivideExpDataByNumMonsGainingExp: ; 5546c (15:546c)
- ld a, [wPartyGainExpFlags]
- ld b, a
- xor a
- ld c, $8
- ld d, $0
-.countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
- xor a
- srl b
- adc d
- ld d, a
- dec c
- jr nz, .countSetBitsLoop
- cp $2
- ret c ; return if only one mon is gaining exp
- ld [wd11e], a ; store number of mons gaining exp
- ld hl, wEnemyMonBaseStats
- ld c, $7
-.divideLoop
- xor a
- ld [H_DIVIDEND], a
- ld a, [hl]
- ld [H_DIVIDEND + 1], a
- ld a, [wd11e]
- ld [H_DIVISOR], a
- ld b, $2
- call Divide ; divide value by number of mons gaining exp
- ld a, [H_QUOTIENT + 3]
- ld [hli], a
- dec c
- jr nz, .divideLoop
- ret
-
-; multiplies exp by 1.5
-BoostExp: ; 5549f (15:549f)
- ld a, [H_QUOTIENT + 2]
- ld b, a
- ld a, [H_QUOTIENT + 3]
- ld c, a
- srl b
- rr c
- add c
- ld [H_QUOTIENT + 3], a
- ld a, [H_QUOTIENT + 2]
- adc b
- ld [H_QUOTIENT + 2], a
- ret
-
-GainedText: ; 554b2 (15:54b2)
- TX_FAR _GainedText
- db $08 ; asm
- ld a, [wBoostExpByExpAll]
- ld hl, WithExpAllText
- and a
- ret nz
- ld hl, ExpPointsText
- ld a, [wGainBoostedExp]
- and a
- ret z
- ld hl, BoostedText
- ret
-
-WithExpAllText: ; 554cb (15:54cb)
- TX_FAR _WithExpAllText
- db $08 ; asm
- ld hl, ExpPointsText
- ret
-
-BoostedText: ; 554d4 (15:54d4)
- TX_FAR _BoostedText
-
-ExpPointsText: ; 554d8 (15:54d8)
- TX_FAR _ExpPointsText
- db "@"
-
-GrewLevelText: ; 554dd (15:54dd)
- TX_FAR _GrewLevelText
- db $0b
- db "@"
--- a/engine/battle/16.asm
+++ /dev/null
@@ -1,238 +1,0 @@
-PrintBeginningBattleText: ; 58d99 (16:4d99)
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- dec a
- jr nz, .trainerBattle
- ld a, [W_CURMAP] ; W_CURMAP
- cp POKEMONTOWER_3
- jr c, .notPokemonTower
- cp LAVENDER_HOUSE_1
- jr c, .pokemonTower
-.notPokemonTower
- ld a, [wEnemyMonSpecies2]
- call PlayCry
- ld hl, WildMonAppearedText
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
- and a
- jr z, .notFishing
- ld hl, HookedMonAttackedText
-.notFishing
- jr .wildBattle
-.trainerBattle
- call .playSFX
- ld c, $14
- call DelayFrames
- ld hl, TrainerWantsToFightText
-.wildBattle
- push hl
- callab DrawAllPokeballs
- pop hl
- call PrintText
- jr .done
-.pokemonTower
- ld b, SILPH_SCOPE
- call IsItemInBag
- ld a, [wEnemyMonSpecies2]
- ld [wcf91], a
- cp MAROWAK
- jr z, .isMarowak
- ld a, b
- and a
- jr z, .noSilphScope
- callab LoadEnemyMonData
- jr .notPokemonTower
-.noSilphScope
- ld hl, EnemyAppearedText
- call PrintText
- ld hl, GhostCantBeIDdText
- call PrintText
- jr .done
-.isMarowak
- ld a, b
- and a
- jr z, .noSilphScope
- ld hl, EnemyAppearedText
- call PrintText
- ld hl, UnveiledGhostText
- call PrintText
- callab LoadEnemyMonData
- callab MarowakAnim
- ld hl, WildMonAppearedText
- call PrintText
-
-.playSFX
- xor a
- ld [wc0f1], a
- ld a, $80
- ld [wc0f2], a
- ld a, (SFX_08_77 - SFX_Headers_08) / 3
- call PlaySound
- jp WaitForSoundToFinish
-.done
- ret
-
-WildMonAppearedText: ; 58e3b (16:4e3b)
- TX_FAR _WildMonAppearedText
- db "@"
-
-HookedMonAttackedText: ; 58e40 (16:4e40)
- TX_FAR _HookedMonAttackedText
- db "@"
-
-EnemyAppearedText: ; 58e45 (16:4e45)
- TX_FAR _EnemyAppearedText
- db "@"
-
-TrainerWantsToFightText: ; 58e4a (16:4e4a)
- TX_FAR _TrainerWantsToFightText
- db "@"
-
-UnveiledGhostText: ; 58e4f (16:4e4f)
- TX_FAR _UnveiledGhostText
- db "@"
-
-GhostCantBeIDdText: ; 58e54 (16:4e54)
- TX_FAR _GhostCantBeIDdText
- db "@"
-
-PrintSendOutMonMessage: ; 58e59 (16:4e59)
- ld hl, wEnemyMonHP
- ld a, [hli]
- or [hl]
- ld hl, GoText
- jr z, .printText
- xor a
- ld [H_MULTIPLICAND], a
- ld hl, wEnemyMonHP
- ld a, [hli]
- ld [wcce3], a
- ld [H_MULTIPLICAND + 1], a
- ld a, [hl]
- ld [wcce4], a
- ld [H_MULTIPLICAND + 2], a
- ld a, 25
- ld [H_MULTIPLIER], a
- call Multiply
- ld hl, wEnemyMonMaxHP
- ld a, [hli]
- ld b, [hl]
- srl a
- rr b
- srl a
- rr b
- ld a, b
- ld b, $4
- ld [H_DIVISOR], a ; enemy mon max HP divided by 4
- call Divide
- ld a, [H_QUOTIENT + 3] ; a = (enemy mon current HP * 25) / (enemy max HP / 4); this approximates the current percentage of max HP
- ld hl, GoText ; 70% or greater
- cp 70
- jr nc, .printText
- ld hl, DoItText ; 40% - 69%
- cp 40
- jr nc, .printText
- ld hl, GetmText ; 10% - 39%
- cp 10
- jr nc, .printText
- ld hl, EnemysWeakText ; 0% - 9%
-.printText
- jp PrintText
-
-GoText: ; 58eae (16:4eae)
- TX_FAR _GoText
- db $08 ; asm
- jr PrintPlayerMon1Text
-
-DoItText: ; 58eb5 (16:4eb5)
- TX_FAR _DoItText
- db $08 ; asm
- jr PrintPlayerMon1Text
-
-GetmText: ; 58ebc (16:4ebc)
- TX_FAR _GetmText
- db $08 ; asm
- jr PrintPlayerMon1Text
-
-EnemysWeakText: ; 58ec3 (16:4ec3)
- TX_FAR _EnemysWeakText
- db $08 ; asm
-
-PrintPlayerMon1Text:
- ld hl, PlayerMon1Text
- ret
-
-PlayerMon1Text: ; 58ecc (16:4ecc)
- TX_FAR _PlayerMon1Text
- db "@"
-
-RetreatMon: ; 58ed1 (16:4ed1)
- ld hl, PlayerMon2Text
- jp PrintText
-
-PlayerMon2Text: ; 58ed7 (16:4ed7)
- TX_FAR _PlayerMon2Text
- db $08 ; asm
- push de
- push bc
- ld hl, wEnemyMonHP + 1
- ld de, wcce4
- ld b, [hl]
- dec hl
- ld a, [de]
- sub b
- ld [$ff98], a
- dec de
- ld b, [hl]
- ld a, [de]
- sbc b
- ld [$ff97], a
- ld a, $19
- ld [H_POWEROFTEN], a
- call Multiply
- ld hl, wEnemyMonMaxHP
- ld a, [hli]
- ld b, [hl]
- srl a
- rr b
- srl a
- rr b
- ld a, b
- ld b, $4
- ld [H_POWEROFTEN], a
- call Divide
- pop bc
- pop de
- ld a, [$ff98]
- ld hl, EnoughText
- and a
- ret z
- ld hl, ComeBackText
- cp $1e
- ret c
- ld hl, OKExclamationText
- cp $46
- ret c
- ld hl, GoodText
- ret
-
-EnoughText: ; 58f25 (16:4f25)
- TX_FAR _EnoughText
- db $08 ; asm
- jr PrintComeBackText
-
-OKExclamationText: ; 58f2c (16:4f2c)
- TX_FAR _OKExclamationText
- db $08 ; asm
- jr PrintComeBackText
-
-GoodText: ; 58f33 (16:4f33)
- TX_FAR _GoodText
- db $08 ; asm
- jr PrintComeBackText
-
-PrintComeBackText: ; 58f3a (16:4f3a)
- ld hl, ComeBackText
- ret
-
-ComeBackText: ; 58f3e (16:4f3e)
- TX_FAR _ComeBackText
- db "@"
--- a/engine/battle/1a.asm
+++ /dev/null
@@ -1,43 +1,0 @@
-DecrementPP: ; 68000 (1a:4000)
-; after using a move, decrement pp in battle and (if not transformed?) in party
- ld a, [de]
- cp a, STRUGGLE
- ret z ; if the pokemon is using "struggle", there's nothing to do
- ; we don't decrement PP for "struggle"
- ld hl, W_PLAYERBATTSTATUS1
- ld a, [hli] ; load the W_PLAYERBATTSTATUS1 pokemon status flags and increment hl to load the
- ; W_PLAYERBATTSTATUS2 status flags later
- and a, (1 << StoringEnergy) | (1 << ThrashingAbout) | (1 << AttackingMultipleTimes)
- ret nz ; if any of these statuses are true, don't decrement PP
- bit UsingRage, [hl]
- ret nz ; don't decrement PP either if Pokemon is using Rage
- ld hl, wBattleMonPP ; PP of first move (in battle)
-
-; decrement PP in the battle struct
- call .DecrementPP
-
-; decrement PP in the party struct
- ld a, [W_PLAYERBATTSTATUS3]
- bit Transformed, a
- ret nz ; Return if transformed. Pokemon Red stores the "current pokemon's" PP
- ; separately from the "Pokemon in your party's" PP. This is
- ; duplication -- in all cases *other* than Pokemon with Transform.
- ; Normally, this means we have to go on and make the same
- ; modification to the "party's pokemon" PP that we made to the
- ; "current pokemon's" PP. But, if we're dealing with a Transformed
- ; Pokemon, it has separate PP for the move set that it copied from
- ; its opponent, which is *not* the same as its real PP as part of your
- ; party. So we return, and don't do that part.
-
- ld hl, wPartyMon1PP ; PP of first move (in party)
- ld a, [wPlayerMonNumber] ; which mon in party is active
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes ; calculate address of the mon to modify
-.DecrementPP
- ld a, [wPlayerMoveListIndex] ; which move (0, 1, 2, 3) did we use?
- ld c, a
- ld b, 0
- add hl ,bc ; calculate the address in memory of the PP we need to decrement
- ; based on the move chosen.
- dec [hl] ; Decrement PP
- ret
--- a/engine/battle/1c.asm
+++ /dev/null
@@ -1,905 +1,0 @@
-MarowakAnim: ; 708ca (1c:48ca)
-; animate the ghost being unveiled as a Marowak
- ld a, $e4
- ld [rOBP1], a
- call CopyMonPicFromBGToSpriteVRAM ; cover the BG ghost pic with a sprite ghost pic that looks the same
-; now that the ghost pic is being displayed using sprites, clear the ghost pic from the BG tilemap
- hlCoord 12, 0
- ld bc, $707
- call ClearScreenArea
- call Delay3
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; disable BG transfer so we don't see the Marowak too soon
-; replace ghost pic with Marowak in BG
- ld a, MAROWAK
- ld [wHPBarMaxHP], a
- ld a, $1
- ld [H_WHOSETURN], a
- callab Func_79793
- ; alternate between black and light grey 8 times.
- ; this makes the ghost's body appear to flash
- ld d, $80
- call FlashSprite8Times
-.fadeOutGhostLoop
- ld c, 10
- call DelayFrames
- ld a, [rOBP1]
- sla a
- sla a
- ld [rOBP1], a
- jr nz, .fadeOutGhostLoop
- call ClearSprites
- call CopyMonPicFromBGToSpriteVRAM ; copy Marowak pic from BG to sprite VRAM
- ld b, $e4
-.fadeInMarowakLoop
- ld c, 10
- call DelayFrames
- ld a, [rOBP1]
- srl b
- rra
- srl b
- rra
- ld [rOBP1], a
- ld a, b
- and a
- jr nz, .fadeInMarowakLoop
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; enable BG transfer so the BG Marowak pic will be visible after the sprite one is cleared
- call Delay3
- jp ClearSprites
-
-; copies a mon pic's from background VRAM to sprite VRAM and sets up OAM
-CopyMonPicFromBGToSpriteVRAM: ; 7092a (1c:492a)
- ld de, vFrontPic
- ld hl, vSprites
- ld bc, 7 * 7
- call CopyVideoData
- ld a, $10
- ld [W_BASECOORDY], a
- ld a, $70
- ld [W_BASECOORDX], a
- ld hl, wOAMBuffer
- ld bc, $606
- ld d, $8
-.oamLoop
- push bc
- ld a, [W_BASECOORDY]
- ld e, a
-.oamInnerLoop
- ld a, e
- add $8
- ld e, a
- ld [hli], a
- ld a, [W_BASECOORDX]
- ld [hli], a
- ld a, d
- ld [hli], a
- ld a, $10 ; use OBP1
- ld [hli], a
- inc d
- dec c
- jr nz, .oamInnerLoop
- inc d
- ld a, [W_BASECOORDX]
- add $8
- ld [W_BASECOORDX], a
- pop bc
- dec b
- jr nz, .oamLoop
- ret
-
-BattleTransition: ; 7096d (1c:496d)
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- call Delay3
- xor a
- ld [hWY], a
- dec a
- ld [wUpdateSpritesEnabled], a
- call DelayFrame
- ld hl, wSpriteStateData1 + 2
- ld a, [H_DOWNARROWBLINKCNT2]
- ld c, a
- ld b, $0
- ld de, $10
-.loop1
- ld a, [hl]
- cp $ff
- jr z, .skip1
- inc b
-.skip1
- add hl, de
- dec c
- jr nz, .loop1
- ld hl, wOAMBuffer + $10
- ld c, $9
-.loop2
- ld a, b
- swap a
- cp l
- jr z, .skip2
- push hl
- push bc
- ld bc, $10
- xor a
- call FillMemory
- pop bc
- pop hl
-.skip2
- ld de, $10
- add hl, de
- dec c
- jr nz, .loop2
- call Delay3
- call LoadBattleTransitionTile
- ld bc, $0
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- jr z, .linkBattle
- call GetBattleTransitionID_WildOrTrainer
- call GetBattleTransitionID_CompareLevels
- call GetBattleTransitionID_IsDungeonMap
-.linkBattle
- ld hl, BattleTransitions
- add hl, bc
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp [hl]
-
-; the three GetBattleTransitionID functions set the first
-; three bits of c, which determines what transition animation
-; to play at the beginning of a battle
-; bit 0: set if trainer battle
-; bit 1: set if enemy is at least 3 levels higher than player
-; bit 2: set if dungeon map
-BattleTransitions: ; 709d2 (1c:49d2)
- dw BattleTransition_DoubleCircle ; %000
- dw BattleTransition_Spiral ; %001
- dw BattleTransition_Circle ; %010
- dw BattleTransition_Spiral ; %011
- dw BattleTransition_HorizontalStripes ; %100
- dw BattleTransition_Shrink ; %101
- dw BattleTransition_VerticalStripes ; %110
- dw BattleTransition_Split ; %111
-
-GetBattleTransitionID_WildOrTrainer: ; 709e2 (1c:49e2)
- ld a, [W_CUROPPONENT]
- cp $c8
- jr nc, .trainer
- res 0, c
- ret
-.trainer
- set 0, c
- ret
-
-GetBattleTransitionID_CompareLevels: ; 709ef (1c:49ef)
- ld hl, wPartyMon1HP
-.faintedLoop
- ld a, [hli]
- or [hl]
- jr nz, .notFainted
- ld de, wPartyMon2 - (wPartyMon1 + 1)
- add hl, de
- jr .faintedLoop
-.notFainted
- ld de, wPartyMon1Level - (wPartyMon1HP + 1)
- add hl, de
- ld a, [hl]
- add $3
- ld e, a
- ld a, [W_CURENEMYLVL]
- sub e
- jr nc, .highLevelEnemy
- res 1, c
- ld a, $1
- ld [wcd47], a
- ret
-.highLevelEnemy
- set 1, c
- xor a
- ld [wcd47], a
- ret
-
-; fails to recognize VICTORY_ROAD_2, VICTORY_ROAD_3, all ROCKET_HIDEOUT maps,
-; MANSION_1, SEAFOAM_ISLANDS_[2-5], POWER_PLANT, DIGLETTS_CAVE
-; and SILPH_CO_[9-11]F as dungeon maps
-GetBattleTransitionID_IsDungeonMap: ; 70a19 (1c:4a19)
- ld a, [W_CURMAP]
- ld e, a
- ld hl, DungeonMaps1
-.loop1
- ld a, [hli]
- cp $ff
- jr z, .noMatch1
- cp e
- jr nz, .loop1
-.match
- set 2, c
- ret
-.noMatch1
- ld hl, DungeonMaps2
-.loop2
- ld a, [hli]
- cp $ff
- jr z, .noMatch2
- ld d, a
- ld a, [hli]
- cp e
- jr c, .loop2
- ld a, e
- cp d
- jr nc, .match
-.noMatch2
- res 2, c
- ret
-
-; GetBattleTransitionID_IsDungeonMap checks if W_CURMAP
-; is equal to one of these maps
-DungeonMaps1: ; 70a3f (1c:4a3f)
- db VIRIDIAN_FOREST
- db ROCK_TUNNEL_1
- db SEAFOAM_ISLANDS_1
- db ROCK_TUNNEL_2
- db $FF
-
-; GetBattleTransitionID_IsDungeonMap checks if W_CURMAP
-; is in between or equal to each pair of maps
-DungeonMaps2: ; 70a44 (1c:4a44)
- ; all MT_MOON maps
- db MT_MOON_1
- db MT_MOON_3
-
- ; all SS_ANNE maps, VICTORY_ROAD_1, LANCES_ROOM, and HALL_OF_FAME
- db SS_ANNE_1
- db HALL_OF_FAME
-
- ; all POKEMONTOWER maps and Lavender Town buildings
- db LAVENDER_POKECENTER
- db LAVENDER_HOUSE_2
-
- ; SILPH_CO_[2-8]F, MANSION[2-4], SAFARI_ZONE, and UNKNOWN_DUNGEON maps,
- ; except for SILPH_CO_1F
- db SILPH_CO_2F
- db UNKNOWN_DUNGEON_1
- db $FF
-
-LoadBattleTransitionTile: ; 70a4d (1c:4a4d)
- ld hl, vChars1 + $7f0
- ld de, BattleTransitionTile
- ld bc, (BANK(BattleTransitionTile) << 8) + $01
- jp CopyVideoData
-
-BattleTransitionTile: ; 70a59 (1c:4a59)
- INCBIN "gfx/battle_transition.2bpp"
-
-BattleTransition_BlackScreen: ; 70a69 (1c:4a69)
- ld a, $ff
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
- ret
-
-; for non-dungeon trainer battles
-; called regardless of mon levels, but does an
-; outward spiral if enemy is at least 3 levels
-; higher than player and does an inward spiral otherwise
-BattleTransition_Spiral: ; 70a72 (1c:4a72)
- ld a, [wcd47]
- and a
- jr z, .outwardSpiral
- call BattleTransition_InwardSpiral
- jr .done
-.outwardSpiral
- hlCoord 10, 10
- ld a, $3
- ld [wd09f], a
- ld a, l
- ld [wd09b], a
- ld a, h
- ld [wd09a], a
- ld b, $78
-.loop1
- ld c, $3
-.loop2
- push bc
- call BattleTransition_OutwardSpiral_
- pop bc
- dec c
- jr nz, .loop2
- call DelayFrame
- dec b
- jr nz, .loop1
-.done
- call BattleTransition_BlackScreen
- xor a
- ld [wd09b], a
- ld [wd09a], a
- ret
-
-BattleTransition_InwardSpiral: ; 70aaa (1c:4aaa)
- ld a, $7
- ld [wWhichTrade], a
- ld hl, wTileMap
- ld c, $11
- ld de, $14
- call BattleTransition_InwardSpiral_
- inc c
- jr .skip
-.loop
- ld de, $14
- call BattleTransition_InwardSpiral_
-.skip
- inc c
- ld de, $1
- call BattleTransition_InwardSpiral_
- dec c
- dec c
- ld de, $ffec
- call BattleTransition_InwardSpiral_
- inc c
- ld de, rIE
- call BattleTransition_InwardSpiral_
- dec c
- dec c
- ld a, c
- and a
- jr nz, .loop
- ret
-
-BattleTransition_InwardSpiral_: ; 70ae0 (1c:4ae0)
- push bc
-.loop
- ld [hl], $ff
- add hl, de
- push bc
- ld a, [wWhichTrade]
- dec a
- jr nz, .skip
- call BattleTransition_TransferDelay3
- ld a, $7
-.skip
- ld [wWhichTrade], a
- pop bc
- dec c
- jr nz, .loop
- pop bc
- ret
-
-BattleTransition_OutwardSpiral_: ; 70af9 (1c:4af9)
- ld bc, $ffec
- ld de, $14
- ld a, [wd09b]
- ld l, a
- ld a, [wd09a]
- ld h, a
- ld a, [wd09f]
- cp $0
- jr z, .zero
- cp $1
- jr z, .one
- cp $2
- jr z, .two
- cp $3
- jr z, .three
-.done1
- ld [hl], $ff
-.done2_
- ld a, l
- ld [wd09b], a
- ld a, h
- ld [wd09a], a
- ret
-.zero
- dec hl
- ld a, [hl]
- cp $ff
- jr nz, .done2
- inc hl
- add hl, bc
- jr .done1
-.one
- add hl, de
- ld a, [hl]
- cp $ff
- jr nz, .done2
- add hl, bc
- dec hl
- jr .done1
-.two
- inc hl
- ld a, [hl]
- cp $ff
- jr nz, .done2
- dec hl
- add hl, de
- jr .done1
-.three
- add hl, bc
- ld a, [hl]
- cp $ff
- jr nz, .done2
- add hl, de
- inc hl
- jr .done1
-.done2
- ld [hl], $ff
- ld a, [wd09f]
- inc a
- cp $4
- jr nz, .skip
- xor a
-.skip
- ld [wd09f], a
- jr .done2_
-
-FlashScreen:
-BattleTransition_FlashScreen_: ; 70b5d (1c:4b5d)
- ld hl, BattleTransition_FlashScreenPalettes
-.loop
- ld a, [hli]
- cp $1
- jr z, .done
- ld [rBGP], a
- ld c, $2
- call DelayFrames
- jr .loop
-.done
- dec b
- jr nz, BattleTransition_FlashScreen_
- ret
-
-BattleTransition_FlashScreenPalettes: ; 70b72 (1c:4b72)
- db $F9,$FE,$FF,$FE,$F9,$E4,$90,$40,$00,$40,$90,$E4
- db $01 ; terminator
-
-; used for low level trainer dungeon battles
-BattleTransition_Shrink: ; 70b7f (1c:4b7f)
- ld c, $9
-.loop
- push bc
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- hlCoord 0, 7
- deCoord 0, 8
- ld bc, $ffd8
- call BattleTransition_CopyTiles1
- hlCoord 0, 10
- deCoord 0, 9
- ld bc, $28
- call BattleTransition_CopyTiles1
- hlCoord 8, 0
- deCoord 9, 0
- ld bc, $fffe
- call BattleTransition_CopyTiles2
- hlCoord 11, 0
- deCoord 10, 0
- ld bc, $2
- call BattleTransition_CopyTiles2
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- ld c, $6
- call DelayFrames
- pop bc
- dec c
- jr nz, .loop
- call BattleTransition_BlackScreen
- ld c, $a
- jp DelayFrames
-
-; used for high level trainer dungeon battles
-BattleTransition_Split: ; 70bca (1c:4bca)
- ld c, $9
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
-.loop
- push bc
- hlCoord 0, 16
- deCoord 0, 17
- ld bc, $ffd8
- call BattleTransition_CopyTiles1
- hlCoord 0, 1
- ld de, wTileMap
- ld bc, $28
- call BattleTransition_CopyTiles1
- hlCoord 18, 0
- deCoord 19, 0
- ld bc, $fffe
- call BattleTransition_CopyTiles2
- hlCoord 1, 0
- ld de, wTileMap
- ld bc, $2
- call BattleTransition_CopyTiles2
- call BattleTransition_TransferDelay3
- call Delay3
- pop bc
- dec c
- jr nz, .loop
- call BattleTransition_BlackScreen
- ld c, $a
- jp DelayFrames
-
-BattleTransition_CopyTiles1: ; 70c12 (1c:4c12)
- ld a, c
- ld [wWhichTrade], a
- ld a, b
- ld [wTrainerEngageDistance], a
- ld c, $8
-.loop1
- push bc
- push hl
- push de
- ld bc, $14
- call CopyData
- pop hl
- pop de
- ld a, [wWhichTrade]
- ld c, a
- ld a, [wTrainerEngageDistance]
- ld b, a
- add hl, bc
- pop bc
- dec c
- jr nz, .loop1
- ld l, e
- ld h, d
- ld a, $ff
- ld c, $14
-.loop2
- ld [hli], a
- dec c
- jr nz, .loop2
- ret
-
-BattleTransition_CopyTiles2: ; 70c3f (1c:4c3f)
- ld a, c
- ld [wWhichTrade], a
- ld a, b
- ld [wTrainerEngageDistance], a
- ld c, $9
-.loop1
- push bc
- push hl
- push de
- ld c, $12
-.loop2
- ld a, [hl]
- ld [de], a
- ld a, e
- add $14
- jr nc, .noCarry1
- inc d
-.noCarry1
- ld e, a
- ld a, l
- add $14
- jr nc, .noCarry2
- inc h
-.noCarry2
- ld l, a
- dec c
- jr nz, .loop2
- pop hl
- pop de
- ld a, [wWhichTrade]
- ld c, a
- ld a, [wTrainerEngageDistance]
- ld b, a
- add hl, bc
- pop bc
- dec c
- jr nz, .loop1
- ld l, e
- ld h, d
- ld de, $14
- ld c, $12
-.loop3
- ld [hl], $ff
- add hl, de
- dec c
- jr nz, .loop3
- ret
-
-; used for high level wild dungeon battles
-BattleTransition_VerticalStripes: ; 70c7e (1c:4c7e)
- ld c, $12
- ld hl, wTileMap
- deCoord 1, 17
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
-.loop
- push bc
- push hl
- push de
- push de
- call BattleTransition_VerticalStripes_
- pop hl
- call BattleTransition_VerticalStripes_
- call BattleTransition_TransferDelay3
- pop hl
- ld bc, $ffec
- add hl, bc
- ld e, l
- ld d, h
- pop hl
- ld bc, $14
- add hl, bc
- pop bc
- dec c
- jr nz, .loop
- jp BattleTransition_BlackScreen
-
-BattleTransition_VerticalStripes_: ; 70caa (1c:4caa)
- ld c, $a
-.loop
- ld [hl], $ff
- inc hl
- inc hl
- dec c
- jr nz, .loop
- ret
-
-; used for low level wild dungeon battles
-BattleTransition_HorizontalStripes: ; 70cb4 (1c:4cb4)
- ld c, $14
- ld hl, wTileMap
- deCoord 19, 1
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
-.loop
- push bc
- push hl
- push de
- push de
- call BattleTransition_HorizontalStripes_
- pop hl
- call BattleTransition_HorizontalStripes_
- call BattleTransition_TransferDelay3
- pop de
- pop hl
- pop bc
- inc hl
- dec de
- dec c
- jr nz, .loop
- jp BattleTransition_BlackScreen
-
-BattleTransition_HorizontalStripes_: ; 70cd8 (1c:4cd8)
- ld c, $9
- ld de, $28
-.loop
- ld [hl], $ff
- add hl, de
- dec c
- jr nz, .loop
- ret
-
-; used for high level wild non-dungeon battles
-; makes one full circle around the screen
-; by animating each half circle one at a time
-BattleTransition_Circle: ; 70ce4 (1c:4ce4)
- call BattleTransition_FlashScreen
- ld bc, $000a
- ld hl, BattleTransition_HalfCircle1
- call BattleTransition_Circle_Sub1
- ld c, $a
- ld b, $1
- ld hl, BattleTransition_HalfCircle2
- call BattleTransition_Circle_Sub1
- jp BattleTransition_BlackScreen
-
-BattleTransition_FlashScreen: ; 70cfd (1c:4cfd)
- ld b, $3
- call BattleTransition_FlashScreen_
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-BattleTransition_Circle_Sub1: ; 70d06 (1c:4d06)
- push bc
- push hl
- ld a, b
- call BattleTransition_Circle_Sub2
- pop hl
- ld bc, $0005
- add hl, bc
- call BattleTransition_TransferDelay3
- pop bc
- dec c
- jr nz, BattleTransition_Circle_Sub1
- ret
-
-BattleTransition_TransferDelay3: ; 70d19 (1c:4d19)
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- call Delay3
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-; used for low level wild non-dungeon battles
-; makes two half circles around the screen
-; by animating both half circles at the same time
-BattleTransition_DoubleCircle: ; 70d24 (1c:4d24)
- call BattleTransition_FlashScreen
- ld c, $a
- ld hl, BattleTransition_HalfCircle1
- ld de, BattleTransition_HalfCircle2
-.loop
- push bc
- push hl
- push de
- push de
- xor a
- call BattleTransition_Circle_Sub2
- pop hl
- ld a, $1
- call BattleTransition_Circle_Sub2
- pop hl
- ld bc, $5
- add hl, bc
- ld e, l
- ld d, h
- pop hl
- add hl, bc
- call BattleTransition_TransferDelay3
- pop bc
- dec c
- jr nz, .loop
- jp BattleTransition_BlackScreen
-
-BattleTransition_Circle_Sub2: ; 70d50 (1c:4d50)
- ld [wWhichTrade], a
- ld a, [hli]
- ld [wTrainerEngageDistance], a
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp BattleTransition_Circle_Sub3
-
-BattleTransition_HalfCircle1: ; 70d61 (1c:4d61)
- db $01
- dw BattleTransition_CircleData1
- dwCoord 18, 6
-
- db $01
- dw BattleTransition_CircleData2
- dwCoord 19, 3
-
- db $01
- dw BattleTransition_CircleData3
- dwCoord 18, 0
-
- db $01
- dw BattleTransition_CircleData4
- dwCoord 14, 0
-
- db $01
- dw BattleTransition_CircleData5
- dwCoord 10, 0
-
- db $00
- dw BattleTransition_CircleData5
- dwCoord 9, 0
-
- db $00
- dw BattleTransition_CircleData4
- dwCoord 5, 0
-
- db $00
- dw BattleTransition_CircleData3
- dwCoord 1, 0
-
- db $00
- dw BattleTransition_CircleData2
- dwCoord 0, 3
-
- db $00
- dw BattleTransition_CircleData1
- dwCoord 1, 6
-
-BattleTransition_HalfCircle2: ; 70d93 (1c:4d93)
- db $00
- dw BattleTransition_CircleData1
- dwCoord 1, 11
-
- db $00
- dw BattleTransition_CircleData2
- dwCoord 0, 14
-
- db $00
- dw BattleTransition_CircleData3
- dwCoord 1, 17
-
- db $00
- dw BattleTransition_CircleData4
- dwCoord 5, 17
-
- db $00
- dw BattleTransition_CircleData5
- dwCoord 9, 17
-
- db $01
- dw BattleTransition_CircleData5
- dwCoord 10, 17
-
- db $01
- dw BattleTransition_CircleData4
- dwCoord 14, 17
-
- db $01
- dw BattleTransition_CircleData3
- dwCoord 18, 17
-
- db $01
- dw BattleTransition_CircleData2
- dwCoord 19, 14
-
- db $01
- dw BattleTransition_CircleData1
- dwCoord 18, 11
-
-BattleTransition_Circle_Sub3: ; 70dc5 (1c:4dc5)
- push hl
- ld a, [de]
- ld c, a
- inc de
-.loop1
- ld [hl], $ff
- ld a, [wTrainerEngageDistance]
- and a
- jr z, .skip1
- inc hl
- jr .skip2
-.skip1
- dec hl
-.skip2
- dec c
- jr nz, .loop1
- pop hl
- ld a, [wWhichTrade]
- and a
- ld bc, $14
- jr z, .skip3
- ld bc, $ffec
-.skip3
- add hl, bc
- ld a, [de]
- inc de
- cp $ff
- ret z
- and a
- jr z, BattleTransition_Circle_Sub3
- ld c, a
-.loop2
- ld a, [wTrainerEngageDistance]
- and a
- jr z, .skip4
- dec hl
- jr .skip5
-.skip4
- inc hl
-.skip5
- dec c
- jr nz, .loop2
- jr BattleTransition_Circle_Sub3
-
-BattleTransition_CircleData1: ; 70dfe (1c:4dfe)
- db $02,$03,$05,$04,$09,$FF
-
-BattleTransition_CircleData2: ; 70e04 (1c:4e04)
- db $01,$01,$02,$02,$04,$02,$04,$02,$03,$FF
-
-BattleTransition_CircleData3: ; 70e0e (1c:4e0e)
- db $02,$01,$03,$01,$04,$01,$04,$01,$04,$01,$03,$01,$02,$01,$01,$01,$01,$FF
-
-BattleTransition_CircleData4: ; 70e20 (1c:4e20)
- db $04,$01,$04,$00,$03,$01,$03,$00,$02,$01,$02,$00,$01,$FF
-
-BattleTransition_CircleData5: ; 70e2e (1c:4e2e)
- db $04,$00,$03,$00,$03,$00,$02,$00,$02,$00,$01,$00,$01,$00,$01,$FF
--- /dev/null
+++ b/engine/battle/battle_transitions.asm
@@ -1,0 +1,815 @@
+BattleTransition: ; 7096d (1c:496d)
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ xor a
+ ld [hWY], a
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ call DelayFrame
+ ld hl, wSpriteStateData1 + 2
+ ld a, [H_DOWNARROWBLINKCNT2]
+ ld c, a
+ ld b, $0
+ ld de, $10
+.loop1
+ ld a, [hl]
+ cp $ff
+ jr z, .skip1
+ inc b
+.skip1
+ add hl, de
+ dec c
+ jr nz, .loop1
+ ld hl, wOAMBuffer + $10
+ ld c, $9
+.loop2
+ ld a, b
+ swap a
+ cp l
+ jr z, .skip2
+ push hl
+ push bc
+ ld bc, $10
+ xor a
+ call FillMemory
+ pop bc
+ pop hl
+.skip2
+ ld de, $10
+ add hl, de
+ dec c
+ jr nz, .loop2
+ call Delay3
+ call LoadBattleTransitionTile
+ ld bc, $0
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .linkBattle
+ call GetBattleTransitionID_WildOrTrainer
+ call GetBattleTransitionID_CompareLevels
+ call GetBattleTransitionID_IsDungeonMap
+.linkBattle
+ ld hl, BattleTransitions
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp [hl]
+
+; the three GetBattleTransitionID functions set the first
+; three bits of c, which determines what transition animation
+; to play at the beginning of a battle
+; bit 0: set if trainer battle
+; bit 1: set if enemy is at least 3 levels higher than player
+; bit 2: set if dungeon map
+BattleTransitions: ; 709d2 (1c:49d2)
+ dw BattleTransition_DoubleCircle ; %000
+ dw BattleTransition_Spiral ; %001
+ dw BattleTransition_Circle ; %010
+ dw BattleTransition_Spiral ; %011
+ dw BattleTransition_HorizontalStripes ; %100
+ dw BattleTransition_Shrink ; %101
+ dw BattleTransition_VerticalStripes ; %110
+ dw BattleTransition_Split ; %111
+
+GetBattleTransitionID_WildOrTrainer: ; 709e2 (1c:49e2)
+ ld a, [W_CUROPPONENT]
+ cp $c8
+ jr nc, .trainer
+ res 0, c
+ ret
+.trainer
+ set 0, c
+ ret
+
+GetBattleTransitionID_CompareLevels: ; 709ef (1c:49ef)
+ ld hl, wPartyMon1HP
+.faintedLoop
+ ld a, [hli]
+ or [hl]
+ jr nz, .notFainted
+ ld de, wPartyMon2 - (wPartyMon1 + 1)
+ add hl, de
+ jr .faintedLoop
+.notFainted
+ ld de, wPartyMon1Level - (wPartyMon1HP + 1)
+ add hl, de
+ ld a, [hl]
+ add $3
+ ld e, a
+ ld a, [W_CURENEMYLVL]
+ sub e
+ jr nc, .highLevelEnemy
+ res 1, c
+ ld a, $1
+ ld [wcd47], a
+ ret
+.highLevelEnemy
+ set 1, c
+ xor a
+ ld [wcd47], a
+ ret
+
+; fails to recognize VICTORY_ROAD_2, VICTORY_ROAD_3, all ROCKET_HIDEOUT maps,
+; MANSION_1, SEAFOAM_ISLANDS_[2-5], POWER_PLANT, DIGLETTS_CAVE
+; and SILPH_CO_[9-11]F as dungeon maps
+GetBattleTransitionID_IsDungeonMap: ; 70a19 (1c:4a19)
+ ld a, [W_CURMAP]
+ ld e, a
+ ld hl, DungeonMaps1
+.loop1
+ ld a, [hli]
+ cp $ff
+ jr z, .noMatch1
+ cp e
+ jr nz, .loop1
+.match
+ set 2, c
+ ret
+.noMatch1
+ ld hl, DungeonMaps2
+.loop2
+ ld a, [hli]
+ cp $ff
+ jr z, .noMatch2
+ ld d, a
+ ld a, [hli]
+ cp e
+ jr c, .loop2
+ ld a, e
+ cp d
+ jr nc, .match
+.noMatch2
+ res 2, c
+ ret
+
+; GetBattleTransitionID_IsDungeonMap checks if W_CURMAP
+; is equal to one of these maps
+DungeonMaps1: ; 70a3f (1c:4a3f)
+ db VIRIDIAN_FOREST
+ db ROCK_TUNNEL_1
+ db SEAFOAM_ISLANDS_1
+ db ROCK_TUNNEL_2
+ db $FF
+
+; GetBattleTransitionID_IsDungeonMap checks if W_CURMAP
+; is in between or equal to each pair of maps
+DungeonMaps2: ; 70a44 (1c:4a44)
+ ; all MT_MOON maps
+ db MT_MOON_1
+ db MT_MOON_3
+
+ ; all SS_ANNE maps, VICTORY_ROAD_1, LANCES_ROOM, and HALL_OF_FAME
+ db SS_ANNE_1
+ db HALL_OF_FAME
+
+ ; all POKEMONTOWER maps and Lavender Town buildings
+ db LAVENDER_POKECENTER
+ db LAVENDER_HOUSE_2
+
+ ; SILPH_CO_[2-8]F, MANSION[2-4], SAFARI_ZONE, and UNKNOWN_DUNGEON maps,
+ ; except for SILPH_CO_1F
+ db SILPH_CO_2F
+ db UNKNOWN_DUNGEON_1
+ db $FF
+
+LoadBattleTransitionTile: ; 70a4d (1c:4a4d)
+ ld hl, vChars1 + $7f0
+ ld de, BattleTransitionTile
+ ld bc, (BANK(BattleTransitionTile) << 8) + $01
+ jp CopyVideoData
+
+BattleTransitionTile: ; 70a59 (1c:4a59)
+ INCBIN "gfx/battle_transition.2bpp"
+
+BattleTransition_BlackScreen: ; 70a69 (1c:4a69)
+ ld a, $ff
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
+ ret
+
+; for non-dungeon trainer battles
+; called regardless of mon levels, but does an
+; outward spiral if enemy is at least 3 levels
+; higher than player and does an inward spiral otherwise
+BattleTransition_Spiral: ; 70a72 (1c:4a72)
+ ld a, [wcd47]
+ and a
+ jr z, .outwardSpiral
+ call BattleTransition_InwardSpiral
+ jr .done
+.outwardSpiral
+ hlCoord 10, 10
+ ld a, $3
+ ld [wd09f], a
+ ld a, l
+ ld [wd09b], a
+ ld a, h
+ ld [wd09a], a
+ ld b, $78
+.loop1
+ ld c, $3
+.loop2
+ push bc
+ call BattleTransition_OutwardSpiral_
+ pop bc
+ dec c
+ jr nz, .loop2
+ call DelayFrame
+ dec b
+ jr nz, .loop1
+.done
+ call BattleTransition_BlackScreen
+ xor a
+ ld [wd09b], a
+ ld [wd09a], a
+ ret
+
+BattleTransition_InwardSpiral: ; 70aaa (1c:4aaa)
+ ld a, $7
+ ld [wWhichTrade], a
+ ld hl, wTileMap
+ ld c, $11
+ ld de, $14
+ call BattleTransition_InwardSpiral_
+ inc c
+ jr .skip
+.loop
+ ld de, $14
+ call BattleTransition_InwardSpiral_
+.skip
+ inc c
+ ld de, $1
+ call BattleTransition_InwardSpiral_
+ dec c
+ dec c
+ ld de, $ffec
+ call BattleTransition_InwardSpiral_
+ inc c
+ ld de, rIE
+ call BattleTransition_InwardSpiral_
+ dec c
+ dec c
+ ld a, c
+ and a
+ jr nz, .loop
+ ret
+
+BattleTransition_InwardSpiral_: ; 70ae0 (1c:4ae0)
+ push bc
+.loop
+ ld [hl], $ff
+ add hl, de
+ push bc
+ ld a, [wWhichTrade]
+ dec a
+ jr nz, .skip
+ call BattleTransition_TransferDelay3
+ ld a, $7
+.skip
+ ld [wWhichTrade], a
+ pop bc
+ dec c
+ jr nz, .loop
+ pop bc
+ ret
+
+BattleTransition_OutwardSpiral_: ; 70af9 (1c:4af9)
+ ld bc, $ffec
+ ld de, $14
+ ld a, [wd09b]
+ ld l, a
+ ld a, [wd09a]
+ ld h, a
+ ld a, [wd09f]
+ cp $0
+ jr z, .zero
+ cp $1
+ jr z, .one
+ cp $2
+ jr z, .two
+ cp $3
+ jr z, .three
+.done1
+ ld [hl], $ff
+.done2_
+ ld a, l
+ ld [wd09b], a
+ ld a, h
+ ld [wd09a], a
+ ret
+.zero
+ dec hl
+ ld a, [hl]
+ cp $ff
+ jr nz, .done2
+ inc hl
+ add hl, bc
+ jr .done1
+.one
+ add hl, de
+ ld a, [hl]
+ cp $ff
+ jr nz, .done2
+ add hl, bc
+ dec hl
+ jr .done1
+.two
+ inc hl
+ ld a, [hl]
+ cp $ff
+ jr nz, .done2
+ dec hl
+ add hl, de
+ jr .done1
+.three
+ add hl, bc
+ ld a, [hl]
+ cp $ff
+ jr nz, .done2
+ add hl, de
+ inc hl
+ jr .done1
+.done2
+ ld [hl], $ff
+ ld a, [wd09f]
+ inc a
+ cp $4
+ jr nz, .skip
+ xor a
+.skip
+ ld [wd09f], a
+ jr .done2_
+
+FlashScreen:
+BattleTransition_FlashScreen_: ; 70b5d (1c:4b5d)
+ ld hl, BattleTransition_FlashScreenPalettes
+.loop
+ ld a, [hli]
+ cp $1
+ jr z, .done
+ ld [rBGP], a
+ ld c, $2
+ call DelayFrames
+ jr .loop
+.done
+ dec b
+ jr nz, BattleTransition_FlashScreen_
+ ret
+
+BattleTransition_FlashScreenPalettes: ; 70b72 (1c:4b72)
+ db $F9,$FE,$FF,$FE,$F9,$E4,$90,$40,$00,$40,$90,$E4
+ db $01 ; terminator
+
+; used for low level trainer dungeon battles
+BattleTransition_Shrink: ; 70b7f (1c:4b7f)
+ ld c, $9
+.loop
+ push bc
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ hlCoord 0, 7
+ deCoord 0, 8
+ ld bc, $ffd8
+ call BattleTransition_CopyTiles1
+ hlCoord 0, 10
+ deCoord 0, 9
+ ld bc, $28
+ call BattleTransition_CopyTiles1
+ hlCoord 8, 0
+ deCoord 9, 0
+ ld bc, $fffe
+ call BattleTransition_CopyTiles2
+ hlCoord 11, 0
+ deCoord 10, 0
+ ld bc, $2
+ call BattleTransition_CopyTiles2
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld c, $6
+ call DelayFrames
+ pop bc
+ dec c
+ jr nz, .loop
+ call BattleTransition_BlackScreen
+ ld c, $a
+ jp DelayFrames
+
+; used for high level trainer dungeon battles
+BattleTransition_Split: ; 70bca (1c:4bca)
+ ld c, $9
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+.loop
+ push bc
+ hlCoord 0, 16
+ deCoord 0, 17
+ ld bc, $ffd8
+ call BattleTransition_CopyTiles1
+ hlCoord 0, 1
+ ld de, wTileMap
+ ld bc, $28
+ call BattleTransition_CopyTiles1
+ hlCoord 18, 0
+ deCoord 19, 0
+ ld bc, $fffe
+ call BattleTransition_CopyTiles2
+ hlCoord 1, 0
+ ld de, wTileMap
+ ld bc, $2
+ call BattleTransition_CopyTiles2
+ call BattleTransition_TransferDelay3
+ call Delay3
+ pop bc
+ dec c
+ jr nz, .loop
+ call BattleTransition_BlackScreen
+ ld c, $a
+ jp DelayFrames
+
+BattleTransition_CopyTiles1: ; 70c12 (1c:4c12)
+ ld a, c
+ ld [wWhichTrade], a
+ ld a, b
+ ld [wTrainerEngageDistance], a
+ ld c, $8
+.loop1
+ push bc
+ push hl
+ push de
+ ld bc, $14
+ call CopyData
+ pop hl
+ pop de
+ ld a, [wWhichTrade]
+ ld c, a
+ ld a, [wTrainerEngageDistance]
+ ld b, a
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop1
+ ld l, e
+ ld h, d
+ ld a, $ff
+ ld c, $14
+.loop2
+ ld [hli], a
+ dec c
+ jr nz, .loop2
+ ret
+
+BattleTransition_CopyTiles2: ; 70c3f (1c:4c3f)
+ ld a, c
+ ld [wWhichTrade], a
+ ld a, b
+ ld [wTrainerEngageDistance], a
+ ld c, $9
+.loop1
+ push bc
+ push hl
+ push de
+ ld c, $12
+.loop2
+ ld a, [hl]
+ ld [de], a
+ ld a, e
+ add $14
+ jr nc, .noCarry1
+ inc d
+.noCarry1
+ ld e, a
+ ld a, l
+ add $14
+ jr nc, .noCarry2
+ inc h
+.noCarry2
+ ld l, a
+ dec c
+ jr nz, .loop2
+ pop hl
+ pop de
+ ld a, [wWhichTrade]
+ ld c, a
+ ld a, [wTrainerEngageDistance]
+ ld b, a
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop1
+ ld l, e
+ ld h, d
+ ld de, $14
+ ld c, $12
+.loop3
+ ld [hl], $ff
+ add hl, de
+ dec c
+ jr nz, .loop3
+ ret
+
+; used for high level wild dungeon battles
+BattleTransition_VerticalStripes: ; 70c7e (1c:4c7e)
+ ld c, $12
+ ld hl, wTileMap
+ deCoord 1, 17
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+.loop
+ push bc
+ push hl
+ push de
+ push de
+ call BattleTransition_VerticalStripes_
+ pop hl
+ call BattleTransition_VerticalStripes_
+ call BattleTransition_TransferDelay3
+ pop hl
+ ld bc, $ffec
+ add hl, bc
+ ld e, l
+ ld d, h
+ pop hl
+ ld bc, $14
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ jp BattleTransition_BlackScreen
+
+BattleTransition_VerticalStripes_: ; 70caa (1c:4caa)
+ ld c, $a
+.loop
+ ld [hl], $ff
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+
+; used for low level wild dungeon battles
+BattleTransition_HorizontalStripes: ; 70cb4 (1c:4cb4)
+ ld c, $14
+ ld hl, wTileMap
+ deCoord 19, 1
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+.loop
+ push bc
+ push hl
+ push de
+ push de
+ call BattleTransition_HorizontalStripes_
+ pop hl
+ call BattleTransition_HorizontalStripes_
+ call BattleTransition_TransferDelay3
+ pop de
+ pop hl
+ pop bc
+ inc hl
+ dec de
+ dec c
+ jr nz, .loop
+ jp BattleTransition_BlackScreen
+
+BattleTransition_HorizontalStripes_: ; 70cd8 (1c:4cd8)
+ ld c, $9
+ ld de, $28
+.loop
+ ld [hl], $ff
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+; used for high level wild non-dungeon battles
+; makes one full circle around the screen
+; by animating each half circle one at a time
+BattleTransition_Circle: ; 70ce4 (1c:4ce4)
+ call BattleTransition_FlashScreen
+ ld bc, $000a
+ ld hl, BattleTransition_HalfCircle1
+ call BattleTransition_Circle_Sub1
+ ld c, $a
+ ld b, $1
+ ld hl, BattleTransition_HalfCircle2
+ call BattleTransition_Circle_Sub1
+ jp BattleTransition_BlackScreen
+
+BattleTransition_FlashScreen: ; 70cfd (1c:4cfd)
+ ld b, $3
+ call BattleTransition_FlashScreen_
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+BattleTransition_Circle_Sub1: ; 70d06 (1c:4d06)
+ push bc
+ push hl
+ ld a, b
+ call BattleTransition_Circle_Sub2
+ pop hl
+ ld bc, $0005
+ add hl, bc
+ call BattleTransition_TransferDelay3
+ pop bc
+ dec c
+ jr nz, BattleTransition_Circle_Sub1
+ ret
+
+BattleTransition_TransferDelay3: ; 70d19 (1c:4d19)
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+; used for low level wild non-dungeon battles
+; makes two half circles around the screen
+; by animating both half circles at the same time
+BattleTransition_DoubleCircle: ; 70d24 (1c:4d24)
+ call BattleTransition_FlashScreen
+ ld c, $a
+ ld hl, BattleTransition_HalfCircle1
+ ld de, BattleTransition_HalfCircle2
+.loop
+ push bc
+ push hl
+ push de
+ push de
+ xor a
+ call BattleTransition_Circle_Sub2
+ pop hl
+ ld a, $1
+ call BattleTransition_Circle_Sub2
+ pop hl
+ ld bc, $5
+ add hl, bc
+ ld e, l
+ ld d, h
+ pop hl
+ add hl, bc
+ call BattleTransition_TransferDelay3
+ pop bc
+ dec c
+ jr nz, .loop
+ jp BattleTransition_BlackScreen
+
+BattleTransition_Circle_Sub2: ; 70d50 (1c:4d50)
+ ld [wWhichTrade], a
+ ld a, [hli]
+ ld [wTrainerEngageDistance], a
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp BattleTransition_Circle_Sub3
+
+BattleTransition_HalfCircle1: ; 70d61 (1c:4d61)
+ db $01
+ dw BattleTransition_CircleData1
+ dwCoord 18, 6
+
+ db $01
+ dw BattleTransition_CircleData2
+ dwCoord 19, 3
+
+ db $01
+ dw BattleTransition_CircleData3
+ dwCoord 18, 0
+
+ db $01
+ dw BattleTransition_CircleData4
+ dwCoord 14, 0
+
+ db $01
+ dw BattleTransition_CircleData5
+ dwCoord 10, 0
+
+ db $00
+ dw BattleTransition_CircleData5
+ dwCoord 9, 0
+
+ db $00
+ dw BattleTransition_CircleData4
+ dwCoord 5, 0
+
+ db $00
+ dw BattleTransition_CircleData3
+ dwCoord 1, 0
+
+ db $00
+ dw BattleTransition_CircleData2
+ dwCoord 0, 3
+
+ db $00
+ dw BattleTransition_CircleData1
+ dwCoord 1, 6
+
+BattleTransition_HalfCircle2: ; 70d93 (1c:4d93)
+ db $00
+ dw BattleTransition_CircleData1
+ dwCoord 1, 11
+
+ db $00
+ dw BattleTransition_CircleData2
+ dwCoord 0, 14
+
+ db $00
+ dw BattleTransition_CircleData3
+ dwCoord 1, 17
+
+ db $00
+ dw BattleTransition_CircleData4
+ dwCoord 5, 17
+
+ db $00
+ dw BattleTransition_CircleData5
+ dwCoord 9, 17
+
+ db $01
+ dw BattleTransition_CircleData5
+ dwCoord 10, 17
+
+ db $01
+ dw BattleTransition_CircleData4
+ dwCoord 14, 17
+
+ db $01
+ dw BattleTransition_CircleData3
+ dwCoord 18, 17
+
+ db $01
+ dw BattleTransition_CircleData2
+ dwCoord 19, 14
+
+ db $01
+ dw BattleTransition_CircleData1
+ dwCoord 18, 11
+
+BattleTransition_Circle_Sub3: ; 70dc5 (1c:4dc5)
+ push hl
+ ld a, [de]
+ ld c, a
+ inc de
+.loop1
+ ld [hl], $ff
+ ld a, [wTrainerEngageDistance]
+ and a
+ jr z, .skip1
+ inc hl
+ jr .skip2
+.skip1
+ dec hl
+.skip2
+ dec c
+ jr nz, .loop1
+ pop hl
+ ld a, [wWhichTrade]
+ and a
+ ld bc, $14
+ jr z, .skip3
+ ld bc, $ffec
+.skip3
+ add hl, bc
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ and a
+ jr z, BattleTransition_Circle_Sub3
+ ld c, a
+.loop2
+ ld a, [wTrainerEngageDistance]
+ and a
+ jr z, .skip4
+ dec hl
+ jr .skip5
+.skip4
+ inc hl
+.skip5
+ dec c
+ jr nz, .loop2
+ jr BattleTransition_Circle_Sub3
+
+BattleTransition_CircleData1: ; 70dfe (1c:4dfe)
+ db $02,$03,$05,$04,$09,$FF
+
+BattleTransition_CircleData2: ; 70e04 (1c:4e04)
+ db $01,$01,$02,$02,$04,$02,$04,$02,$03,$FF
+
+BattleTransition_CircleData3: ; 70e0e (1c:4e0e)
+ db $02,$01,$03,$01,$04,$01,$04,$01,$04,$01,$03,$01,$02,$01,$01,$01,$01,$FF
+
+BattleTransition_CircleData4: ; 70e20 (1c:4e20)
+ db $04,$01,$04,$00,$03,$01,$03,$00,$02,$01,$02,$00,$01,$FF
+
+BattleTransition_CircleData5: ; 70e2e (1c:4e2e)
+ db $04,$00,$03,$00,$03,$00,$02,$00,$02,$00,$01,$00,$01,$00,$01,$FF
--- /dev/null
+++ b/engine/battle/common_text.asm
@@ -1,0 +1,238 @@
+PrintBeginningBattleText: ; 58d99 (16:4d99)
+ ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ dec a
+ jr nz, .trainerBattle
+ ld a, [W_CURMAP] ; W_CURMAP
+ cp POKEMONTOWER_3
+ jr c, .notPokemonTower
+ cp LAVENDER_HOUSE_1
+ jr c, .pokemonTower
+.notPokemonTower
+ ld a, [wEnemyMonSpecies2]
+ call PlayCry
+ ld hl, WildMonAppearedText
+ ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ and a
+ jr z, .notFishing
+ ld hl, HookedMonAttackedText
+.notFishing
+ jr .wildBattle
+.trainerBattle
+ call .playSFX
+ ld c, $14
+ call DelayFrames
+ ld hl, TrainerWantsToFightText
+.wildBattle
+ push hl
+ callab DrawAllPokeballs
+ pop hl
+ call PrintText
+ jr .done
+.pokemonTower
+ ld b, SILPH_SCOPE
+ call IsItemInBag
+ ld a, [wEnemyMonSpecies2]
+ ld [wcf91], a
+ cp MAROWAK
+ jr z, .isMarowak
+ ld a, b
+ and a
+ jr z, .noSilphScope
+ callab LoadEnemyMonData
+ jr .notPokemonTower
+.noSilphScope
+ ld hl, EnemyAppearedText
+ call PrintText
+ ld hl, GhostCantBeIDdText
+ call PrintText
+ jr .done
+.isMarowak
+ ld a, b
+ and a
+ jr z, .noSilphScope
+ ld hl, EnemyAppearedText
+ call PrintText
+ ld hl, UnveiledGhostText
+ call PrintText
+ callab LoadEnemyMonData
+ callab MarowakAnim
+ ld hl, WildMonAppearedText
+ call PrintText
+
+.playSFX
+ xor a
+ ld [wc0f1], a
+ ld a, $80
+ ld [wc0f2], a
+ ld a, (SFX_08_77 - SFX_Headers_08) / 3
+ call PlaySound
+ jp WaitForSoundToFinish
+.done
+ ret
+
+WildMonAppearedText: ; 58e3b (16:4e3b)
+ TX_FAR _WildMonAppearedText
+ db "@"
+
+HookedMonAttackedText: ; 58e40 (16:4e40)
+ TX_FAR _HookedMonAttackedText
+ db "@"
+
+EnemyAppearedText: ; 58e45 (16:4e45)
+ TX_FAR _EnemyAppearedText
+ db "@"
+
+TrainerWantsToFightText: ; 58e4a (16:4e4a)
+ TX_FAR _TrainerWantsToFightText
+ db "@"
+
+UnveiledGhostText: ; 58e4f (16:4e4f)
+ TX_FAR _UnveiledGhostText
+ db "@"
+
+GhostCantBeIDdText: ; 58e54 (16:4e54)
+ TX_FAR _GhostCantBeIDdText
+ db "@"
+
+PrintSendOutMonMessage: ; 58e59 (16:4e59)
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ ld hl, GoText
+ jr z, .printText
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [wcce3], a
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [wcce4], a
+ ld [H_MULTIPLICAND + 2], a
+ ld a, 25
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, $4
+ ld [H_DIVISOR], a ; enemy mon max HP divided by 4
+ call Divide
+ ld a, [H_QUOTIENT + 3] ; a = (enemy mon current HP * 25) / (enemy max HP / 4); this approximates the current percentage of max HP
+ ld hl, GoText ; 70% or greater
+ cp 70
+ jr nc, .printText
+ ld hl, DoItText ; 40% - 69%
+ cp 40
+ jr nc, .printText
+ ld hl, GetmText ; 10% - 39%
+ cp 10
+ jr nc, .printText
+ ld hl, EnemysWeakText ; 0% - 9%
+.printText
+ jp PrintText
+
+GoText: ; 58eae (16:4eae)
+ TX_FAR _GoText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+DoItText: ; 58eb5 (16:4eb5)
+ TX_FAR _DoItText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+GetmText: ; 58ebc (16:4ebc)
+ TX_FAR _GetmText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+EnemysWeakText: ; 58ec3 (16:4ec3)
+ TX_FAR _EnemysWeakText
+ db $08 ; asm
+
+PrintPlayerMon1Text:
+ ld hl, PlayerMon1Text
+ ret
+
+PlayerMon1Text: ; 58ecc (16:4ecc)
+ TX_FAR _PlayerMon1Text
+ db "@"
+
+RetreatMon: ; 58ed1 (16:4ed1)
+ ld hl, PlayerMon2Text
+ jp PrintText
+
+PlayerMon2Text: ; 58ed7 (16:4ed7)
+ TX_FAR _PlayerMon2Text
+ db $08 ; asm
+ push de
+ push bc
+ ld hl, wEnemyMonHP + 1
+ ld de, wcce4
+ ld b, [hl]
+ dec hl
+ ld a, [de]
+ sub b
+ ld [$ff98], a
+ dec de
+ ld b, [hl]
+ ld a, [de]
+ sbc b
+ ld [$ff97], a
+ ld a, $19
+ ld [H_POWEROFTEN], a
+ call Multiply
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, $4
+ ld [H_POWEROFTEN], a
+ call Divide
+ pop bc
+ pop de
+ ld a, [$ff98]
+ ld hl, EnoughText
+ and a
+ ret z
+ ld hl, ComeBackText
+ cp $1e
+ ret c
+ ld hl, OKExclamationText
+ cp $46
+ ret c
+ ld hl, GoodText
+ ret
+
+EnoughText: ; 58f25 (16:4f25)
+ TX_FAR _EnoughText
+ db $08 ; asm
+ jr PrintComeBackText
+
+OKExclamationText: ; 58f2c (16:4f2c)
+ TX_FAR _OKExclamationText
+ db $08 ; asm
+ jr PrintComeBackText
+
+GoodText: ; 58f33 (16:4f33)
+ TX_FAR _GoodText
+ db $08 ; asm
+ jr PrintComeBackText
+
+PrintComeBackText: ; 58f3a (16:4f3a)
+ ld hl, ComeBackText
+ ret
+
+ComeBackText: ; 58f3e (16:4f3e)
+ TX_FAR _ComeBackText
+ db "@"
--- /dev/null
+++ b/engine/battle/decrement_pp.asm
@@ -1,0 +1,43 @@
+DecrementPP: ; 68000 (1a:4000)
+; after using a move, decrement pp in battle and (if not transformed?) in party
+ ld a, [de]
+ cp a, STRUGGLE
+ ret z ; if the pokemon is using "struggle", there's nothing to do
+ ; we don't decrement PP for "struggle"
+ ld hl, W_PLAYERBATTSTATUS1
+ ld a, [hli] ; load the W_PLAYERBATTSTATUS1 pokemon status flags and increment hl to load the
+ ; W_PLAYERBATTSTATUS2 status flags later
+ and a, (1 << StoringEnergy) | (1 << ThrashingAbout) | (1 << AttackingMultipleTimes)
+ ret nz ; if any of these statuses are true, don't decrement PP
+ bit UsingRage, [hl]
+ ret nz ; don't decrement PP either if Pokemon is using Rage
+ ld hl, wBattleMonPP ; PP of first move (in battle)
+
+; decrement PP in the battle struct
+ call .DecrementPP
+
+; decrement PP in the party struct
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit Transformed, a
+ ret nz ; Return if transformed. Pokemon Red stores the "current pokemon's" PP
+ ; separately from the "Pokemon in your party's" PP. This is
+ ; duplication -- in all cases *other* than Pokemon with Transform.
+ ; Normally, this means we have to go on and make the same
+ ; modification to the "party's pokemon" PP that we made to the
+ ; "current pokemon's" PP. But, if we're dealing with a Transformed
+ ; Pokemon, it has separate PP for the move set that it copied from
+ ; its opponent, which is *not* the same as its real PP as part of your
+ ; party. So we return, and don't do that part.
+
+ ld hl, wPartyMon1PP ; PP of first move (in party)
+ ld a, [wPlayerMonNumber] ; which mon in party is active
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes ; calculate address of the mon to modify
+.DecrementPP
+ ld a, [wPlayerMoveListIndex] ; which move (0, 1, 2, 3) did we use?
+ ld c, a
+ ld b, 0
+ add hl ,bc ; calculate the address in memory of the PP we need to decrement
+ ; based on the move chosen.
+ dec [hl] ; Decrement PP
+ ret
--- /dev/null
+++ b/engine/battle/experience.asm
@@ -1,0 +1,372 @@
+GainExperience: ; 5524f (15:524f)
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ret z ; return if link battle
+ call DivideExpDataByNumMonsGainingExp
+ ld hl, wPartyMon1
+ xor a
+ ld [wWhichPokemon], a
+.partyMonLoop ; loop over each mon and add gained exp
+ inc hl
+ ld a, [hli]
+ or [hl] ; is mon's HP 0?
+ jp z, .nextMon ; if so, go to next mon
+ push hl
+ ld hl, wPartyGainExpFlags
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, $2
+ predef FlagActionPredef
+ ld a, c
+ and a ; is mon's gain exp flag set?
+ pop hl
+ jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
+ ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
+ add hl, de
+ ld d, h
+ ld e, l
+ ld hl, wEnemyMonBaseStats
+ ld c, $5
+.gainStatExpLoop
+ ld a, [hli]
+ ld b, a ; enemy mon base stat
+ ld a, [de] ; stat exp
+ add b ; add enemy mon base state to stat exp
+ ld [de], a
+ jr nc, .nextBaseStat
+; if there was a carry, increment the upper byte
+ dec de
+ ld a, [de]
+ inc a
+ jr z, .maxStatExp ; jump if the value overflowed
+ ld [de], a
+ inc de
+ jr .nextBaseStat
+.maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
+ ld a, $ff
+ ld [de], a
+ inc de
+ ld [de], a
+.nextBaseStat
+ dec c
+ jr z, .asm_552a1
+ inc de
+ inc de
+ jr .gainStatExpLoop
+.asm_552a1
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [wEnemyMonBaseExp]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [wEnemyMonLevel]
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, 7
+ ld [H_DIVISOR], a
+ ld b, 4
+ call Divide
+ ld hl, -((wPartyMon1HPExp + 1) - wPartyMon1OTID + 4 * 2)
+ add hl, de
+ ld b, [hl] ; party mon OTID
+ inc hl
+ ld a, [wPlayerID]
+ cp b
+ jr nz, .tradedMon
+ ld b, [hl]
+ ld a, [wPlayerID + 1]
+ cp b
+ ld a, $0
+ jr z, .next
+.tradedMon
+ call BoostExp ; traded mon exp boost
+ ld a, $1
+.next
+ ld [wGainBoostedExp], a
+ ld a, [W_ISINBATTLE]
+ dec a ; is it a trainer battle?
+ call nz, BoostExp ; if so, boost exp
+ inc hl
+ inc hl
+ inc hl
+; add the gained exp to the party mon's exp
+ ld b, [hl]
+ ld a, [H_QUOTIENT + 3]
+ ld [wcf4c], a
+ add b
+ ld [hld], a
+ ld b, [hl]
+ ld a, [H_QUOTIENT + 2]
+ ld [wcf4b], a
+ adc b
+ ld [hl], a
+ jr nc, .noCarry
+ dec hl
+ inc [hl]
+ inc hl
+.noCarry
+; calculate exp for the mon at max level, and cap the exp at that value
+ inc hl
+ push hl
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, 0
+ ld hl, wPartySpecies
+ add hl, bc
+ ld a, [hl] ; species
+ ld [wd0b5], a
+ call GetMonHeader
+ ld d, MAX_LEVEL
+ callab CalcExperience ; get max exp
+; compare max exp with current exp
+ ld a, [$ff96]
+ ld b, a
+ ld a, [$ff97]
+ ld c, a
+ ld a, [$ff98]
+ ld d, a
+ pop hl
+ ld a, [hld]
+ sub d
+ ld a, [hld]
+ sbc c
+ ld a, [hl]
+ sbc b
+ jr c, .next2
+; the mon's exp is greater than the max exp, so overwrite it with the max exp
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, d
+ ld [hld], a
+ dec hl
+.next2
+ push hl
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ ld hl, GainedText
+ call PrintText
+ xor a ; party mon data
+ ld [wcc49], a
+ call LoadMonData
+ pop hl
+ ld bc, wPartyMon1Level - wPartyMon1Exp
+ add hl, bc
+ push hl
+ callba CalcLevelFromExperience
+ pop hl
+ ld a, [hl] ; current level
+ cp d
+ jp z, .nextMon ; if level didn't change, go to next mon
+ ld a, [W_CURENEMYLVL]
+ push af
+ push hl
+ ld a, d
+ ld [W_CURENEMYLVL], a
+ ld [hl], a
+ ld bc, wPartyMon1Species - wPartyMon1Level
+ add hl, bc
+ ld a, [hl] ; species
+ ld [wd0b5], a
+ ld [wd11e], a
+ call GetMonHeader
+ ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
+ add hl, bc
+ push hl
+ ld a, [hld]
+ ld c, a
+ ld b, [hl]
+ push bc ; push max HP (from before levelling up)
+ ld d, h
+ ld e, l
+ ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
+ add hl, bc
+ ld b, $1 ; consider stat exp when calculating stats
+ call CalcStats
+ pop bc ; pop max HP (from before levelling up)
+ pop hl
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a ; bc = difference between old max HP and new max HP after levelling
+ ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
+ add hl, de
+; add to the current HP the amount of max HP gained when levelling
+ ld a, [hl] ; wPartyMon1HP + 1
+ add c
+ ld [hld], a
+ ld a, [hl] ; wPartyMon1HP + 1
+ adc b
+ ld [hl], a ; wPartyMon1HP
+ ld a, [wPlayerMonNumber]
+ ld b, a
+ ld a, [wWhichPokemon]
+ cp b ; is the current mon in battle?
+ jr nz, .printGrewLevelText
+; current mon is in battle
+ ld de, wBattleMonHP
+; copy party mon HP to battle mon HP
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+; copy other stats from party mon to battle mon
+ ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
+ add hl, bc
+ push hl
+ ld de, wBattleMonLevel
+ ld bc, $b ; size of stats
+ call CopyData
+ pop hl
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 3, a ; is the mon transformed?
+ jr nz, .recalcStatChanges
+; the mon is not transformed, so update the unmodified stats
+ ld de, wPlayerMonUnmodifiedLevel
+ ld bc, $b
+ call CopyData
+.recalcStatChanges
+ xor a
+ ld [wd11e], a
+ callab CalculateModifiedStats
+ callab ApplyBurnAndParalysisPenaltiesToPlayer
+ callab ApplyBadgeStatBoosts
+ callab DrawPlayerHUDAndHPBar
+ callab PrintEmptyString
+ call SaveScreenTilesToBuffer1
+.printGrewLevelText
+ ld hl, GrewLevelText
+ call PrintText
+ xor a ; party mon data
+ ld [wcc49], a
+ call LoadMonData
+ ld d, $1
+ callab PrintStatsBox
+ call WaitForTextScrollButtonPress
+ call LoadScreenTilesFromBuffer1
+ xor a
+ ld [wcc49], a
+ ld a, [wd0b5]
+ ld [wd11e], a
+ predef LearnMoveFromLevelUp
+ ld hl, wccd3
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, $1
+ predef FlagActionPredef
+ pop hl
+ pop af
+ ld [W_CURENEMYLVL], a
+
+.nextMon
+ ld a, [wPartyCount]
+ ld b, a
+ ld a, [wWhichPokemon]
+ inc a
+ cp b
+ jr z, .done
+ ld [wWhichPokemon], a
+ ld bc, wPartyMon2 - wPartyMon1
+ ld hl, wPartyMon1
+ call AddNTimes
+ jp .partyMonLoop
+.done
+ ld hl, wPartyGainExpFlags
+ xor a
+ ld [hl], a ; clear gain exp flags
+ ld a, [wPlayerMonNumber]
+ ld c, a
+ ld b, $1
+ push bc
+ predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ xor a
+ ld [hl], a
+ pop bc
+ predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
+
+; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
+DivideExpDataByNumMonsGainingExp: ; 5546c (15:546c)
+ ld a, [wPartyGainExpFlags]
+ ld b, a
+ xor a
+ ld c, $8
+ ld d, $0
+.countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
+ xor a
+ srl b
+ adc d
+ ld d, a
+ dec c
+ jr nz, .countSetBitsLoop
+ cp $2
+ ret c ; return if only one mon is gaining exp
+ ld [wd11e], a ; store number of mons gaining exp
+ ld hl, wEnemyMonBaseStats
+ ld c, $7
+.divideLoop
+ xor a
+ ld [H_DIVIDEND], a
+ ld a, [hl]
+ ld [H_DIVIDEND + 1], a
+ ld a, [wd11e]
+ ld [H_DIVISOR], a
+ ld b, $2
+ call Divide ; divide value by number of mons gaining exp
+ ld a, [H_QUOTIENT + 3]
+ ld [hli], a
+ dec c
+ jr nz, .divideLoop
+ ret
+
+; multiplies exp by 1.5
+BoostExp: ; 5549f (15:549f)
+ ld a, [H_QUOTIENT + 2]
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ ld c, a
+ srl b
+ rr c
+ add c
+ ld [H_QUOTIENT + 3], a
+ ld a, [H_QUOTIENT + 2]
+ adc b
+ ld [H_QUOTIENT + 2], a
+ ret
+
+GainedText: ; 554b2 (15:54b2)
+ TX_FAR _GainedText
+ db $08 ; asm
+ ld a, [wBoostExpByExpAll]
+ ld hl, WithExpAllText
+ and a
+ ret nz
+ ld hl, ExpPointsText
+ ld a, [wGainBoostedExp]
+ and a
+ ret z
+ ld hl, BoostedText
+ ret
+
+WithExpAllText: ; 554cb (15:54cb)
+ TX_FAR _WithExpAllText
+ db $08 ; asm
+ ld hl, ExpPointsText
+ ret
+
+BoostedText: ; 554d4 (15:54d4)
+ TX_FAR _BoostedText
+
+ExpPointsText: ; 554d8 (15:54d8)
+ TX_FAR _ExpPointsText
+ db "@"
+
+GrewLevelText: ; 554dd (15:54dd)
+ TX_FAR _GrewLevelText
+ db $0b
+ db "@"
--- /dev/null
+++ b/engine/battle/ghost_marowak_anim.asm
@@ -1,0 +1,89 @@
+MarowakAnim: ; 708ca (1c:48ca)
+; animate the ghost being unveiled as a Marowak
+ ld a, $e4
+ ld [rOBP1], a
+ call CopyMonPicFromBGToSpriteVRAM ; cover the BG ghost pic with a sprite ghost pic that looks the same
+; now that the ghost pic is being displayed using sprites, clear the ghost pic from the BG tilemap
+ hlCoord 12, 0
+ ld bc, $707
+ call ClearScreenArea
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; disable BG transfer so we don't see the Marowak too soon
+; replace ghost pic with Marowak in BG
+ ld a, MAROWAK
+ ld [wHPBarMaxHP], a
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab Func_79793
+ ; alternate between black and light grey 8 times.
+ ; this makes the ghost's body appear to flash
+ ld d, $80
+ call FlashSprite8Times
+.fadeOutGhostLoop
+ ld c, 10
+ call DelayFrames
+ ld a, [rOBP1]
+ sla a
+ sla a
+ ld [rOBP1], a
+ jr nz, .fadeOutGhostLoop
+ call ClearSprites
+ call CopyMonPicFromBGToSpriteVRAM ; copy Marowak pic from BG to sprite VRAM
+ ld b, $e4
+.fadeInMarowakLoop
+ ld c, 10
+ call DelayFrames
+ ld a, [rOBP1]
+ srl b
+ rra
+ srl b
+ rra
+ ld [rOBP1], a
+ ld a, b
+ and a
+ jr nz, .fadeInMarowakLoop
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; enable BG transfer so the BG Marowak pic will be visible after the sprite one is cleared
+ call Delay3
+ jp ClearSprites
+
+; copies a mon pic's from background VRAM to sprite VRAM and sets up OAM
+CopyMonPicFromBGToSpriteVRAM: ; 7092a (1c:492a)
+ ld de, vFrontPic
+ ld hl, vSprites
+ ld bc, 7 * 7
+ call CopyVideoData
+ ld a, $10
+ ld [W_BASECOORDY], a
+ ld a, $70
+ ld [W_BASECOORDX], a
+ ld hl, wOAMBuffer
+ ld bc, $606
+ ld d, $8
+.oamLoop
+ push bc
+ ld a, [W_BASECOORDY]
+ ld e, a
+.oamInnerLoop
+ ld a, e
+ add $8
+ ld e, a
+ ld [hli], a
+ ld a, [W_BASECOORDX]
+ ld [hli], a
+ ld a, d
+ ld [hli], a
+ ld a, $10 ; use OBP1
+ ld [hli], a
+ inc d
+ dec c
+ jr nz, .oamInnerLoop
+ inc d
+ ld a, [W_BASECOORDX]
+ add $8
+ ld [W_BASECOORDX], a
+ pop bc
+ dec b
+ jr nz, .oamLoop
+ ret
--- a/main.asm
+++ b/main.asm
@@ -6014,7 +6014,7 @@
FuchsiaHouse3Blocks: INCBIN "maps/fuchsiahouse3.blk"
-INCLUDE "engine/battle/15.asm"
+INCLUDE "engine/battle/experience.asm"
INCLUDE "scripts/route2.asm"
INCLUDE "scripts/route3.asm"
@@ -6094,7 +6094,7 @@
INCBIN "maps/unusedblocks58d7d.blk"
-INCLUDE "engine/battle/16.asm"
+INCLUDE "engine/battle/common_text.asm"
INCLUDE "engine/experience.asm"
@@ -6451,7 +6451,7 @@
SECTION "bank1A",ROMX,BANK[$1A]
-INCLUDE "engine/battle/1a.asm"
+INCLUDE "engine/battle/decrement_pp.asm"
Version_GFX:
IF DEF(_RED)
@@ -6508,7 +6508,8 @@
INCLUDE "engine/hall_of_fame.asm"
INCLUDE "engine/overworld/healing_machine.asm"
INCLUDE "engine/overworld/player_animations.asm"
-INCLUDE "engine/battle/1c.asm"
+INCLUDE "engine/battle/ghost_marowak_anim.asm"
+INCLUDE "engine/battle/battle_transitions.asm"
INCLUDE "engine/town_map.asm"
INCLUDE "engine/mon_party_sprites.asm"
INCLUDE "engine/in_game_trades.asm"