summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xengine/items/items.asm5740
-rwxr-xr-xengine/overworld/map_sprites.asm880
-rw-r--r--home.asm9572
-rw-r--r--home/audio.asm369
-rw-r--r--home/init.asm273
-rw-r--r--home/overworld.asm4518
-rw-r--r--macros.asm1169
-rwxr-xr-xmain.asm13368
-rwxr-xr-xwram.asm4602
-rw-r--r--yellow/bank3c/overworld.asm438
-rw-r--r--yellow/bank3d/random.asm30
-rw-r--r--yellow/bank3f/main.asm22
12 files changed, 20576 insertions, 20405 deletions
diff --git a/engine/items/items.asm b/engine/items/items.asm
index 21e6e924..beb85cde 100755
--- a/engine/items/items.asm
+++ b/engine/items/items.asm
@@ -1,2868 +1,2872 @@
-UseItem_: ; d5c7 (3:55c7)
- ld a,1
- ld [wcd6a],a
- ld a,[wcf91] ;contains item_ID
- cp a,HM_01
- jp nc,ItemUseTMHM
- ld hl,ItemUsePtrTable
- dec a
- add a
- ld c,a
- ld b,0
- add hl,bc
- ld a,[hli]
- ld h,[hl]
- ld l,a
- jp [hl]
-
-ItemUsePtrTable: ; d5e1 (3:55e1)
- dw ItemUseBall ; MASTER_BALL
- dw ItemUseBall ; ULTRA_BALL
- dw ItemUseBall ; GREAT_BALL
- dw ItemUseBall ; POKE_BALL
- dw ItemUseTownMap ; TOWN_MAP
- dw ItemUseBicycle ; BICYCLE
- dw ItemUseSurfboard ; out-of-battle Surf effect
- dw ItemUseBall ; SAFARI_BALL
- dw ItemUsePokedex ; POKEDEX
- dw ItemUseEvoStone ; MOON_STONE
- dw ItemUseMedicine ; ANTIDOTE
- dw ItemUseMedicine ; BURN_HEAL
- dw ItemUseMedicine ; ICE_HEAL
- dw ItemUseMedicine ; AWAKENING
- dw ItemUseMedicine ; PARLYZ_HEAL
- dw ItemUseMedicine ; FULL_RESTORE
- dw ItemUseMedicine ; MAX_POTION
- dw ItemUseMedicine ; HYPER_POTION
- dw ItemUseMedicine ; SUPER_POTION
- dw ItemUseMedicine ; POTION
- dw ItemUseBait ; BOULDERBADGE
- dw ItemUseRock ; CASCADEBADGE
- dw UnusableItem ; THUNDERBADGE
- dw UnusableItem ; RAINBOWBADGE
- dw UnusableItem ; SOULBADGE
- dw UnusableItem ; MARSHBADGE
- dw UnusableItem ; VOLCANOBADGE
- dw UnusableItem ; EARTHBADGE
- dw ItemUseEscapeRope ; ESCAPE_ROPE
- dw ItemUseRepel ; REPEL
- dw UnusableItem ; OLD_AMBER
- dw ItemUseEvoStone ; FIRE_STONE
- dw ItemUseEvoStone ; THUNDER_STONE
- dw ItemUseEvoStone ; WATER_STONE
- dw ItemUseVitamin ; HP_UP
- dw ItemUseVitamin ; PROTEIN
- dw ItemUseVitamin ; IRON
- dw ItemUseVitamin ; CARBOS
- dw ItemUseVitamin ; CALCIUM
- dw ItemUseVitamin ; RARE_CANDY
- dw UnusableItem ; DOME_FOSSIL
- dw UnusableItem ; HELIX_FOSSIL
- dw UnusableItem ; SECRET_KEY
- dw UnusableItem
- dw UnusableItem ; BIKE_VOUCHER
- dw ItemUseXAccuracy ; X_ACCURACY
- dw ItemUseEvoStone ; LEAF_STONE
- dw ItemUseCardKey ; CARD_KEY
- dw UnusableItem ; NUGGET
- dw UnusableItem ; ??? PP_UP
- dw ItemUsePokedoll ; POKE_DOLL
- dw ItemUseMedicine ; FULL_HEAL
- dw ItemUseMedicine ; REVIVE
- dw ItemUseMedicine ; MAX_REVIVE
- dw ItemUseGuardSpec ; GUARD_SPEC_
- dw ItemUseSuperRepel ; SUPER_REPL
- dw ItemUseMaxRepel ; MAX_REPEL
- dw ItemUseDireHit ; DIRE_HIT
- dw UnusableItem ; COIN
- dw ItemUseMedicine ; FRESH_WATER
- dw ItemUseMedicine ; SODA_POP
- dw ItemUseMedicine ; LEMONADE
- dw UnusableItem ; S_S__TICKET
- dw UnusableItem ; GOLD_TEETH
- dw ItemUseXStat ; X_ATTACK
- dw ItemUseXStat ; X_DEFEND
- dw ItemUseXStat ; X_SPEED
- dw ItemUseXStat ; X_SPECIAL
- dw ItemUseCoinCase ; COIN_CASE
- dw ItemUseOaksParcel ; OAKS_PARCEL
- dw ItemUseItemfinder ; ITEMFINDER
- dw UnusableItem ; SILPH_SCOPE
- dw ItemUsePokeflute ; POKE_FLUTE
- dw UnusableItem ; LIFT_KEY
- dw UnusableItem ; EXP__ALL
- dw OldRodCode ; OLD_ROD
- dw GoodRodCode ; GOOD_ROD
- dw SuperRodCode ; SUPER_ROD
- dw ItemUsePPUp ; PP_UP (real one)
- dw ItemUsePPRestore ; ETHER
- dw ItemUsePPRestore ; MAX_ETHER
- dw ItemUsePPRestore ; ELIXER
- dw ItemUsePPRestore ; MAX_ELIXER
-
-ItemUseBall: ; d687 (3:5687)
- ld a,[W_ISINBATTLE]
- and a
- jp z,ItemUseNotTime ; not in battle
- dec a
- jp nz,ThrowBallAtTrainerMon
- ld a,[W_BATTLETYPE]
- dec a
- jr z,.UseBall
- ld a,[wPartyCount] ;is Party full?
- cp a,PARTY_LENGTH
- jr nz,.UseBall
- ld a,[W_NUMINBOX] ;is Box full?
- cp a,MONS_PER_BOX
- jp z,BoxFullCannotThrowBall
-.UseBall ;$56a7
-;ok, you can use a ball
- xor a
- ld [wd11c],a
- ld a,[W_BATTLETYPE]
- cp a,2 ;SafariBattle
- jr nz,.skipSafariZoneCode
-.safariZone
- ; remove a Safari Ball from inventory
- ld hl,W_NUMSAFARIBALLS
- dec [hl]
-.skipSafariZoneCode ;$56b6
- call GoPAL_SET_CF1C
- ld a,$43
- ld [wd11e],a
- call LoadScreenTilesFromBuffer1 ;restore screenBuffer from Backup
- ld hl,ItemUseText00
- call PrintText
- callab IsGhostBattle
- ld b,$10
- jp z,.next12
- ld a,[W_BATTLETYPE]
- dec a
- jr nz,.notOldManBattle
-.oldManBattle
- ld hl,W_GRASSRATE
- ld de,wPlayerName
- ld bc,11
- call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno glitch)
- jp .BallSuccess ;$578b
-.notOldManBattle ;$56e9
- ld a,[W_CURMAP]
- cp a,POKEMONTOWER_6
- jr nz,.loop
- ld a,[wEnemyMonSpecies2]
- cp a,MAROWAK
- ld b,$10
- jp z,.next12
-; if not fighting ghost Marowak, loop until a random number in the current
-; pokeball's allowed range is found
-.loop ;$56fa
- call Random
- ld b,a
- ld hl,wcf91
- ld a,[hl]
- cp a,MASTER_BALL
- jp z,.BallSuccess ;$578b
- cp a,POKE_BALL
- jr z,.checkForAilments
- ld a,200
- cp b
- jr c,.loop ;get only numbers <= 200 for Great Ball
- ld a,[hl]
- cp a,GREAT_BALL
- jr z,.checkForAilments
- ld a,150 ;get only numbers <= 150 for Ultra Ball
- cp b
- jr c,.loop
-.checkForAilments ;$571a
-; pokemon can be caught more easily with any (primary) status ailment
-; Frozen/Asleep pokemon are relatively even easier to catch
-; for Frozen/Asleep pokemon, any random number from 0-24 ensures a catch.
-; for the others, a random number from 0-11 ensures a catch.
- ld a,[wEnemyMonStatus] ;status ailments
- and a
- jr z,.noAilments
- and a, 1 << FRZ | SLP ;is frozen and/or asleep?
- ld c,12
- jr z,.notFrozenOrAsleep
- ld c,25
-.notFrozenOrAsleep ;$5728
- ld a,b
- sub c
- jp c,.BallSuccess ;$578b
- ld b,a
-.noAilments ;$572e
- push bc ;save RANDOM number
- xor a
- ld [H_MULTIPLICAND],a
- ld hl,wEnemyMonMaxHP
- ld a,[hli]
- ld [H_MULTIPLICAND + 1],a
- ld a,[hl]
- ld [H_MULTIPLICAND + 2],a
- ld a,255
- ld [H_MULTIPLIER],a
- call Multiply ; MaxHP * 255
- ld a,[wcf91]
- cp a,GREAT_BALL
- ld a,12 ;any other BallFactor
- jr nz,.next7
- ld a,8
-.next7 ;$574d
- ld [H_DIVISOR],a
- ld b,4 ; number of bytes in dividend
- call Divide
- ld hl,wEnemyMonHP
- ld a,[hli]
- ld b,a
- ld a,[hl]
-
-; explanation: we have a 16-bit value equal to [b << 8 | a].
-; This number is divided by 4. The result is 8 bit (reg. a).
-; Always bigger than zero.
- srl b
- rr a
- srl b
- rr a ; a = current HP / 4
- and a
- jr nz,.next8
- inc a
-.next8 ;$5766
- ld [H_DIVISOR],a
- ld b,4
- call Divide ; ((MaxHP * 255) / BallFactor) / (CurHP / 4)
- ld a,[H_QUOTIENT + 2]
- and a
- jr z,.next9
- ld a,255
- ld [H_QUOTIENT + 3],a
-.next9 ;$5776
- pop bc
- ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
- cp b
- jr c,.next10
- ld a,[H_QUOTIENT + 2]
- and a
- jr nz,.BallSuccess ; if ((MaxHP * 255) / BallFactor) / (CurHP / 4) > 0x255, automatic success
- call Random
- ld b,a
- ld a,[H_QUOTIENT + 3]
- cp b
- jr c,.next10
-.BallSuccess ;$578b
- jr .BallSuccess2
-.next10 ;$578d
- ld a,[H_QUOTIENT + 3]
- ld [wd11e],a
- xor a
- ld [H_MULTIPLICAND],a
- ld [H_MULTIPLICAND + 1],a
- ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
- ld [H_MULTIPLICAND + 2],a
- ld a,100
- ld [H_MULTIPLIER],a
- call Multiply ; CatchRate * 100
- ld a,[wcf91]
- ld b,255
- cp a,POKE_BALL
- jr z,.next11
- ld b,200
- cp a,GREAT_BALL
- jr z,.next11
- ld b,150
- cp a,ULTRA_BALL
- jr z,.next11
-.next11 ;$57b8
- ld a,b
- ld [H_DIVISOR],a
- ld b,4
- call Divide
- ld a,[H_QUOTIENT + 2]
- and a
- ld b,$63
- jr nz,.next12
- ld a,[wd11e]
- ld [H_MULTIPLIER],a
- call Multiply
- ld a,255
- ld [H_DIVISOR],a
- ld b,4
- call Divide
- ld a,[wEnemyMonStatus] ;status ailments
- and a
- jr z,.next13
- and a, 1 << FRZ | SLP
- ld b,5
- jr z,.next14
- ld b,10
-.next14 ;$57e6
- ld a,[H_QUOTIENT + 3]
- add b
- ld [H_QUOTIENT + 3],a
-.next13 ;$57eb
- ld a,[H_QUOTIENT + 3]
- cp a,10
- ld b,$20
- jr c,.next12
- cp a,30
- ld b,$61
- jr c,.next12
- cp a,70
- ld b,$62
- jr c,.next12
- ld b,$63
-.next12 ;$5801
- ld a,b
- ld [wd11e],a
-.BallSuccess2 ;$5805
- ld c,20
- call DelayFrames
- ld a,TOSS_ANIM
- ld [W_ANIMATIONID],a
- xor a
- ld [$fff3],a
- ld [wAnimationType],a
- ld [wDamageMultipliers],a
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- push af
- predef MoveAnimation
- pop af
- ld [wcf91],a
- pop af
- ld [wWhichPokemon],a
- ld a,[wd11e]
- cp a,$10
- ld hl,ItemUseBallText00
- jp z,.printText0
- cp a,$20
- ld hl,ItemUseBallText01
- jp z,.printText0
- cp a,$61
- ld hl,ItemUseBallText02
- jp z,.printText0
- cp a,$62
- ld hl,ItemUseBallText03
- jp z,.printText0
- cp a,$63
- ld hl,ItemUseBallText04
- jp z,.printText0
- ld hl,wEnemyMonHP ;current HP
- ld a,[hli]
- push af
- ld a,[hli]
- push af ;backup currentHP...
- inc hl
- ld a,[hl]
- push af ;...and status ailments
- push hl
- ld hl,W_ENEMYBATTSTATUS3
- bit Transformed,[hl]
- jr z,.next15
- ld a,$4c
- ld [wEnemyMonSpecies2],a
- jr .next16
-.next15 ;$5871
- set Transformed,[hl]
- ld hl,wcceb
- ld a,[wEnemyMonDVs]
- ld [hli],a
- ld a,[wEnemyMonDVs + 1]
- ld [hl],a
-.next16 ;$587e
- ld a,[wcf91]
- push af
- ld a,[wEnemyMonSpecies2]
- ld [wcf91],a
- ld a,[wEnemyMonLevel]
- ld [W_CURENEMYLVL],a
- callab LoadEnemyMonData
- pop af
- ld [wcf91],a
- pop hl
- pop af
- ld [hld],a
- dec hl
- pop af
- ld [hld],a
- pop af
- ld [hl],a
- ld a,[wEnemyMonSpecies] ;enemy
- ld [wd11c],a
- ld [wcf91],a
- ld [wd11e],a
- ld a,[W_BATTLETYPE]
- dec a
- jr z,.printText1
- ld hl,ItemUseBallText05
- call PrintText
- predef IndexToPokedex
- ld a,[wd11e]
- dec a
- ld c,a
- ld b,2
- ld hl,wPokedexOwned ;Dex_own_flags (pokemon)
- predef FlagActionPredef
- ld a,c
- push af
- ld a,[wd11e]
- dec a
- ld c,a
- ld b,1
- predef FlagActionPredef
- pop af
- and a
- jr nz,.checkParty
- ld hl,ItemUseBallText06
- call PrintText
- call ClearSprites
- ld a,[wEnemyMonSpecies] ;caught mon_ID
- ld [wd11e],a
- predef ShowPokedexData
-.checkParty ;$58f4
- ld a,[wPartyCount]
- cp a,PARTY_LENGTH ;is party full?
- jr z,.sendToBox
- xor a
- ld [wcc49],a
- call ClearSprites
- call AddPartyMon ;add mon to Party
- jr .End
-.sendToBox ;$5907
- call ClearSprites
- call SendNewMonToBox
- ld hl,ItemUseBallText07
- ld a,[wd7f1]
- bit 0,a ;already met Bill?
- jr nz,.sendToBox2
- ld hl,ItemUseBallText08
-.sendToBox2 ;$591a
- call PrintText
- jr .End
-.printText1 ;$591f
- ld hl,ItemUseBallText05
-.printText0 ;$5922
- call PrintText
- call ClearSprites
-.End ;$5928
- ld a,[W_BATTLETYPE]
- and a
- ret nz
- ld hl,wNumBagItems
- inc a
- ld [wcf96],a
- jp RemoveItemFromInventory ;remove ITEM (XXX)
-ItemUseBallText00: ; d937 (3:5937)
-;"It dodged the thrown ball!"
-;"This pokemon can't be caught"
- TX_FAR _ItemUseBallText00
- db "@"
-ItemUseBallText01: ; d93c (3:593c)
-;"You missed the pokemon!"
- TX_FAR _ItemUseBallText01
- db "@"
-ItemUseBallText02: ; d941 (3:5941)
-;"Darn! The pokemon broke free!"
- TX_FAR _ItemUseBallText02
- db "@"
-ItemUseBallText03: ; d946 (3:5946)
-;"Aww! It appeared to be caught!"
- TX_FAR _ItemUseBallText03
- db "@"
-ItemUseBallText04: ; d94b (3:594b)
-;"Shoot! It was so close too!"
- TX_FAR _ItemUseBallText04
- db "@"
-ItemUseBallText05: ; d950 (3:5950)
-;"All right! {MonName} was caught!"
-;play sound
- TX_FAR _ItemUseBallText05
- db $12,$06
- db "@"
-ItemUseBallText07: ; d957 (3:5957)
-;"X was transferred to Bill's PC"
- TX_FAR _ItemUseBallText07
- db "@"
-ItemUseBallText08: ; d95c (3:595c)
-;"X was transferred to someone's PC"
- TX_FAR _ItemUseBallText08
- db "@"
-
-ItemUseBallText06: ; d961 (3:5961)
-;"New DEX data will be added..."
-;play sound
- TX_FAR _ItemUseBallText06
- db $13,$06
- db "@"
-
-ItemUseTownMap: ; d968 (3:5968)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld b, BANK(DisplayTownMap)
- ld hl, DisplayTownMap
- jp Bankswitch ; display Town Map
-
-ItemUseBicycle: ; d977 (3:5977)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld a,[wWalkBikeSurfState]
- ld [wWalkBikeSurfStateCopy],a
- cp a,2 ; is the player surfing?
- jp z,ItemUseNotTime
- dec a ; is player already bicycling?
- jr nz,.tryToGetOnBike
-.getOffBike
- call ItemUseReloadOverworldData
- xor a
- ld [wWalkBikeSurfState],a ; change player state to walking
- call PlayDefaultMusic ; play walking music
- ld hl,GotOffBicycleText
- jr .printText
-.tryToGetOnBike
- call IsBikeRidingAllowed
- jp nc,NoCyclingAllowedHere
- call ItemUseReloadOverworldData
- xor a ; no keys pressed
- ld [hJoyHeld],a ; current joypad state
- inc a
- ld [wWalkBikeSurfState],a ; change player state to bicycling
- ld hl,GotOnBicycleText
- call PlayDefaultMusic ; play bike riding music
-.printText
- jp PrintText
-
-; used for Surf out-of-battle effect
-ItemUseSurfboard: ; d9b4 (3:59b4)
- ld a,[wWalkBikeSurfState]
- ld [wWalkBikeSurfStateCopy],a
- cp a,2 ; is the player already surfing?
- jr z,.tryToStopSurfing
-.tryToSurf
- call IsNextTileShoreOrWater
- jp c,SurfingAttemptFailed
- ld hl,TilePairCollisionsWater
- call CheckForTilePairCollisions
- jp c,SurfingAttemptFailed
-.surf
- call .makePlayerMoveForward
- ld hl,wd730
- set 7,[hl]
- ld a,2
- ld [wWalkBikeSurfState],a ; change player state to surfing
- call PlayDefaultMusic ; play surfing music
- ld hl,SurfingGotOnText
- jp PrintText
-.tryToStopSurfing
- xor a
- ld [$ff8c],a
- ld d,16 ; talking range in pixels (normal range)
- call IsSpriteInFrontOfPlayer2
- res 7,[hl]
- ld a,[$ff8c]
- and a ; is there a sprite in the way?
- jr nz,.cannotStopSurfing
- ld hl,TilePairCollisionsWater
- call CheckForTilePairCollisions
- jr c,.cannotStopSurfing
- ld hl,W_TILESETCOLLISIONPTR ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl now points to passable tiles
- ld a,[wTileInFrontOfPlayer] ; tile in front of the player
- ld b,a
-.passableTileLoop
- ld a,[hli]
- cp b
- jr z,.stopSurfing
- cp a,$ff
- jr nz,.passableTileLoop
-.cannotStopSurfing
- ld hl,SurfingNoPlaceToGetOffText
- jp PrintText
-.stopSurfing
- call .makePlayerMoveForward
- ld hl,wd730
- set 7,[hl]
- xor a
- ld [wWalkBikeSurfState],a ; change player state to walking
- dec a
- ld [wJoyIgnore],a
- call PlayDefaultMusic ; play walking music
- jp LoadWalkingPlayerSpriteGraphics
-; uses a simulated button press to make the player move forward
-.makePlayerMoveForward
- ld a,[wd52a] ; direction the player is going
- bit 3,a
- ld b,D_UP
- jr nz,.storeSimulatedButtonPress
- bit 2,a
- ld b,D_DOWN
- jr nz,.storeSimulatedButtonPress
- bit 1,a
- ld b,D_LEFT
- jr nz,.storeSimulatedButtonPress
- ld b,D_RIGHT
-.storeSimulatedButtonPress
- ld a,b
- ld [wSimulatedJoypadStatesEnd],a
- xor a
- ld [wWastedByteCD39],a
- inc a
- ld [wSimulatedJoypadStatesIndex],a
- ret
-
-SurfingGotOnText: ; da4c (3:5a4c)
- TX_FAR _SurfingGotOnText
- db "@"
-
-SurfingNoPlaceToGetOffText: ; da51 (3:5a51)
- TX_FAR _SurfingNoPlaceToGetOffText
- db "@"
-
-ItemUsePokedex: ; da56 (3:5a56)
- predef_jump ShowPokedexMenu
-
-ItemUseEvoStone: ; da5b (3:5a5b)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- ld [wd156],a
- push af
- ld a,$05 ; evolution stone party menu
- ld [wd07d],a
- ld a,$ff
- ld [wUpdateSpritesEnabled],a
- call DisplayPartyMenu
- pop bc
- jr c,.canceledItemUse
- ld a,b
- ld [wcf91],a
- ld a,$01
- ld [wccd4],a
- ld a,(SFX_02_3e - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- call WaitForSoundToFinish ; wait for sound to end
- callab TryEvolvingMon ; try to evolve pokemon
- ld a,[wd121]
- and a
- jr z,.noEffect
- pop af
- ld [wWhichPokemon],a
- ld hl,wNumBagItems
- ld a,1 ; remove 1 stone
- ld [wcf96],a
- jp RemoveItemFromInventory
-.noEffect
- call ItemUseNoEffect
-.canceledItemUse
- xor a
- ld [wcd6a],a
- pop af
- ret
-
-ItemUseVitamin: ; dab4 (3:5ab4)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
-
-ItemUseMedicine: ; dabb (3:5abb)
- ld a,[wPartyCount]
- and a
- jp z,.emptyParty
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- push af
- ld a,$01
- ld [wd07d],a ; item use party menu
- ld a,$ff
- ld [wUpdateSpritesEnabled],a
- ld a,[wd152]
- and a ; using Softboiled?
- jr z,.notUsingSoftboiled
-; if using softboiled
- call GoBackToPartyMenu
- jr .getPartyMonDataAddress
-.emptyParty
- ld hl,.emptyPartyText
- xor a
- ld [wcd6a],a ; item use failed
- jp PrintText
-.emptyPartyText
- text "You don't have"
- line "any #MON!"
- prompt
-.notUsingSoftboiled
- call DisplayPartyMenu
-.getPartyMonDataAddress
- jp c,.canceledItemUse
- ld hl,wPartyMons
- ld bc,wPartyMon2 - wPartyMon1
- ld a,[wWhichPokemon]
- call AddNTimes
- ld a,[wWhichPokemon]
- ld [wcf06],a
- ld d,a
- ld a,[wcf91]
- ld e,a
- ld [wd0b5],a
- pop af
- ld [wcf91],a
- pop af
- ld [wWhichPokemon],a
- ld a,[wd152]
- and a ; using Softboiled?
- jr z,.checkItemType
-; if using softboiled
- ld a,[wWhichPokemon]
- cp d ; is the pokemon trying to use softboiled on itself?
- jr z,ItemUseMedicine ; if so, force another choice
-.checkItemType
- ld a,[wcf91]
- cp a,REVIVE
- jr nc,.healHP ; if it's a Revive or Max Revive
- cp a,FULL_HEAL
- jr z,.cureStatusAilment ; if it's a Full Heal
- cp a,HP_UP
- jp nc,.useVitamin ; if it's a vitamin or Rare Candy
- cp a,FULL_RESTORE
- jr nc,.healHP ; if it's a Full Restore or one of the potions
-; fall through if it's one of the status-specifc healing items
-.cureStatusAilment
- ld bc,4
- add hl,bc ; hl now points to status
- ld a,[wcf91]
- ld bc,$f008
- cp a,ANTIDOTE
- jr z,.checkMonStatus
- ld bc,$f110
- cp a,BURN_HEAL
- jr z,.checkMonStatus
- ld bc,$f220
- cp a,ICE_HEAL
- jr z,.checkMonStatus
- ld bc,$f307
- cp a,AWAKENING
- jr z,.checkMonStatus
- ld bc,$f440
- cp a,PARLYZ_HEAL
- jr z,.checkMonStatus
- ld bc,$f6ff ; Full Heal
-.checkMonStatus
- ld a,[hl] ; pokemon's status
- and c ; does the pokemon have a status ailment the item can cure?
- jp z,.healingItemNoEffect
-; if the pokemon has a status the item can heal
- xor a
- ld [hl],a ; remove the status ailment in the party data
- ld a,b
- ld [wd07d],a ; the message to display for the item used
- ld a,[wPlayerMonNumber]
- cp d ; is pokemon the item was used on active in battle?
- jp nz,.doneHealing
-; if it is active in battle
- xor a
- ld [wBattleMonStatus],a ; remove the status ailment in the in-battle pokemon data
- push hl
- ld hl,W_PLAYERBATTSTATUS3
- res BadlyPoisoned,[hl] ; heal Toxic status
- pop hl
- ld bc,30
- add hl,bc ; hl now points to party stats
- ld de,wBattleMonMaxHP
- ld bc,10
- call CopyData ; copy party stats to in-battle stat data
- predef DoubleOrHalveSelectedStats
- jp .doneHealing
-.healHP
- inc hl ; hl = address of current HP
- ld a,[hli]
- ld b,a
- ld [wHPBarOldHP+1],a
- ld a,[hl]
- ld c,a
- ld [wHPBarOldHP],a ; current HP stored at wHPBarOldHP (2 bytes, big-endian)
- or b
- jr nz,.notFainted
-.fainted
- ld a,[wcf91]
- cp a,REVIVE
- jr z,.updateInBattleFaintedData
- cp a,MAX_REVIVE
- jr z,.updateInBattleFaintedData
- jp .healingItemNoEffect
-.updateInBattleFaintedData
- ld a,[W_ISINBATTLE]
- and a
- jr z,.compareCurrentHPToMaxHP
- push hl
- push de
- push bc
- ld a,[wcf06]
- ld c,a
- ld hl,wPartyFoughtCurrentEnemyFlags
- ld b,$02
- predef FlagActionPredef
- ld a,c
- and a
- jr z,.next
- ld a,[wcf06]
- ld c,a
- ld hl,wPartyGainExpFlags
- ld b,$01
- predef FlagActionPredef
-.next
- pop bc
- pop de
- pop hl
- jr .compareCurrentHPToMaxHP
-.notFainted
- ld a,[wcf91]
- cp a,REVIVE
- jp z,.healingItemNoEffect
- cp a,MAX_REVIVE
- jp z,.healingItemNoEffect
-.compareCurrentHPToMaxHP
- push hl
- push bc
- ld bc,32
- add hl,bc ; hl now points to max HP
- pop bc
- ld a,[hli]
- cp b
- jr nz,.skipComparingLSB ; no need to compare the LSB's if the MSB's don't match
- ld a,[hl]
- cp c
-.skipComparingLSB
- pop hl
- jr nz,.notFullHP
-.fullHP ; if the pokemon's current HP equals its max HP
- ld a,[wcf91]
- cp a,FULL_RESTORE
- jp nz,.healingItemNoEffect
- inc hl
- inc hl
- ld a,[hld] ; status ailment
- and a ; does the pokemon have a status ailment?
- jp z,.healingItemNoEffect
- ld a,FULL_HEAL
- ld [wcf91],a
- dec hl
- dec hl
- dec hl
- jp .cureStatusAilment
-.notFullHP ; if the pokemon's current HP doesn't equal its max HP
- xor a
- ld [wLowHealthAlarm],a ;disable low health alarm
- ld [wc02a],a
- push hl
- push de
- ld bc,32
- add hl,bc ; hl now points to max HP
- ld a,[hli]
- ld [wHPBarMaxHP+1],a
- ld a,[hl]
- ld [wHPBarMaxHP],a ; max HP stored at wHPBarMaxHP (2 bytes, big-endian)
- ld a,[wd152]
- and a ; using Softboiled?
- jp z,.notUsingSoftboiled2
-; if using softboiled
- ld hl,wHPBarMaxHP
- ld a,[hli]
- push af
- ld a,[hli]
- push af
- ld a,[hli]
- push af
- ld a,[hl]
- push af
- ld hl,wPartyMon1MaxHP
- ld a,[wWhichPokemon]
- ld bc,wPartyMon2 - wPartyMon1
- call AddNTimes
- ld a,[hli]
- ld [wHPBarMaxHP + 1],a
- ld [H_DIVIDEND],a
- ld a,[hl]
- ld [wHPBarMaxHP],a
- ld [H_DIVIDEND + 1],a
- ld a,5
- ld [H_DIVISOR],a
- ld b,2 ; number of bytes
- call Divide ; get 1/5 of max HP of pokemon that used Softboiled
- ld bc,wPartyMon1HP - wPartyMon1MaxHP
- add hl,bc ; hl now points to LSB of current HP of pokemon that used Softboiled
-; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
- ld a,[H_QUOTIENT + 3]
- push af
- ld b,a
- ld a,[hl]
- ld [wHPBarOldHP],a
- sub b
- ld [hld],a
- ld [wHPBarNewHP],a
- ld a,[H_QUOTIENT + 2]
- ld b,a
- ld a,[hl]
- ld [wHPBarOldHP+1],a
- sbc b
- ld [hl],a
- ld [wHPBarNewHP+1],a
- hlCoord 4, 1
- ld a,[wWhichPokemon]
- ld bc,2 * 20
- call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
- ld a,(SFX_02_3d - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- ld a,[hFlags_0xFFF6]
- set 0,a
- ld [hFlags_0xFFF6],a
- ld a,$02
- ld [wHPBarType],a
- predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
- ld a,[hFlags_0xFFF6]
- res 0,a
- ld [hFlags_0xFFF6],a
- pop af
- ld b,a ; store heal amount (1/5 of max HP)
- ld hl,wHPBarOldHP + 1
- pop af
- ld [hld],a
- pop af
- ld [hld],a
- pop af
- ld [hld],a
- pop af
- ld [hl],a
- jr .addHealAmount
-.notUsingSoftboiled2
- ld a,[wcf91]
- cp a,SODA_POP
- ld b,60 ; Soda Pop heal amount
- jr z,.addHealAmount
- ld b,80 ; Lemonade heal amount
- jr nc,.addHealAmount
- cp a,FRESH_WATER
- ld b,50 ; Fresh Water heal amount
- jr z,.addHealAmount
- cp a,SUPER_POTION
- ld b,200 ; Hyper Potion heal amount
- jr c,.addHealAmount
- ld b,50 ; Super Potion heal amount
- jr z,.addHealAmount
- ld b,20 ; Potion heal amount
-.addHealAmount
- pop de
- pop hl
- ld a,[hl]
- add b
- ld [hld],a
- ld [wHPBarNewHP],a
- ld a,[hl]
- ld [wHPBarNewHP+1],a
- jr nc,.noCarry
- inc [hl]
- ld a,[hl]
- ld [wHPBarNewHP + 1],a
-.noCarry
- push de
- inc hl
- ld d,h
- ld e,l ; de now points to current HP
- ld hl,33
- add hl,de ; hl now points to max HP
- ld a,[wcf91]
- cp a,REVIVE
- jr z,.setCurrentHPToHalfMaxHP
- ld a,[hld]
- ld b,a
- ld a,[de]
- sub b
- dec de
- ld b,[hl]
- ld a,[de]
- sbc b
- jr nc,.setCurrentHPToMaxHp ; if current HP exceeds max HP after healing
- ld a,[wcf91]
- cp a,HYPER_POTION
- jr c,.setCurrentHPToMaxHp ; if using a Full Restore or Max Potion
- cp a,MAX_REVIVE
- jr z,.setCurrentHPToMaxHp ; if using a Max Revive
- jr .updateInBattleData
-.setCurrentHPToHalfMaxHP
- dec hl
- dec de
- ld a,[hli]
- srl a
- ld [de],a
- ld [wHPBarNewHP+1],a
- ld a,[hl]
- rr a
- inc de
- ld [de],a
- ld [wHPBarNewHP],a
- dec de
- jr .doneHealingPartyHP
-.setCurrentHPToMaxHp
- ld a,[hli]
- ld [de],a
- ld [wHPBarNewHP+1],a
- inc de
- ld a,[hl]
- ld [de],a
- ld [wHPBarNewHP],a
- dec de
-.doneHealingPartyHP ; done updating the pokemon's current HP in the party data structure
- ld a,[wcf91]
- cp a,FULL_RESTORE
- jr nz,.updateInBattleData
- ld bc,-31
- add hl,bc
- xor a
- ld [hl],a ; remove the status ailment in the party data
-.updateInBattleData
- ld h,d
- ld l,e
- pop de
- ld a,[wPlayerMonNumber]
- cp d ; is pokemon the item was used on active in battle?
- jr nz,.calculateHPBarCoords
-; copy party HP to in-battle HP
- ld a,[hli]
- ld [wBattleMonHP],a
- ld a,[hld]
- ld [wBattleMonHP + 1],a
- ld a,[wcf91]
- cp a,FULL_RESTORE
- jr nz,.calculateHPBarCoords
- xor a
- ld [wBattleMonStatus],a ; remove the status ailment in the in-battle pokemon data
-.calculateHPBarCoords
- ld hl,wOAMBuffer + $90
- ld bc,2 * 20
- inc d
-.calculateHPBarCoordsLoop
- add hl,bc
- dec d
- jr nz,.calculateHPBarCoordsLoop
- jr .doneHealing
-.healingItemNoEffect
- call ItemUseNoEffect
- jp .done
-.doneHealing
- ld a,[wd152]
- and a ; using Softboiled?
- jr nz,.skipRemovingItem ; no item to remove if using Softboiled
- push hl
- call RemoveUsedItem
- pop hl
-.skipRemovingItem
- ld a,[wcf91]
- cp a,FULL_RESTORE
- jr c,.playStatusAilmentCuringSound
- cp a,FULL_HEAL
- jr z,.playStatusAilmentCuringSound
- ld a,(SFX_02_3d - SFX_Headers_02) / 3 ; HP healing sound
- call PlaySoundWaitForCurrent ; play sound
- ld a,[hFlags_0xFFF6]
- set 0,a
- ld [hFlags_0xFFF6],a
- ld a,$02
- ld [wHPBarType],a
- predef UpdateHPBar2 ; animate the HP bar lengthening
- ld a,[hFlags_0xFFF6]
- res 0,a
- ld [hFlags_0xFFF6],a
- ld a,$f7 ; revived message
- ld [wd07d],a
- ld a,[wcf91]
- cp a,REVIVE
- jr z,.showHealingItemMessage
- cp a,MAX_REVIVE
- jr z,.showHealingItemMessage
- ld a,$f5 ; standard HP healed message
- ld [wd07d],a
- jr .showHealingItemMessage
-.playStatusAilmentCuringSound
- ld a,(SFX_02_3e - SFX_Headers_02) / 3 ; status ailment curing sound
- call PlaySoundWaitForCurrent
-.showHealingItemMessage
- xor a
- ld [H_AUTOBGTRANSFERENABLED],a
- call ClearScreen
- dec a
- ld [wUpdateSpritesEnabled],a
- call RedrawPartyMenu ; redraws the party menu and displays the message
- ld a,1
- ld [H_AUTOBGTRANSFERENABLED],a
- ld c,50
- call DelayFrames
- call WaitForTextScrollButtonPress
- jr .done
-.canceledItemUse
- xor a
- ld [wcd6a],a ; item use failed
- pop af
- pop af
-.done
- ld a,[wd152]
- and a ; using Softboiled?
- ret nz ; if so, return
- call GBPalWhiteOut
- call z,GoPAL_SET_CF1C
- ld a,[W_ISINBATTLE]
- and a
- ret nz
- jp ReloadMapData
-.useVitamin
- push hl
- ld a,[hl]
- ld [wd0b5],a
- ld [wd11e],a
- ld bc,33
- add hl,bc ; hl now points to level
- ld a,[hl] ; a = level
- ld [W_CURENEMYLVL],a ; store level
- call GetMonHeader
- push de
- ld a,d
- ld hl,wPartyMonNicks
- call GetPartyMonName
- pop de
- pop hl
- ld a,[wcf91]
- cp a,RARE_CANDY
- jp z,.useRareCandy
- push hl
- sub a,HP_UP
- add a
- ld bc,17
- add hl,bc
- add l
- ld l,a
- jr nc,.noCarry2
- inc h
-.noCarry2
- ld a,10
- ld b,a
- ld a,[hl] ; a = MSB of stat experience of the appropriate stat
- cp a,100 ; is there already at least 25600 (256 * 100) stat experience?
- jr nc,.vitaminNoEffect ; if so, vitamins can't add any more
- add b ; add 2560 (256 * 10) stat experience
- jr nc,.noCarry3 ; a carry should be impossible here, so this will always jump
- ld a,255
-.noCarry3
- ld [hl],a
- pop hl
- call .recalculateStats
- ld hl,VitaminText
- ld a,[wcf91]
- sub a,HP_UP - 1
- ld c,a
-.statNameLoop ; loop to get the address of the name of the stat the vitamin increases
- dec c
- jr z,.gotStatName
-.statNameInnerLoop
- ld a,[hli]
- ld b,a
- ld a,$50
- cp b
- jr nz,.statNameInnerLoop
- jr .statNameLoop
-.gotStatName
- ld de,wcf4b
- ld bc,10
- call CopyData ; copy the stat's name to wcf4b
- ld a,(SFX_02_3e - SFX_Headers_02) / 3
- call PlaySound ; play sound
- ld hl,VitaminStatRoseText
- call PrintText
- jp RemoveUsedItem
-.vitaminNoEffect
- pop hl
- ld hl,VitaminNoEffectText
- call PrintText
- jp GBPalWhiteOut
-.recalculateStats
- ld bc,34
- add hl,bc
- ld d,h
- ld e,l ; de now points to stats
- ld bc,-18
- add hl,bc ; hl now points to byte 3 of experience
- ld b,1
- jp CalcStats ; recalculate stats
-.useRareCandy
- push hl
- ld bc,33
- add hl,bc ; hl now points to level
- ld a,[hl] ; a = level
- cp a, MAX_LEVEL
- jr z,.vitaminNoEffect ; can't raise level above 100
- inc a
- ld [hl],a ; store incremented level
- ld [W_CURENEMYLVL],a
- push hl
- push de
- ld d,a
- callab CalcExperience ; calculate experience for next level and store it at $ff96
- pop de
- pop hl
- ld bc,-19
- add hl,bc ; hl now points to experience
-; update experience to minimum for new level
- ld a,[$ff96]
- ld [hli],a
- ld a,[$ff97]
- ld [hli],a
- ld a,[$ff98]
- ld [hl],a
- pop hl
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- push af
- push de
- push hl
- ld bc,34
- add hl,bc ; hl now points to MSB of max HP
- ld a,[hli]
- ld b,a
- ld c,[hl]
- pop hl
- push bc
- push hl
- call .recalculateStats
- pop hl
- ld bc,35 ; hl now points to LSB of max HP
- add hl,bc
- pop bc
- ld a,[hld]
- sub c
- ld c,a
- ld a,[hl]
- sbc b
- ld b,a ; bc = the amount of max HP gained from leveling up
-; add the amount gained to the current HP
- ld de,-32
- add hl,de ; hl now points to MSB of current HP
- ld a,[hl]
- add c
- ld [hld],a
- ld a,[hl]
- adc b
- ld [hl],a
- ld a,$f8 ; level up message
- ld [wd07d],a
- call RedrawPartyMenu
- pop de
- ld a,d
- ld [wWhichPokemon],a
- ld a,e
- ld [wd11e],a
- xor a
- ld [wcc49],a ; load from player's party
- call LoadMonData
- ld d,$01
- callab PrintStatsBox ; display new stats text box
- call WaitForTextScrollButtonPress ; wait for button press
- xor a
- ld [wcc49],a
- predef LearnMoveFromLevelUp ; learn level up move, if any
- xor a
- ld [wccd4],a
- callab TryEvolvingMon ; evolve pokemon, if appropriate
- ld a,$01
- ld [wUpdateSpritesEnabled],a
- pop af
- ld [wcf91],a
- pop af
- ld [wWhichPokemon],a
- jp RemoveUsedItem
-
-VitaminStatRoseText: ; df24 (3:5f24)
- TX_FAR _VitaminStatRoseText
- db "@"
-
-VitaminNoEffectText: ; df29 (3:5f29)
- TX_FAR _VitaminNoEffectText
- db "@"
-
-VitaminText: ; df2e (3:5f2e)
- db "HEALTH@"
- db "ATTACK@"
- db "DEFENSE@"
- db "SPEED@"
- db "SPECIAL@"
-
-ItemUseBait: ; df52 (3:5f52)
- ld hl,ThrewBaitText
- call PrintText
- ld hl,wEnemyMonCatchRate ; catch rate
- srl [hl] ; halve catch rate
- ld a,BAIT_ANIM
- ld hl,wSafariBaitFactor ; bait factor
- ld de,wSafariEscapeFactor ; escape factor
- jr BaitRockCommon
-
-ItemUseRock: ; df67 (3:5f67)
- ld hl,ThrewRockText
- call PrintText
- ld hl,wEnemyMonCatchRate ; catch rate
- ld a,[hl]
- add a ; double catch rate
- jr nc,.noCarry
- ld a,$ff
-.noCarry
- ld [hl],a
- ld a,ROCK_ANIM
- ld hl,wSafariEscapeFactor ; escape factor
- ld de,wSafariBaitFactor ; bait factor
-
-BaitRockCommon: ; df7f (3:5f7f)
- ld [W_ANIMATIONID],a
- xor a
- ld [wcc5b],a
- ld [H_WHOSETURN],a
- ld [de],a ; zero escape factor (for bait), zero bait factor (for rock)
-.randomLoop ; loop until a random number less than 5 is generated
- call Random
- and a,7
- cp a,5
- jr nc,.randomLoop
- inc a ; increment the random number, giving a range from 1 to 5 inclusive
- ld b,a
- ld a,[hl]
- add b ; increase bait factor (for bait), increase escape factor (for rock)
- jr nc,.noCarry
- ld a,$ff
-.noCarry
- ld [hl],a
- predef MoveAnimation ; do animation
- ld c,70
- jp DelayFrames
-
-ThrewBaitText: ; dfa5 (3:5fa5)
- TX_FAR _ThrewBaitText
- db "@"
-
-ThrewRockText: ; dfaa (3:5faa)
- TX_FAR _ThrewRockText
- db "@"
-
-; also used for Dig out-of-battle effect
-ItemUseEscapeRope: ; dfaf (3:5faf)
- ld a,[W_ISINBATTLE]
- and a
- jr nz,.notUsable
- ld a,[W_CURMAP]
- cp a,AGATHAS_ROOM
- jr z,.notUsable
- ld a,[W_CURMAPTILESET]
- ld b,a
- ld hl,EscapeRopeTilesets
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.notUsable
- cp b
- jr nz,.loop
- ld hl,wd732
- set 3,[hl]
- set 6,[hl]
- ld hl,wd72e
- res 4,[hl]
- ld hl,wd790
- res 7,[hl] ; unset Safari Zone bit
- xor a
- ld [W_NUMSAFARIBALLS],a
- ld [W_SAFARIZONEENTRANCECURSCRIPT],a
- inc a
- ld [wEscapedFromBattle],a
- ld [wcd6a],a ; item used
- ld a,[wd152]
- and a ; using Dig?
- ret nz ; if so, return
- call ItemUseReloadOverworldData
- ld c,30
- call DelayFrames
- jp RemoveUsedItem
-.notUsable
- jp ItemUseNotTime
-
-EscapeRopeTilesets: ; dffd (3:5ffd)
- db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
- db $ff ; terminator
-
-ItemUseRepel: ; e003 (3:6003)
- ld b,100
-
-ItemUseRepelCommon: ; e005 (3:6005)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld a,b
- ld [wRepelRemainingSteps],a
- jp PrintItemUseTextAndRemoveItem
-
-; handles X Accuracy item
-ItemUseXAccuracy: ; e013 (3:6013)
- ld a,[W_ISINBATTLE]
- and a
- jp z,ItemUseNotTime
- ld hl,W_PLAYERBATTSTATUS2
- set UsingXAccuracy,[hl] ; X Accuracy bit
- jp PrintItemUseTextAndRemoveItem
-
-; This function is bugged and never works. It always jumps to ItemUseNotTime.
-; The Card Key is handled in a different way.
-ItemUseCardKey: ; e022 (3:6022)
- xor a
- ld [wd71f],a
- call GetTileAndCoordsInFrontOfPlayer
- ld a,[GetTileAndCoordsInFrontOfPlayer] ; $4586
- cp a,$18
- jr nz,.next0
- ld hl,CardKeyTable1
- jr .next1
-.next0
- cp a,$24
- jr nz,.next2
- ld hl,CardKeyTable2
- jr .next1
-.next2
- cp a,$5e
- jp nz,ItemUseNotTime
- ld hl,CardKeyTable3
-.next1
- ld a,[W_CURMAP]
- ld b,a
-.loop
- ld a,[hli]
- cp a,$ff
- jp z,ItemUseNotTime
- cp b
- jr nz,.nextEntry1
- ld a,[hli]
- cp d
- jr nz,.nextEntry2
- ld a,[hli]
- cp e
- jr nz,.nextEntry3
- ld a,[hl]
- ld [wd71f],a
- jr .done
-.nextEntry1
- inc hl
-.nextEntry2
- inc hl
-.nextEntry3
- inc hl
- jr .loop
-.done
- ld hl,ItemUseText00
- call PrintText
- ld hl,wd728
- set 7,[hl]
- ret
-
-; These tables are probably supposed to be door locations in Silph Co.,
-; but they are unused.
-; The reason there are 3 tables is unknown.
-
-; Format:
-; 00: Map ID
-; 01: Y
-; 02: X
-; 03: ID?
-
-CardKeyTable1: ; e072 (3:6072)
- db SILPH_CO_2F,$04,$04,$00
- db SILPH_CO_2F,$04,$05,$01
- db SILPH_CO_4F,$0C,$04,$02
- db SILPH_CO_4F,$0C,$05,$03
- db SILPH_CO_7F,$06,$0A,$04
- db SILPH_CO_7F,$06,$0B,$05
- db SILPH_CO_9F,$04,$12,$06
- db SILPH_CO_9F,$04,$13,$07
- db SILPH_CO_10F,$08,$0A,$08
- db SILPH_CO_10F,$08,$0B,$09
- db $ff
-
-CardKeyTable2: ; e09b (3:609b)
- db SILPH_CO_3F,$08,$09,$0A
- db SILPH_CO_3F,$09,$09,$0B
- db SILPH_CO_5F,$04,$07,$0C
- db SILPH_CO_5F,$05,$07,$0D
- db SILPH_CO_6F,$0C,$05,$0E
- db SILPH_CO_6F,$0D,$05,$0F
- db SILPH_CO_8F,$08,$07,$10
- db SILPH_CO_8F,$09,$07,$11
- db SILPH_CO_9F,$08,$03,$12
- db SILPH_CO_9F,$09,$03,$13
- db $ff
-
-CardKeyTable3: ; e0c4 (3:60c4)
- db SILPH_CO_11F,$08,$09,$14
- db SILPH_CO_11F,$09,$09,$15
- db $ff
-
-ItemUsePokedoll: ; e0cd (3:60cd)
- ld a,[W_ISINBATTLE]
- dec a
- jp nz,ItemUseNotTime
- ld a,$01
- ld [wEscapedFromBattle],a
- jp PrintItemUseTextAndRemoveItem
-
-ItemUseGuardSpec: ; e0dc (3:60dc)
- ld a,[W_ISINBATTLE]
- and a
- jp z,ItemUseNotTime
- ld hl,W_PLAYERBATTSTATUS2
- set ProtectedByMist,[hl] ; Mist bit
- jp PrintItemUseTextAndRemoveItem
-
-ItemUseSuperRepel: ; e0eb (3:60eb)
- ld b,200
- jp ItemUseRepelCommon
-
-ItemUseMaxRepel: ; e0f0 (3:60f0)
- ld b,250
- jp ItemUseRepelCommon
-
-ItemUseDireHit: ; e0f5 (3:60f5)
- ld a,[W_ISINBATTLE]
- and a
- jp z,ItemUseNotTime
- ld hl,W_PLAYERBATTSTATUS2
- set GettingPumped,[hl] ; Focus Energy bit
- jp PrintItemUseTextAndRemoveItem
-
-ItemUseXStat: ; e104 (3:6104)
- ld a,[W_ISINBATTLE]
- and a
- jr nz,.inBattle
- call ItemUseNotTime
- ld a,2
- ld [wcd6a],a ; item not used
- ret
-.inBattle
- ld hl,W_PLAYERMOVENUM
- ld a,[hli]
- push af ; save [W_PLAYERMOVENUM]
- ld a,[hl]
- push af ; save [W_PLAYERMOVEEFFECT]
- push hl
- ld a,[wcf91]
- sub a,X_ATTACK - ATTACK_UP1_EFFECT
- ld [hl],a ; store player move effect
- call PrintItemUseTextAndRemoveItem
- ld a,XSTATITEM_ANIM ; X stat item animation ID
- ld [W_PLAYERMOVENUM],a
- call LoadScreenTilesFromBuffer1 ; restore saved screen
- call Delay3
- xor a
- ld [H_WHOSETURN],a ; set turn to player's turn
- callba StatModifierUpEffect ; do stat increase move
- pop hl
- pop af
- ld [hld],a ; restore [W_PLAYERMOVEEFFECT]
- pop af
- ld [hl],a ; restore [W_PLAYERMOVENUM]
- ret
-
-ItemUsePokeflute: ; e140 (3:6140)
- ld a,[W_ISINBATTLE]
- and a
- jr nz,.inBattle
-; if not in battle
- call ItemUseReloadOverworldData
- ld a,[W_CURMAP]
- cp a,ROUTE_12
- jr nz,.notRoute12
- ld a,[wd7d8]
- bit 7,a ; has the player beaten Route 12 Snorlax yet?
- jr nz,.noSnorlaxToWakeUp
-; if the player hasn't beaten Route 12 Snorlax
- ld hl,Route12SnorlaxFluteCoords
- call ArePlayerCoordsInArray
- jr nc,.noSnorlaxToWakeUp
- ld hl,PlayedFluteHadEffectText
- call PrintText
- ld hl,wd7d8
- set 6,[hl] ; trigger Snorlax fight (handled by map script)
- ret
-.notRoute12
- cp a,ROUTE_16
- jr nz,.noSnorlaxToWakeUp
- ld a,[wd7e0]
- bit 1,a ; has the player beaten Route 16 Snorlax yet?
- jr nz,.noSnorlaxToWakeUp
-; if the player hasn't beaten Route 16 Snorlax
- ld hl,Route16SnorlaxFluteCoords
- call ArePlayerCoordsInArray
- jr nc,.noSnorlaxToWakeUp
- ld hl,PlayedFluteHadEffectText
- call PrintText
- ld hl,wd7e0
- set 0,[hl] ; trigger Snorlax fight (handled by map script)
- ret
-.noSnorlaxToWakeUp
- ld hl,PlayedFluteNoEffectText
- jp PrintText
-.inBattle
- xor a
- ld [wWhichTrade],a ; initialize variable that indicates if any pokemon were woken up to zero
- ld b,~SLP & $FF
- ld hl,wPartyMon1Status
- call WakeUpEntireParty
- ld a,[W_ISINBATTLE]
- dec a ; is it a trainer battle?
- jr z,.skipWakingUpEnemyParty
-; if it's a trainer battle
- ld hl,wEnemyMon1Status
- call WakeUpEntireParty
-.skipWakingUpEnemyParty
- ld hl,wBattleMonStatus
- ld a,[hl]
- and b ; remove Sleep status
- ld [hl],a
- ld hl,wEnemyMonStatus
- ld a,[hl]
- and b ; remove Sleep status
- ld [hl],a
- call LoadScreenTilesFromBuffer2 ; restore saved screen
- ld a,[wWhichTrade]
- and a ; were any pokemon asleep before playing the flute?
- ld hl,PlayedFluteNoEffectText
- jp z,PrintText ; if no pokemon were asleep
-; if some pokemon were asleep
- ld hl,PlayedFluteHadEffectText
- call PrintText
- ld a,[wLowHealthAlarm]
- and a,$80
- jr nz,.skipMusic
- call WaitForSoundToFinish ; wait for sound to end
- callba Music_PokeFluteInBattle ; play in-battle pokeflute music
-.musicWaitLoop ; wait for music to finish playing
- ld a,[wc02c]
- and a ; music off?
- jr nz,.musicWaitLoop
-.skipMusic
- ld hl,FluteWokeUpText
- jp PrintText
-
-; wakes up all party pokemon
-; INPUT:
-; hl must point to status of first pokemon in party (player's or enemy's)
-; b must equal ~SLP
-; [wWhichTrade] should be initialized to 0
-; OUTPUT:
-; [wWhichTrade]: set to 1 if any pokemon were asleep
-WakeUpEntireParty: ; e1e5 (3:61e5)
- ld de,44
- ld c,6
-.loop
- ld a,[hl]
- push af
- and a,SLP ; is pokemon asleep?
- jr z,.notAsleep
- ld a,1
- ld [wWhichTrade],a ; indicate that a pokemon had to be woken up
-.notAsleep
- pop af
- and b ; remove Sleep status
- ld [hl],a
- add hl,de
- dec c
- jr nz,.loop
- ret
-
-; Format:
-; 00: Y
-; 01: X
-Route12SnorlaxFluteCoords: ; e1fd (3:61fd)
- db 62,9 ; one space West of Snorlax
- db 61,10 ; one space North of Snorlax
- db 63,10 ; one space South of Snorlax
- db 62,11 ; one space East of Snorlax
- db $ff ; terminator
-
-; Format:
-; 00: Y
-; 01: X
-Route16SnorlaxFluteCoords: ; e206 (3:6206)
- db 10,27 ; one space East of Snorlax
- db 10,25 ; one space West of Snorlax
- db $ff ; terminator
-
-PlayedFluteNoEffectText: ; e20b (3:620b)
- TX_FAR _PlayedFluteNoEffectText
- db "@"
-
-FluteWokeUpText: ; e210 (3:6210)
- TX_FAR _FluteWokeUpText
- db "@"
-
-PlayedFluteHadEffectText: ; e215 (3:6215)
- TX_FAR _PlayedFluteHadEffectText
- db $06
- db $08
- ld a,[W_ISINBATTLE]
- and a
- jr nz,.done
-; play out-of-battle pokeflute music
- ld a,$ff
- call PlaySound ; turn off music
- ld a, (SFX_02_5e - SFX_Headers_02) / 3
- ld c, BANK(SFX_02_5e)
- call PlayMusic ; play music
-.musicWaitLoop ; wait for music to finish playing
- ld a,[wc028]
- cp a,$b8
- jr z,.musicWaitLoop
- call PlayDefaultMusic ; start playing normal music again
-.done
- jp TextScriptEnd ; end text
-
-ItemUseCoinCase: ; e23a (3:623a)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld hl,CoinCaseNumCoinsText
- jp PrintText
-
-CoinCaseNumCoinsText: ; e247 (3:6247)
- TX_FAR _CoinCaseNumCoinsText
- db "@"
-
-OldRodCode: ; e24c (3:624c)
- call FishingInit
- jp c, ItemUseNotTime
- ld bc, (5 << 8) | MAGIKARP
- ld a, $1 ; set bite
- jr RodResponse ; 0xe257 $34
-
-GoodRodCode: ; e259 (3:6259)
- call FishingInit
- jp c,ItemUseNotTime
-.RandomLoop
- call Random
- srl a
- jr c, .SetBite
- and %11
- cp 2
- jr nc, .RandomLoop
- ; choose which monster appears
- ld hl,GoodRodMons
- add a,a
- ld c,a
- ld b,0
- add hl,bc
- ld b,[hl]
- inc hl
- ld c,[hl]
- and a
-.SetBite
- ld a,0
- rla
- xor 1
- jr RodResponse
-
-INCLUDE "data/good_rod.asm"
-
-SuperRodCode: ; e283 (3:6283)
- call FishingInit
- jp c, ItemUseNotTime
- call ReadSuperRodData ; 0xe8ea
- ld a, e
-RodResponse: ; e28d (3:628d)
- ld [wWhichTrade], a
-
- dec a ; is there a bite?
- jr nz, .next
- ; if yes, store level and species data
- ld a, 1
- ld [W_MOVEMISSED], a
- ld a, b ; level
- ld [W_CURENEMYLVL], a
- ld a, c ; species
- ld [W_CUROPPONENT], a
-
-.next
- ld hl, wWalkBikeSurfState
- ld a, [hl] ; store the value in a
- push af
- push hl
- ld [hl], 0
- callba Func_707b6
- pop hl
- pop af
- ld [hl], a
- ret
-
-; checks if fishing is possible and if so, runs initialization code common to all rods
-; unsets carry if fishing is possible, sets carry if not
-FishingInit: ; e2b4 (3:62b4)
- ld a,[W_ISINBATTLE]
- and a
- jr z,.notInBattle
- scf ; can't fish during battle
- ret
-.notInBattle
- call IsNextTileShoreOrWater
- ret c
- ld a,[wWalkBikeSurfState]
- cp a,2 ; Surfing?
- jr z,.surfing
- call ItemUseReloadOverworldData
- ld hl,ItemUseText00
- call PrintText
- ld a,(SFX_02_3e - SFX_Headers_02) / 3
- call PlaySound ; play sound
- ld c,80
- call DelayFrames
- and a
- ret
-.surfing
- scf ; can't fish when surfing
- ret
-
-ItemUseOaksParcel: ; e2de (3:62de)
- jp ItemUseNotYoursToUse
-
-ItemUseItemfinder: ; e2e1 (3:62e1)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- call ItemUseReloadOverworldData
- callba HiddenItemNear ; check for hidden items
- ld hl,ItemfinderFoundNothingText
- jr nc,.printText ; if no hidden items
- ld c,4
-.loop
- ld a,(SFX_02_4a - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- ld a,(SFX_02_5a - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- dec c
- jr nz,.loop
- ld hl,ItemfinderFoundItemText
-.printText
- jp PrintText
-
-ItemfinderFoundItemText: ; e30d (3:630d)
- TX_FAR _ItemfinderFoundItemText
- db "@"
-
-ItemfinderFoundNothingText: ; e312 (3:6312)
- TX_FAR _ItemfinderFoundNothingText
- db "@"
-
-ItemUsePPUp: ; e317 (3:6317)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
-
-ItemUsePPRestore: ; e31e (3:631e)
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- ld [wWhichTrade],a
-.chooseMon
- xor a
- ld [wUpdateSpritesEnabled],a
- ld a,$01 ; item use party menu
- ld [wd07d],a
- call DisplayPartyMenu
- jr nc,.chooseMove
- jp .itemNotUsed
-.chooseMove
- ld a,[wWhichTrade]
- cp a,ELIXER
- jp nc,.useElixir ; if Elixir or Max Elixir
- ld a,$02
- ld [wMoveMenuType],a
- ld hl,RaisePPWhichTechniqueText
- ld a,[wWhichTrade]
- cp a,ETHER ; is it a PP Up?
- jr c,.printWhichTechniqueMessage ; if so, print the raise PP message
- ld hl,RestorePPWhichTechniqueText ; otherwise, print the restore PP message
-.printWhichTechniqueMessage
- call PrintText
- xor a
- ld [wPlayerMoveListIndex],a
- callab MoveSelectionMenu ; move selection menu
- ld a,0
- ld [wPlayerMoveListIndex],a
- jr nz,.chooseMon
- ld hl,wPartyMon1Moves
- ld bc,44
- call GetSelectedMoveOffset
- push hl
- ld a,[hl]
- ld [wd11e],a
- call GetMoveName
- call CopyStringToCF4B ; copy name to wcf4b
- pop hl
- ld a,[wWhichTrade]
- cp a,ETHER
- jr nc,.useEther ; if Ether or Max Ether
-.usePPUp
- ld bc,21
- add hl,bc
- ld a,[hl] ; move PP
- cp a,3 << 6 ; have 3 PP Ups already been used?
- jr c,.PPNotMaxedOut
- ld hl,PPMaxedOutText
- call PrintText
- jr .chooseMove
-.PPNotMaxedOut
- ld a,[hl]
- add a,1 << 6 ; increase PP Up count by 1
- ld [hl],a
- ld a,1 ; 1 PP Up used
- ld [wd11e],a
- call RestoreBonusPP ; add the bonus PP to current PP
- ld hl,PPIncreasedText
- call PrintText
-.done
- pop af
- ld [wWhichPokemon],a
- call GBPalWhiteOut
- call GoPAL_SET_CF1C
- jp RemoveUsedItem
-.afterRestoringPP ; after using a (Max) Ether/Elixir
- ld a,[wWhichPokemon]
- ld b,a
- ld a,[wPlayerMonNumber]
- cp b ; is the pokemon whose PP was restored active in battle?
- jr nz,.skipUpdatingInBattleData
- ld hl,wPartyMon1PP
- ld bc,44
- call AddNTimes
- ld de,wBattleMonPP
- ld bc,4
- call CopyData ; copy party data to in-battle data
-.skipUpdatingInBattleData
- ld a,(SFX_02_3e - SFX_Headers_02) / 3
- call PlaySound
- ld hl,PPRestoredText
- call PrintText
- jr .done
-.useEther
- call .restorePP
- jr nz,.afterRestoringPP
- jp .noEffect
-; unsets zero flag if PP was restored, sets zero flag if not
-; however, this is bugged for Max Ethers and Max Elixirs (see below)
-.restorePP
- xor a
- ld [wcc49],a ; party pokemon
- call GetMaxPP
- ld hl,wPartyMon1Moves
- ld bc,44
- call GetSelectedMoveOffset
- ld bc,21
- add hl,bc ; hl now points to move's PP
- ld a,[wd11e]
- ld b,a ; b = max PP
- ld a,[wWhichTrade]
- cp a,MAX_ETHER
- jr z,.fullyRestorePP
- ld a,[hl] ; move PP
- and a,%00111111 ; lower 6 bit bits store current PP
- cp b ; does current PP equal max PP?
- ret z ; if so, return
- add a,10 ; increase current PP by 10
-; b holds the max PP amount and b will hold the new PP amount.
-; So, if the new amount meets or exceeds the max amount,
-; cap the amount to the max amount by leaving b unchanged.
-; Otherwise, store the new amount in b.
- cp b ; does the new amount meet or exceed the maximum?
- jr nc,.storeNewAmount
- ld b,a
-.storeNewAmount
- ld a,[hl] ; move PP
- and a,%11000000 ; PP Up counter bits
- add b
- ld [hl],a
- ret
-.fullyRestorePP
- ld a,[hl] ; move PP
-; Note that this code has a bug. It doesn't mask out the upper two bits, which
-; are used to count how many PP Ups have been used on the move. So, Max Ethers
-; and Max Elixirs will not be detected as having no effect on a move with full
-; PP if the move has had any PP Ups used on it.
- cp b ; does current PP equal max PP?
- ret z
- jr .storeNewAmount
-.useElixir
-; decrement the item ID so that ELIXER becomes ETHER and MAX_ELIXER becomes MAX_ETHER
- ld hl,wWhichTrade
- dec [hl]
- dec [hl]
- xor a
- ld hl,wCurrentMenuItem
- ld [hli],a
- ld [hl],a ; zero the counter for number of moves that had their PP restored
- ld b,4
-; loop through each move and restore PP
-.elixirLoop
- push bc
- ld hl,wPartyMon1Moves
- ld bc,44
- call GetSelectedMoveOffset
- ld a,[hl]
- and a ; does the current slot have a move?
- jr z,.nextMove
- call .restorePP
- jr z,.nextMove
-; if some PP was restored
- ld hl,wTileBehindCursor ; counter for number of moves that had their PP restored
- inc [hl]
-.nextMove
- ld hl,wCurrentMenuItem
- inc [hl]
- pop bc
- dec b
- jr nz,.elixirLoop
- ld a,[wTileBehindCursor]
- and a ; did any moves have their PP restored?
- jp nz,.afterRestoringPP
-.noEffect
- call ItemUseNoEffect
-.itemNotUsed
- call GBPalWhiteOut
- call GoPAL_SET_CF1C
- pop af
- xor a
- ld [wcd6a],a ; item use failed
- ret
-
-RaisePPWhichTechniqueText: ; e45d (3:645d)
- TX_FAR _RaisePPWhichTechniqueText
- db "@"
-
-RestorePPWhichTechniqueText: ; e462 (3:6462)
- TX_FAR _RestorePPWhichTechniqueText
- db "@"
-
-PPMaxedOutText: ; e467 (3:6467)
- TX_FAR _PPMaxedOutText
- db "@"
-
-PPIncreasedText: ; e46c (3:646c)
- TX_FAR _PPIncreasedText
- db "@"
-
-PPRestoredText: ; e471 (3:6471)
- TX_FAR _PPRestoredText
- db "@"
-
-; for items that can't be used from the Item menu
-UnusableItem: ; e476 (3:6476)
- jp ItemUseNotTime
-
-ItemUseTMHM: ; e479 (3:6479)
- ld a,[W_ISINBATTLE]
- and a
- jp nz,ItemUseNotTime
- ld a,[wcf91]
- sub a,TM_01
- push af
- jr nc,.skipAdding
- add a,55 ; if item is an HM, add 55
-.skipAdding
- inc a
- ld [wd11e],a
- predef TMToMove ; get move ID from TM/HM ID
- ld a,[wd11e]
- ld [wMoveNum],a
- call GetMoveName
- call CopyStringToCF4B ; copy name to wcf4b
- pop af
- ld hl,BootedUpTMText
- jr nc,.printBootedUpMachineText
- ld hl,BootedUpHMText
-.printBootedUpMachineText
- call PrintText
- ld hl,TeachMachineMoveText
- call PrintText
- hlCoord 14, 7
- ld bc,$080f
- ld a,TWO_OPTION_MENU
- ld [wTextBoxID],a
- call DisplayTextBoxID ; yes/no menu
- ld a,[wCurrentMenuItem]
- and a
- jr z,.useMachine
- ld a,2
- ld [wcd6a],a ; item not used
- ret
-.useMachine
- ld a,[wWhichPokemon]
- push af
- ld a,[wcf91]
- push af
-.chooseMon
- ld hl,wcf4b
- ld de,wd036
- ld bc,14
- call CopyData
- ld a,$ff
- ld [wUpdateSpritesEnabled],a
- ld a,$03 ; teach TM/HM party menu
- ld [wd07d],a
- call DisplayPartyMenu
- push af
- ld hl,wd036
- ld de,wcf4b
- ld bc,14
- call CopyData
- pop af
- jr nc,.checkIfAbleToLearnMove
-; if the player canceled teaching the move
- pop af
- pop af
- call GBPalWhiteOutWithDelay3
- call ClearSprites
- call GoPAL_SET_CF1C
- jp LoadScreenTilesFromBuffer1 ; restore saved screen
-.checkIfAbleToLearnMove
- predef CanLearnTM ; check if the pokemon can learn the move
- push bc
- ld a,[wWhichPokemon]
- ld hl,wPartyMonNicks
- call GetPartyMonName
- pop bc
- ld a,c
- and a ; can the pokemon learn the move?
- jr nz,.checkIfAlreadyLearnedMove
-; if the pokemon can't learn the move
- ld a,(SFX_02_51 - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- ld hl,MonCannotLearnMachineMoveText
- call PrintText
- jr .chooseMon
-.checkIfAlreadyLearnedMove
- callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
- jr c,.chooseMon
- predef LearnMove ; teach move
- pop af
- ld [wcf91],a
- pop af
- ld [wWhichPokemon],a
- ld a,b
- and a
- ret z
- ld a,[wcf91]
- call IsItemHM
- ret c
- jp RemoveUsedItem
-
-BootedUpTMText: ; e54f (3:654f)
- TX_FAR _BootedUpTMText
- db "@"
-
-BootedUpHMText: ; e554 (3:6554)
- TX_FAR _BootedUpHMText
- db "@"
-
-TeachMachineMoveText: ; e559 (3:6559)
- TX_FAR _TeachMachineMoveText
- db "@"
-
-MonCannotLearnMachineMoveText: ; e55e (3:655e)
- TX_FAR _MonCannotLearnMachineMoveText
- db "@"
-
-PrintItemUseTextAndRemoveItem: ; e563 (3:6563)
- ld hl,ItemUseText00
- call PrintText
- ld a,(SFX_02_3e - SFX_Headers_02) / 3
- call PlaySound ; play sound
- call WaitForTextScrollButtonPress ; wait for button press
-
-RemoveUsedItem: ; e571 (3:6571)
- ld hl,wNumBagItems
- ld a,1 ; one item
- ld [wcf96],a ; store quantity
- jp RemoveItemFromInventory
-
-ItemUseNoEffect: ; e57c (3:657c)
- ld hl,ItemUseNoEffectText
- jr ItemUseFailed
-
-ItemUseNotTime: ; e581 (3:6581)
- ld hl,ItemUseNotTimeText
- jr ItemUseFailed
-
-ItemUseNotYoursToUse: ; e586 (3:6586)
- ld hl,ItemUseNotYoursToUseText
- jr ItemUseFailed
-
-ThrowBallAtTrainerMon: ; e58b (3:658b)
- call GoPAL_SET_CF1C
- call LoadScreenTilesFromBuffer1 ; restore saved screen
- call Delay3
- ld a,TOSS_ANIM
- ld [W_ANIMATIONID],a
- predef MoveAnimation ; do animation
- ld hl,ThrowBallAtTrainerMonText1
- call PrintText
- ld hl,ThrowBallAtTrainerMonText2
- call PrintText
- jr RemoveUsedItem
-
-NoCyclingAllowedHere: ; e5ac (3:65ac)
- ld hl,NoCyclingAllowedHereText
- jr ItemUseFailed
-
-BoxFullCannotThrowBall: ; e5b1 (3:65b1)
- ld hl,BoxFullCannotThrowBallText
- jr ItemUseFailed
-
-SurfingAttemptFailed: ; e5b6 (3:65b6)
- ld hl,NoSurfingHereText
-
-ItemUseFailed: ; e5b9 (3:65b9)
- xor a
- ld [wcd6a],a ; item use failed
- jp PrintText
-
-ItemUseNotTimeText: ; e5c0 (3:65c0)
- TX_FAR _ItemUseNotTimeText
- db "@"
-
-ItemUseNotYoursToUseText: ; e5c5 (3:65c5)
- TX_FAR _ItemUseNotYoursToUseText
- db "@"
-
-ItemUseNoEffectText: ; e5ca (3:65ca)
- TX_FAR _ItemUseNoEffectText
- db "@"
-
-ThrowBallAtTrainerMonText1: ; e5cf (3:65cf)
- TX_FAR _ThrowBallAtTrainerMonText1
- db "@"
-
-ThrowBallAtTrainerMonText2: ; e5d4 (3:65d4)
- TX_FAR _ThrowBallAtTrainerMonText2
- db "@"
-
-NoCyclingAllowedHereText: ; e5d9 (3:65d9)
- TX_FAR _NoCyclingAllowedHereText
- db "@"
-
-NoSurfingHereText: ; e5de (3:65de)
- TX_FAR _NoSurfingHereText
- db "@"
-
-BoxFullCannotThrowBallText: ; e5e3 (3:65e3)
- TX_FAR _BoxFullCannotThrowBallText
- db "@"
-
-ItemUseText00: ; e5e8 (3:65e8)
- TX_FAR _ItemUseText001
- db $05
- TX_FAR _ItemUseText002
- db "@"
-
-GotOnBicycleText: ; e5f2 (3:65f2)
- TX_FAR _GotOnBicycleText1
- db $05
- TX_FAR _GotOnBicycleText2
- db "@"
-
-GotOffBicycleText: ; e5fc (3:65fc)
- TX_FAR _GotOffBicycleText1
- db $05
- TX_FAR _GotOffBicycleText2
- db "@"
-
-; restores bonus PP (from PP Ups) when healing at a pokemon center
-; also, when a PP Up is used, it increases the current PP by one PP Up bonus
-; INPUT:
-; [wWhichPokemon] = index of pokemon in party
-; [wd11e] = mode
-; 0: Pokemon Center healing
-; 1: using a PP Up
-; [wCurrentMenuItem] = index of move (when using a PP Up)
-RestoreBonusPP: ; e606 (3:6606)
- ld hl,wPartyMon1Moves
- ld bc,44
- ld a,[wWhichPokemon]
- call AddNTimes
- push hl
- ld de,wcd78 - 1
- predef LoadMovePPs ; loads the normal max PP of each of the pokemon's moves to wcd78
- pop hl
- ld c,21
- ld b,0
- add hl,bc ; hl now points to move 1 PP
- ld de,wcd78
- ld b,0 ; initialize move counter to zero
-; loop through the pokemon's moves
-.loop
- inc b
- ld a,b
- cp a,5 ; reached the end of the pokemon's moves?
- ret z ; if so, return
- ld a,[wd11e]
- dec a ; using a PP Up?
- jr nz,.skipMenuItemIDCheck
-; if using a PP Up, check if this is the move it's being used on
- ld a,[wCurrentMenuItem]
- inc a
- cp b
- jr nz,.nextMove
-.skipMenuItemIDCheck
- ld a,[hl]
- and a,%11000000 ; have any PP Ups been used?
- call nz,AddBonusPP ; if so, add bonus PP
-.nextMove
- inc hl
- inc de
- jr .loop
-
-; adds bonus PP from PP Ups to current PP
-; 1/5 of normal max PP (capped at 7) is added for each PP Up
-; INPUT:
-; [de] = normal max PP
-; [hl] = move PP
-; [wd11e] = max number of times to add bonus
-; set to 1 when using a PP Up, set to 255 otherwise
-AddBonusPP: ; e642 (3:6642)
- push bc
- ld a,[de] ; normal max PP of move
- ld [H_DIVIDEND + 3],a
- xor a
- ld [H_DIVIDEND],a
- ld [H_DIVIDEND + 1],a
- ld [H_DIVIDEND + 2],a
- ld a,5
- ld [H_DIVISOR],a
- ld b,4
- call Divide
- ld a,[hl] ; move PP
- ld b,a
- swap a
- and a,%00001111
- srl a
- srl a
- ld c,a ; c = number of PP Ups used
-.loop
- ld a,[H_QUOTIENT + 3]
- cp a,8 ; is the amount greater than or equal to 8?
- jr c,.addAmount
- ld a,7 ; cap the amount at 7
-.addAmount
- add b
- ld b,a
- ld a,[wd11e]
- dec a
- jr z,.done
- dec c
- jr nz,.loop
-.done
- ld [hl],b
- pop bc
- ret
-
-; gets max PP of a pokemon's move (including PP from PP Ups)
-; INPUT:
-; [wWhichPokemon] = index of pokemon within party/box
-; [wcc49] = pokemon source
-; 00: player's party
-; 01: enemy's party
-; 02: current box
-; 03: daycare
-; 04: player's in-battle pokemon
-; [wCurrentMenuItem] = move index
-; OUTPUT:
-; [wd11e] = max PP
-GetMaxPP: ; e677 (3:6677)
- ld a,[wcc49]
- and a
- ld hl,wPartyMon1Moves
- ld bc,wPartyMon2 - wPartyMon1
- jr z,.sourceWithMultipleMon
- ld hl,wEnemyMon1Moves
- dec a
- jr z,.sourceWithMultipleMon
- ld hl,wBoxMon1Moves
- ld bc,wBoxMon2 - wBoxMon1
- dec a
- jr z,.sourceWithMultipleMon
- ld hl,wDayCareMonMoves
- dec a
- jr z,.sourceWithOneMon
- ld hl,wBattleMonMoves ; player's in-battle pokemon
-.sourceWithOneMon
- call GetSelectedMoveOffset2
- jr .next
-.sourceWithMultipleMon
- call GetSelectedMoveOffset
-.next
- ld a,[hl]
- dec a
- push hl
- ld hl,Moves
- ld bc,6
- call AddNTimes
- ld de,wcd6d
- ld a,BANK(Moves)
- call FarCopyData
- ld de,wcd72
- ld a,[de]
- ld b,a ; b = normal max PP
- pop hl
- push bc
- ld bc,21 ; PP offset if not player's in-battle pokemon data
- ld a,[wcc49]
- cp a,4 ; player's in-battle pokemon?
- jr nz,.addPPOffset
- ld bc,17 ; PP offset if player's in-battle pokemon data
-.addPPOffset
- add hl,bc
- ld a,[hl] ; a = current PP
- and a,%11000000 ; get PP Up count
- pop bc
- or b ; place normal max PP in 6 lower bits of a
- ld h,d
- ld l,e
- inc hl ; hl = wcd73
- ld [hl],a
- xor a
- ld [wd11e],a ; no limit on PP Up amount
- call AddBonusPP ; add bonus PP from PP Ups
- ld a,[hl]
- and a,%00111111 ; mask out the PP Up count
- ld [wd11e],a ; store max PP
- ret
-
-GetSelectedMoveOffset: ; e6e3 (3:66e3)
- ld a,[wWhichPokemon]
- call AddNTimes
-
-GetSelectedMoveOffset2: ; e6e9 (3:66e9)
- ld a,[wCurrentMenuItem]
- ld c,a
- ld b,0
- add hl,bc
- ret
-
-; confirms the item toss and then tosses the item
-; INPUT:
-; hl = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wWhichPokemon] = index of item within inventory
-; [wcf96] = quantity to toss
-; OUTPUT:
-; clears carry flag if the item is tossed, sets carry flag if not
-TossItem_: ; e6f1 (3:66f1)
- push hl
- ld a,[wcf91]
- call IsItemHM
- pop hl
- jr c,.tooImportantToToss
- push hl
- call IsKeyItem_
- ld a,[wd124]
- pop hl
- and a
- jr nz,.tooImportantToToss
- push hl
- ld a,[wcf91]
- ld [wd11e],a
- call GetItemName
- call CopyStringToCF4B ; copy name to wcf4b
- ld hl,IsItOKToTossItemText
- call PrintText
- hlCoord 14, 7
- ld bc,$080f
- ld a,TWO_OPTION_MENU
- ld [wTextBoxID],a
- call DisplayTextBoxID ; yes/no menu
- ld a,[wd12e]
- cp a,2
- pop hl
- scf
- ret z
-; if the player chose Yes
- push hl
- ld a,[wWhichPokemon]
- call RemoveItemFromInventory
- ld a,[wcf91]
- ld [wd11e],a
- call GetItemName
- call CopyStringToCF4B ; copy name to wcf4b
- ld hl,ThrewAwayItemText
- call PrintText
- pop hl
- and a
- ret
-.tooImportantToToss
- push hl
- ld hl,TooImportantToTossText
- call PrintText
- pop hl
- scf
- ret
-
-ThrewAwayItemText: ; e755 (3:6755)
- TX_FAR _ThrewAwayItemText
- db "@"
-
-IsItOKToTossItemText: ; e75a (3:675a)
- TX_FAR _IsItOKToTossItemText
- db "@"
-
-TooImportantToTossText: ; e75f (3:675f)
- TX_FAR _TooImportantToTossText
- db "@"
-
-; checks if an item is a key item
-; INPUT:
-; [wcf91] = item ID
-; OUTPUT:
-; [wd124] = result
-; 00: item is not key item
-; 01: item is key item
-IsKeyItem_: ; e764 (3:6764)
- ld a,$01
- ld [wd124],a
- ld a,[wcf91]
- cp a,HM_01 ; is the item an HM or TM?
- jr nc,.checkIfItemIsHM
-; if the item is not an HM or TM
- push af
- ld hl,KeyItemBitfield
- ld de,wHPBarMaxHP
- ld bc,15 ; only 11 bytes are actually used
- call CopyData
- pop af
- dec a
- ld c,a
- ld hl,wHPBarMaxHP
- ld b,$02 ; test bit
- predef FlagActionPredef ; bitfield operation function
- ld a,c
- and a
- ret nz
-.checkIfItemIsHM
- ld a,[wcf91]
- call IsItemHM
- ret c
- xor a
- ld [wd124],a
- ret
-
-INCLUDE "data/key_items.asm"
-
-SendNewMonToBox: ; e7a4 (3:67a4)
- ld de, W_NUMINBOX ; wda80
- ld a, [de]
- inc a
- ld [de], a
- ld a, [wcf91]
- ld [wd0b5], a
- ld c, a
-.asm_e7b1
- inc de
- ld a, [de]
- ld b, a
- ld a, c
- ld c, b
- ld [de], a
- cp $ff
- jr nz, .asm_e7b1
- call GetMonHeader
- ld hl, wBoxMonOT
- ld bc, $b
- ld a, [W_NUMINBOX] ; wda80
- dec a
- jr z, .asm_e7ee
- dec a
- call AddNTimes
- push hl
- ld bc, $b
- add hl, bc
- ld d, h
- ld e, l
- pop hl
- ld a, [W_NUMINBOX] ; wda80
- dec a
- ld b, a
-.asm_e7db
- push bc
- push hl
- ld bc, $b
- call CopyData
- pop hl
- ld d, h
- ld e, l
- ld bc, $fff5
- add hl, bc
- pop bc
- dec b
- jr nz, .asm_e7db
-.asm_e7ee
- ld hl, wPlayerName ; wd158
- ld de, wBoxMonOT
- ld bc, $b
- call CopyData
- ld a, [W_NUMINBOX] ; wda80
- dec a
- jr z, .asm_e82a
- ld hl, wBoxMonNicks
- ld bc, $b
- dec a
- call AddNTimes
- push hl
- ld bc, $b
- add hl, bc
- ld d, h
- ld e, l
- pop hl
- ld a, [W_NUMINBOX] ; wda80
- dec a
- ld b, a
-.asm_e817
- push bc
- push hl
- ld bc, $b
- call CopyData
- pop hl
- ld d, h
- ld e, l
- ld bc, $fff5
- add hl, bc
- pop bc
- dec b
- jr nz, .asm_e817
-.asm_e82a
- ld hl, wBoxMonNicks
- ld a, $2
- ld [wd07d], a
- predef AskName
- ld a, [W_NUMINBOX] ; wda80
- dec a
- jr z, .asm_e867
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1
- dec a
- call AddNTimes
- push hl
- ld bc, wBoxMon2 - wBoxMon1
- add hl, bc
- ld d, h
- ld e, l
- pop hl
- ld a, [W_NUMINBOX] ; wda80
- dec a
- ld b, a
-.asm_e854
- push bc
- push hl
- ld bc, wBoxMon2 - wBoxMon1
- call CopyData
- pop hl
- ld d, h
- ld e, l
- ld bc, $ffdf
- add hl, bc
- pop bc
- dec b
- jr nz, .asm_e854
-.asm_e867
- ld a, [wEnemyMonLevel] ; wEnemyMonLevel
- ld [wEnemyMonBoxLevel], a
- ld hl, wEnemyMon
- ld de, wBoxMon1
- ld bc, $c
- call CopyData
- ld hl, wPlayerID ; wPlayerID
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hl]
- ld [de], a
- inc de
- push de
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
- ld d, a
- callab CalcExperience
- pop de
- ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
- ld [de], a
- inc de
- ld a, [$ff97]
- ld [de], a
- inc de
- ld a, [$ff98]
- ld [de], a
- inc de
- xor a
- ld b, $a
-.asm_e89f
- ld [de], a
- inc de
- dec b
- jr nz, .asm_e89f
- ld hl, wEnemyMonDVs
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- ld hl, wEnemyMonPP ; wcffe
- ld b, $4
-.asm_e8b1
- ld a, [hli]
- inc de
- ld [de], a
- dec b
- jr nz, .asm_e8b1
- ret
-
-; checks if the tile in front of the player is a shore or water tile
-; used for surfing and fishing
-; unsets carry if it is, sets carry if not
-IsNextTileShoreOrWater: ; e8b8 (3:68b8)
- ld a, [W_CURMAPTILESET]
- ld hl, WaterTilesets
- ld de,1
- call IsInArray
- jr nc, .notShoreOrWater
- ld a, [W_CURMAPTILESET]
- cp SHIP_PORT ; Vermilion Dock tileset
- ld a, [wTileInFrontOfPlayer] ; tile in front of player
- jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
- cp $48 ; eastern shore tile in Safari Zone
- jr z, .shoreOrWater
- cp $32 ; usual eastern shore tile
- jr z, .shoreOrWater
-.skipShoreTiles
- cp $14 ; water tile
- jr z, .shoreOrWater
-.notShoreOrWater
- scf
- ret
-.shoreOrWater
- and a
- ret
-
-; tilesets with water
-WaterTilesets: ; e8e0 (3:68e0)
- db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
- db $ff ; terminator
-
-ReadSuperRodData: ; e8ea (3:68ea)
-; return e = 2 if no fish on this map
-; return e = 1 if a bite, bc = level,species
-; return e = 0 if no bite
- ld a, [W_CURMAP]
- ld de, 3 ; each fishing group is three bytes wide
- ld hl, SuperRodData
- call IsInArray
- jr c, .ReadFishingGroup
- ld e, $2 ; $2 if no fishing groups found
- ret
-
-.ReadFishingGroup ; 0xe8f6
-; hl points to the fishing group entry in the index
- inc hl ; skip map id
-
- ; read fishing group address
- ld a, [hli]
- ld h, [hl]
- ld l, a
-
- ld b, [hl] ; how many mons in group
- inc hl ; point to data
- ld e, $0 ; no bite yet
-
-.RandomLoop ; 0xe90c
- call Random
- srl a
- ret c ; 50% chance of no battle
-
- and %11 ; 2-bit random number
- cp b
- jr nc, .RandomLoop ; if a is greater than the number of mons, regenerate
-
- ; get the mon
- add a
- ld c, a
- ld b, $0
- add hl, bc
- ld b, [hl] ; level
- inc hl
- ld c, [hl] ; species
- ld e, $1 ; $1 if there's a bite
- ret
-
-INCLUDE "data/super_rod.asm"
-
-; reloads map view and processes sprite data
-; for items that cause the overworld to be displayed
-ItemUseReloadOverworldData: ; e9c5 (3:69c5)
- call LoadCurrentMapView
- jp UpdateSprites
-
-; creates a list at wBuffer of maps where the mon in [wd11e] can be found.
-; this is used by the pokedex to display locations the mon can be found on the map.
-FindWildLocationsOfMon: ; e9cb (3:69cb)
- ld hl, WildDataPointers
- ld de, wBuffer
- ld c, $0
-.loop
- inc hl
- ld a, [hld]
- inc a
- jr z, .done
- push hl
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [hli]
- and a
- call nz, CheckMapForMon ; land
- ld a, [hli]
- and a
- call nz, CheckMapForMon ; water
- pop hl
- inc hl
- inc hl
- inc c
- jr .loop
-.done
- ld a, $ff ; list terminator
- ld [de], a
- ret
-
-CheckMapForMon: ; e9f0 (3:69f0)
- inc hl
- ld b, $a
-.loop
- ld a, [wd11e]
- cp [hl]
- jr nz, .nextEntry
- ld a, c
- ld [de], a
- inc de
-.nextEntry
- inc hl
- inc hl
- dec b
- jr nz, .loop
- dec hl
- ret
+UseItem_: ; d5c7 (3:55c7)
+ ld a,1
+ ld [wcd6a],a
+ ld a,[wcf91] ;contains item_ID
+ cp a,HM_01
+ jp nc,ItemUseTMHM
+ ld hl,ItemUsePtrTable
+ dec a
+ add a
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ jp [hl]
+
+ItemUsePtrTable: ; d5e1 (3:55e1)
+ dw ItemUseBall ; MASTER_BALL
+ dw ItemUseBall ; ULTRA_BALL
+ dw ItemUseBall ; GREAT_BALL
+ dw ItemUseBall ; POKE_BALL
+ dw ItemUseTownMap ; TOWN_MAP
+ dw ItemUseBicycle ; BICYCLE
+ dw ItemUseSurfboard ; out-of-battle Surf effect
+ dw ItemUseBall ; SAFARI_BALL
+ dw ItemUsePokedex ; POKEDEX
+ dw ItemUseEvoStone ; MOON_STONE
+ dw ItemUseMedicine ; ANTIDOTE
+ dw ItemUseMedicine ; BURN_HEAL
+ dw ItemUseMedicine ; ICE_HEAL
+ dw ItemUseMedicine ; AWAKENING
+ dw ItemUseMedicine ; PARLYZ_HEAL
+ dw ItemUseMedicine ; FULL_RESTORE
+ dw ItemUseMedicine ; MAX_POTION
+ dw ItemUseMedicine ; HYPER_POTION
+ dw ItemUseMedicine ; SUPER_POTION
+ dw ItemUseMedicine ; POTION
+ dw ItemUseBait ; BOULDERBADGE
+ dw ItemUseRock ; CASCADEBADGE
+ dw UnusableItem ; THUNDERBADGE
+ dw UnusableItem ; RAINBOWBADGE
+ dw UnusableItem ; SOULBADGE
+ dw UnusableItem ; MARSHBADGE
+ dw UnusableItem ; VOLCANOBADGE
+ dw UnusableItem ; EARTHBADGE
+ dw ItemUseEscapeRope ; ESCAPE_ROPE
+ dw ItemUseRepel ; REPEL
+ dw UnusableItem ; OLD_AMBER
+ dw ItemUseEvoStone ; FIRE_STONE
+ dw ItemUseEvoStone ; THUNDER_STONE
+ dw ItemUseEvoStone ; WATER_STONE
+ dw ItemUseVitamin ; HP_UP
+ dw ItemUseVitamin ; PROTEIN
+ dw ItemUseVitamin ; IRON
+ dw ItemUseVitamin ; CARBOS
+ dw ItemUseVitamin ; CALCIUM
+ dw ItemUseVitamin ; RARE_CANDY
+ dw UnusableItem ; DOME_FOSSIL
+ dw UnusableItem ; HELIX_FOSSIL
+ dw UnusableItem ; SECRET_KEY
+ dw UnusableItem
+ dw UnusableItem ; BIKE_VOUCHER
+ dw ItemUseXAccuracy ; X_ACCURACY
+ dw ItemUseEvoStone ; LEAF_STONE
+ dw ItemUseCardKey ; CARD_KEY
+ dw UnusableItem ; NUGGET
+ dw UnusableItem ; ??? PP_UP
+ dw ItemUsePokedoll ; POKE_DOLL
+ dw ItemUseMedicine ; FULL_HEAL
+ dw ItemUseMedicine ; REVIVE
+ dw ItemUseMedicine ; MAX_REVIVE
+ dw ItemUseGuardSpec ; GUARD_SPEC_
+ dw ItemUseSuperRepel ; SUPER_REPL
+ dw ItemUseMaxRepel ; MAX_REPEL
+ dw ItemUseDireHit ; DIRE_HIT
+ dw UnusableItem ; COIN
+ dw ItemUseMedicine ; FRESH_WATER
+ dw ItemUseMedicine ; SODA_POP
+ dw ItemUseMedicine ; LEMONADE
+ dw UnusableItem ; S_S__TICKET
+ dw UnusableItem ; GOLD_TEETH
+ dw ItemUseXStat ; X_ATTACK
+ dw ItemUseXStat ; X_DEFEND
+ dw ItemUseXStat ; X_SPEED
+ dw ItemUseXStat ; X_SPECIAL
+ dw ItemUseCoinCase ; COIN_CASE
+ dw ItemUseOaksParcel ; OAKS_PARCEL
+ dw ItemUseItemfinder ; ITEMFINDER
+ dw UnusableItem ; SILPH_SCOPE
+ dw ItemUsePokeflute ; POKE_FLUTE
+ dw UnusableItem ; LIFT_KEY
+ dw UnusableItem ; EXP__ALL
+ dw OldRodCode ; OLD_ROD
+ dw GoodRodCode ; GOOD_ROD
+ dw SuperRodCode ; SUPER_ROD
+ dw ItemUsePPUp ; PP_UP (real one)
+ dw ItemUsePPRestore ; ETHER
+ dw ItemUsePPRestore ; MAX_ETHER
+ dw ItemUsePPRestore ; ELIXER
+ dw ItemUsePPRestore ; MAX_ELIXER
+
+ItemUseBall: ; d687 (3:5687)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp z,ItemUseNotTime ; not in battle
+ dec a
+ jp nz,ThrowBallAtTrainerMon
+ ld a,[W_BATTLETYPE]
+ dec a
+ jr z,.UseBall
+ ld a,[wPartyCount] ;is Party full?
+ cp a,PARTY_LENGTH
+ jr nz,.UseBall
+ ld a,[W_NUMINBOX] ;is Box full?
+ cp a,MONS_PER_BOX
+ jp z,BoxFullCannotThrowBall
+.UseBall ;$56a7
+;ok, you can use a ball
+ xor a
+ ld [wd11c],a
+ ld a,[W_BATTLETYPE]
+ cp a,2 ;SafariBattle
+ jr nz,.skipSafariZoneCode
+.safariZone
+ ; remove a Safari Ball from inventory
+ ld hl,W_NUMSAFARIBALLS
+ dec [hl]
+.skipSafariZoneCode ;$56b6
+ call GoPAL_SET_CF1C
+ ld a,$43
+ ld [wd11e],a
+ call LoadScreenTilesFromBuffer1 ;restore screenBuffer from Backup
+ ld hl,ItemUseText00
+ call PrintText
+ callab IsGhostBattle
+ ld b,$10
+ jp z,.next12
+ ld a,[W_BATTLETYPE]
+ dec a
+ jr nz,.notOldManBattle
+.oldManBattle
+ ld hl,W_GRASSRATE
+ ld de,wPlayerName
+ ld bc,11
+ call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno glitch)
+ jp .BallSuccess ;$578b
+.notOldManBattle ;$56e9
+ ld a,[W_CURMAP]
+ cp a,POKEMONTOWER_6
+ jr nz,.loop
+ ld a,[wEnemyMonSpecies2]
+ cp a,MAROWAK
+ ld b,$10
+ jp z,.next12
+; if not fighting ghost Marowak, loop until a random number in the current
+; pokeball's allowed range is found
+.loop ;$56fa
+ call Random
+ ld b,a
+ ld hl,wcf91
+ ld a,[hl]
+ cp a,MASTER_BALL
+ jp z,.BallSuccess ;$578b
+ cp a,POKE_BALL
+ jr z,.checkForAilments
+ ld a,200
+ cp b
+ jr c,.loop ;get only numbers <= 200 for Great Ball
+ ld a,[hl]
+ cp a,GREAT_BALL
+ jr z,.checkForAilments
+ ld a,150 ;get only numbers <= 150 for Ultra Ball
+ cp b
+ jr c,.loop
+.checkForAilments ;$571a
+; pokemon can be caught more easily with any (primary) status ailment
+; Frozen/Asleep pokemon are relatively even easier to catch
+; for Frozen/Asleep pokemon, any random number from 0-24 ensures a catch.
+; for the others, a random number from 0-11 ensures a catch.
+ ld a,[wEnemyMonStatus] ;status ailments
+ and a
+ jr z,.noAilments
+ and a, 1 << FRZ | SLP ;is frozen and/or asleep?
+ ld c,12
+ jr z,.notFrozenOrAsleep
+ ld c,25
+.notFrozenOrAsleep ;$5728
+ ld a,b
+ sub c
+ jp c,.BallSuccess ;$578b
+ ld b,a
+.noAilments ;$572e
+ push bc ;save RANDOM number
+ xor a
+ ld [H_MULTIPLICAND],a
+ ld hl,wEnemyMonMaxHP
+ ld a,[hli]
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[hl]
+ ld [H_MULTIPLICAND + 2],a
+ ld a,255
+ ld [H_MULTIPLIER],a
+ call Multiply ; MaxHP * 255
+ ld a,[wcf91]
+ cp a,GREAT_BALL
+ ld a,12 ;any other BallFactor
+ jr nz,.next7
+ ld a,8
+.next7 ;$574d
+ ld [H_DIVISOR],a
+ ld b,4 ; number of bytes in dividend
+ call Divide
+ ld hl,wEnemyMonHP
+ ld a,[hli]
+ ld b,a
+ ld a,[hl]
+
+; explanation: we have a 16-bit value equal to [b << 8 | a].
+; This number is divided by 4. The result is 8 bit (reg. a).
+; Always bigger than zero.
+ srl b
+ rr a
+ srl b
+ rr a ; a = current HP / 4
+ and a
+ jr nz,.next8
+ inc a
+.next8 ;$5766
+ ld [H_DIVISOR],a
+ ld b,4
+ call Divide ; ((MaxHP * 255) / BallFactor) / (CurHP / 4)
+ ld a,[H_QUOTIENT + 2]
+ and a
+ jr z,.next9
+ ld a,255
+ ld [H_QUOTIENT + 3],a
+.next9 ;$5776
+ pop bc
+ ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
+ cp b
+ jr c,.next10
+ ld a,[H_QUOTIENT + 2]
+ and a
+ jr nz,.BallSuccess ; if ((MaxHP * 255) / BallFactor) / (CurHP / 4) > 0x255, automatic success
+ call Random
+ ld b,a
+ ld a,[H_QUOTIENT + 3]
+ cp b
+ jr c,.next10
+.BallSuccess ;$578b
+ jr .BallSuccess2
+.next10 ;$578d
+ ld a,[H_QUOTIENT + 3]
+ ld [wd11e],a
+ xor a
+ ld [H_MULTIPLICAND],a
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
+ ld [H_MULTIPLICAND + 2],a
+ ld a,100
+ ld [H_MULTIPLIER],a
+ call Multiply ; CatchRate * 100
+ ld a,[wcf91]
+ ld b,255
+ cp a,POKE_BALL
+ jr z,.next11
+ ld b,200
+ cp a,GREAT_BALL
+ jr z,.next11
+ ld b,150
+ cp a,ULTRA_BALL
+ jr z,.next11
+.next11 ;$57b8
+ ld a,b
+ ld [H_DIVISOR],a
+ ld b,4
+ call Divide
+ ld a,[H_QUOTIENT + 2]
+ and a
+ ld b,$63
+ jr nz,.next12
+ ld a,[wd11e]
+ ld [H_MULTIPLIER],a
+ call Multiply
+ ld a,255
+ ld [H_DIVISOR],a
+ ld b,4
+ call Divide
+ ld a,[wEnemyMonStatus] ;status ailments
+ and a
+ jr z,.next13
+ and a, 1 << FRZ | SLP
+ ld b,5
+ jr z,.next14
+ ld b,10
+.next14 ;$57e6
+ ld a,[H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3],a
+.next13 ;$57eb
+ ld a,[H_QUOTIENT + 3]
+ cp a,10
+ ld b,$20
+ jr c,.next12
+ cp a,30
+ ld b,$61
+ jr c,.next12
+ cp a,70
+ ld b,$62
+ jr c,.next12
+ ld b,$63
+.next12 ;$5801
+ ld a,b
+ ld [wd11e],a
+.BallSuccess2 ;$5805
+ ld c,20
+ call DelayFrames
+ ld a,TOSS_ANIM
+ ld [W_ANIMATIONID],a
+ xor a
+ ld [$fff3],a
+ ld [wAnimationType],a
+ ld [wDamageMultipliers],a
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ push af
+ predef MoveAnimation
+ pop af
+ ld [wcf91],a
+ pop af
+ ld [wWhichPokemon],a
+ ld a,[wd11e]
+ cp a,$10
+ ld hl,ItemUseBallText00
+ jp z,.printText0
+ cp a,$20
+ ld hl,ItemUseBallText01
+ jp z,.printText0
+ cp a,$61
+ ld hl,ItemUseBallText02
+ jp z,.printText0
+ cp a,$62
+ ld hl,ItemUseBallText03
+ jp z,.printText0
+ cp a,$63
+ ld hl,ItemUseBallText04
+ jp z,.printText0
+ ld hl,wEnemyMonHP ;current HP
+ ld a,[hli]
+ push af
+ ld a,[hli]
+ push af ;backup currentHP...
+ inc hl
+ ld a,[hl]
+ push af ;...and status ailments
+ push hl
+ ld hl,W_ENEMYBATTSTATUS3
+ bit Transformed,[hl]
+ jr z,.next15
+ ld a,$4c
+ ld [wEnemyMonSpecies2],a
+ jr .next16
+.next15 ;$5871
+ set Transformed,[hl]
+ ld hl,wcceb
+ ld a,[wEnemyMonDVs]
+ ld [hli],a
+ ld a,[wEnemyMonDVs + 1]
+ ld [hl],a
+.next16 ;$587e
+ ld a,[wcf91]
+ push af
+ ld a,[wEnemyMonSpecies2]
+ ld [wcf91],a
+ ld a,[wEnemyMonLevel]
+ ld [W_CURENEMYLVL],a
+ callab LoadEnemyMonData
+ pop af
+ ld [wcf91],a
+ pop hl
+ pop af
+ ld [hld],a
+ dec hl
+ pop af
+ ld [hld],a
+ pop af
+ ld [hl],a
+ ld a,[wEnemyMonSpecies] ;enemy
+ ld [wd11c],a
+ ld [wcf91],a
+ ld [wd11e],a
+ ld a,[W_BATTLETYPE]
+ dec a
+ jr z,.printText1
+ ld hl,ItemUseBallText05
+ call PrintText
+ predef IndexToPokedex
+ ld a,[wd11e]
+ dec a
+ ld c,a
+ ld b,2
+ ld hl,wPokedexOwned ;Dex_own_flags (pokemon)
+ predef FlagActionPredef
+ ld a,c
+ push af
+ ld a,[wd11e]
+ dec a
+ ld c,a
+ ld b,1
+ predef FlagActionPredef
+ pop af
+ and a
+ jr nz,.checkParty
+ ld hl,ItemUseBallText06
+ call PrintText
+ call ClearSprites
+ ld a,[wEnemyMonSpecies] ;caught mon_ID
+ ld [wd11e],a
+ predef ShowPokedexData
+.checkParty ;$58f4
+ ld a,[wPartyCount]
+ cp a,PARTY_LENGTH ;is party full?
+ jr z,.sendToBox
+ xor a
+ ld [wcc49],a
+ call ClearSprites
+ call AddPartyMon ;add mon to Party
+ jr .End
+.sendToBox ;$5907
+ call ClearSprites
+ call SendNewMonToBox
+ ld hl,ItemUseBallText07
+ ld a,[wd7f1]
+ bit 0,a ;already met Bill?
+ jr nz,.sendToBox2
+ ld hl,ItemUseBallText08
+.sendToBox2 ;$591a
+ call PrintText
+ jr .End
+.printText1 ;$591f
+ ld hl,ItemUseBallText05
+.printText0 ;$5922
+ call PrintText
+ call ClearSprites
+.End ;$5928
+ ld a,[W_BATTLETYPE]
+ and a
+ ret nz
+ ld hl,wNumBagItems
+ inc a
+ ld [wcf96],a
+ jp RemoveItemFromInventory ;remove ITEM (XXX)
+ItemUseBallText00: ; d937 (3:5937)
+;"It dodged the thrown ball!"
+;"This pokemon can't be caught"
+ TX_FAR _ItemUseBallText00
+ db "@"
+ItemUseBallText01: ; d93c (3:593c)
+;"You missed the pokemon!"
+ TX_FAR _ItemUseBallText01
+ db "@"
+ItemUseBallText02: ; d941 (3:5941)
+;"Darn! The pokemon broke free!"
+ TX_FAR _ItemUseBallText02
+ db "@"
+ItemUseBallText03: ; d946 (3:5946)
+;"Aww! It appeared to be caught!"
+ TX_FAR _ItemUseBallText03
+ db "@"
+ItemUseBallText04: ; d94b (3:594b)
+;"Shoot! It was so close too!"
+ TX_FAR _ItemUseBallText04
+ db "@"
+ItemUseBallText05: ; d950 (3:5950)
+;"All right! {MonName} was caught!"
+;play sound
+ TX_FAR _ItemUseBallText05
+ db $12,$06
+ db "@"
+ItemUseBallText07: ; d957 (3:5957)
+;"X was transferred to Bill's PC"
+ TX_FAR _ItemUseBallText07
+ db "@"
+ItemUseBallText08: ; d95c (3:595c)
+;"X was transferred to someone's PC"
+ TX_FAR _ItemUseBallText08
+ db "@"
+
+ItemUseBallText06: ; d961 (3:5961)
+;"New DEX data will be added..."
+;play sound
+ TX_FAR _ItemUseBallText06
+ db $13,$06
+ db "@"
+
+ItemUseTownMap: ; d968 (3:5968)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld b, BANK(DisplayTownMap)
+ ld hl, DisplayTownMap
+ jp Bankswitch ; display Town Map
+
+ItemUseBicycle: ; d977 (3:5977)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld a,[wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy],a
+ cp a,2 ; is the player surfing?
+ jp z,ItemUseNotTime
+ dec a ; is player already bicycling?
+ jr nz,.tryToGetOnBike
+.getOffBike
+ call ItemUseReloadOverworldData
+ xor a
+ ld [wWalkBikeSurfState],a ; change player state to walking
+ call PlayDefaultMusic ; play walking music
+ ld hl,GotOffBicycleText
+ jr .printText
+.tryToGetOnBike
+ call IsBikeRidingAllowed
+ jp nc,NoCyclingAllowedHere
+ call ItemUseReloadOverworldData
+ xor a ; no keys pressed
+ ld [hJoyHeld],a ; current joypad state
+ inc a
+ ld [wWalkBikeSurfState],a ; change player state to bicycling
+ ld hl,GotOnBicycleText
+ call PlayDefaultMusic ; play bike riding music
+.printText
+ jp PrintText
+
+; used for Surf out-of-battle effect
+ItemUseSurfboard: ; d9b4 (3:59b4)
+ ld a,[wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy],a
+ cp a,2 ; is the player already surfing?
+ jr z,.tryToStopSurfing
+.tryToSurf
+ call IsNextTileShoreOrWater
+ jp c,SurfingAttemptFailed
+ ld hl,TilePairCollisionsWater
+ call CheckForTilePairCollisions
+ jp c,SurfingAttemptFailed
+.surf
+ call .makePlayerMoveForward
+ ld hl,wd730
+ set 7,[hl]
+ ld a,2
+ ld [wWalkBikeSurfState],a ; change player state to surfing
+ call PlayDefaultMusic ; play surfing music
+ ld hl,SurfingGotOnText
+ jp PrintText
+.tryToStopSurfing
+ xor a
+ ld [$ff8c],a
+ ld d,16 ; talking range in pixels (normal range)
+ call IsSpriteInFrontOfPlayer2
+ res 7,[hl]
+ ld a,[$ff8c]
+ and a ; is there a sprite in the way?
+ jr nz,.cannotStopSurfing
+ ld hl,TilePairCollisionsWater
+ call CheckForTilePairCollisions
+ jr c,.cannotStopSurfing
+ ld hl,W_TILESETCOLLISIONPTR ; pointer to list of passable tiles
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a ; hl now points to passable tiles
+ ld a,[wTileInFrontOfPlayer] ; tile in front of the player
+ ld b,a
+.passableTileLoop
+ ld a,[hli]
+ cp b
+ jr z,.stopSurfing
+ cp a,$ff
+ jr nz,.passableTileLoop
+.cannotStopSurfing
+ ld hl,SurfingNoPlaceToGetOffText
+ jp PrintText
+.stopSurfing
+ call .makePlayerMoveForward
+ ld hl,wd730
+ set 7,[hl]
+ xor a
+ ld [wWalkBikeSurfState],a ; change player state to walking
+ dec a
+ ld [wJoyIgnore],a
+ call PlayDefaultMusic ; play walking music
+ jp LoadWalkingPlayerSpriteGraphics
+; uses a simulated button press to make the player move forward
+.makePlayerMoveForward
+ ld a,[wd52a] ; direction the player is going
+ bit 3,a
+ ld b,D_UP
+ jr nz,.storeSimulatedButtonPress
+ bit 2,a
+ ld b,D_DOWN
+ jr nz,.storeSimulatedButtonPress
+ bit 1,a
+ ld b,D_LEFT
+ jr nz,.storeSimulatedButtonPress
+ ld b,D_RIGHT
+.storeSimulatedButtonPress
+ ld a,b
+ ld [wSimulatedJoypadStatesEnd],a
+ xor a
+ ld [wWastedByteCD39],a
+ inc a
+ ld [wSimulatedJoypadStatesIndex],a
+ ret
+
+SurfingGotOnText: ; da4c (3:5a4c)
+ TX_FAR _SurfingGotOnText
+ db "@"
+
+SurfingNoPlaceToGetOffText: ; da51 (3:5a51)
+ TX_FAR _SurfingNoPlaceToGetOffText
+ db "@"
+
+ItemUsePokedex: ; da56 (3:5a56)
+ predef_jump ShowPokedexMenu
+
+ItemUseEvoStone: ; da5b (3:5a5b)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ ld [wd156],a
+ push af
+ ld a,$05 ; evolution stone party menu
+ ld [wd07d],a
+ ld a,$ff
+ ld [wUpdateSpritesEnabled],a
+ call DisplayPartyMenu
+ pop bc
+ jr c,.canceledItemUse
+ ld a,b
+ ld [wcf91],a
+ ld a,$01
+ ld [wccd4],a
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ call WaitForSoundToFinish ; wait for sound to end
+ callab TryEvolvingMon ; try to evolve pokemon
+ ld a,[wd121]
+ and a
+ jr z,.noEffect
+ pop af
+ ld [wWhichPokemon],a
+ ld hl,wNumBagItems
+ ld a,1 ; remove 1 stone
+ ld [wcf96],a
+ jp RemoveItemFromInventory
+.noEffect
+ call ItemUseNoEffect
+.canceledItemUse
+ xor a
+ ld [wcd6a],a
+ pop af
+ ret
+
+ItemUseVitamin: ; dab4 (3:5ab4)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+
+ItemUseMedicine: ; dabb (3:5abb)
+ ld a,[wPartyCount]
+ and a
+ jp z,.emptyParty
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ push af
+ ld a,$01
+ ld [wd07d],a ; item use party menu
+ ld a,$ff
+ ld [wUpdateSpritesEnabled],a
+ ld a,[wd152]
+ and a ; using Softboiled?
+ jr z,.notUsingSoftboiled
+; if using softboiled
+ call GoBackToPartyMenu
+ jr .getPartyMonDataAddress
+.emptyParty
+ ld hl,.emptyPartyText
+ xor a
+ ld [wcd6a],a ; item use failed
+ jp PrintText
+.emptyPartyText
+ text "You don't have"
+ line "any #MON!"
+ prompt
+.notUsingSoftboiled
+ call DisplayPartyMenu
+.getPartyMonDataAddress
+ jp c,.canceledItemUse
+ ld hl,wPartyMons
+ ld bc,wPartyMon2 - wPartyMon1
+ ld a,[wWhichPokemon]
+ call AddNTimes
+ ld a,[wWhichPokemon]
+ ld [wcf06],a
+ ld d,a
+ ld a,[wcf91]
+ ld e,a
+ ld [wd0b5],a
+ pop af
+ ld [wcf91],a
+ pop af
+ ld [wWhichPokemon],a
+ ld a,[wd152]
+ and a ; using Softboiled?
+ jr z,.checkItemType
+; if using softboiled
+ ld a,[wWhichPokemon]
+ cp d ; is the pokemon trying to use softboiled on itself?
+ jr z,ItemUseMedicine ; if so, force another choice
+.checkItemType
+ ld a,[wcf91]
+ cp a,REVIVE
+ jr nc,.healHP ; if it's a Revive or Max Revive
+ cp a,FULL_HEAL
+ jr z,.cureStatusAilment ; if it's a Full Heal
+ cp a,HP_UP
+ jp nc,.useVitamin ; if it's a vitamin or Rare Candy
+ cp a,FULL_RESTORE
+ jr nc,.healHP ; if it's a Full Restore or one of the potions
+; fall through if it's one of the status-specifc healing items
+.cureStatusAilment
+ ld bc,4
+ add hl,bc ; hl now points to status
+ ld a,[wcf91]
+ ld bc,$f008
+ cp a,ANTIDOTE
+ jr z,.checkMonStatus
+ ld bc,$f110
+ cp a,BURN_HEAL
+ jr z,.checkMonStatus
+ ld bc,$f220
+ cp a,ICE_HEAL
+ jr z,.checkMonStatus
+ ld bc,$f307
+ cp a,AWAKENING
+ jr z,.checkMonStatus
+ ld bc,$f440
+ cp a,PARLYZ_HEAL
+ jr z,.checkMonStatus
+ ld bc,$f6ff ; Full Heal
+.checkMonStatus
+ ld a,[hl] ; pokemon's status
+ and c ; does the pokemon have a status ailment the item can cure?
+ jp z,.healingItemNoEffect
+; if the pokemon has a status the item can heal
+ xor a
+ ld [hl],a ; remove the status ailment in the party data
+ ld a,b
+ ld [wd07d],a ; the message to display for the item used
+ ld a,[wPlayerMonNumber]
+ cp d ; is pokemon the item was used on active in battle?
+ jp nz,.doneHealing
+; if it is active in battle
+ xor a
+ ld [wBattleMonStatus],a ; remove the status ailment in the in-battle pokemon data
+ push hl
+ ld hl,W_PLAYERBATTSTATUS3
+ res BadlyPoisoned,[hl] ; heal Toxic status
+ pop hl
+ ld bc,30
+ add hl,bc ; hl now points to party stats
+ ld de,wBattleMonMaxHP
+ ld bc,10
+ call CopyData ; copy party stats to in-battle stat data
+ predef DoubleOrHalveSelectedStats
+ jp .doneHealing
+.healHP
+ inc hl ; hl = address of current HP
+ ld a,[hli]
+ ld b,a
+ ld [wHPBarOldHP+1],a
+ ld a,[hl]
+ ld c,a
+ ld [wHPBarOldHP],a ; current HP stored at wHPBarOldHP (2 bytes, big-endian)
+ or b
+ jr nz,.notFainted
+.fainted
+ ld a,[wcf91]
+ cp a,REVIVE
+ jr z,.updateInBattleFaintedData
+ cp a,MAX_REVIVE
+ jr z,.updateInBattleFaintedData
+ jp .healingItemNoEffect
+.updateInBattleFaintedData
+ ld a,[W_ISINBATTLE]
+ and a
+ jr z,.compareCurrentHPToMaxHP
+ push hl
+ push de
+ push bc
+ ld a,[wcf06]
+ ld c,a
+ ld hl,wPartyFoughtCurrentEnemyFlags
+ ld b,$02
+ predef FlagActionPredef
+ ld a,c
+ and a
+ jr z,.next
+ ld a,[wcf06]
+ ld c,a
+ ld hl,wPartyGainExpFlags
+ ld b,$01
+ predef FlagActionPredef
+.next
+ pop bc
+ pop de
+ pop hl
+ jr .compareCurrentHPToMaxHP
+.notFainted
+ ld a,[wcf91]
+ cp a,REVIVE
+ jp z,.healingItemNoEffect
+ cp a,MAX_REVIVE
+ jp z,.healingItemNoEffect
+.compareCurrentHPToMaxHP
+ push hl
+ push bc
+ ld bc,32
+ add hl,bc ; hl now points to max HP
+ pop bc
+ ld a,[hli]
+ cp b
+ jr nz,.skipComparingLSB ; no need to compare the LSB's if the MSB's don't match
+ ld a,[hl]
+ cp c
+.skipComparingLSB
+ pop hl
+ jr nz,.notFullHP
+.fullHP ; if the pokemon's current HP equals its max HP
+ ld a,[wcf91]
+ cp a,FULL_RESTORE
+ jp nz,.healingItemNoEffect
+ inc hl
+ inc hl
+ ld a,[hld] ; status ailment
+ and a ; does the pokemon have a status ailment?
+ jp z,.healingItemNoEffect
+ ld a,FULL_HEAL
+ ld [wcf91],a
+ dec hl
+ dec hl
+ dec hl
+ jp .cureStatusAilment
+.notFullHP ; if the pokemon's current HP doesn't equal its max HP
+ xor a
+ ld [wLowHealthAlarm],a ;disable low health alarm
+ ld [wc02a],a
+ push hl
+ push de
+ ld bc,32
+ add hl,bc ; hl now points to max HP
+ ld a,[hli]
+ ld [wHPBarMaxHP+1],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a ; max HP stored at wHPBarMaxHP (2 bytes, big-endian)
+ ld a,[wd152]
+ and a ; using Softboiled?
+ jp z,.notUsingSoftboiled2
+; if using softboiled
+ ld hl,wHPBarMaxHP
+ ld a,[hli]
+ push af
+ ld a,[hli]
+ push af
+ ld a,[hli]
+ push af
+ ld a,[hl]
+ push af
+ ld hl,wPartyMon1MaxHP
+ ld a,[wWhichPokemon]
+ ld bc,wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a,[hli]
+ ld [wHPBarMaxHP + 1],a
+ ld [H_DIVIDEND],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a
+ ld [H_DIVIDEND + 1],a
+ ld a,5
+ ld [H_DIVISOR],a
+ ld b,2 ; number of bytes
+ call Divide ; get 1/5 of max HP of pokemon that used Softboiled
+ ld bc,wPartyMon1HP - wPartyMon1MaxHP
+ add hl,bc ; hl now points to LSB of current HP of pokemon that used Softboiled
+; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
+ ld a,[H_QUOTIENT + 3]
+ push af
+ ld b,a
+ ld a,[hl]
+ ld [wHPBarOldHP],a
+ sub b
+ ld [hld],a
+ ld [wHPBarNewHP],a
+ ld a,[H_QUOTIENT + 2]
+ ld b,a
+ ld a,[hl]
+ ld [wHPBarOldHP+1],a
+ sbc b
+ ld [hl],a
+ ld [wHPBarNewHP+1],a
+ hlCoord 4, 1
+ ld a,[wWhichPokemon]
+ ld bc,2 * 20
+ call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
+ ld a,(SFX_02_3d - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ ld a,[hFlags_0xFFF6]
+ set 0,a
+ ld [hFlags_0xFFF6],a
+ ld a,$02
+ ld [wHPBarType],a
+ predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
+ ld a,[hFlags_0xFFF6]
+ res 0,a
+ ld [hFlags_0xFFF6],a
+ pop af
+ ld b,a ; store heal amount (1/5 of max HP)
+ ld hl,wHPBarOldHP + 1
+ pop af
+ ld [hld],a
+ pop af
+ ld [hld],a
+ pop af
+ ld [hld],a
+ pop af
+ ld [hl],a
+ jr .addHealAmount
+.notUsingSoftboiled2
+ ld a,[wcf91]
+ cp a,SODA_POP
+ ld b,60 ; Soda Pop heal amount
+ jr z,.addHealAmount
+ ld b,80 ; Lemonade heal amount
+ jr nc,.addHealAmount
+ cp a,FRESH_WATER
+ ld b,50 ; Fresh Water heal amount
+ jr z,.addHealAmount
+ cp a,SUPER_POTION
+ ld b,200 ; Hyper Potion heal amount
+ jr c,.addHealAmount
+ ld b,50 ; Super Potion heal amount
+ jr z,.addHealAmount
+ ld b,20 ; Potion heal amount
+.addHealAmount
+ pop de
+ pop hl
+ ld a,[hl]
+ add b
+ ld [hld],a
+ ld [wHPBarNewHP],a
+ ld a,[hl]
+ ld [wHPBarNewHP+1],a
+ jr nc,.noCarry
+ inc [hl]
+ ld a,[hl]
+ ld [wHPBarNewHP + 1],a
+.noCarry
+ push de
+ inc hl
+ ld d,h
+ ld e,l ; de now points to current HP
+ ld hl,33
+ add hl,de ; hl now points to max HP
+ ld a,[wcf91]
+ cp a,REVIVE
+ jr z,.setCurrentHPToHalfMaxHP
+ ld a,[hld]
+ ld b,a
+ ld a,[de]
+ sub b
+ dec de
+ ld b,[hl]
+ ld a,[de]
+ sbc b
+ jr nc,.setCurrentHPToMaxHp ; if current HP exceeds max HP after healing
+ ld a,[wcf91]
+ cp a,HYPER_POTION
+ jr c,.setCurrentHPToMaxHp ; if using a Full Restore or Max Potion
+ cp a,MAX_REVIVE
+ jr z,.setCurrentHPToMaxHp ; if using a Max Revive
+ jr .updateInBattleData
+.setCurrentHPToHalfMaxHP
+ dec hl
+ dec de
+ ld a,[hli]
+ srl a
+ ld [de],a
+ ld [wHPBarNewHP+1],a
+ ld a,[hl]
+ rr a
+ inc de
+ ld [de],a
+ ld [wHPBarNewHP],a
+ dec de
+ jr .doneHealingPartyHP
+.setCurrentHPToMaxHp
+ ld a,[hli]
+ ld [de],a
+ ld [wHPBarNewHP+1],a
+ inc de
+ ld a,[hl]
+ ld [de],a
+ ld [wHPBarNewHP],a
+ dec de
+.doneHealingPartyHP ; done updating the pokemon's current HP in the party data structure
+ ld a,[wcf91]
+ cp a,FULL_RESTORE
+ jr nz,.updateInBattleData
+ ld bc,-31
+ add hl,bc
+ xor a
+ ld [hl],a ; remove the status ailment in the party data
+.updateInBattleData
+ ld h,d
+ ld l,e
+ pop de
+ ld a,[wPlayerMonNumber]
+ cp d ; is pokemon the item was used on active in battle?
+ jr nz,.calculateHPBarCoords
+; copy party HP to in-battle HP
+ ld a,[hli]
+ ld [wBattleMonHP],a
+ ld a,[hld]
+ ld [wBattleMonHP + 1],a
+ ld a,[wcf91]
+ cp a,FULL_RESTORE
+ jr nz,.calculateHPBarCoords
+ xor a
+ ld [wBattleMonStatus],a ; remove the status ailment in the in-battle pokemon data
+.calculateHPBarCoords
+ ld hl,wOAMBuffer + $90
+ ld bc,2 * 20
+ inc d
+.calculateHPBarCoordsLoop
+ add hl,bc
+ dec d
+ jr nz,.calculateHPBarCoordsLoop
+ jr .doneHealing
+.healingItemNoEffect
+ call ItemUseNoEffect
+ jp .done
+.doneHealing
+ ld a,[wd152]
+ and a ; using Softboiled?
+ jr nz,.skipRemovingItem ; no item to remove if using Softboiled
+ push hl
+ call RemoveUsedItem
+ pop hl
+.skipRemovingItem
+ ld a,[wcf91]
+ cp a,FULL_RESTORE
+ jr c,.playStatusAilmentCuringSound
+ cp a,FULL_HEAL
+ jr z,.playStatusAilmentCuringSound
+ ld a,(SFX_02_3d - SFX_Headers_02) / 3 ; HP healing sound
+ call PlaySoundWaitForCurrent ; play sound
+ ld a,[hFlags_0xFFF6]
+ set 0,a
+ ld [hFlags_0xFFF6],a
+ ld a,$02
+ ld [wHPBarType],a
+ predef UpdateHPBar2 ; animate the HP bar lengthening
+ ld a,[hFlags_0xFFF6]
+ res 0,a
+ ld [hFlags_0xFFF6],a
+ ld a,$f7 ; revived message
+ ld [wd07d],a
+ ld a,[wcf91]
+ cp a,REVIVE
+ jr z,.showHealingItemMessage
+ cp a,MAX_REVIVE
+ jr z,.showHealingItemMessage
+ ld a,$f5 ; standard HP healed message
+ ld [wd07d],a
+ jr .showHealingItemMessage
+.playStatusAilmentCuringSound
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3 ; status ailment curing sound
+ call PlaySoundWaitForCurrent
+.showHealingItemMessage
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call ClearScreen
+ dec a
+ ld [wUpdateSpritesEnabled],a
+ call RedrawPartyMenu ; redraws the party menu and displays the message
+ ld a,1
+ ld [H_AUTOBGTRANSFERENABLED],a
+ ld c,50
+ call DelayFrames
+ call WaitForTextScrollButtonPress
+ jr .done
+.canceledItemUse
+ xor a
+ ld [wcd6a],a ; item use failed
+ pop af
+ pop af
+.done
+ ld a,[wd152]
+ and a ; using Softboiled?
+ ret nz ; if so, return
+ call GBPalWhiteOut
+ call z,GoPAL_SET_CF1C
+ ld a,[W_ISINBATTLE]
+ and a
+ ret nz
+ jp ReloadMapData
+.useVitamin
+ push hl
+ ld a,[hl]
+ ld [wd0b5],a
+ ld [wd11e],a
+ ld bc,33
+ add hl,bc ; hl now points to level
+ ld a,[hl] ; a = level
+ ld [W_CURENEMYLVL],a ; store level
+ call GetMonHeader
+ push de
+ ld a,d
+ ld hl,wPartyMonNicks
+ call GetPartyMonName
+ pop de
+ pop hl
+ ld a,[wcf91]
+ cp a,RARE_CANDY
+ jp z,.useRareCandy
+ push hl
+ sub a,HP_UP
+ add a
+ ld bc,17
+ add hl,bc
+ add l
+ ld l,a
+ jr nc,.noCarry2
+ inc h
+.noCarry2
+ ld a,10
+ ld b,a
+ ld a,[hl] ; a = MSB of stat experience of the appropriate stat
+ cp a,100 ; is there already at least 25600 (256 * 100) stat experience?
+ jr nc,.vitaminNoEffect ; if so, vitamins can't add any more
+ add b ; add 2560 (256 * 10) stat experience
+ jr nc,.noCarry3 ; a carry should be impossible here, so this will always jump
+ ld a,255
+.noCarry3
+ ld [hl],a
+ pop hl
+ call .recalculateStats
+ ld hl,VitaminText
+ ld a,[wcf91]
+ sub a,HP_UP - 1
+ ld c,a
+.statNameLoop ; loop to get the address of the name of the stat the vitamin increases
+ dec c
+ jr z,.gotStatName
+.statNameInnerLoop
+ ld a,[hli]
+ ld b,a
+ ld a,$50
+ cp b
+ jr nz,.statNameInnerLoop
+ jr .statNameLoop
+.gotStatName
+ ld de,wcf4b
+ ld bc,10
+ call CopyData ; copy the stat's name to wcf4b
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySound ; play sound
+ ld hl,VitaminStatRoseText
+ call PrintText
+ jp RemoveUsedItem
+.vitaminNoEffect
+ pop hl
+ ld hl,VitaminNoEffectText
+ call PrintText
+ jp GBPalWhiteOut
+.recalculateStats
+ ld bc,34
+ add hl,bc
+ ld d,h
+ ld e,l ; de now points to stats
+ ld bc,-18
+ add hl,bc ; hl now points to byte 3 of experience
+ ld b,1
+ jp CalcStats ; recalculate stats
+.useRareCandy
+ push hl
+ ld bc,33
+ add hl,bc ; hl now points to level
+ ld a,[hl] ; a = level
+ cp a, MAX_LEVEL
+ jr z,.vitaminNoEffect ; can't raise level above 100
+ inc a
+ ld [hl],a ; store incremented level
+ ld [W_CURENEMYLVL],a
+ push hl
+ push de
+ ld d,a
+ callab CalcExperience ; calculate experience for next level and store it at $ff96
+ pop de
+ pop hl
+ ld bc,-19
+ add hl,bc ; hl now points to experience
+; update experience to minimum for new level
+ ld a,[$ff96]
+ ld [hli],a
+ ld a,[$ff97]
+ ld [hli],a
+ ld a,[$ff98]
+ ld [hl],a
+ pop hl
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ push af
+ push de
+ push hl
+ ld bc,34
+ add hl,bc ; hl now points to MSB of max HP
+ ld a,[hli]
+ ld b,a
+ ld c,[hl]
+ pop hl
+ push bc
+ push hl
+ call .recalculateStats
+ pop hl
+ ld bc,35 ; hl now points to LSB of max HP
+ add hl,bc
+ pop bc
+ ld a,[hld]
+ sub c
+ ld c,a
+ ld a,[hl]
+ sbc b
+ ld b,a ; bc = the amount of max HP gained from leveling up
+; add the amount gained to the current HP
+ ld de,-32
+ add hl,de ; hl now points to MSB of current HP
+ ld a,[hl]
+ add c
+ ld [hld],a
+ ld a,[hl]
+ adc b
+ ld [hl],a
+ ld a,$f8 ; level up message
+ ld [wd07d],a
+ call RedrawPartyMenu
+ pop de
+ ld a,d
+ ld [wWhichPokemon],a
+ ld a,e
+ ld [wd11e],a
+ xor a
+ ld [wcc49],a ; load from player's party
+ call LoadMonData
+ ld d,$01
+ callab PrintStatsBox ; display new stats text box
+ call WaitForTextScrollButtonPress ; wait for button press
+ xor a
+ ld [wcc49],a
+ predef LearnMoveFromLevelUp ; learn level up move, if any
+ xor a
+ ld [wccd4],a
+ callab TryEvolvingMon ; evolve pokemon, if appropriate
+ ld a,$01
+ ld [wUpdateSpritesEnabled],a
+ pop af
+ ld [wcf91],a
+ pop af
+ ld [wWhichPokemon],a
+ jp RemoveUsedItem
+
+VitaminStatRoseText: ; df24 (3:5f24)
+ TX_FAR _VitaminStatRoseText
+ db "@"
+
+VitaminNoEffectText: ; df29 (3:5f29)
+ TX_FAR _VitaminNoEffectText
+ db "@"
+
+VitaminText: ; df2e (3:5f2e)
+ db "HEALTH@"
+ db "ATTACK@"
+ db "DEFENSE@"
+ db "SPEED@"
+ db "SPECIAL@"
+
+ItemUseBait: ; df52 (3:5f52)
+ ld hl,ThrewBaitText
+ call PrintText
+ ld hl,wEnemyMonCatchRate ; catch rate
+ srl [hl] ; halve catch rate
+ ld a,BAIT_ANIM
+ ld hl,wSafariBaitFactor ; bait factor
+ ld de,wSafariEscapeFactor ; escape factor
+ jr BaitRockCommon
+
+ItemUseRock: ; df67 (3:5f67)
+ ld hl,ThrewRockText
+ call PrintText
+ ld hl,wEnemyMonCatchRate ; catch rate
+ ld a,[hl]
+ add a ; double catch rate
+ jr nc,.noCarry
+ ld a,$ff
+.noCarry
+ ld [hl],a
+ ld a,ROCK_ANIM
+ ld hl,wSafariEscapeFactor ; escape factor
+ ld de,wSafariBaitFactor ; bait factor
+
+BaitRockCommon: ; df7f (3:5f7f)
+ ld [W_ANIMATIONID],a
+ xor a
+ ld [wcc5b],a
+ ld [H_WHOSETURN],a
+ ld [de],a ; zero escape factor (for bait), zero bait factor (for rock)
+.randomLoop ; loop until a random number less than 5 is generated
+ call Random
+ and a,7
+ cp a,5
+ jr nc,.randomLoop
+ inc a ; increment the random number, giving a range from 1 to 5 inclusive
+ ld b,a
+ ld a,[hl]
+ add b ; increase bait factor (for bait), increase escape factor (for rock)
+ jr nc,.noCarry
+ ld a,$ff
+.noCarry
+ ld [hl],a
+ predef MoveAnimation ; do animation
+ ld c,70
+ jp DelayFrames
+
+ThrewBaitText: ; dfa5 (3:5fa5)
+ TX_FAR _ThrewBaitText
+ db "@"
+
+ThrewRockText: ; dfaa (3:5faa)
+ TX_FAR _ThrewRockText
+ db "@"
+
+; also used for Dig out-of-battle effect
+ItemUseEscapeRope: ; dfaf (3:5faf)
+ ld a,[W_ISINBATTLE]
+ and a
+ jr nz,.notUsable
+ ld a,[W_CURMAP]
+ cp a,AGATHAS_ROOM
+ jr z,.notUsable
+ ld a,[W_CURMAPTILESET]
+ ld b,a
+ ld hl,EscapeRopeTilesets
+.loop
+ ld a,[hli]
+ cp a,$ff
+ jr z,.notUsable
+ cp b
+ jr nz,.loop
+ ld hl,wd732
+ set 3,[hl]
+ set 6,[hl]
+ ld hl,wd72e
+ res 4,[hl]
+ ld hl,wd790
+ res 7,[hl] ; unset Safari Zone bit
+ xor a
+ ld [W_NUMSAFARIBALLS],a
+ ld [W_SAFARIZONEENTRANCECURSCRIPT],a
+ inc a
+ ld [wEscapedFromBattle],a
+ ld [wcd6a],a ; item used
+ ld a,[wd152]
+ and a ; using Dig?
+ ret nz ; if so, return
+ call ItemUseReloadOverworldData
+ ld c,30
+ call DelayFrames
+ jp RemoveUsedItem
+.notUsable
+ jp ItemUseNotTime
+
+EscapeRopeTilesets: ; dffd (3:5ffd)
+ db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
+ db $ff ; terminator
+
+ItemUseRepel: ; e003 (3:6003)
+ ld b,100
+
+ItemUseRepelCommon: ; e005 (3:6005)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld a,b
+ ld [wRepelRemainingSteps],a
+ jp PrintItemUseTextAndRemoveItem
+
+; handles X Accuracy item
+ItemUseXAccuracy: ; e013 (3:6013)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp z,ItemUseNotTime
+ ld hl,W_PLAYERBATTSTATUS2
+ set UsingXAccuracy,[hl] ; X Accuracy bit
+ jp PrintItemUseTextAndRemoveItem
+
+; This function is bugged and never works. It always jumps to ItemUseNotTime.
+; The Card Key is handled in a different way.
+ItemUseCardKey: ; e022 (3:6022)
+ xor a
+ ld [wd71f],a
+ call GetTileAndCoordsInFrontOfPlayer
+ ld a,[GetTileAndCoordsInFrontOfPlayer] ; $4586
+ cp a,$18
+ jr nz,.next0
+ ld hl,CardKeyTable1
+ jr .next1
+.next0
+ cp a,$24
+ jr nz,.next2
+ ld hl,CardKeyTable2
+ jr .next1
+.next2
+ cp a,$5e
+ jp nz,ItemUseNotTime
+ ld hl,CardKeyTable3
+.next1
+ ld a,[W_CURMAP]
+ ld b,a
+.loop
+ ld a,[hli]
+ cp a,$ff
+ jp z,ItemUseNotTime
+ cp b
+ jr nz,.nextEntry1
+ ld a,[hli]
+ cp d
+ jr nz,.nextEntry2
+ ld a,[hli]
+ cp e
+ jr nz,.nextEntry3
+ ld a,[hl]
+ ld [wd71f],a
+ jr .done
+.nextEntry1
+ inc hl
+.nextEntry2
+ inc hl
+.nextEntry3
+ inc hl
+ jr .loop
+.done
+ ld hl,ItemUseText00
+ call PrintText
+ ld hl,wd728
+ set 7,[hl]
+ ret
+
+; These tables are probably supposed to be door locations in Silph Co.,
+; but they are unused.
+; The reason there are 3 tables is unknown.
+
+; Format:
+; 00: Map ID
+; 01: Y
+; 02: X
+; 03: ID?
+
+CardKeyTable1: ; e072 (3:6072)
+ db SILPH_CO_2F,$04,$04,$00
+ db SILPH_CO_2F,$04,$05,$01
+ db SILPH_CO_4F,$0C,$04,$02
+ db SILPH_CO_4F,$0C,$05,$03
+ db SILPH_CO_7F,$06,$0A,$04
+ db SILPH_CO_7F,$06,$0B,$05
+ db SILPH_CO_9F,$04,$12,$06
+ db SILPH_CO_9F,$04,$13,$07
+ db SILPH_CO_10F,$08,$0A,$08
+ db SILPH_CO_10F,$08,$0B,$09
+ db $ff
+
+CardKeyTable2: ; e09b (3:609b)
+ db SILPH_CO_3F,$08,$09,$0A
+ db SILPH_CO_3F,$09,$09,$0B
+ db SILPH_CO_5F,$04,$07,$0C
+ db SILPH_CO_5F,$05,$07,$0D
+ db SILPH_CO_6F,$0C,$05,$0E
+ db SILPH_CO_6F,$0D,$05,$0F
+ db SILPH_CO_8F,$08,$07,$10
+ db SILPH_CO_8F,$09,$07,$11
+ db SILPH_CO_9F,$08,$03,$12
+ db SILPH_CO_9F,$09,$03,$13
+ db $ff
+
+CardKeyTable3: ; e0c4 (3:60c4)
+ db SILPH_CO_11F,$08,$09,$14
+ db SILPH_CO_11F,$09,$09,$15
+ db $ff
+
+ItemUsePokedoll: ; e0cd (3:60cd)
+ ld a,[W_ISINBATTLE]
+ dec a
+ jp nz,ItemUseNotTime
+ ld a,$01
+ ld [wEscapedFromBattle],a
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseGuardSpec: ; e0dc (3:60dc)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp z,ItemUseNotTime
+ ld hl,W_PLAYERBATTSTATUS2
+ set ProtectedByMist,[hl] ; Mist bit
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseSuperRepel: ; e0eb (3:60eb)
+ ld b,200
+ jp ItemUseRepelCommon
+
+ItemUseMaxRepel: ; e0f0 (3:60f0)
+ ld b,250
+ jp ItemUseRepelCommon
+
+ItemUseDireHit: ; e0f5 (3:60f5)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp z,ItemUseNotTime
+ ld hl,W_PLAYERBATTSTATUS2
+ set GettingPumped,[hl] ; Focus Energy bit
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseXStat: ; e104 (3:6104)
+ ld a,[W_ISINBATTLE]
+ and a
+ jr nz,.inBattle
+ call ItemUseNotTime
+ ld a,2
+ ld [wcd6a],a ; item not used
+ ret
+.inBattle
+ ld hl,W_PLAYERMOVENUM
+ ld a,[hli]
+ push af ; save [W_PLAYERMOVENUM]
+ ld a,[hl]
+ push af ; save [W_PLAYERMOVEEFFECT]
+ push hl
+ ld a,[wcf91]
+ sub a,X_ATTACK - ATTACK_UP1_EFFECT
+ ld [hl],a ; store player move effect
+ call PrintItemUseTextAndRemoveItem
+ ld a,XSTATITEM_ANIM ; X stat item animation ID
+ ld [W_PLAYERMOVENUM],a
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ call Delay3
+ xor a
+ ld [H_WHOSETURN],a ; set turn to player's turn
+ callba StatModifierUpEffect ; do stat increase move
+ pop hl
+ pop af
+ ld [hld],a ; restore [W_PLAYERMOVEEFFECT]
+ pop af
+ ld [hl],a ; restore [W_PLAYERMOVENUM]
+ ret
+
+ItemUsePokeflute: ; e140 (3:6140)
+ ld a,[W_ISINBATTLE]
+ and a
+ jr nz,.inBattle
+; if not in battle
+ call ItemUseReloadOverworldData
+ ld a,[W_CURMAP]
+ cp a,ROUTE_12
+ jr nz,.notRoute12
+ ld a,[wd7d8]
+ bit 7,a ; has the player beaten Route 12 Snorlax yet?
+ jr nz,.noSnorlaxToWakeUp
+; if the player hasn't beaten Route 12 Snorlax
+ ld hl,Route12SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc,.noSnorlaxToWakeUp
+ ld hl,PlayedFluteHadEffectText
+ call PrintText
+ ld hl,wd7d8
+ set 6,[hl] ; trigger Snorlax fight (handled by map script)
+ ret
+.notRoute12
+ cp a,ROUTE_16
+ jr nz,.noSnorlaxToWakeUp
+ ld a,[wd7e0]
+ bit 1,a ; has the player beaten Route 16 Snorlax yet?
+ jr nz,.noSnorlaxToWakeUp
+; if the player hasn't beaten Route 16 Snorlax
+ ld hl,Route16SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc,.noSnorlaxToWakeUp
+ ld hl,PlayedFluteHadEffectText
+ call PrintText
+ ld hl,wd7e0
+ set 0,[hl] ; trigger Snorlax fight (handled by map script)
+ ret
+.noSnorlaxToWakeUp
+ ld hl,PlayedFluteNoEffectText
+ jp PrintText
+.inBattle
+ xor a
+ ld [wWhichTrade],a ; initialize variable that indicates if any pokemon were woken up to zero
+ ld b,~SLP & $FF
+ ld hl,wPartyMon1Status
+ call WakeUpEntireParty
+ ld a,[W_ISINBATTLE]
+ dec a ; is it a trainer battle?
+ jr z,.skipWakingUpEnemyParty
+; if it's a trainer battle
+ ld hl,wEnemyMon1Status
+ call WakeUpEntireParty
+.skipWakingUpEnemyParty
+ ld hl,wBattleMonStatus
+ ld a,[hl]
+ and b ; remove Sleep status
+ ld [hl],a
+ ld hl,wEnemyMonStatus
+ ld a,[hl]
+ and b ; remove Sleep status
+ ld [hl],a
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ ld a,[wWhichTrade]
+ and a ; were any pokemon asleep before playing the flute?
+ ld hl,PlayedFluteNoEffectText
+ jp z,PrintText ; if no pokemon were asleep
+; if some pokemon were asleep
+ ld hl,PlayedFluteHadEffectText
+ call PrintText
+ ld a,[wLowHealthAlarm]
+ and a,$80
+ jr nz,.skipMusic
+ call WaitForSoundToFinish ; wait for sound to end
+ callba Music_PokeFluteInBattle ; play in-battle pokeflute music
+.musicWaitLoop ; wait for music to finish playing
+ ld a,[wc02c]
+ and a ; music off?
+ jr nz,.musicWaitLoop
+.skipMusic
+ ld hl,FluteWokeUpText
+ jp PrintText
+
+; wakes up all party pokemon
+; INPUT:
+; hl must point to status of first pokemon in party (player's or enemy's)
+; b must equal ~SLP
+; [wWhichTrade] should be initialized to 0
+; OUTPUT:
+; [wWhichTrade]: set to 1 if any pokemon were asleep
+WakeUpEntireParty: ; e1e5 (3:61e5)
+ ld de,44
+ ld c,6
+.loop
+ ld a,[hl]
+ push af
+ and a,SLP ; is pokemon asleep?
+ jr z,.notAsleep
+ ld a,1
+ ld [wWhichTrade],a ; indicate that a pokemon had to be woken up
+.notAsleep
+ pop af
+ and b ; remove Sleep status
+ ld [hl],a
+ add hl,de
+ dec c
+ jr nz,.loop
+ ret
+
+; Format:
+; 00: Y
+; 01: X
+Route12SnorlaxFluteCoords: ; e1fd (3:61fd)
+ db 62,9 ; one space West of Snorlax
+ db 61,10 ; one space North of Snorlax
+ db 63,10 ; one space South of Snorlax
+ db 62,11 ; one space East of Snorlax
+ db $ff ; terminator
+
+; Format:
+; 00: Y
+; 01: X
+Route16SnorlaxFluteCoords: ; e206 (3:6206)
+ db 10,27 ; one space East of Snorlax
+ db 10,25 ; one space West of Snorlax
+ db $ff ; terminator
+
+PlayedFluteNoEffectText: ; e20b (3:620b)
+ TX_FAR _PlayedFluteNoEffectText
+ db "@"
+
+FluteWokeUpText: ; e210 (3:6210)
+ TX_FAR _FluteWokeUpText
+ db "@"
+
+PlayedFluteHadEffectText: ; e215 (3:6215)
+ TX_FAR _PlayedFluteHadEffectText
+ db $06
+ db $08
+ ld a,[W_ISINBATTLE]
+ and a
+ jr nz,.done
+; play out-of-battle pokeflute music
+ ld a,$ff
+ call PlaySound ; turn off music
+ ld a, (SFX_02_5e - SFX_Headers_02) / 3
+ ld c, BANK(SFX_02_5e)
+ call PlayMusic ; play music
+.musicWaitLoop ; wait for music to finish playing
+ ld a,[wc028]
+ cp a,$b8
+ jr z,.musicWaitLoop
+ call PlayDefaultMusic ; start playing normal music again
+.done
+ jp TextScriptEnd ; end text
+
+ItemUseCoinCase: ; e23a (3:623a)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld hl,CoinCaseNumCoinsText
+ jp PrintText
+
+CoinCaseNumCoinsText: ; e247 (3:6247)
+ TX_FAR _CoinCaseNumCoinsText
+ db "@"
+
+OldRodCode: ; e24c (3:624c)
+ call FishingInit
+ jp c, ItemUseNotTime
+ ld bc, (5 << 8) | MAGIKARP
+ ld a, $1 ; set bite
+ jr RodResponse ; 0xe257 $34
+
+GoodRodCode: ; e259 (3:6259)
+ call FishingInit
+ jp c,ItemUseNotTime
+.RandomLoop
+ call Random
+ srl a
+ jr c, .SetBite
+ and %11
+ cp 2
+ jr nc, .RandomLoop
+ ; choose which monster appears
+ ld hl,GoodRodMons
+ add a,a
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld b,[hl]
+ inc hl
+ ld c,[hl]
+ and a
+.SetBite
+ ld a,0
+ rla
+ xor 1
+ jr RodResponse
+
+INCLUDE "data/good_rod.asm"
+
+SuperRodCode: ; e283 (3:6283)
+ call FishingInit
+ jp c, ItemUseNotTime
+ call ReadSuperRodData ; 0xe8ea
+ ld a, e
+RodResponse: ; e28d (3:628d)
+ ld [wWhichTrade], a
+
+ dec a ; is there a bite?
+ jr nz, .next
+ ; if yes, store level and species data
+ ld a, 1
+ ld [W_MOVEMISSED], a
+ ld a, b ; level
+ ld [W_CURENEMYLVL], a
+ ld a, c ; species
+ ld [W_CUROPPONENT], a
+
+.next
+ ld hl, wWalkBikeSurfState
+ ld a, [hl] ; store the value in a
+ push af
+ push hl
+ ld [hl], 0
+ callba Func_707b6
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+
+; checks if fishing is possible and if so, runs initialization code common to all rods
+; unsets carry if fishing is possible, sets carry if not
+FishingInit: ; e2b4 (3:62b4)
+ ld a,[W_ISINBATTLE]
+ and a
+ jr z,.notInBattle
+ scf ; can't fish during battle
+ ret
+.notInBattle
+ call IsNextTileShoreOrWater
+ ret c
+ ld a,[wWalkBikeSurfState]
+ cp a,2 ; Surfing?
+ jr z,.surfing
+ call ItemUseReloadOverworldData
+ ld hl,ItemUseText00
+ call PrintText
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySound ; play sound
+ ld c,80
+ call DelayFrames
+ and a
+ ret
+.surfing
+ scf ; can't fish when surfing
+ ret
+
+ItemUseOaksParcel: ; e2de (3:62de)
+ jp ItemUseNotYoursToUse
+
+ItemUseItemfinder: ; e2e1 (3:62e1)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ call ItemUseReloadOverworldData
+ callba HiddenItemNear ; check for hidden items
+ ld hl,ItemfinderFoundNothingText
+ jr nc,.printText ; if no hidden items
+ ld c,4
+.loop
+ ld a,(SFX_02_4a - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ ld a,(SFX_02_5a - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ dec c
+ jr nz,.loop
+ ld hl,ItemfinderFoundItemText
+.printText
+ jp PrintText
+
+ItemfinderFoundItemText: ; e30d (3:630d)
+ TX_FAR _ItemfinderFoundItemText
+ db "@"
+
+ItemfinderFoundNothingText: ; e312 (3:6312)
+ TX_FAR _ItemfinderFoundNothingText
+ db "@"
+
+ItemUsePPUp: ; e317 (3:6317)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+
+ItemUsePPRestore: ; e31e (3:631e)
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ ld [wWhichTrade],a
+.chooseMon
+ xor a
+ ld [wUpdateSpritesEnabled],a
+ ld a,$01 ; item use party menu
+ ld [wd07d],a
+ call DisplayPartyMenu
+ jr nc,.chooseMove
+ jp .itemNotUsed
+.chooseMove
+ ld a,[wWhichTrade]
+ cp a,ELIXER
+ jp nc,.useElixir ; if Elixir or Max Elixir
+ ld a,$02
+ ld [wMoveMenuType],a
+ ld hl,RaisePPWhichTechniqueText
+ ld a,[wWhichTrade]
+ cp a,ETHER ; is it a PP Up?
+ jr c,.printWhichTechniqueMessage ; if so, print the raise PP message
+ ld hl,RestorePPWhichTechniqueText ; otherwise, print the restore PP message
+.printWhichTechniqueMessage
+ call PrintText
+ xor a
+ ld [wPlayerMoveListIndex],a
+ callab MoveSelectionMenu ; move selection menu
+ ld a,0
+ ld [wPlayerMoveListIndex],a
+ jr nz,.chooseMon
+ ld hl,wPartyMon1Moves
+ ld bc,44
+ call GetSelectedMoveOffset
+ push hl
+ ld a,[hl]
+ ld [wd11e],a
+ call GetMoveName
+ call CopyStringToCF4B ; copy name to wcf4b
+ pop hl
+ ld a,[wWhichTrade]
+ cp a,ETHER
+ jr nc,.useEther ; if Ether or Max Ether
+.usePPUp
+ ld bc,21
+ add hl,bc
+ ld a,[hl] ; move PP
+ cp a,3 << 6 ; have 3 PP Ups already been used?
+ jr c,.PPNotMaxedOut
+ ld hl,PPMaxedOutText
+ call PrintText
+ jr .chooseMove
+.PPNotMaxedOut
+ ld a,[hl]
+ add a,1 << 6 ; increase PP Up count by 1
+ ld [hl],a
+ ld a,1 ; 1 PP Up used
+ ld [wd11e],a
+ call RestoreBonusPP ; add the bonus PP to current PP
+ ld hl,PPIncreasedText
+ call PrintText
+.done
+ pop af
+ ld [wWhichPokemon],a
+ call GBPalWhiteOut
+ call GoPAL_SET_CF1C
+ jp RemoveUsedItem
+.afterRestoringPP ; after using a (Max) Ether/Elixir
+ ld a,[wWhichPokemon]
+ ld b,a
+ ld a,[wPlayerMonNumber]
+ cp b ; is the pokemon whose PP was restored active in battle?
+ jr nz,.skipUpdatingInBattleData
+ ld hl,wPartyMon1PP
+ ld bc,44
+ call AddNTimes
+ ld de,wBattleMonPP
+ ld bc,4
+ call CopyData ; copy party data to in-battle data
+.skipUpdatingInBattleData
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySound
+ ld hl,PPRestoredText
+ call PrintText
+ jr .done
+.useEther
+ call .restorePP
+ jr nz,.afterRestoringPP
+ jp .noEffect
+; unsets zero flag if PP was restored, sets zero flag if not
+; however, this is bugged for Max Ethers and Max Elixirs (see below)
+.restorePP
+ xor a
+ ld [wcc49],a ; party pokemon
+ call GetMaxPP
+ ld hl,wPartyMon1Moves
+ ld bc,44
+ call GetSelectedMoveOffset
+ ld bc,21
+ add hl,bc ; hl now points to move's PP
+ ld a,[wd11e]
+ ld b,a ; b = max PP
+ ld a,[wWhichTrade]
+ cp a,MAX_ETHER
+ jr z,.fullyRestorePP
+ ld a,[hl] ; move PP
+ and a,%00111111 ; lower 6 bit bits store current PP
+ cp b ; does current PP equal max PP?
+ ret z ; if so, return
+ add a,10 ; increase current PP by 10
+; b holds the max PP amount and b will hold the new PP amount.
+; So, if the new amount meets or exceeds the max amount,
+; cap the amount to the max amount by leaving b unchanged.
+; Otherwise, store the new amount in b.
+ cp b ; does the new amount meet or exceed the maximum?
+ jr nc,.storeNewAmount
+ ld b,a
+.storeNewAmount
+ ld a,[hl] ; move PP
+ and a,%11000000 ; PP Up counter bits
+ add b
+ ld [hl],a
+ ret
+.fullyRestorePP
+ ld a,[hl] ; move PP
+; Note that this code has a bug. It doesn't mask out the upper two bits, which
+; are used to count how many PP Ups have been used on the move. So, Max Ethers
+; and Max Elixirs will not be detected as having no effect on a move with full
+; PP if the move has had any PP Ups used on it.
+ cp b ; does current PP equal max PP?
+ ret z
+ jr .storeNewAmount
+.useElixir
+; decrement the item ID so that ELIXER becomes ETHER and MAX_ELIXER becomes MAX_ETHER
+ ld hl,wWhichTrade
+ dec [hl]
+ dec [hl]
+ xor a
+ ld hl,wCurrentMenuItem
+ ld [hli],a
+ ld [hl],a ; zero the counter for number of moves that had their PP restored
+ ld b,4
+; loop through each move and restore PP
+.elixirLoop
+ push bc
+ ld hl,wPartyMon1Moves
+ ld bc,44
+ call GetSelectedMoveOffset
+ ld a,[hl]
+ and a ; does the current slot have a move?
+ jr z,.nextMove
+ call .restorePP
+ jr z,.nextMove
+; if some PP was restored
+ ld hl,wTileBehindCursor ; counter for number of moves that had their PP restored
+ inc [hl]
+.nextMove
+ ld hl,wCurrentMenuItem
+ inc [hl]
+ pop bc
+ dec b
+ jr nz,.elixirLoop
+ ld a,[wTileBehindCursor]
+ and a ; did any moves have their PP restored?
+ jp nz,.afterRestoringPP
+.noEffect
+ call ItemUseNoEffect
+.itemNotUsed
+ call GBPalWhiteOut
+ call GoPAL_SET_CF1C
+ pop af
+ xor a
+ ld [wcd6a],a ; item use failed
+ ret
+
+RaisePPWhichTechniqueText: ; e45d (3:645d)
+ TX_FAR _RaisePPWhichTechniqueText
+ db "@"
+
+RestorePPWhichTechniqueText: ; e462 (3:6462)
+ TX_FAR _RestorePPWhichTechniqueText
+ db "@"
+
+PPMaxedOutText: ; e467 (3:6467)
+ TX_FAR _PPMaxedOutText
+ db "@"
+
+PPIncreasedText: ; e46c (3:646c)
+ TX_FAR _PPIncreasedText
+ db "@"
+
+PPRestoredText: ; e471 (3:6471)
+ TX_FAR _PPRestoredText
+ db "@"
+
+; for items that can't be used from the Item menu
+UnusableItem: ; e476 (3:6476)
+ jp ItemUseNotTime
+
+ItemUseTMHM: ; e479 (3:6479)
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,ItemUseNotTime
+ ld a,[wcf91]
+ sub a,TM_01
+ push af
+ jr nc,.skipAdding
+ add a,55 ; if item is an HM, add 55
+.skipAdding
+ inc a
+ ld [wd11e],a
+ predef TMToMove ; get move ID from TM/HM ID
+ ld a,[wd11e]
+ ld [wMoveNum],a
+ call GetMoveName
+ call CopyStringToCF4B ; copy name to wcf4b
+ pop af
+ ld hl,BootedUpTMText
+ jr nc,.printBootedUpMachineText
+ ld hl,BootedUpHMText
+.printBootedUpMachineText
+ call PrintText
+ ld hl,TeachMachineMoveText
+ call PrintText
+ hlCoord 14, 7
+ ld bc,$080f
+ ld a,TWO_OPTION_MENU
+ ld [wTextBoxID],a
+ call DisplayTextBoxID ; yes/no menu
+ ld a,[wCurrentMenuItem]
+ and a
+ jr z,.useMachine
+ ld a,2
+ ld [wcd6a],a ; item not used
+ ret
+.useMachine
+ ld a,[wWhichPokemon]
+ push af
+ ld a,[wcf91]
+ push af
+.chooseMon
+ ld hl,wcf4b
+ ld de,wd036
+ ld bc,14
+ call CopyData
+ ld a,$ff
+ ld [wUpdateSpritesEnabled],a
+ ld a,$03 ; teach TM/HM party menu
+ ld [wd07d],a
+ call DisplayPartyMenu
+ push af
+ ld hl,wd036
+ ld de,wcf4b
+ ld bc,14
+ call CopyData
+ pop af
+ jr nc,.checkIfAbleToLearnMove
+; if the player canceled teaching the move
+ pop af
+ pop af
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ call GoPAL_SET_CF1C
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen
+.checkIfAbleToLearnMove
+ predef CanLearnTM ; check if the pokemon can learn the move
+ push bc
+ ld a,[wWhichPokemon]
+ ld hl,wPartyMonNicks
+ call GetPartyMonName
+ pop bc
+ ld a,c
+ and a ; can the pokemon learn the move?
+ jr nz,.checkIfAlreadyLearnedMove
+; if the pokemon can't learn the move
+ ld a,(SFX_02_51 - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ ld hl,MonCannotLearnMachineMoveText
+ call PrintText
+ jr .chooseMon
+.checkIfAlreadyLearnedMove
+ callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
+ jr c,.chooseMon
+ predef LearnMove ; teach move
+ pop af
+ ld [wcf91],a
+ pop af
+ ld [wWhichPokemon],a
+ ld a,b
+ and a
+ ret z
+ ld a,[wcf91]
+ call IsItemHM
+ ret c
+ jp RemoveUsedItem
+
+BootedUpTMText: ; e54f (3:654f)
+ TX_FAR _BootedUpTMText
+ db "@"
+
+BootedUpHMText: ; e554 (3:6554)
+ TX_FAR _BootedUpHMText
+ db "@"
+
+TeachMachineMoveText: ; e559 (3:6559)
+ TX_FAR _TeachMachineMoveText
+ db "@"
+
+MonCannotLearnMachineMoveText: ; e55e (3:655e)
+ TX_FAR _MonCannotLearnMachineMoveText
+ db "@"
+
+PrintItemUseTextAndRemoveItem: ; e563 (3:6563)
+ ld hl,ItemUseText00
+ call PrintText
+ ld a,(SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySound ; play sound
+ call WaitForTextScrollButtonPress ; wait for button press
+
+RemoveUsedItem: ; e571 (3:6571)
+ ld hl,wNumBagItems
+ ld a,1 ; one item
+ ld [wcf96],a ; store quantity
+ jp RemoveItemFromInventory
+
+ItemUseNoEffect: ; e57c (3:657c)
+ ld hl,ItemUseNoEffectText
+ jr ItemUseFailed
+
+ItemUseNotTime: ; e581 (3:6581)
+ ld hl,ItemUseNotTimeText
+ jr ItemUseFailed
+
+ItemUseNotYoursToUse: ; e586 (3:6586)
+ ld hl,ItemUseNotYoursToUseText
+ jr ItemUseFailed
+
+ThrowBallAtTrainerMon: ; e58b (3:658b)
+ call GoPAL_SET_CF1C
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ call Delay3
+ ld a,TOSS_ANIM
+ ld [W_ANIMATIONID],a
+ predef MoveAnimation ; do animation
+ ld hl,ThrowBallAtTrainerMonText1
+ call PrintText
+ ld hl,ThrowBallAtTrainerMonText2
+ call PrintText
+ jr RemoveUsedItem
+
+NoCyclingAllowedHere: ; e5ac (3:65ac)
+ ld hl,NoCyclingAllowedHereText
+ jr ItemUseFailed
+
+BoxFullCannotThrowBall: ; e5b1 (3:65b1)
+ ld hl,BoxFullCannotThrowBallText
+ jr ItemUseFailed
+
+SurfingAttemptFailed: ; e5b6 (3:65b6)
+ ld hl,NoSurfingHereText
+
+ItemUseFailed: ; e5b9 (3:65b9)
+ xor a
+ ld [wcd6a],a ; item use failed
+ jp PrintText
+
+ItemUseNotTimeText: ; e5c0 (3:65c0)
+ TX_FAR _ItemUseNotTimeText
+ db "@"
+
+ItemUseNotYoursToUseText: ; e5c5 (3:65c5)
+ TX_FAR _ItemUseNotYoursToUseText
+ db "@"
+
+ItemUseNoEffectText: ; e5ca (3:65ca)
+ TX_FAR _ItemUseNoEffectText
+ db "@"
+
+ThrowBallAtTrainerMonText1: ; e5cf (3:65cf)
+ TX_FAR _ThrowBallAtTrainerMonText1
+ db "@"
+
+ThrowBallAtTrainerMonText2: ; e5d4 (3:65d4)
+ TX_FAR _ThrowBallAtTrainerMonText2
+ db "@"
+
+NoCyclingAllowedHereText: ; e5d9 (3:65d9)
+ TX_FAR _NoCyclingAllowedHereText
+ db "@"
+
+NoSurfingHereText: ; e5de (3:65de)
+ TX_FAR _NoSurfingHereText
+ db "@"
+
+BoxFullCannotThrowBallText: ; e5e3 (3:65e3)
+ TX_FAR _BoxFullCannotThrowBallText
+ db "@"
+
+ItemUseText00: ; e5e8 (3:65e8)
+ TX_FAR _ItemUseText001
+ db $05
+ TX_FAR _ItemUseText002
+ db "@"
+
+GotOnBicycleText: ; e5f2 (3:65f2)
+ TX_FAR _GotOnBicycleText1
+ db $05
+ TX_FAR _GotOnBicycleText2
+ db "@"
+
+GotOffBicycleText: ; e5fc (3:65fc)
+ TX_FAR _GotOffBicycleText1
+ db $05
+ TX_FAR _GotOffBicycleText2
+ db "@"
+
+; restores bonus PP (from PP Ups) when healing at a pokemon center
+; also, when a PP Up is used, it increases the current PP by one PP Up bonus
+; INPUT:
+; [wWhichPokemon] = index of pokemon in party
+; [wd11e] = mode
+; 0: Pokemon Center healing
+; 1: using a PP Up
+; [wCurrentMenuItem] = index of move (when using a PP Up)
+RestoreBonusPP: ; e606 (3:6606)
+ ld hl,wPartyMon1Moves
+ ld bc,44
+ ld a,[wWhichPokemon]
+ call AddNTimes
+ push hl
+ ld de,wcd78 - 1
+ predef LoadMovePPs ; loads the normal max PP of each of the pokemon's moves to wcd78
+ pop hl
+ ld c,21
+ ld b,0
+ add hl,bc ; hl now points to move 1 PP
+ ld de,wcd78
+ ld b,0 ; initialize move counter to zero
+; loop through the pokemon's moves
+.loop
+ inc b
+ ld a,b
+ cp a,5 ; reached the end of the pokemon's moves?
+ ret z ; if so, return
+ ld a,[wd11e]
+ dec a ; using a PP Up?
+ jr nz,.skipMenuItemIDCheck
+; if using a PP Up, check if this is the move it's being used on
+ ld a,[wCurrentMenuItem]
+ inc a
+ cp b
+ jr nz,.nextMove
+.skipMenuItemIDCheck
+ ld a,[hl]
+ and a,%11000000 ; have any PP Ups been used?
+ call nz,AddBonusPP ; if so, add bonus PP
+.nextMove
+ inc hl
+ inc de
+ jr .loop
+
+; adds bonus PP from PP Ups to current PP
+; 1/5 of normal max PP (capped at 7) is added for each PP Up
+; INPUT:
+; [de] = normal max PP
+; [hl] = move PP
+; [wd11e] = max number of times to add bonus
+; set to 1 when using a PP Up, set to 255 otherwise
+AddBonusPP: ; e642 (3:6642)
+ push bc
+ ld a,[de] ; normal max PP of move
+ ld [H_DIVIDEND + 3],a
+ xor a
+ ld [H_DIVIDEND],a
+ ld [H_DIVIDEND + 1],a
+ ld [H_DIVIDEND + 2],a
+ ld a,5
+ ld [H_DIVISOR],a
+ ld b,4
+ call Divide
+ ld a,[hl] ; move PP
+ ld b,a
+ swap a
+ and a,%00001111
+ srl a
+ srl a
+ ld c,a ; c = number of PP Ups used
+.loop
+ ld a,[H_QUOTIENT + 3]
+ cp a,8 ; is the amount greater than or equal to 8?
+ jr c,.addAmount
+ ld a,7 ; cap the amount at 7
+.addAmount
+ add b
+ ld b,a
+ ld a,[wd11e]
+ dec a
+ jr z,.done
+ dec c
+ jr nz,.loop
+.done
+ ld [hl],b
+ pop bc
+ ret
+
+; gets max PP of a pokemon's move (including PP from PP Ups)
+; INPUT:
+; [wWhichPokemon] = index of pokemon within party/box
+; [wcc49] = pokemon source
+; 00: player's party
+; 01: enemy's party
+; 02: current box
+; 03: daycare
+; 04: player's in-battle pokemon
+; [wCurrentMenuItem] = move index
+; OUTPUT:
+; [wd11e] = max PP
+GetMaxPP: ; e677 (3:6677)
+ ld a,[wcc49]
+ and a
+ ld hl,wPartyMon1Moves
+ ld bc,wPartyMon2 - wPartyMon1
+ jr z,.sourceWithMultipleMon
+ ld hl,wEnemyMon1Moves
+ dec a
+ jr z,.sourceWithMultipleMon
+ ld hl,wBoxMon1Moves
+ ld bc,wBoxMon2 - wBoxMon1
+ dec a
+ jr z,.sourceWithMultipleMon
+ ld hl,wDayCareMonMoves
+ dec a
+ jr z,.sourceWithOneMon
+ ld hl,wBattleMonMoves ; player's in-battle pokemon
+.sourceWithOneMon
+ call GetSelectedMoveOffset2
+ jr .next
+.sourceWithMultipleMon
+ call GetSelectedMoveOffset
+.next
+ ld a,[hl]
+ dec a
+ push hl
+ ld hl,Moves
+ ld bc,6
+ call AddNTimes
+ ld de,wcd6d
+ ld a,BANK(Moves)
+ call FarCopyData
+ ld de,wcd72
+ ld a,[de]
+ ld b,a ; b = normal max PP
+ pop hl
+ push bc
+ ld bc,21 ; PP offset if not player's in-battle pokemon data
+ ld a,[wcc49]
+ cp a,4 ; player's in-battle pokemon?
+ jr nz,.addPPOffset
+ ld bc,17 ; PP offset if player's in-battle pokemon data
+.addPPOffset
+ add hl,bc
+ ld a,[hl] ; a = current PP
+ and a,%11000000 ; get PP Up count
+ pop bc
+ or b ; place normal max PP in 6 lower bits of a
+ ld h,d
+ ld l,e
+ inc hl ; hl = wcd73
+ ld [hl],a
+ xor a
+ ld [wd11e],a ; no limit on PP Up amount
+ call AddBonusPP ; add bonus PP from PP Ups
+ ld a,[hl]
+ and a,%00111111 ; mask out the PP Up count
+ ld [wd11e],a ; store max PP
+ ret
+
+GetSelectedMoveOffset: ; e6e3 (3:66e3)
+ ld a,[wWhichPokemon]
+ call AddNTimes
+
+GetSelectedMoveOffset2: ; e6e9 (3:66e9)
+ ld a,[wCurrentMenuItem]
+ ld c,a
+ ld b,0
+ add hl,bc
+ ret
+
+; confirms the item toss and then tosses the item
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wWhichPokemon] = index of item within inventory
+; [wcf96] = quantity to toss
+; OUTPUT:
+; clears carry flag if the item is tossed, sets carry flag if not
+TossItem_: ; e6f1 (3:66f1)
+ push hl
+ ld a,[wcf91]
+ call IsItemHM
+ pop hl
+ jr c,.tooImportantToToss
+ push hl
+ call IsKeyItem_
+ ld a,[wd124]
+ pop hl
+ and a
+ jr nz,.tooImportantToToss
+ push hl
+ ld a,[wcf91]
+ ld [wd11e],a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld hl,IsItOKToTossItemText
+ call PrintText
+ hlCoord 14, 7
+ ld bc,$080f
+ ld a,TWO_OPTION_MENU
+ ld [wTextBoxID],a
+ call DisplayTextBoxID ; yes/no menu
+ ld a,[wd12e]
+ cp a,2
+ pop hl
+ scf
+ ret z
+; if the player chose Yes
+ push hl
+ ld a,[wWhichPokemon]
+ call RemoveItemFromInventory
+ ld a,[wcf91]
+ ld [wd11e],a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld hl,ThrewAwayItemText
+ call PrintText
+ pop hl
+ and a
+ ret
+.tooImportantToToss
+ push hl
+ ld hl,TooImportantToTossText
+ call PrintText
+ pop hl
+ scf
+ ret
+
+ThrewAwayItemText: ; e755 (3:6755)
+ TX_FAR _ThrewAwayItemText
+ db "@"
+
+IsItOKToTossItemText: ; e75a (3:675a)
+ TX_FAR _IsItOKToTossItemText
+ db "@"
+
+TooImportantToTossText: ; e75f (3:675f)
+ TX_FAR _TooImportantToTossText
+ db "@"
+
+; checks if an item is a key item
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wd124] = result
+; 00: item is not key item
+; 01: item is key item
+IsKeyItem_: ; e764 (3:6764)
+ ld a,$01
+ ld [wd124],a
+ ld a,[wcf91]
+ cp a,HM_01 ; is the item an HM or TM?
+ jr nc,.checkIfItemIsHM
+; if the item is not an HM or TM
+ push af
+ ld hl,KeyItemBitfield
+ ld de,wHPBarMaxHP
+ ld bc,15 ; only 11 bytes are actually used
+ call CopyData
+ pop af
+ dec a
+ ld c,a
+ ld hl,wHPBarMaxHP
+ ld b,$02 ; test bit
+ predef FlagActionPredef ; bitfield operation function
+ ld a,c
+ and a
+ ret nz
+.checkIfItemIsHM
+ ld a,[wcf91]
+ call IsItemHM
+ ret c
+ xor a
+ ld [wd124],a
+ ret
+
+INCLUDE "data/key_items.asm"
+
+SendNewMonToBox: ; e7a4 (3:67a4)
+ ld de, W_NUMINBOX ; wda80
+ ld a, [de]
+ inc a
+ ld [de], a
+ ld a, [wcf91]
+ ld [wd0b5], a
+ ld c, a
+.asm_e7b1
+ inc de
+ ld a, [de]
+ ld b, a
+ ld a, c
+ ld c, b
+ ld [de], a
+ cp $ff
+ jr nz, .asm_e7b1
+ call GetMonHeader
+ ld hl, wBoxMonOT
+ ld bc, $b
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ jr z, .asm_e7ee
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, $b
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ ld b, a
+.asm_e7db
+ push bc
+ push hl
+ ld bc, $b
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, $fff5
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e7db
+.asm_e7ee
+ ld hl, wPlayerName ; wd158
+ ld de, wBoxMonOT
+ ld bc, $b
+ call CopyData
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ jr z, .asm_e82a
+ ld hl, wBoxMonNicks
+ ld bc, $b
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, $b
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ ld b, a
+.asm_e817
+ push bc
+ push hl
+ ld bc, $b
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, $fff5
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e817
+.asm_e82a
+ ld hl, wBoxMonNicks
+ ld a, $2
+ ld [wd07d], a
+ predef AskName
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ jr z, .asm_e867
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [W_NUMINBOX] ; wda80
+ dec a
+ ld b, a
+.asm_e854
+ push bc
+ push hl
+ ld bc, wBoxMon2 - wBoxMon1
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, $ffdf
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e854
+.asm_e867
+ ld a, [wEnemyMonLevel] ; wEnemyMonLevel
+ ld [wEnemyMonBoxLevel], a
+ ld hl, wEnemyMon
+ ld de, wBoxMon1
+ ld bc, $c
+ call CopyData
+ ld hl, wPlayerID ; wPlayerID
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ inc de
+ push de
+ ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld d, a
+ callab CalcExperience
+ pop de
+ ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
+ ld [de], a
+ inc de
+ ld a, [$ff97]
+ ld [de], a
+ inc de
+ ld a, [$ff98]
+ ld [de], a
+ inc de
+ xor a
+ ld b, $a
+.asm_e89f
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_e89f
+ ld hl, wEnemyMonDVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld hl, wEnemyMonPP ; wcffe
+ ld b, $4
+.asm_e8b1
+ ld a, [hli]
+ inc de
+ ld [de], a
+ dec b
+ jr nz, .asm_e8b1
+ ret
+
+; checks if the tile in front of the player is a shore or water tile
+; used for surfing and fishing
+; unsets carry if it is, sets carry if not
+IsNextTileShoreOrWater: ; e8b8 (3:68b8)
+ ld a, [W_CURMAPTILESET]
+ ld hl, WaterTilesets
+ ld de,1
+ call IsInArray ; does the current map allow surfing?
+ ret nc ; if not, return
+ ld hl,WaterTile
+ ld a, [W_CURMAPTILESET]
+ cp SHIP_PORT ; Vermilion Dock tileset
+ jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
+ cp GYM ; eastern shore tile in Safari Zone
+ jr z, .skipShoreTiles
+ cp DOJO ; usual eastern shore tile
+ jr z, .skipShoreTiles
+ ld hl,ShoreTiles
+.skipShoreTiles
+ ld a,[wTileInFrontOfPlayer]
+ ld de,$1
+ call IsInArray
+ ret
+
+; tilesets with water
+WaterTilesets: ; e834 (3:6834)
+ db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
+ db $ff ; terminator
+
+; shore tiles
+ShoreTiles: ; e83e (3:683e)
+ db $48, $32
+WaterTile: ; e840 (3:6840)
+ db $14
+ db $ff ; terminator
+
+ReadSuperRodData: ; e8ea (3:68ea)
+; return e = 2 if no fish on this map
+; return e = 1 if a bite, bc = level,species
+; return e = 0 if no bite
+ ld a, [W_CURMAP]
+ ld de, 3 ; each fishing group is three bytes wide
+ ld hl, SuperRodData
+ call IsInArray
+ jr c, .ReadFishingGroup
+ ld e, $2 ; $2 if no fishing groups found
+ ret
+
+.ReadFishingGroup ; 0xe8f6
+; hl points to the fishing group entry in the index
+ inc hl ; skip map id
+
+ ; read fishing group address
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ ld b, [hl] ; how many mons in group
+ inc hl ; point to data
+ ld e, $0 ; no bite yet
+
+.RandomLoop ; 0xe90c
+ call Random
+ srl a
+ ret c ; 50% chance of no battle
+
+ and %11 ; 2-bit random number
+ cp b
+ jr nc, .RandomLoop ; if a is greater than the number of mons, regenerate
+
+ ; get the mon
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl] ; level
+ inc hl
+ ld c, [hl] ; species
+ ld e, $1 ; $1 if there's a bite
+ ret
+
+INCLUDE "data/super_rod.asm"
+
+; reloads map view and processes sprite data
+; for items that cause the overworld to be displayed
+ItemUseReloadOverworldData: ; e9c5 (3:69c5)
+ call LoadCurrentMapView
+ jp UpdateSprites
+
+; creates a list at wBuffer of maps where the mon in [wd11e] can be found.
+; this is used by the pokedex to display locations the mon can be found on the map.
+FindWildLocationsOfMon: ; e9cb (3:69cb)
+ ld hl, WildDataPointers
+ ld de, wBuffer
+ ld c, $0
+.loop
+ inc hl
+ ld a, [hld]
+ inc a
+ jr z, .done
+ push hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [hli]
+ and a
+ call nz, CheckMapForMon ; land
+ ld a, [hli]
+ and a
+ call nz, CheckMapForMon ; water
+ pop hl
+ inc hl
+ inc hl
+ inc c
+ jr .loop
+.done
+ ld a, $ff ; list terminator
+ ld [de], a
+ ret
+
+CheckMapForMon: ; e9f0 (3:69f0)
+ inc hl
+ ld b, $a
+.loop
+ ld a, [wd11e]
+ cp [hl]
+ jr nz, .nextEntry
+ ld a, c
+ ld [de], a
+ inc de
+.nextEntry
+ inc hl
+ inc hl
+ dec b
+ jr nz, .loop
+ dec hl
+ ret
diff --git a/engine/overworld/map_sprites.asm b/engine/overworld/map_sprites.asm
index df39d112..54312c6f 100755
--- a/engine/overworld/map_sprites.asm
+++ b/engine/overworld/map_sprites.asm
@@ -1,440 +1,440 @@
-; Loads tile patterns for map's sprites.
-; For outside maps, it loads one of several fixed sets of sprites.
-; For inside maps, it loads each sprite picture ID used in the map header.
-; This is also called after displaying text because loading
-; text tile patterns overwrites half of the sprite tile pattern data.
-; Note on notation:
-; $C1X* and $C2X* are used to denote wSpriteStateData1-wSpriteStateData1 + $ff and wSpriteStateData2 + $00-wSpriteStateData2 + $ff sprite slot
-; fields, respectively, within loops. The X is the loop index.
-; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y*
-; denote fields of the sprite slots interated over in the inner loop.
-InitMapSprites: ; 1785b (5:785b)
- call InitOutsideMapSprites
- ret c ; return if the map is an outside map (already handled by above call)
-; if the map is an inside map (i.e. mapID >= $25)
- ld hl,wSpriteStateData1
- ld de,wSpriteStateData2 + $0d
-; Loop to copy picture ID's from $C1X0 to $C2XD for LoadMapSpriteTilePatterns.
-.copyPictureIDLoop
- ld a,[hl] ; $C1X0 (picture ID)
- ld [de],a ; $C2XD
- ld a,$10
- add e
- ld e,a
- ld a,$10
- add l
- ld l,a
- jr nz,.copyPictureIDLoop
-
-; This is used for both inside and outside maps, since it is called by
-; InitOutsideMapSprites.
-; Loads tile pattern data for sprites into VRAM.
-LoadMapSpriteTilePatterns: ; 17871 (5:7871)
- ld a,[W_NUMSPRITES]
- and a ; are there any sprites?
- jr nz,.spritesExist
- ret
-.spritesExist
- ld c,a ; c = [W_NUMSPRITES]
- ld b,$10 ; number of sprite slots
- ld hl,wSpriteStateData2 + $0d
- xor a
- ld [$ff8e],a ; 4-tile sprite counter
-.copyPictureIDLoop ; loop to copy picture ID from $C2XD to $C2XE
- ld a,[hli] ; $C2XD (sprite picture ID)
- ld [hld],a ; $C2XE
- ld a,l
- add a,$10
- ld l,a
- dec b
- jr nz,.copyPictureIDLoop
- ld hl,wSpriteStateData2 + $1e
-.loadTilePatternLoop
- ld de,wSpriteStateData2 + $1d
-; Check if the current picture ID has already had its tile patterns loaded.
-; This done by looping through the previous sprite slots and seeing if any of
-; their picture ID's match that of the current sprite slot.
-.checkIfAlreadyLoadedLoop
- ld a,e
- and a,$f0
- ld b,a ; b = offset of the wSpriteStateData2 sprite slot being checked against
- ld a,l
- and a,$f0 ; a = offset of current wSpriteStateData2 sprite slot
- cp b ; done checking all previous sprite slots?
- jr z,.notAlreadyLoaded
- ld a,[de] ; picture ID of the wSpriteStateData2 sprite slot being checked against
- cp [hl] ; do the picture ID's match?
- jp z,.alreadyLoaded
- ld a,e
- add a,$10
- ld e,a
- jr .checkIfAlreadyLoadedLoop
-.notAlreadyLoaded
- ld de,wSpriteStateData2 + $0e
- ld b,$01
-; loop to find the highest tile pattern VRAM slot (among the first 10 slots) used by a previous sprite slot
-; this is done in order to find the first free VRAM slot available
-.findNextVRAMSlotLoop
- ld a,e
- add a,$10
- ld e,a
- ld a,l
- cp e ; reached current slot?
- jr z,.foundNextVRAMSlot
- ld a,[de] ; $C2YE (VRAM slot)
- cp a,11 ; is it one of the first 10 slots?
- jr nc,.findNextVRAMSlotLoop
- cp b ; compare the slot being checked to the current max
- jr c,.findNextVRAMSlotLoop ; if the slot being checked is less than the current max
-; if the slot being checked is greater than or equal to the current max
- ld b,a ; store new max VRAM slot
- jr .findNextVRAMSlotLoop
-.foundNextVRAMSlot
- inc b ; increment previous max value to get next VRAM tile pattern slot
- ld a,b ; a = next VRAM tile pattern slot
- push af
- ld a,[hl] ; $C2XE (sprite picture ID)
- ld b,a ; b = current sprite picture ID
- cp a,SPRITE_BALL ; is it a 4-tile sprite?
- jr c,.notFourTileSprite
- pop af
- ld a,[$ff8e] ; 4-tile sprite counter
- add a,11
- jr .storeVRAMSlot
-.notFourTileSprite
- pop af
-.storeVRAMSlot
- ld [hl],a ; store VRAM slot at $C2XE
- ld [$ff8d],a ; used to determine if it's 4-tile sprite later
- ld a,b ; a = current sprite picture ID
- dec a
- add a
- add a
- push bc
- push hl
- ld hl,SpriteSheetPointerTable
- jr nc,.noCarry
- inc h
-.noCarry
- add l
- ld l,a
- jr nc,.noCarry2
- inc h
-.noCarry2
- push hl
- call ReadSpriteSheetData
- push af
- push de
- push bc
- ld hl,vNPCSprites ; VRAM base address
- ld bc,$c0 ; number of bytes per VRAM slot
- ld a,[$ff8d]
- cp a,11 ; is it a 4-tile sprite?
- jr nc,.fourTileSpriteVRAMAddr
- ld d,a
- dec d
-; Equivalent to multiplying $C0 (number of bytes in 12 tiles) times the VRAM
-; slot and adding the result to $8000 (the VRAM base address).
-.calculateVRAMAddrLoop
- add hl,bc
- dec d
- jr nz,.calculateVRAMAddrLoop
- jr .loadStillTilePattern
-.fourTileSpriteVRAMAddr
- ld hl,vSprites + $7c0 ; address for second 4-tile sprite
- ld a,[$ff8e] ; 4-tile sprite counter
- and a ; is it the first 4-tile sprite?
- jr nz,.loadStillTilePattern
-; if it's the first 4-tile sprite
- ld hl,vSprites + $780 ; address for first 4-tile sprite
- inc a
- ld [$ff8e],a ; 4-tile sprite counter
-.loadStillTilePattern
- pop bc
- pop de
- pop af
- push hl
- push hl
- ld h,d
- ld l,e
- pop de
- ld b,a
- ld a,[wFontLoaded]
- bit 0,a ; reloading upper half of tile patterns after displaying text?
- jr nz,.skipFirstLoad ; if so, skip loading data into the lower half
- ld a,b
- ld b,0
- call FarCopyData2 ; load tile pattern data for sprite when standing still
-.skipFirstLoad
- pop de
- pop hl
- ld a,[$ff8d]
- cp a,11 ; is it a 4-tile sprite?
- jr nc,.skipSecondLoad ; if so, there is no second block
- push de
- call ReadSpriteSheetData
- push af
- ld a,$c0
- add e
- ld e,a
- jr nc,.noCarry3
- inc d
-.noCarry3
- ld a,[wFontLoaded]
- bit 0,a ; reloading upper half of tile patterns after displaying text?
- jr nz,.loadWhileLCDOn
- pop af
- pop hl
- set 3,h ; add $800 to hl
- push hl
- ld h,d
- ld l,e
- pop de
- call FarCopyData2 ; load tile pattern data for sprite when walking
- jr .skipSecondLoad
-; When reloading the upper half of tile patterns after diplaying text, the LCD
-; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must
-; be used instead of FarCopyData2.
-.loadWhileLCDOn
- pop af
- pop hl
- set 3,h ; add $800 to hl
- ld b,a
- swap c
- call CopyVideoData ; load tile pattern data for sprite when walking
-.skipSecondLoad
- pop hl
- pop bc
- jr .nextSpriteSlot
-.alreadyLoaded ; if the current picture ID has already had its tile patterns loaded
- inc de
- ld a,[de] ; a = VRAM slot for the current picture ID (from $C2YE)
- ld [hl],a ; store VRAM slot in current wSpriteStateData2 sprite slot (at $C2XE)
-.nextSpriteSlot
- ld a,l
- add a,$10
- ld l,a
- dec c
- jp nz,.loadTilePatternLoop
- ld hl,wSpriteStateData2 + $0d
- ld b,$10
-; the pictures ID's stored at $C2XD are no longer needed, so zero them
-.zeroStoredPictureIDLoop
- xor a
- ld [hl],a ; $C2XD
- ld a,$10
- add l
- ld l,a
- dec b
- jr nz,.zeroStoredPictureIDLoop
- ret
-
-; reads data from SpriteSheetPointerTable
-; INPUT:
-; hl = address of sprite sheet entry
-; OUTPUT:
-; de = pointer to sprite sheet
-; bc = length in bytes
-; a = ROM bank
-ReadSpriteSheetData: ; 17971 (5:7971)
- ld a,[hli]
- ld e,a
- ld a,[hli]
- ld d,a
- ld a,[hli]
- ld c,a
- xor a
- ld b,a
- ld a,[hli]
- ret
-
-; Loads sprite set for outside maps (cities and routes) and sets VRAM slots.
-; sets carry if the map is a city or route, unsets carry if not
-InitOutsideMapSprites: ; 1797b (5:797b)
- ld a,[W_CURMAP]
- cp a,REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)?
- ret nc ; if not, return
- ld hl,MapSpriteSets
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- ld a,[hl] ; a = spriteSetID
- cp a,$f0 ; does the map have 2 sprite sets?
- call nc,GetSplitMapSpriteSetID ; if so, choose the appropriate one
- ld b,a ; b = spriteSetID
- ld a,[wFontLoaded]
- bit 0,a ; reloading upper half of tile patterns after displaying text?
- jr nz,.loadSpriteSet ; if so, forcibly reload the sprite set
- ld a,[W_SPRITESETID]
- cp b ; has the sprite set ID changed?
- jr z,.skipLoadingSpriteSet ; if not, don't load it again
-.loadSpriteSet
- ld a,b
- ld [W_SPRITESETID],a
- dec a
- ld b,a
- sla a
- ld c,a
- sla a
- sla a
- add c
- add b ; a = (spriteSetID - 1) * 11
- ld de,SpriteSets
-; add a to de to get offset of sprite set
- add e
- ld e,a
- jr nc,.noCarry2
- inc d
-.noCarry2
- ld hl,wSpriteStateData2 + $0d
- ld a,SPRITE_RED
- ld [hl],a
- ld bc,W_SPRITESET
-; Load the sprite set into RAM.
-; This loop also fills $C2XD (sprite picture ID) where X is from $0 to $A
-; with picture ID's. This is done so that LoadMapSpriteTilePatterns will
-; load tile patterns for all sprite pictures in the sprite set.
-.loadSpriteSetLoop
- ld a,$10
- add l
- ld l,a
- ld a,[de] ; sprite picture ID from sprite set
- ld [hl],a ; $C2XD (sprite picture ID)
- ld [bc],a
- inc de
- inc bc
- ld a,l
- cp a,$bd ; reached 11th sprite slot?
- jr nz,.loadSpriteSetLoop
- ld b,4 ; 4 remaining sprite slots
-.zeroRemainingSlotsLoop ; loop to zero the picture ID's of the remaining sprite slots
- ld a,$10
- add l
- ld l,a
- xor a
- ld [hl],a ; $C2XD (sprite picture ID)
- dec b
- jr nz,.zeroRemainingSlotsLoop
- ld a,[W_NUMSPRITES]
- push af ; save number of sprites
- ld a,11 ; 11 sprites in sprite set
- ld [W_NUMSPRITES],a
- call LoadMapSpriteTilePatterns
- pop af
- ld [W_NUMSPRITES],a ; restore number of sprites
- ld hl,wSpriteStateData2 + $1e
- ld b,$0f
-; The VRAM tile pattern slots that LoadMapSpriteTilePatterns set are in the
-; order of the map's sprite set, not the order of the actual sprites loaded
-; for the current map. So, they are not needed and are zeroed by this loop.
-.zeroVRAMSlotsLoop
- xor a
- ld [hl],a ; $C2XE (VRAM slot)
- ld a,$10
- add l
- ld l,a
- dec b
- jr nz,.zeroVRAMSlotsLoop
-.skipLoadingSpriteSet
- ld hl,wSpriteStateData1 + $10
-; This loop stores the correct VRAM tile pattern slots according the sprite
-; data from the map's header. Since the VRAM tile pattern slots are filled in
-; the order of the sprite set, in order to find the VRAM tile pattern slot
-; for a sprite slot, the picture ID for the sprite is looked up within the
-; sprite set. The index of the picture ID within the sprite set plus one
-; (since the Red sprite always has the first VRAM tile pattern slot) is the
-; VRAM tile pattern slot.
-.storeVRAMSlotsLoop
- ld c,0
- ld a,[hl] ; $C1X0 (picture ID) (zero if sprite slot is not used)
- and a ; is the sprite slot used?
- jr z,.skipGettingPictureIndex ; if the sprite slot is not used
- ld b,a ; b = picture ID
- ld de,W_SPRITESET
-; Loop to find the index of the sprite's picture ID within the sprite set.
-.getPictureIndexLoop
- inc c
- ld a,[de]
- inc de
- cp b ; does the picture ID match?
- jr nz,.getPictureIndexLoop
- inc c
-.skipGettingPictureIndex
- push hl
- inc h
- ld a,$0e
- add l
- ld l,a
- ld a,c ; a = VRAM slot (zero if sprite slot is not used)
- ld [hl],a ; $C2XE (VRAM slot)
- pop hl
- ld a,$10
- add l
- ld l,a
- and a
- jr nz,.storeVRAMSlotsLoop
- scf
- ret
-
-; Chooses the correct sprite set ID depending on the player's position within
-; the map for maps with two sprite sets.
-GetSplitMapSpriteSetID: ; 17a1a (5:7a1a)
- cp a,$f8
- jr z,.route20
- ld hl,SplitMapSpriteSets
- and a,$0f
- dec a
- sla a
- sla a
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- ld a,[hli] ; determines whether the map is split East/West or North/South
- cp a,$01
- ld a,[hli] ; position of dividing line
- ld b,a
- jr z,.eastWestDivide
-.northSouthDivide
- ld a,[W_YCOORD]
- jr .compareCoord
-.eastWestDivide
- ld a,[W_XCOORD]
-.compareCoord
- cp b
- jr c,.loadSpriteSetID
-; if in the East side or South side
- inc hl
-.loadSpriteSetID
- ld a,[hl]
- ret
-; Uses sprite set $01 for West side and $0A for East side.
-; Route 20 is a special case because the two map sections have a more complex
-; shape instead of the map simply being split horizontally or vertically.
-.route20
- ld hl,W_XCOORD
- ld a,[hl]
- cp a,$2b
- ld a,$01
- ret c
- ld a,[hl]
- cp a,$3e
- ld a,$0a
- ret nc
- ld a,[hl]
- cp a,$37
- ld b,$08
- jr nc,.next
- ld b,$0d
-.next
- ld a,[W_YCOORD]
- cp b
- ld a,$0a
- ret c
- ld a,$01
- ret
-
-INCLUDE "data/sprite_sets.asm"
+; Loads tile patterns for map's sprites.
+; For outside maps, it loads one of several fixed sets of sprites.
+; For inside maps, it loads each sprite picture ID used in the map header.
+; This is also called after displaying text because loading
+; text tile patterns overwrites half of the sprite tile pattern data.
+; Note on notation:
+; $C1X* and $C2X* are used to denote wSpriteStateData1-wSpriteStateData1 + $ff and wSpriteStateData2 + $00-wSpriteStateData2 + $ff sprite slot
+; fields, respectively, within loops. The X is the loop index.
+; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y*
+; denote fields of the sprite slots interated over in the inner loop.
+_InitMapSprites: ; 1785b (5:785b)
+ call InitOutsideMapSprites
+ ret c ; return if the map is an outside map (already handled by above call)
+; if the map is an inside map (i.e. mapID >= $25)
+ ld hl,wSpriteStateData1
+ ld de,wSpriteStateData2 + $0d
+; Loop to copy picture ID's from $C1X0 to $C2XD for LoadMapSpriteTilePatterns.
+.copyPictureIDLoop
+ ld a,[hl] ; $C1X0 (picture ID)
+ ld [de],a ; $C2XD
+ ld a,$10
+ add e
+ ld e,a
+ ld a,$10
+ add l
+ ld l,a
+ jr nz,.copyPictureIDLoop
+
+; This is used for both inside and outside maps, since it is called by
+; InitOutsideMapSprites.
+; Loads tile pattern data for sprites into VRAM.
+LoadMapSpriteTilePatterns: ; 17871 (5:7871)
+ ld a,[W_NUMSPRITES]
+ and a ; are there any sprites?
+ jr nz,.spritesExist
+ ret
+.spritesExist
+ ld c,a ; c = [W_NUMSPRITES]
+ ld b,$10 ; number of sprite slots
+ ld hl,wSpriteStateData2 + $0d
+ xor a
+ ld [$ff8e],a ; 4-tile sprite counter
+.copyPictureIDLoop ; loop to copy picture ID from $C2XD to $C2XE
+ ld a,[hli] ; $C2XD (sprite picture ID)
+ ld [hld],a ; $C2XE
+ ld a,l
+ add a,$10
+ ld l,a
+ dec b
+ jr nz,.copyPictureIDLoop
+ ld hl,wSpriteStateData2 + $1e
+.loadTilePatternLoop
+ ld de,wSpriteStateData2 + $1d
+; Check if the current picture ID has already had its tile patterns loaded.
+; This done by looping through the previous sprite slots and seeing if any of
+; their picture ID's match that of the current sprite slot.
+.checkIfAlreadyLoadedLoop
+ ld a,e
+ and a,$f0
+ ld b,a ; b = offset of the wSpriteStateData2 sprite slot being checked against
+ ld a,l
+ and a,$f0 ; a = offset of current wSpriteStateData2 sprite slot
+ cp b ; done checking all previous sprite slots?
+ jr z,.notAlreadyLoaded
+ ld a,[de] ; picture ID of the wSpriteStateData2 sprite slot being checked against
+ cp [hl] ; do the picture ID's match?
+ jp z,.alreadyLoaded
+ ld a,e
+ add a,$10
+ ld e,a
+ jr .checkIfAlreadyLoadedLoop
+.notAlreadyLoaded
+ ld de,wSpriteStateData2 + $0e
+ ld b,$01
+; loop to find the highest tile pattern VRAM slot (among the first 10 slots) used by a previous sprite slot
+; this is done in order to find the first free VRAM slot available
+.findNextVRAMSlotLoop
+ ld a,e
+ add a,$10
+ ld e,a
+ ld a,l
+ cp e ; reached current slot?
+ jr z,.foundNextVRAMSlot
+ ld a,[de] ; $C2YE (VRAM slot)
+ cp a,11 ; is it one of the first 10 slots?
+ jr nc,.findNextVRAMSlotLoop
+ cp b ; compare the slot being checked to the current max
+ jr c,.findNextVRAMSlotLoop ; if the slot being checked is less than the current max
+; if the slot being checked is greater than or equal to the current max
+ ld b,a ; store new max VRAM slot
+ jr .findNextVRAMSlotLoop
+.foundNextVRAMSlot
+ inc b ; increment previous max value to get next VRAM tile pattern slot
+ ld a,b ; a = next VRAM tile pattern slot
+ push af
+ ld a,[hl] ; $C2XE (sprite picture ID)
+ ld b,a ; b = current sprite picture ID
+ cp a,SPRITE_BALL ; is it a 4-tile sprite?
+ jr c,.notFourTileSprite
+ pop af
+ ld a,[$ff8e] ; 4-tile sprite counter
+ add a,11
+ jr .storeVRAMSlot
+.notFourTileSprite
+ pop af
+.storeVRAMSlot
+ ld [hl],a ; store VRAM slot at $C2XE
+ ld [$ff8d],a ; used to determine if it's 4-tile sprite later
+ ld a,b ; a = current sprite picture ID
+ dec a
+ add a
+ add a
+ push bc
+ push hl
+ ld hl,SpriteSheetPointerTable
+ jr nc,.noCarry
+ inc h
+.noCarry
+ add l
+ ld l,a
+ jr nc,.noCarry2
+ inc h
+.noCarry2
+ push hl
+ call ReadSpriteSheetData
+ push af
+ push de
+ push bc
+ ld hl,vNPCSprites ; VRAM base address
+ ld bc,$c0 ; number of bytes per VRAM slot
+ ld a,[$ff8d]
+ cp a,11 ; is it a 4-tile sprite?
+ jr nc,.fourTileSpriteVRAMAddr
+ ld d,a
+ dec d
+; Equivalent to multiplying $C0 (number of bytes in 12 tiles) times the VRAM
+; slot and adding the result to $8000 (the VRAM base address).
+.calculateVRAMAddrLoop
+ add hl,bc
+ dec d
+ jr nz,.calculateVRAMAddrLoop
+ jr .loadStillTilePattern
+.fourTileSpriteVRAMAddr
+ ld hl,vSprites + $7c0 ; address for second 4-tile sprite
+ ld a,[$ff8e] ; 4-tile sprite counter
+ and a ; is it the first 4-tile sprite?
+ jr nz,.loadStillTilePattern
+; if it's the first 4-tile sprite
+ ld hl,vSprites + $780 ; address for first 4-tile sprite
+ inc a
+ ld [$ff8e],a ; 4-tile sprite counter
+.loadStillTilePattern
+ pop bc
+ pop de
+ pop af
+ push hl
+ push hl
+ ld h,d
+ ld l,e
+ pop de
+ ld b,a
+ ld a,[wFontLoaded]
+ bit 0,a ; reloading upper half of tile patterns after displaying text?
+ jr nz,.skipFirstLoad ; if so, skip loading data into the lower half
+ ld a,b
+ ld b,0
+ call FarCopyData2 ; load tile pattern data for sprite when standing still
+.skipFirstLoad
+ pop de
+ pop hl
+ ld a,[$ff8d]
+ cp a,11 ; is it a 4-tile sprite?
+ jr nc,.skipSecondLoad ; if so, there is no second block
+ push de
+ call ReadSpriteSheetData
+ push af
+ ld a,$c0
+ add e
+ ld e,a
+ jr nc,.noCarry3
+ inc d
+.noCarry3
+ ld a,[wFontLoaded]
+ bit 0,a ; reloading upper half of tile patterns after displaying text?
+ jr nz,.loadWhileLCDOn
+ pop af
+ pop hl
+ set 3,h ; add $800 to hl
+ push hl
+ ld h,d
+ ld l,e
+ pop de
+ call FarCopyData2 ; load tile pattern data for sprite when walking
+ jr .skipSecondLoad
+; When reloading the upper half of tile patterns after diplaying text, the LCD
+; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must
+; be used instead of FarCopyData2.
+.loadWhileLCDOn
+ pop af
+ pop hl
+ set 3,h ; add $800 to hl
+ ld b,a
+ swap c
+ call CopyVideoData ; load tile pattern data for sprite when walking
+.skipSecondLoad
+ pop hl
+ pop bc
+ jr .nextSpriteSlot
+.alreadyLoaded ; if the current picture ID has already had its tile patterns loaded
+ inc de
+ ld a,[de] ; a = VRAM slot for the current picture ID (from $C2YE)
+ ld [hl],a ; store VRAM slot in current wSpriteStateData2 sprite slot (at $C2XE)
+.nextSpriteSlot
+ ld a,l
+ add a,$10
+ ld l,a
+ dec c
+ jp nz,.loadTilePatternLoop
+ ld hl,wSpriteStateData2 + $0d
+ ld b,$10
+; the pictures ID's stored at $C2XD are no longer needed, so zero them
+.zeroStoredPictureIDLoop
+ xor a
+ ld [hl],a ; $C2XD
+ ld a,$10
+ add l
+ ld l,a
+ dec b
+ jr nz,.zeroStoredPictureIDLoop
+ ret
+
+; reads data from SpriteSheetPointerTable
+; INPUT:
+; hl = address of sprite sheet entry
+; OUTPUT:
+; de = pointer to sprite sheet
+; bc = length in bytes
+; a = ROM bank
+ReadSpriteSheetData: ; 17971 (5:7971)
+ ld a,[hli]
+ ld e,a
+ ld a,[hli]
+ ld d,a
+ ld a,[hli]
+ ld c,a
+ xor a
+ ld b,a
+ ld a,[hli]
+ ret
+
+; Loads sprite set for outside maps (cities and routes) and sets VRAM slots.
+; sets carry if the map is a city or route, unsets carry if not
+InitOutsideMapSprites: ; 1797b (5:797b)
+ ld a,[W_CURMAP]
+ cp a,REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)?
+ ret nc ; if not, return
+ ld hl,MapSpriteSets
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ ld a,[hl] ; a = spriteSetID
+ cp a,$f0 ; does the map have 2 sprite sets?
+ call nc,GetSplitMapSpriteSetID ; if so, choose the appropriate one
+ ld b,a ; b = spriteSetID
+ ld a,[wFontLoaded]
+ bit 0,a ; reloading upper half of tile patterns after displaying text?
+ jr nz,.loadSpriteSet ; if so, forcibly reload the sprite set
+ ld a,[W_SPRITESETID]
+ cp b ; has the sprite set ID changed?
+ jr z,.skipLoadingSpriteSet ; if not, don't load it again
+.loadSpriteSet
+ ld a,b
+ ld [W_SPRITESETID],a
+ dec a
+ ld b,a
+ sla a
+ ld c,a
+ sla a
+ sla a
+ add c
+ add b ; a = (spriteSetID - 1) * 11
+ ld de,SpriteSets
+; add a to de to get offset of sprite set
+ add e
+ ld e,a
+ jr nc,.noCarry2
+ inc d
+.noCarry2
+ ld hl,wSpriteStateData2 + $0d
+ ld a,SPRITE_RED
+ ld [hl],a
+ ld bc,W_SPRITESET
+; Load the sprite set into RAM.
+; This loop also fills $C2XD (sprite picture ID) where X is from $0 to $A
+; with picture ID's. This is done so that LoadMapSpriteTilePatterns will
+; load tile patterns for all sprite pictures in the sprite set.
+.loadSpriteSetLoop
+ ld a,$10
+ add l
+ ld l,a
+ ld a,[de] ; sprite picture ID from sprite set
+ ld [hl],a ; $C2XD (sprite picture ID)
+ ld [bc],a
+ inc de
+ inc bc
+ ld a,l
+ cp a,$bd ; reached 11th sprite slot?
+ jr nz,.loadSpriteSetLoop
+ ld b,4 ; 4 remaining sprite slots
+.zeroRemainingSlotsLoop ; loop to zero the picture ID's of the remaining sprite slots
+ ld a,$10
+ add l
+ ld l,a
+ xor a
+ ld [hl],a ; $C2XD (sprite picture ID)
+ dec b
+ jr nz,.zeroRemainingSlotsLoop
+ ld a,[W_NUMSPRITES]
+ push af ; save number of sprites
+ ld a,11 ; 11 sprites in sprite set
+ ld [W_NUMSPRITES],a
+ call LoadMapSpriteTilePatterns
+ pop af
+ ld [W_NUMSPRITES],a ; restore number of sprites
+ ld hl,wSpriteStateData2 + $1e
+ ld b,$0f
+; The VRAM tile pattern slots that LoadMapSpriteTilePatterns set are in the
+; order of the map's sprite set, not the order of the actual sprites loaded
+; for the current map. So, they are not needed and are zeroed by this loop.
+.zeroVRAMSlotsLoop
+ xor a
+ ld [hl],a ; $C2XE (VRAM slot)
+ ld a,$10
+ add l
+ ld l,a
+ dec b
+ jr nz,.zeroVRAMSlotsLoop
+.skipLoadingSpriteSet
+ ld hl,wSpriteStateData1 + $10
+; This loop stores the correct VRAM tile pattern slots according the sprite
+; data from the map's header. Since the VRAM tile pattern slots are filled in
+; the order of the sprite set, in order to find the VRAM tile pattern slot
+; for a sprite slot, the picture ID for the sprite is looked up within the
+; sprite set. The index of the picture ID within the sprite set plus one
+; (since the Red sprite always has the first VRAM tile pattern slot) is the
+; VRAM tile pattern slot.
+.storeVRAMSlotsLoop
+ ld c,0
+ ld a,[hl] ; $C1X0 (picture ID) (zero if sprite slot is not used)
+ and a ; is the sprite slot used?
+ jr z,.skipGettingPictureIndex ; if the sprite slot is not used
+ ld b,a ; b = picture ID
+ ld de,W_SPRITESET
+; Loop to find the index of the sprite's picture ID within the sprite set.
+.getPictureIndexLoop
+ inc c
+ ld a,[de]
+ inc de
+ cp b ; does the picture ID match?
+ jr nz,.getPictureIndexLoop
+ inc c
+.skipGettingPictureIndex
+ push hl
+ inc h
+ ld a,$0e
+ add l
+ ld l,a
+ ld a,c ; a = VRAM slot (zero if sprite slot is not used)
+ ld [hl],a ; $C2XE (VRAM slot)
+ pop hl
+ ld a,$10
+ add l
+ ld l,a
+ and a
+ jr nz,.storeVRAMSlotsLoop
+ scf
+ ret
+
+; Chooses the correct sprite set ID depending on the player's position within
+; the map for maps with two sprite sets.
+GetSplitMapSpriteSetID: ; 17a1a (5:7a1a)
+ cp a,$f8
+ jr z,.route20
+ ld hl,SplitMapSpriteSets
+ and a,$0f
+ dec a
+ sla a
+ sla a
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ ld a,[hli] ; determines whether the map is split East/West or North/South
+ cp a,$01
+ ld a,[hli] ; position of dividing line
+ ld b,a
+ jr z,.eastWestDivide
+.northSouthDivide
+ ld a,[W_YCOORD]
+ jr .compareCoord
+.eastWestDivide
+ ld a,[W_XCOORD]
+.compareCoord
+ cp b
+ jr c,.loadSpriteSetID
+; if in the East side or South side
+ inc hl
+.loadSpriteSetID
+ ld a,[hl]
+ ret
+; Uses sprite set $01 for West side and $0A for East side.
+; Route 20 is a special case because the two map sections have a more complex
+; shape instead of the map simply being split horizontally or vertically.
+.route20
+ ld hl,W_XCOORD
+ ld a,[hl]
+ cp a,$2b
+ ld a,$01
+ ret c
+ ld a,[hl]
+ cp a,$3e
+ ld a,$0a
+ ret nc
+ ld a,[hl]
+ cp a,$37
+ ld b,$08
+ jr nc,.next
+ ld b,$0d
+.next
+ ld a,[W_YCOORD]
+ cp b
+ ld a,$0a
+ ret c
+ ld a,$01
+ ret
+
+INCLUDE "data/sprite_sets.asm"
diff --git a/home.asm b/home.asm
index cbbd2250..a54c2685 100644
--- a/home.asm
+++ b/home.asm
@@ -1,4781 +1,4791 @@
-
-; The rst vectors are unused.
-SECTION "rst 00", ROM0 [$00]
- rst $38
-SECTION "rst 08", ROM0 [$08]
- rst $38
-SECTION "rst 10", ROM0 [$10]
- rst $38
-SECTION "rst 18", ROM0 [$18]
- rst $38
-SECTION "rst 20", ROM0 [$20]
- rst $38
-SECTION "rst 28", ROM0 [$28]
- rst $38
-SECTION "rst 30", ROM0 [$30]
- rst $38
-SECTION "rst 38", ROM0 [$38]
- rst $38
-
-; Hardware interrupts
-SECTION "vblank", ROM0 [$40]
- jp VBlank
-SECTION "hblank", ROM0 [$48]
- rst $38
-SECTION "timer", ROM0 [$50]
- jp Timer
-SECTION "serial", ROM0 [$58]
- jp Serial
-SECTION "joypad", ROM0 [$60]
- reti
-
-
-SECTION "Home", ROM0
-
-DisableLCD::
- xor a
- ld [rIF], a
- ld a, [rIE]
- ld b, a
- res 0, a
- ld [rIE], a
-
-.wait
- ld a, [rLY]
- cp LY_VBLANK
- jr nz, .wait
-
- ld a, [rLCDC]
- and $ff ^ rLCDC_ENABLE_MASK
- ld [rLCDC], a
- ld a, b
- ld [rIE], a
- ret
-
-EnableLCD::
- ld a, [rLCDC]
- set rLCDC_ENABLE, a
- ld [rLCDC], a
- ret
-
-ClearSprites::
- xor a
- ld hl, wOAMBuffer
- ld b, 40 * 4
-.loop
- ld [hli], a
- dec b
- jr nz, .loop
- ret
-
-HideSprites::
- ld a, 160
- ld hl, wOAMBuffer
- ld de, 4
- ld b, 40
-.loop
- ld [hl], a
- add hl, de
- dec b
- jr nz, .loop
- ret
-
-INCLUDE "home/copy.asm"
-
-
-
-SECTION "Entry", ROM0 [$100]
-
- nop
- jp Start ; 01ab
-
-
-SECTION "Header", ROM0 [$104]
-
- ; The header is generated by rgbfix.
- ; The space here is allocated to prevent code from being overwritten.
-
- ds $150 - $104
-
-
-
-SECTION "Main", ROM0
-
-Func_150:: ; 0150 (0:0150)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,b
- call BankswitchCommon
- ld a,[hli]
- ld c,a
- ld a,[hli]
- ld b,a
-.loop
- ld a,[hli]
- ld d,a
- ld a,$3
-.unknownloop
- dec a
- jr nz,.unknownloop
-
- rept 7
- call Func_199
- call Func_1a5
- endr
-
- call Func_199
- dec bc
- ld a,c
- or b
- jr nz,.loop
- pop af
- call BankswitchCommon
- ret
-
-Func_199:: ; 0199 (0:0199)
- ld a,d
- and $80
- srl a
- srl a
- ld [rNR32],a
- sla d
- ret
-
-Func_1a5:: ; 01a5 (0:01a5)
- ld a,$3
-.unknownloop2
- dec a
- jr nz,.unknownloop2
- ret
-
-Start::
- cp GBC
- jr z, .gbc
- xor a
- jr .ok
-.gbc
- ld a, $1
-.ok
- ld [hGBC], a
- jp Init
-
-Joypad:: ; 01b9
- homecall _Joypad
-
-ReadJoypad: ; 01c8 (0:01c8)
- homecall ReadJoypad_
-
-INCLUDE "data/map_header_pointers.asm"
-INCLUDE "home/overworld.asm"
-
-
-CheckForUserInterruption:: ; 12f8 (0:12f8)
-; Return carry if Up+Select+B, Start or A are pressed in c frames.
-; Used only in the intro and title screen.
- call DelayFrame
-
- push bc
- call JoypadLowSensitivity
- pop bc
-
- ld a, [hJoyHeld]
- cp D_UP + SELECT + B_BUTTON
- jr z, .input
-
- ld a, [hJoy5]
- and START | A_BUTTON
- jr nz, .input
-
- dec c
- jr nz, CheckForUserInterruption
-
- and a
- ret
-
-.input
- scf
- ret
-
-; function to load position data for destination warp when switching maps
-; INPUT:
-; a = ID of destination warp within destination map
-LoadDestinationWarpPosition:: ; 1313 (0:1313)
- ld b,a
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,[wPredefParentBank]
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ld a,b
- add a
- add a
- ld c,a
- ld b,0
- add hl,bc
- ld bc,4
- ld de,wCurrentTileBlockMapViewPointer
- call CopyData
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-
-DrawHPBar:: ; 1336 (0:1336)
-; 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 iz 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 W_MONHDEXNUM
-; INPUT:
-; [wWhichPokemon] = index of pokemon within party/box
-; [wcc49] = source
-; 00: player's party
-; 01: enemy's party
-; 02: current box
-; 03: daycare
-; OUTPUT:
-; [wcf91] = pokemon ID
-; wLoadedMon = base address of pokemon data
-; W_MONHDEXNUM = base address of base stats
-LoadMonData:: ; 1372 (0:1372)
- ld hl, LoadMonData_
- ld b, BANK(LoadMonData_)
- jp Bankswitch
-
-
-Func_137a:: ; 137a (0:137a)
-; 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:: ; 1384 (0:1384)
- ld a, 1
- ld [W_SPRITEFLIPPED], a
-
-LoadFrontSpriteByMonIndex:: ; 1389 (0:1389)
- 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, [H_LOADEDROMBANK]
- push af
- ld a, Bank(asm_3f0d0)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- xor a
- ld [$ffe1], a
- call asm_3f0d0
- xor a
- ld [W_SPRITEFLIPPED], a
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-
-PlayCry:: ; 13d0 (0:13d0)
-; Play monster a's cry.
- call GetCryData
- call PlaySound
- jp WaitForSoundToFinish
-
-GetCryData:: ; 13d9 (0:13d9)
-; 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 [wc0f1], a
- ld a, [hl]
- ld [wc0f2], a
- call BankswitchBack
-
- ; Cry headers have 3 channels,
- ; and start from index $14,
- ; so add 3 times the cry id.
- ld a, b
- ld c, $14
- rlca ; * 2
- add b
- add c
- ret
-
-
-DisplayPartyMenu:: ; 13fc (0:13fc)
- ld a,[hTilesetType]
- push af
- xor a
- ld [hTilesetType],a
- call GBPalWhiteOutWithDelay3
- call ClearSprites
- call PartyMenuInit
- call DrawPartyMenu
- jp HandlePartyMenuInput
-
-GoBackToPartyMenu:: ; 1411 (0:1411)
- ld a,[hTilesetType]
- push af
- xor a
- ld [hTilesetType],a
- call PartyMenuInit
- call RedrawPartyMenu
- jp HandlePartyMenuInput
-
-PartyMenuInit:: ; 1420 (0:1420)
- ld a, 1 ; hardcoded bank
- call BankswitchHome
- call LoadHpBarAndStatusTilePatterns
- ld hl, wd730
- set 6, [hl] ; turn off letter printing delay
- xor a
- ld [wcc49], a
- ld [wcc37], a
- ld hl, wTopMenuItemY
- inc a
- ld [hli], a ; top menu item Y
- xor a
- ld [hli], a ; top menu item X
- ld a, [wcc2b]
- 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, [wd11f]
- and a
- ld a, A_BUTTON + B_BUTTON
- jr z, .next
- xor a
- ld [wd11f], a
- inc a
-.next
- ld [hli], a ; menu watched keys
- pop af
- ld [hl], a ; old menu item ID
- ret
-
-HandlePartyMenuInput:: ; 145a (0:145a)
- ld a,1
- ld [wMenuWrappingEnabled],a
- ld a,$40
- ld [wd09b],a
- call HandleMenuInputPokemonSelection
- call PlaceUnfilledArrowMenuCursor
- ld b,a
- xor a
- ld [wd09b],a
- ld a,[wCurrentMenuItem]
- ld [wcc2b],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 [wd07d],a
- call RedrawPartyMenu
- jr HandlePartyMenuInput
-.handleSwap
- ld a,[wCurrentMenuItem]
- ld [wWhichPokemon],a
- callba SwitchPartyMon
- jr HandlePartyMenuInput
-
-DrawPartyMenu:: ; 14d4 (0:14d4)
- ld hl, DrawPartyMenu_
- jr DrawPartyMenuCommon
-
-RedrawPartyMenu:: ; 14d9 (0:14d9)
- ld hl, RedrawPartyMenu_
-
-DrawPartyMenuCommon:: ; 14dc (0:14dc)
- ld b, BANK(RedrawPartyMenu_)
- jp Bankswitch
-
-; prints a pokemon's status condition
-; INPUT:
-; de = address of status condition
-; hl = destination address
-PrintStatusCondition:: ; 14e1 (0:14e1)
- 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 ; 14f6
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(PrintStatusAilment)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call PrintStatusAilment ; print status condition
- pop bc
- ld a,b
- ld [H_LOADEDROMBANK],a
- ld [$2000],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:: ; 150b (0:150b)
- ld a,$6e ; ":L" tile ID
- ld [hli],a
- ld c,2 ; number of digits
- ld a,[wLoadedMonLevel] ; level
- cp a,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:: ; 151b (0:151b)
- ld a,$6e ; ":L" tile ID
- ld [hli],a
- ld c,3 ; number of digits
- ld a,[wLoadedMonLevel] ; level
-
-PrintLevelCommon:: ; 1523 (0:1523)
- ld [wd11e],a
- ld de,wd11e
- ld b,$41 ; no leading zeroes, left-aligned, one byte
- jp PrintNumber
-
-Func_152e:: ; 152e (0:152e)
-; Unused.
- 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 W_MONHDEXNUM (W_MONHEADER)
-; INPUT:
-; [wd0b5] = pokemon ID
-GetMonHeader:: ; 1537 (0:1537)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(BaseStats)
- ld [H_LOADEDROMBANK],a
- ld [$2000],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 a,FOSSIL_KABUTOPS ; Kabutops fossil
- jr z,.specialID
- ld de,GhostPic
- cp a,MON_GHOST ; Ghost
- jr z,.specialID
- ld de,FossilAerodactylPic
- ld b,$77 ; size of Aerodactyl fossil sprite
- cp a,FOSSIL_AERODACTYL ; Aerodactyl fossil
- jr z,.specialID
- cp a,MEW
- jr z,.mew
- predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
- ld a,[wd11e]
- dec a
- ld bc,28
- ld hl,BaseStats
- call AddNTimes
- ld de,W_MONHEADER
- ld bc,28
- call CopyData
- jr .done
-.specialID
- ld hl,W_MONHSPRITEDIM
- 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,W_MONHEADER
- ld bc,28
- ld a,BANK(MewBaseStats)
- call FarCopyData
-.done
- ld a,[wd0b5]
- ld [W_MONHDEXNUM],a
- pop af
- ld [wd11e],a
- pop hl
- pop de
- pop bc
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; copy party pokemon's name to wcd6d
-GetPartyMonName2:: ; 15b4 (0:15b4)
- ld a,[wWhichPokemon] ; index within party
- ld hl,wPartyMonNicks
-
-; this is called more often
-GetPartyMonName:: ; 15ba (0:15ba)
- push hl
- push bc
- call SkipFixedLengthTextEntries ; add 11 to hl, a times
- ld de,wcd6d
- push de
- ld bc,11
- call CopyData
- pop de
- pop bc
- pop hl
- ret
-
-; function to print a BCD (Binary-coded decimal) number
-; de = address of BCD number
-; hl = destination address
-; c = flags and length
-; bit 7: if set, do not print leading zeroes
-; if unset, print leading zeroes
-; bit 6: if set, left-align the string (do not pad empty digits with spaces)
-; if unset, right-align the string
-; bit 5: if set, print currency symbol at the beginning of the string
-; if unset, do not print the currency symbol
-; bits 0-4: length of BCD number in bytes
-; Note that bits 5 and 7 are modified during execution. The above reflects
-; their meaning at the beginning of the functions's execution.
-PrintBCDNumber:: ; 15cd (0:15cd)
- ld b,c ; save flags in b
- res 7,c
- res 6,c
- res 5,c ; c now holds the length
- bit 5,b
- jr z,.loop
- bit 7,b
- jr nz,.loop
- ld [hl],"¥"
- inc hl
-.loop
- ld a,[de]
- swap a
- call PrintBCDDigit ; print upper digit
- ld a,[de]
- call PrintBCDDigit ; print lower digit
- inc de
- dec c
- jr nz,.loop
- bit 7,b ; were any non-zero digits printed?
- jr z,.done ; if so, we are done
-.numberEqualsZero ; if every digit of the BCD number is zero
- bit 6,b ; left or right alignment?
- jr nz,.skipRightAlignmentAdjustment
- dec hl ; if the string is right-aligned, it needs to be moved back one space
-.skipRightAlignmentAdjustment
- bit 5,b
- jr z,.skipCurrencySymbol
- ld [hl],"¥"
- inc hl
-.skipCurrencySymbol
- ld [hl],"0"
- call PrintLetterDelay
- inc hl
-.done
- ret
-
-PrintBCDDigit:: ; 1604 (0:1604)
- and $f
- and a
- jr z,.zeroDigit
-.nonzeroDigit
- bit 7,b ; have any non-space characters been printed?
- jr z,.outputDigit
-; if bit 7 is set, then no numbers have been printed yet
- bit 5,b ; print the currency symbol?
- jr z,.skipCurrencySymbol
- ld [hl],"¥"
- inc hl
- res 5,b
-.skipCurrencySymbol
- res 7,b ; unset 7 to indicate that a nonzero digit has been reached
-.outputDigit
- add a,"0"
- ld [hli],a
- jp PrintLetterDelay
-.zeroDigit
- bit 7,b ; either printing leading zeroes or already reached a nonzero digit?
- jr z,.outputDigit ; if so, print a zero digit
- bit 6,b ; left or right alignment?
- ret nz
- inc hl ; if right-aligned, "print" a space by advancing the pointer
- ret
-
-; uncompresses the front or back sprite of the specified mon
-; assumes the corresponding mon header is already loaded
-; hl contains offset to sprite pointer ($b for front or $d for back)
-UncompressMonSprite:: ; 1627 (0:1627)
- ld bc,W_MONHEADER
- add hl,bc
- ld a,[hli]
- ld [W_SPRITEINPUTPTR],a ; fetch sprite input pointer
- ld a,[hl]
- ld [W_SPRITEINPUTPTR+1],a
-; define (by index number) the bank that a pokemon's image is in
-; index = Mew, bank 1
-; index = Kabutops fossil, bank $B
-; index < $1F, bank 9
-; $1F ≤ index < $4A, bank $A
-; $4A ≤ index < $74, bank $B
-; $74 ≤ index < $99, bank $C
-; $99 ≤ index, bank $D
- ld a,[wcf91] ; XXX name for this ram location
- ld b,a
- cp MEW
- ld a,BANK(MewPicFront)
- jr z,.GotBank
- ld a,b
- cp FOSSIL_KABUTOPS
- ld a,BANK(FossilKabutopsPic)
- jr z,.GotBank
- ld a,b
- cp TANGELA + 1
- ld a,BANK(TangelaPicFront)
- jr c,.GotBank
- ld a,b
- cp MOLTRES + 1
- ld a,BANK(MoltresPicFront)
- jr c,.GotBank
- ld a,b
- cp BEEDRILL + 2
- ld a,BANK(BeedrillPicFront)
- jr c,.GotBank
- ld a,b
- cp STARMIE + 1
- ld a,BANK(StarmiePicFront)
- jr c,.GotBank
- ld a,BANK(VictreebelPicFront)
-.GotBank
- jp UncompressSpriteData
-
-; de: destination location
-LoadMonFrontSprite:: ; 1665 (0:1665)
- push de
- ld hl, W_MONHFRONTSPRITE - W_MONHEADER
- call UncompressMonSprite
- ld hl, W_MONHSPRITEDIM
- ld a, [hli]
- ld c, a
- pop de
- ; fall through
-
-; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram
-; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers
-; de: destination location
-; a,c: sprite dimensions (in tiles of 8x8 each)
-LoadUncompressedSpriteData:: ; 1672 (0:1672)
- push de
- and $f
- ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width
- ld b, a
- ld a, $7
- sub b ; 7-w
- inc a ; 8-w
- srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up)
- ld b, a
- add a
- add a
- add a
- sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles)
- ld [H_SPRITEOFFSET], a
- ld a, c
- swap a
- and $f
- ld b, a
- add a
- add a
- add a ; 8*tiles is height in bytes
- ld [H_SPRITEHEIGHT], a ; $ff8c
- ld a, $7
- sub b ; 7-h ; skip for vertical center (in tiles, relative to current column)
- ld b, a
- ld a, [H_SPRITEOFFSET]
- add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles)
- add a
- add a
- add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes)
- ld [H_SPRITEOFFSET], a
- xor a
- ld [$4000], a
- ld hl, S_SPRITEBUFFER0
- call ZeroSpriteBuffer ; zero buffer 0
- ld de, S_SPRITEBUFFER1
- ld hl, S_SPRITEBUFFER0
- call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
- ld hl, S_SPRITEBUFFER1
- call ZeroSpriteBuffer ; zero buffer 1
- ld de, S_SPRITEBUFFER2
- ld hl, S_SPRITEBUFFER1
- call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
- pop de
- jp InterlaceMergeSpriteBuffers
-
-; copies and aligns the sprite data properly inside the sprite buffer
-; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area
-AlignSpriteDataCentered:: ; 16c2 (0:16c2)
- ld a, [H_SPRITEOFFSET]
- ld b, $0
- ld c, a
- add hl, bc
- ld a, [H_SPRITEWIDTH] ; $ff8b
-.columnLoop
- push af
- push hl
- ld a, [H_SPRITEHEIGHT] ; $ff8c
- ld c, a
-.columnInnerLoop
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .columnInnerLoop
- pop hl
- ld bc, 7*8 ; 7 tiles
- add hl, bc ; advance one full column
- pop af
- dec a
- jr nz, .columnLoop
- ret
-
-; fills the sprite buffer (pointed to in hl) with zeros
-ZeroSpriteBuffer:: ; 16df (0:16df)
- ld bc, SPRITEBUFFERSIZE
-.nextByteLoop
- xor a
- ld [hli], a
- dec bc
- ld a, b
- or c
- jr nz, .nextByteLoop
- ret
-
-; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2
-; in the resulting sprite, the rows of the two source sprites are interlaced
-; de: output address
-InterlaceMergeSpriteBuffers:: ; 16ea (0:16ea)
- xor a
- ld [$4000], a
- push de
- ld hl, S_SPRITEBUFFER2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2
- ld de, S_SPRITEBUFFER1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1
- ld bc, S_SPRITEBUFFER0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0
- ld a, SPRITEBUFFERSIZE/2 ; $c4
- ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
-.interlaceLoop
- ld a, [de]
- dec de
- ld [hld], a ; write byte of source 2
- ld a, [bc]
- dec bc
- ld [hld], a ; write byte of source 1
- ld a, [de]
- dec de
- ld [hld], a ; write byte of source 2
- ld a, [bc]
- dec bc
- ld [hld], a ; write byte of source 1
- ld a, [H_SPRITEINTERLACECOUNTER] ; $ff8b
- dec a
- ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
- jr nz, .interlaceLoop
- ld a, [W_SPRITEFLIPPED]
- and a
- jr z, .notFlipped
- ld bc, 2*SPRITEBUFFERSIZE
- ld hl, S_SPRITEBUFFER1
-.swapLoop
- swap [hl] ; if flipped swap nybbles in all bytes
- inc hl
- dec bc
- ld a, b
- or c
- jr nz, .swapLoop
-.notFlipped
- pop hl
- ld de, S_SPRITEBUFFER1
- ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
- ld a, [H_LOADEDROMBANK]
- ld b, a
- jp CopyVideoData
-
-
-INCLUDE "data/collision.asm"
-INCLUDE "home/copy2.asm"
-INCLUDE "home/text.asm"
-INCLUDE "home/vcopy.asm"
-INCLUDE "home/init.asm"
-INCLUDE "home/vblank.asm"
-INCLUDE "home/fade.asm"
-INCLUDE "home/serial.asm"
-INCLUDE "home/timer.asm"
-INCLUDE "home/audio.asm"
-
-
-UpdateSprites:: ; 2429 (0:2429)
- ld a, [wUpdateSpritesEnabled]
- dec a
- ret nz
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, Bank(_UpdateSprites)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- call _UpdateSprites
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-INCLUDE "data/mart_inventories.asm"
-
-TextScriptEndingChar:: ; 24d6 (0:24d6)
- db "@"
-TextScriptEnd:: ; 24d7 (0:24d7)
- ld hl,TextScriptEndingChar
- ret
-
-ExclamationText:: ; 24db (0:24db)
- TX_FAR _ExclamationText
- db "@"
-
-GroundRoseText:: ; 24e0 (0:24e0)
- TX_FAR _GroundRoseText
- db "@"
-
-BoulderText:: ; 24e5 (0:24e5)
- TX_FAR _BoulderText
- db "@"
-
-MartSignText:: ; 24ea (0:24ea)
- TX_FAR _MartSignText
- db "@"
-
-PokeCenterSignText:: ; 24ef (0:24ef)
- TX_FAR _PokeCenterSignText
- db "@"
-
-Predef5CText:: ; 24f4 (0:24f4)
-; XXX better label (what does predef $5C do?)
- db $08 ; asm
- predef PickupItem
- jp TextScriptEnd
-
-
-INCLUDE "home/pic.asm"
-
-
-ResetPlayerSpriteData:: ; 28a6 (0:28a6)
- ld hl, wSpriteStateData1
- call ResetPlayerSpriteData_ClearSpriteData
- ld hl, wSpriteStateData2
- call ResetPlayerSpriteData_ClearSpriteData
- ld a, $1
- ld [wSpriteStateData1], a
- ld [wSpriteStateData2 + $0e], a
- ld hl, wSpriteStateData1 + 4
- ld [hl], $3c ; set Y screen pos
- inc hl
- inc hl
- ld [hl], $40 ; set X screen pos
- ret
-
-; overwrites sprite data with zeroes
-ResetPlayerSpriteData_ClearSpriteData:: ; 28c4 (0:28c4)
- ld bc, $10
- xor a
- jp FillMemory
-
-Func_28cb:: ; 28cb (0:28cb)
- ld a, [wMusicHeaderPointer]
- and a
- jr nz, .asm_28dc
- ld a, [wd72c]
- bit 1, a
- ret nz
- ld a, $77
- ld [$ff24], a
- ret
-.asm_28dc
- ld a, [wcfc9]
- and a
- jr z, .asm_28e7
- dec a
- ld [wcfc9], a
- ret
-.asm_28e7
- ld a, [wcfc8]
- ld [wcfc9], a
- ld a, [$ff24]
- and a
- jr z, .asm_2903
- ld b, a
- and $f
- dec a
- ld c, a
- ld a, b
- and $f0
- swap a
- dec a
- swap a
- or c
- ld [$ff24], a
- ret
-.asm_2903
- ld a, [wMusicHeaderPointer]
- ld b, a
- xor a
- ld [wMusicHeaderPointer], a
- ld a, $ff
- ld [wc0ee], a
- call PlaySound
- ld a, [wc0f0]
- ld [wc0ef], a
- ld a, b
- ld [wc0ee], a
- jp PlaySound
-
-; this function is used to display sign messages, sprite dialog, etc.
-; INPUT: [$ff8c] = sprite ID or text ID
-DisplayTextID:: ; 2920 (0:2920)
- ld a,[H_LOADEDROMBANK]
- push af
- callba DisplayTextIDInit ; initialization
- ld hl,wcf11
- bit 0,[hl]
- res 0,[hl]
- jr nz,.skipSwitchToMapBank
- ld a,[W_CURMAP]
- call SwitchToMapRomBank
-.skipSwitchToMapBank
- ld a,30 ; half a second
- ld [H_FRAMECOUNTER],a ; used as joypad poll timer
- ld hl,W_MAPTEXTPTR
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl = map text pointer
- ld d,$00
- ld a,[$ff8c] ; text ID
- ld [wSpriteIndex],a
- and a
- jp z,DisplayStartMenu
- cp a,$d3
- jp z,DisplaySafariGameOverText
- cp a,$d0
- jp z,DisplayPokemonFaintedText
- cp a,$d1
- jp z,DisplayPlayerBlackedOutText
- cp a,$d2
- jp z,DisplayRepelWoreOffText
- ld a,[W_NUMSPRITES]
- ld e,a
- ld a,[$ff8c] ; sprite ID
- cp e
- jr z,.spriteHandling
- jr nc,.skipSpriteHandling
-.spriteHandling
-; get the text ID of the sprite
- push hl
- push de
- push bc
- callba UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction)
- pop bc
- pop de
- ld hl,W_MAPSPRITEDATA ; NPC text entries
- ld a,[$ff8c]
- dec a
- add a
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- inc hl
- ld a,[hl] ; a = text ID of the sprite
- pop hl
-.skipSpriteHandling
-; look up the address of the text in the map's text entries
- dec a
- ld e,a
- sla e
- add hl,de
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl = address of the text
- ld a,[hl] ; a = first byte of text
-; check first byte of text for special cases
- cp a,$fe ; Pokemart NPC
- jp z,DisplayPokemartDialogue
- cp a,$ff ; Pokemon Center NPC
- jp z,DisplayPokemonCenterDialogue
- cp a,$fc ; Item Storage PC
- jp z,FuncTX_ItemStoragePC
- cp a,$fd ; Bill's PC
- jp z,FuncTX_BillsPC
- cp a,$f9 ; Pokemon Center PC
- jp z,FuncTX_PokemonCenterPC
- cp a,$f5 ; Vending Machine
- jr nz,.notVendingMachine
- callba VendingMachineMenu ; jump banks to vending machine routine
- jr AfterDisplayingTextID
-.notVendingMachine
- cp a,$f7 ; slot machine
- jp z,FuncTX_SlotMachine
- cp a,$f6 ; cable connection NPC in Pokemon Center
- jr nz,.notSpecialCase
- callab CableClubNPC
- jr AfterDisplayingTextID
-.notSpecialCase
- call Func_3c59 ; display the text
- ld a,[wDoNotWaitForButtonPressAfterDisplayingText]
- and a
- jr nz,HoldTextDisplayOpen
-
-AfterDisplayingTextID:: ; 29d6 (0:29d6)
- ld a,[wcc47]
- and a
- jr nz,HoldTextDisplayOpen
- call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text
-
-; loop to hold the dialogue box open as long as the player keeps holding down the A button
-HoldTextDisplayOpen:: ; 29df (0:29df)
- call Joypad
- ld a,[hJoyHeld]
- bit 0,a ; is the A button being pressed?
- jr nz,HoldTextDisplayOpen
-
-CloseTextDisplay:: ; 29e8 (0:29e8)
- ld a,[W_CURMAP]
- call SwitchToMapRomBank
- ld a,$90
- ld [hWY],a ; move the window off the screen
- call DelayFrame
- call LoadGBPal
- xor a
- ld [H_AUTOBGTRANSFERENABLED],a ; disable continuous WRAM to VRAM transfer each V-blank
-; loop to make sprites face the directions they originally faced before the dialogue
- ld hl,wSpriteStateData2 + $19
- ld c,$0f
- ld de,$0010
-.restoreSpriteFacingDirectionLoop
- ld a,[hl]
- dec h
- ld [hl],a
- inc h
- add hl,de
- dec c
- jr nz,.restoreSpriteFacingDirectionLoop
- ld a,BANK(InitMapSprites)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
- ld hl,wFontLoaded
- res 0,[hl]
- ld a,[wd732]
- bit 3,a ; used fly warp
- call z,LoadPlayerSpriteGraphics
- call LoadCurrentMapView
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- jp UpdateSprites
-
-DisplayPokemartDialogue:: ; 2a2e (0:2a2e)
- push hl
- ld hl,PokemartGreetingText
- call PrintText
- pop hl
- inc hl
- call LoadItemList
- ld a,$02
- ld [wListMenuID],a ; selects between subtypes of menus
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,Bank(DisplayPokemartDialogue_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call DisplayPokemartDialogue_
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- jp AfterDisplayingTextID
-
-PokemartGreetingText:: ; 2a55 (0:2a55)
- TX_FAR _PokemartGreetingText
- db "@"
-
-LoadItemList:: ; 2a5a (0:2a5a)
- ld a,$01
- ld [wUpdateSpritesEnabled],a
- ld a,h
- ld [wd128],a
- ld a,l
- ld [wd129],a
- ld de,wStringBuffer2 + 11
-.loop
- ld a,[hli]
- ld [de],a
- inc de
- cp a,$ff
- jr nz,.loop
- ret
-
-DisplayPokemonCenterDialogue:: ; 2a72 (0:2a72)
- xor a
- ld [$ff8b],a
- ld [$ff8c],a
- ld [$ff8d],a
- inc hl
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,Bank(DisplayPokemonCenterDialogue_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call DisplayPokemonCenterDialogue_
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- jp AfterDisplayingTextID
-
-DisplaySafariGameOverText:: ; 2a90 (0:2a90)
- callab PrintSafariGameOverText
- jp AfterDisplayingTextID
-
-DisplayPokemonFaintedText:: ; 2a9b (0:2a9b)
- ld hl,PokemonFaintedText
- call PrintText
- jp AfterDisplayingTextID
-
-PokemonFaintedText:: ; 2aa4 (0:2aa4)
- TX_FAR _PokemonFaintedText
- db "@"
-
-DisplayPlayerBlackedOutText:: ; 2aa9 (0:2aa9)
- ld hl,PlayerBlackedOutText
- call PrintText
- ld a,[wd732]
- res 5,a ; reset forced to use bike bit
- ld [wd732],a
- jp HoldTextDisplayOpen
-
-PlayerBlackedOutText:: ; 2aba (0:2aba)
- TX_FAR _PlayerBlackedOutText
- db "@"
-
-DisplayRepelWoreOffText:: ; 2abf (0:2abf)
- ld hl,RepelWoreOffText
- call PrintText
- jp AfterDisplayingTextID
-
-RepelWoreOffText:: ; 2ac8 (0:2ac8)
- TX_FAR _RepelWoreOffText
- db "@"
-
-INCLUDE "engine/menu/start_menu.asm"
-
-; function to count how many bits are set in a string of bytes
-; INPUT:
-; hl = address of string of bytes
-; b = length of string of bytes
-; OUTPUT:
-; [wd11e] = number of set bits
-CountSetBits:: ; 2b7f (0:2b7f)
- ld c,0
-.loop
- ld a,[hli]
- ld e,a
- ld d,8
-.innerLoop ; count how many bits are set in the current byte
- srl e
- ld a,0
- adc c
- ld c,a
- dec d
- jr nz,.innerLoop
- dec b
- jr nz,.loop
- ld a,c
- ld [wd11e],a ; store number of set bits
- ret
-
-; subtracts the amount the player paid from their money
-; sets carry flag if there is enough money and unsets carry flag if not
-SubtractAmountPaidFromMoney:: ; 2b96 (0:2b96)
- ld b,BANK(SubtractAmountPaidFromMoney_)
- ld hl,SubtractAmountPaidFromMoney_
- jp Bankswitch
-
-; adds the amount the player sold to their money
-AddAmountSoldToMoney:: ; 2b9e (0:2b9e)
- ld de,wPlayerMoney + 2
- ld hl,$ffa1 ; total price of items
- ld c,3 ; length of money in bytes
- predef AddBCDPredef ; add total price to money
- ld a,MONEY_BOX
- ld [wTextBoxID],a
- call DisplayTextBoxID ; redraw money text box
- ld a, (SFX_02_5a - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- jp WaitForSoundToFinish ; wait until sound is done playing
-
-; function to remove an item (in varying quantities) from the player's bag or PC box
-; INPUT:
-; HL = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wWhichPokemon] = index (within the inventory) of the item to remove
-; [wcf96] = quantity to remove
-RemoveItemFromInventory:: ; 2bbb (0:2bbb)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(RemoveItemFromInventory_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call RemoveItemFromInventory_
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; function to add an item (in varying quantities) to the player's bag or PC box
-; INPUT:
-; HL = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wcf96] = item quantity
-; sets carry flag if successful, unsets carry flag if unsuccessful
-AddItemToInventory:: ; 2bcf (0:2bcf)
- push bc
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(AddItemToInventory_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call AddItemToInventory_
- pop bc
- ld a,b
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- pop bc
- ret
-
-; INPUT:
-; [wListMenuID] = list menu ID
-; [wList] = address of the list (2 bytes)
-DisplayListMenuID:: ; 2be6 (0:2be6)
- xor a
- ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer
- ld a,1
- ld [hJoy7],a ; joypad state update flag
- ld a,[W_BATTLETYPE]
- and a ; is it the Old Man battle?
- jr nz,.specialBattleType
- ld a,$01 ; hardcoded bank
- jr .bankswitch
-.specialBattleType ; Old Man battle
- ld a, Bank(DisplayBattleMenu)
-.bankswitch
- call BankswitchHome
- ld hl,wd730
- set 6,[hl] ; turn off letter printing delay
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- ld [wd12a],a
- ld a,[wList]
- ld l,a
- ld a,[wList + 1]
- ld h,a ; hl = address of the list
- ld a,[hl]
- ld [wd12a],a ; [wd12a] = number of list entries
- ld a,LIST_MENU_BOX
- ld [wTextBoxID],a
- call DisplayTextBoxID ; draw the menu text box
- call UpdateSprites ; disable sprites behind the text box
-; the code up to .skipMovingSprites appears to be useless
- hlCoord 4, 2 ; coordinates of upper left corner of menu text box
- ld de,$090e ; height and width of menu text box
- ld a,[wListMenuID]
- and a ; is it a PC pokemon list?
- jr nz,.skipMovingSprites
- call UpdateSprites ; move sprites
-.skipMovingSprites
- ld a,1 ; max menu item ID is 1 if the list has less than 2 entries
- ld [wcc37],a
- ld a,[wd12a]
- cp a,2 ; does the list have less than 2 entries?
- jr c,.setMenuVariables
- ld a,2 ; max menu item ID is 2 if the list has at least 2 entries
-.setMenuVariables
- ld [wMaxMenuItem],a
- ld a,4
- ld [wTopMenuItemY],a
- ld a,5
- ld [wTopMenuItemX],a
- ld a,A_BUTTON | B_BUTTON | SELECT
- ld [wMenuWatchedKeys],a
- ld c,10
- call DelayFrames
-
-DisplayListMenuIDLoop:: ; 2c53 (0:2c53)
- xor a
- ld [H_AUTOBGTRANSFERENABLED],a ; disable transfer
- call PrintListMenuEntries
- ld a,1
- ld [H_AUTOBGTRANSFERENABLED],a ; enable transfer
- call Delay3
- ld a,[W_BATTLETYPE]
- and a ; is it the Old Man battle?
- jr z,.notOldManBattle
-.oldManBattle
- ld a,"▶"
- Coorda 5, 4 ; place menu cursor in front of first menu entry
- ld c,80
- call DelayFrames
- xor a
- ld [wCurrentMenuItem],a
- hlCoord 5, 4
- ld a,l
- ld [wMenuCursorLocation],a
- ld a,h
- ld [wMenuCursorLocation + 1],a
- jr .buttonAPressed
-.notOldManBattle
- call LoadGBPal
- call HandleMenuInput
- push af
- call PlaceMenuCursor
- pop af
- bit 0,a ; was the A button pressed?
- jp z,.checkOtherKeys
-.buttonAPressed
- ld a,[wCurrentMenuItem]
- call PlaceUnfilledArrowMenuCursor
- ld a,$01
- ld [wd12e],a
- ld [wd12d],a
- xor a
- ld [wcc37],a
- ld a,[wCurrentMenuItem]
- ld c,a
- ld a,[wListScrollOffset]
- add c
- ld c,a
- ld a,[wd12a] ; number of list entries
- and a ; is the list empty?
- jp z,ExitListMenu ; if so, exit the menu
- dec a
- cp c ; did the player select Cancel?
- jp c,ExitListMenu ; if so, exit the menu
- ld a,c
- ld [wWhichPokemon],a
- ld a,[wListMenuID]
- cp a,ITEMLISTMENU
- jr nz,.skipMultiplying
-; if it's an item menu
- sla c ; item entries are 2 bytes long, so multiply by 2
-.skipMultiplying
- ld a,[wList]
- ld l,a
- ld a,[wList + 1]
- ld h,a
- inc hl ; hl = beginning of list entries
- ld b,0
- add hl,bc
- ld a,[hl]
- ld [wcf91],a
- ld a,[wListMenuID]
- and a ; is it a PC pokemon list?
- jr z,.pokemonList
- push hl
- call GetItemPrice
- pop hl
- ld a,[wListMenuID]
- cp a,ITEMLISTMENU
- jr nz,.skipGettingQuantity
-; if it's an item menu
- inc hl
- ld a,[hl] ; a = item quantity
- ld [wcf97],a
-.skipGettingQuantity
- ld a,[wcf91]
- ld [wd0b5],a
- ld a,BANK(ItemNames)
- ld [wPredefBank],a
- call GetName
- jr .storeChosenEntry
-.pokemonList
- ld hl,wPartyCount
- ld a,[wList]
- cp l ; is it a list of party pokemon or box pokemon?
- ld hl,wPartyMonNicks
- jr z,.getPokemonName
- ld hl, wBoxMonNicks ; box pokemon names
-.getPokemonName
- ld a,[wWhichPokemon]
- call GetPartyMonName
-.storeChosenEntry ; store the menu entry that the player chose and return
- ld de,wcd6d
- call CopyStringToCF4B ; copy name to wcf4b
- ld a,$01
- ld [wd12e],a
- ld a,[wCurrentMenuItem]
- ld [wd12d],a
- xor a
- ld [hJoy7],a ; joypad state update flag
- ld hl,wd730
- res 6,[hl] ; turn on letter printing delay
- jp BankswitchBack
-.checkOtherKeys ; check B, SELECT, Up, and Down keys
- bit 1,a ; was the B button pressed?
- jp nz,ExitListMenu ; if so, exit the menu
- bit 2,a ; was the select button pressed?
- jp nz,HandleItemListSwapping ; if so, allow the player to swap menu entries
- ld b,a
- bit 7,b ; was Down pressed?
- ld hl,wListScrollOffset
- jr z,.upPressed
-.downPressed
- ld a,[hl]
- add a,3
- ld b,a
- ld a,[wd12a] ; number of list entries
- cp b ; will going down scroll past the Cancel button?
- jp c,DisplayListMenuIDLoop
- inc [hl] ; if not, go down
- jp DisplayListMenuIDLoop
-.upPressed
- ld a,[hl]
- and a
- jp z,DisplayListMenuIDLoop
- dec [hl]
- jp DisplayListMenuIDLoop
-
-DisplayChooseQuantityMenu:: ; 2d57 (0:2d57)
-; text box dimensions/coordinates for just quantity
- hlCoord 15, 9
- ld b,1 ; height
- ld c,3 ; width
- ld a,[wListMenuID]
- cp a,PRICEDITEMLISTMENU
- jr nz,.drawTextBox
-; text box dimensions/coordinates for quantity and price
- hlCoord 7, 9
- ld b,1 ; height
- ld c,11 ; width
-.drawTextBox
- call TextBoxBorder
- hlCoord 16, 10
- ld a,[wListMenuID]
- cp a,PRICEDITEMLISTMENU
- jr nz,.printInitialQuantity
- hlCoord 8, 10
-.printInitialQuantity
- ld de,InitialQuantityText
- call PlaceString
- xor a
- ld [wcf96],a ; initialize current quantity to 0
- jp .incrementQuantity
-.waitForKeyPressLoop
- call JoypadLowSensitivity
- ld a,[hJoyPressed] ; newly pressed buttons
- bit 0,a ; was the A button pressed?
- jp nz,.buttonAPressed
- bit 1,a ; was the B button pressed?
- jp nz,.buttonBPressed
- bit 6,a ; was Up pressed?
- jr nz,.incrementQuantity
- bit 7,a ; was Down pressed?
- jr nz,.decrementQuantity
- jr .waitForKeyPressLoop
-.incrementQuantity
- ld a,[wcf97] ; max quantity
- inc a
- ld b,a
- ld hl,wcf96 ; current quantity
- inc [hl]
- ld a,[hl]
- cp b
- jr nz,.handleNewQuantity
-; wrap to 1 if the player goes above the max quantity
- ld a,1
- ld [hl],a
- jr .handleNewQuantity
-.decrementQuantity
- ld hl,wcf96 ; current quantity
- dec [hl]
- jr nz,.handleNewQuantity
-; wrap to the max quantity if the player goes below 1
- ld a,[wcf97] ; max quantity
- ld [hl],a
-.handleNewQuantity
- hlCoord 17, 10
- ld a,[wListMenuID]
- cp a,PRICEDITEMLISTMENU
- jr nz,.printQuantity
-.printPrice
- ld c,$03
- ld a,[wcf96]
- ld b,a
- ld hl,$ff9f ; total price
-; initialize total price to 0
- xor a
- ld [hli],a
- ld [hli],a
- ld [hl],a
-.addLoop ; loop to multiply the individual price by the quantity to get the total price
- ld de,$ffa1
- ld hl,$ff8d
- push bc
- predef AddBCDPredef ; add the individual price to the current sum
- pop bc
- dec b
- jr nz,.addLoop
- ld a,[$ff8e]
- and a ; should the price be halved (for selling items)?
- jr z,.skipHalvingPrice
- xor a
- ld [$ffa2],a
- ld [$ffa3],a
- ld a,$02
- ld [$ffa4],a
- predef DivideBCDPredef3 ; halves the price
-; store the halved price
- ld a,[$ffa2]
- ld [$ff9f],a
- ld a,[$ffa3]
- ld [$ffa0],a
- ld a,[$ffa4]
- ld [$ffa1],a
-.skipHalvingPrice
- hlCoord 12, 10
- ld de,SpacesBetweenQuantityAndPriceText
- call PlaceString
- ld de,$ff9f ; total price
- ld c,$a3
- call PrintBCDNumber
- hlCoord 9, 10
-.printQuantity
- ld de,wcf96 ; current quantity
- ld bc,$8102 ; print leading zeroes, 1 byte, 2 digits
- call PrintNumber
- jp .waitForKeyPressLoop
-.buttonAPressed ; the player chose to make the transaction
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- ret
-.buttonBPressed ; the player chose to cancel the transaction
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- ld a,$ff
- ret
-
-InitialQuantityText:: ; 2e30 (0:2e30)
- db "×01@"
-
-SpacesBetweenQuantityAndPriceText:: ; 2e34 (0:2e34)
- db " @"
-
-ExitListMenu:: ; 2e3b (0:2e3b)
- ld a,[wCurrentMenuItem]
- ld [wd12d],a
- ld a,$02
- ld [wd12e],a
- ld [wcc37],a
- xor a
- ld [hJoy7],a
- ld hl,wd730
- res 6,[hl]
- call BankswitchBack
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- scf
- ret
-
-PrintListMenuEntries:: ; 2e5a (0:2e5a)
- hlCoord 5, 3
- ld b,$09
- ld c,$0e
- call ClearScreenArea
- ld a,[wList]
- ld e,a
- ld a,[wList + 1]
- ld d,a
- inc de ; de = beginning of list entries
- ld a,[wListScrollOffset]
- ld c,a
- ld a,[wListMenuID]
- cp a,ITEMLISTMENU
- ld a,c
- jr nz,.skipMultiplying
-; if it's an item menu
-; item entries are 2 bytes long, so multiply by 2
- sla a
- sla c
-.skipMultiplying
- add e
- ld e,a
- jr nc,.noCarry
- inc d
-.noCarry
- hlCoord 6, 4 ; coordinates of first list entry name
- ld b,4 ; print 4 names
-.loop
- ld a,b
- ld [wWhichPokemon],a
- ld a,[de]
- ld [wd11e],a
- cp a,$ff
- jp z,.printCancelMenuItem
- push bc
- push de
- push hl
- push hl
- push de
- ld a,[wListMenuID]
- and a
- jr z,.pokemonPCMenu
- cp a,$01
- jr z,.movesMenu
-.itemMenu
- call GetItemName
- jr .placeNameString
-.pokemonPCMenu
- push hl
- ld hl,wPartyCount
- ld a,[wList]
- cp l ; is it a list of party pokemon or box pokemon?
- ld hl,wPartyMonNicks
- jr z,.getPokemonName
- ld hl, wBoxMonNicks ; box pokemon names
-.getPokemonName
- ld a,[wWhichPokemon]
- ld b,a
- ld a,4
- sub b
- ld b,a
- ld a,[wListScrollOffset]
- add b
- call GetPartyMonName
- pop hl
- jr .placeNameString
-.movesMenu
- call GetMoveName
-.placeNameString
- call PlaceString
- pop de
- pop hl
- ld a,[wcf93]
- and a ; should prices be printed?
- jr z,.skipPrintingItemPrice
-.printItemPrice
- push hl
- ld a,[de]
- ld de,ItemPrices
- ld [wcf91],a
- call GetItemPrice ; get price
- pop hl
- ld bc,20 + 5 ; 1 row down and 5 columns right
- add hl,bc
- ld c,$a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
- call PrintBCDNumber
-.skipPrintingItemPrice
- ld a,[wListMenuID]
- and a
- jr nz,.skipPrintingPokemonLevel
-.printPokemonLevel
- ld a,[wd11e]
- push af
- push hl
- ld hl,wPartyCount
- ld a,[wList]
- cp l ; is it a list of party pokemon or box pokemon?
- ld a,$00
- jr z,.next
- ld a,$02
-.next
- ld [wcc49],a
- ld hl,wWhichPokemon
- ld a,[hl]
- ld b,a
- ld a,$04
- sub b
- ld b,a
- ld a,[wListScrollOffset]
- add b
- ld [hl],a
- call LoadMonData ; load pokemon info
- ld a,[wcc49]
- and a ; is it a list of party pokemon or box pokemon?
- jr z,.skipCopyingLevel
-.copyLevel
- ld a,[wLoadedMonBoxLevel]
- ld [wLoadedMonLevel],a
-.skipCopyingLevel
- pop hl
- ld bc,$001c
- add hl,bc
- call PrintLevel ; print level
- pop af
- ld [wd11e],a
-.skipPrintingPokemonLevel
- pop hl
- pop de
- inc de
- ld a,[wListMenuID]
- cp a,ITEMLISTMENU
- jr nz,.nextListEntry
-.printItemQuantity
- ld a,[wd11e]
- ld [wcf91],a
- call IsKeyItem ; check if item is unsellable
- ld a,[wd124]
- and a ; is the item unsellable?
- jr nz,.skipPrintingItemQuantity ; if so, don't print the quantity
- push hl
- ld bc,20 + 8 ; 1 row down and 8 columns right
- add hl,bc
- ld a,"×"
- ld [hli],a
- ld a,[wd11e]
- push af
- ld a,[de]
- ld [wcf97],a
- push de
- ld de,wd11e
- ld [de],a
- ld bc,$0102
- call PrintNumber
- pop de
- pop af
- ld [wd11e],a
- pop hl
-.skipPrintingItemQuantity
- inc de
- pop bc
- inc c
- push bc
- inc c
- ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
- and a ; is an item being swapped?
- jr z,.nextListEntry
- sla a
- cp c ; is it this item?
- jr nz,.nextListEntry
- dec hl
- ld a,$ec ; unfilled right arrow menu cursor to indicate an item being swapped
- ld [hli],a
-.nextListEntry
- ld bc,2 * 20 ; 2 rows
- add hl,bc
- pop bc
- inc c
- dec b
- jp nz,.loop
- ld bc,-8
- add hl,bc
- ld a,$ee ; down arrow
- ld [hl],a
- ret
-.printCancelMenuItem
- ld de,ListMenuCancelText
- jp PlaceString
-
-ListMenuCancelText:: ; 2f97 (0:2f97)
- db "CANCEL@"
-
-GetMonName:: ; 2f9e (0:2f9e)
- push hl
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(MonsterNames) ; 07
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ld a,[wd11e]
- dec a
- ld hl,MonsterNames ; 421E
- ld c,10
- ld b,0
- call AddNTimes
- ld de,wcd6d
- push de
- ld bc,10
- call CopyData
- ld hl,wcd77
- ld [hl], "@"
- pop de
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- pop hl
- ret
-
-GetItemName:: ; 2fcf (0:2fcf)
-; given an item ID at [wd11e], store the name of the item into a string
-; starting at wcd6d
- push hl
- push bc
- ld a,[wd11e]
- cp HM_01 ; is this a TM/HM?
- jr nc,.Machine
-
- ld [wd0b5],a
- ld a,ITEM_NAME
- ld [wNameListType],a
- ld a,BANK(ItemNames)
- ld [wPredefBank],a
- call GetName
- jr .Finish
-
-.Machine
- call GetMachineName
-.Finish
- ld de,wcd6d ; pointer to where item name is stored in RAM
- pop bc
- pop hl
- ret
-
-GetMachineName:: ; 2ff3 (0:2ff3)
-; copies the name of the TM/HM in [wd11e] to wcd6d
- push hl
- push de
- push bc
- ld a,[wd11e]
- push af
- cp TM_01 ; is this a TM? [not HM]
- jr nc,.WriteTM
-; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
-; TM printing code
- add 5
- ld [wd11e],a
- ld hl,HiddenPrefix ; points to "HM"
- ld bc,2
- jr .WriteMachinePrefix
-.WriteTM
- ld hl,TechnicalPrefix ; points to "TM"
- ld bc,2
-.WriteMachinePrefix
- ld de,wcd6d
- call CopyData
-
-; now get the machine number and convert it to text
- ld a,[wd11e]
- sub TM_01 - 1
- ld b,$F6 ; "0"
-.FirstDigit
- sub 10
- jr c,.SecondDigit
- inc b
- jr .FirstDigit
-.SecondDigit
- add 10
- push af
- ld a,b
- ld [de],a
- inc de
- pop af
- ld b,$F6 ; "0"
- add b
- ld [de],a
- inc de
- ld a,"@"
- ld [de],a
-
- pop af
- ld [wd11e],a
- pop bc
- pop de
- pop hl
- ret
-
-TechnicalPrefix:: ; 303c (0:303c)
- db "TM"
-HiddenPrefix:: ; 303e (0:303e)
- db "HM"
-
-; sets carry if item is HM, clears carry if item is not HM
-; Input: a = item ID
-IsItemHM:: ; 3040 (0:3040)
- cp a,HM_01
- jr c,.notHM
- cp a,TM_01
- ret
-.notHM
- and a
- ret
-
-; sets carry if move is an HM, clears carry if move is not an HM
-; Input: a = move ID
-IsMoveHM:: ; 3049 (0:3049)
- ld hl,HMMoves
- ld de,1
- jp IsInArray
-
-HMMoves:: ; 3052 (0:3052)
- db CUT,FLY,SURF,STRENGTH,FLASH
- db $ff ; terminator
-
-GetMoveName:: ; 3058 (0:3058)
- push hl
- ld a,MOVE_NAME
- ld [wNameListType],a
- ld a,[wd11e]
- ld [wd0b5],a
- ld a,BANK(MoveNames)
- ld [wPredefBank],a
- call GetName
- ld de,wcd6d ; pointer to where move name is stored in RAM
- pop hl
- ret
-
-; reloads text box tile patterns, current map view, and tileset tile patterns
-ReloadMapData:: ; 3071 (0:3071)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,[W_CURMAP]
- call SwitchToMapRomBank
- call DisableLCD
- call LoadTextBoxTilePatterns
- call LoadCurrentMapView
- call LoadTilesetTilePatternData
- call EnableLCD
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; reloads tileset tile patterns
-ReloadTilesetTilePatterns:: ; 3090 (0:3090)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,[W_CURMAP]
- call SwitchToMapRomBank
- call DisableLCD
- call LoadTilesetTilePatternData
- call EnableLCD
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; shows the town map and lets the player choose a destination to fly to
-ChooseFlyDestination:: ; 30a9 (0:30a9)
- ld hl,wd72e
- res 4,[hl]
- ld b, BANK(LoadTownMap_Fly)
- ld hl, LoadTownMap_Fly
- jp Bankswitch
-
-; causes the text box to close without waiting for a button press after displaying text
-DisableWaitingAfterTextDisplay:: ; 30b6 (0:30b6)
- ld a,$01
- ld [wDoNotWaitForButtonPressAfterDisplayingText],a
- ret
-
-; uses an item
-; UseItem is used with dummy items to perform certain other functions as well
-; INPUT:
-; [wcf91] = item ID
-; OUTPUT:
-; [wcd6a] = success
-; 00: unsucessful
-; 01: successful
-; 02: not able to be used right now, no extra menu displayed (only certain items use this)
-UseItem:: ; 30bc (0:30bc)
- ld b,BANK(UseItem_)
- ld hl,UseItem_
- jp Bankswitch
-
-; confirms the item toss and then tosses the item
-; INPUT:
-; hl = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wWhichPokemon] = index of item within inventory
-; [wcf96] = quantity to toss
-; OUTPUT:
-; clears carry flag if the item is tossed, sets carry flag if not
-TossItem:: ; 30c4 (0:30c4)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(TossItem_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call TossItem_
- pop de
- ld a,d
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; checks if an item is a key item
-; INPUT:
-; [wcf91] = item ID
-; OUTPUT:
-; [wd124] = result
-; 00: item is not key item
-; 01: item is key item
-IsKeyItem:: ; 30d9 (0:30d9)
- push hl
- push de
- push bc
- callba IsKeyItem_
- pop bc
- pop de
- pop hl
- ret
-
-; function to draw various text boxes
-; INPUT:
-; [wTextBoxID] = text box ID
-DisplayTextBoxID:: ; 30e8 (0:30e8)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,BANK(DisplayTextBoxID_)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call DisplayTextBoxID_
- pop bc
- ld a,b
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; not zero if an NPC movement script is running, the player character is
-; automatically stepping down from a door, or joypad states are being simulated
-IsPlayerCharacterBeingControlledByGame:: ; 30fd (0:30fd)
- ld a, [wNPCMovementScriptPointerTableNum]
- and a
- ret nz
- ld a, [wd736]
- bit 1, a ; currently stepping down from door bit
- ret nz
- ld a, [wd730]
- and $80
- ret
-
-RunNPCMovementScript:: ; 310e (0:310e)
- ld hl, wd736
- bit 0, [hl]
- res 0, [hl]
- jr nz, .playerStepOutFromDoor
- ld a, [wNPCMovementScriptPointerTableNum]
- and a
- ret z
- dec a
- add a
- ld d, 0
- ld e, a
- ld hl, .NPCMovementScriptPointerTables
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wNPCMovementScriptBank]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ld a, [wNPCMovementScriptFunctionNum]
- call CallFunctionInTable
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-.NPCMovementScriptPointerTables
- dw ProfOakMovementScriptPointerTable
- dw PewterMuseumGuyMovementScriptPointerTable
- dw PewterGymGuyMovementScriptPointerTable
-.playerStepOutFromDoor
- ld b, BANK(PlayerStepOutFromDoor)
- ld hl, PlayerStepOutFromDoor
- jp Bankswitch
-
-EndNPCMovementScript:: ; 314e (0:314e)
- ld b, BANK(_EndNPCMovementScript)
- ld hl, _EndNPCMovementScript
- jp Bankswitch
-
-EmptyFunc2:: ; 3156 (0:3156)
- ret
-
-; stores hl in [W_TRAINERHEADERPTR]
-StoreTrainerHeaderPointer:: ; 3157 (0:3157)
- ld a, h
- ld [W_TRAINERHEADERPTR], a
- ld a, l
- ld [W_TRAINERHEADERPTR+1], a
- ret
-
-; executes the current map script from the function pointer array provided in hl.
-; a: map script index to execute (unless overridden by [wd733] bit 4)
-ExecuteCurMapScriptInTable:: ; 3160 (0:3160)
- push af
- push de
- call StoreTrainerHeaderPointer
- pop hl
- pop af
- push hl
- ld hl, W_FLAGS_D733
- bit 4, [hl]
- res 4, [hl]
- jr z, .useProvidedIndex ; test if map script index was overridden manually
- ld a, [W_CURMAPSCRIPT]
-.useProvidedIndex
- pop hl
- ld [W_CURMAPSCRIPT], a
- call CallFunctionInTable
- ld a, [W_CURMAPSCRIPT]
- ret
-
-LoadGymLeaderAndCityName:: ; 317f (0:317f)
- push de
- ld de, wGymCityName
- ld bc, $11
- call CopyData ; load city name
- pop hl
- ld de, wGymLeaderName
- ld bc, $b
- jp CopyData ; load gym leader name
-
-; reads specific information from trainer header (pointed to at W_TRAINERHEADERPTR)
-; a: offset in header data
-; 0 -> flag's bit (into wTrainerHeaderFlagBit)
-; 2 -> flag's byte ptr (into hl)
-; 4 -> before battle text (into hl)
-; 6 -> after battle text (into hl)
-; 8 -> end battle text (into hl)
-ReadTrainerHeaderInfo:: ; 3193 (0:3193)
- push de
- push af
- ld d, $0
- ld e, a
- ld hl, W_TRAINERHEADERPTR
- ld a, [hli]
- ld l, [hl]
- ld h, a
- add hl, de
- pop af
- and a
- jr nz, .nonZeroOffset
- ld a, [hl]
- ld [wTrainerHeaderFlagBit], a ; store flag's bit
- jr .done
-.nonZeroOffset
- cp $2
- jr z, .readPointer ; read flag's byte ptr
- cp $4
- jr z, .readPointer ; read before battle text
- cp $6
- jr z, .readPointer ; read after battle text
- cp $8
- jr z, .readPointer ; read end battle text
- cp $a
- jr nz, .done
- ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?)
- ld d, [hl]
- ld e, a
- jr .done
-.readPointer
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.done
- pop de
- ret
-
-TrainerFlagAction::
- predef_jump FlagActionPredef
-
-TalkToTrainer:: ; 31cc (0:31cc)
- call StoreTrainerHeaderPointer
- xor a
- call ReadTrainerHeaderInfo ; read flag's bit
- ld a, $2
- call ReadTrainerHeaderInfo ; read flag's byte ptr
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- ld b, $2
- call TrainerFlagAction ; read trainer's flag
- ld a, c
- and a
- jr z, .trainerNotYetFought ; test trainer's flag
- ld a, $6
- call ReadTrainerHeaderInfo ; print after battle text
- jp PrintText
-.trainerNotYetFought ; 0x31ed
- ld a, $4
- call ReadTrainerHeaderInfo ; print before battle text
- call PrintText
- ld a, $a
- call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
- push de
- ld a, $8
- call ReadTrainerHeaderInfo ; read end battle text
- pop de
- call SaveEndBattleTextPointers
- ld hl, W_FLAGS_D733
- set 4, [hl] ; activate map script index override (index is set below)
- ld hl, wFlags_0xcd60
- bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
- ret nz
-; if the player talked to the trainer of his own volition
- call EngageMapTrainer
- ld hl, W_CURMAPSCRIPT
- inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
- jp StartTrainerBattle
-
-; checks if any trainers are seeing the player and wanting to fight
-CheckFightingMapTrainers:: ; 3219 (0:3219)
- call CheckForEngagingTrainers
- ld a, [wSpriteIndex]
- cp $ff
- jr nz, .trainerEngaging
- xor a
- ld [wSpriteIndex], a
- ld [wTrainerHeaderFlagBit], a
- ret
-.trainerEngaging
- ld hl, W_FLAGS_D733
- set 3, [hl]
- ld [wcd4f], a
- xor a
- ld [wcd50], a
- predef EmotionBubble
- ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN
- ld [wJoyIgnore], a
- xor a
- ldh [$b4], a
- call TrainerWalkUpToPlayer_Bank0
- ld hl, W_CURMAPSCRIPT
- inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
- ret
-
-; display the before battle text after the enemy trainer has walked up to the player's sprite
-DisplayEnemyTrainerTextAndStartBattle:: ; 324c (0:324c)
- ld a, [wd730]
- and $1
- ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
- ld [wJoyIgnore], a
- ld a, [wSpriteIndex]
- ld [hSpriteIndexOrTextID], a
- call DisplayTextID
- ; fall through
-
-StartTrainerBattle:: ; 325d (0:325d)
- xor a
- ld [wJoyIgnore], a
- call InitBattleEnemyParameters
- ld hl, wd72d
- set 6, [hl]
- set 7, [hl]
- ld hl, wd72e
- set 1, [hl]
- ld hl, W_CURMAPSCRIPT
- inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
- ret
-
-EndTrainerBattle:: ; 3275 (0:3275)
- ld hl, wd126
- set 5, [hl]
- set 6, [hl]
- ld hl, wd72d
- res 7, [hl]
- ld hl, wFlags_0xcd60
- res 0, [hl] ; player is no longer engaged by any trainer
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- cp $ff
- jp z, ResetButtonPressedAndMapScript
- ld a, $2
- call ReadTrainerHeaderInfo
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- ld b, $1
- call TrainerFlagAction ; flag trainer as fought
- ld a, [W_ENEMYMONORTRAINERCLASS]
- cp $c8
- jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
- ld hl, W_MISSABLEOBJECTLIST
- ld de, $2
- ld a, [wSpriteIndex]
- call IsInArray ; search for sprite ID
- inc hl
- ld a, [hl]
- ld [wcc4d], a ; load corresponding missable object index and remove it
- predef HideObject
-.skipRemoveSprite
- ld hl, wd730
- bit 4, [hl]
- res 4, [hl]
- ret nz
-
-ResetButtonPressedAndMapScript:: ; 32c1 (0:32c1)
- xor a
- ld [wJoyIgnore], a
- ld [hJoyHeld], a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
- ld [W_CURMAPSCRIPT], a ; reset battle status
- ret
-
-; calls TrainerWalkUpToPlayer
-TrainerWalkUpToPlayer_Bank0:: ; 32cf (0:32cf)
- ld b, BANK(TrainerWalkUpToPlayer)
- ld hl, TrainerWalkUpToPlayer
- jp Bankswitch
-
-; sets opponent type and mon set/lvl based on the engaging trainer data
-InitBattleEnemyParameters:: ; 32d7 (0:32d7)
- ld a, [wEngagedTrainerClass]
- ld [W_CUROPPONENT], a ; wd059
- ld [W_ENEMYMONORTRAINERCLASS], a
- cp $c8
- ld a, [wEngagedTrainerSet] ; wcd2e
- jr c, .noTrainer
- ld [W_TRAINERNO], a ; wd05d
- ret
-.noTrainer
- ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
- ret
-
-GetSpritePosition1:: ; 32ef (0:32ef)
- ld hl, _GetSpritePosition1
- jr asm_3301
-
-GetSpritePosition2:: ; 32f4 (0:32f4)
- ld hl, _GetSpritePosition2
- jr asm_3301 ; 0x32f7 $8
-
-SetSpritePosition1:: ; 32f9 (0:32f9)
- ld hl, _SetSpritePosition1
- jr asm_3301
-
-SetSpritePosition2:: ; 32fe (0:32fe)
- ld hl, _SetSpritePosition2
-asm_3301:: ; 3301 (0:3301)
- ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2)
- jp Bankswitch ; indirect jump to one of the four functions
-
-CheckForEngagingTrainers:: ; 3306 (0:3306)
- xor a
- call ReadTrainerHeaderInfo ; read trainer flag's bit (unused)
- ld d, h ; store trainer header address in de
- ld e, l
-.trainerLoop
- call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer
- ld a, [de]
- ld [wSpriteIndex], a ; store trainer flag's bit
- ld [wTrainerHeaderFlagBit], a
- cp $ff
- ret z
- ld a, $2
- call ReadTrainerHeaderInfo ; read trainer flag's byte ptr
- ld b, $2
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- call TrainerFlagAction ; read trainer flag
- ld a, c
- and a
- jr nz, .trainerAlreadyFought
- push hl
- push de
- push hl
- xor a
- call ReadTrainerHeaderInfo ; get trainer header pointer
- inc hl
- ld a, [hl] ; read trainer engage distance
- pop hl
- ld [wTrainerEngageDistance], a
- ld a, [wSpriteIndex]
- swap a
- ld [wTrainerSpriteOffset], a ; wWhichTrade
- predef TrainerEngage
- pop de
- pop hl
- ld a, [wTrainerSpriteOffset] ; wWhichTrade
- and a
- ret nz ; break if the trainer is engaging
-.trainerAlreadyFought
- ld hl, $c
- add hl, de
- ld d, h
- ld e, l
- jr .trainerLoop
-
-; hl = text if the player wins
-; de = text if the player loses
-SaveEndBattleTextPointers:: ; 3354 (0:3354)
- ld a, [H_LOADEDROMBANK]
- ld [wEndBattleTextRomBank], a
- ld a, h
- ld [wEndBattleWinTextPointer], a
- ld a, l
- ld [wEndBattleWinTextPointer + 1], a
- ld a, d
- ld [wEndBattleLoseTextPointer], a
- ld a, e
- ld [wEndBattleLoseTextPointer + 1], a
- ret
-
-; loads data of some trainer on the current map and plays pre-battle music
-; [wSpriteIndex]: sprite ID of trainer who is engaged
-EngageMapTrainer:: ; 336a (0:336a)
- ld hl, W_MAPSPRITEEXTRADATA
- ld d, $0
- ld a, [wSpriteIndex]
- dec a
- add a
- ld e, a
- add hl, de ; seek to engaged trainer data
- ld a, [hli] ; load trainer class
- ld [wEngagedTrainerClass], a
- ld a, [hl] ; load trainer mon set
- ld [wEnemyMonAttackMod], a ; wcd2e
- jp PlayTrainerMusic
-
-PrintEndBattleText:: ; 3381 (0:3381)
- push hl
- ld hl, wd72d
- bit 7, [hl]
- res 7, [hl]
- pop hl
- ret z
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wEndBattleTextRomBank]
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- push hl
- callba SaveTrainerName
- ld hl, TrainerEndBattleText
- call PrintText
- pop hl
- pop af
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- callba FreezeEnemyTrainerSprite
- jp WaitForSoundToFinish
-
-GetSavedEndBattleTextPointer:: ; 33b7 (0:33b7)
- ld a, [wBattleResult]
- and a
-; won battle
- jr nz, .lostBattle
- ld a, [wEndBattleWinTextPointer]
- ld h, a
- ld a, [wEndBattleWinTextPointer + 1]
- ld l, a
- ret
-.lostBattle
- ld a, [wEndBattleLoseTextPointer]
- ld h, a
- ld a, [wEndBattleLoseTextPointer + 1]
- ld l, a
- ret
-
-TrainerEndBattleText:: ; 33cf (0:33cf)
- TX_FAR _TrainerNameText
- db $08
- call GetSavedEndBattleTextPointer
- call TextCommandProcessor
- jp TextScriptEnd
-
-; XXX unused?
-Func_33dd:: ; 33dd (0:33dd)
- ld a, [wFlags_0xcd60]
- bit 0, a
- ret nz
- call EngageMapTrainer
- xor a
- ret
-
-PlayTrainerMusic:: ; 33e8 (0:33e8)
- ld a, [wEngagedTrainerClass]
- cp $c8 + SONY1
- ret z
- cp $c8 + SONY2
- ret z
- cp $c8 + SONY3
- ret z
- ld a, [W_GYMLEADERNO] ; W_GYMLEADERNO
- and a
- ret nz
- xor a
- ld [wMusicHeaderPointer], a
- ld a, $ff
- call PlaySound ; stop music
- ld a, BANK(Music_MeetEvilTrainer)
- ld [wc0ef], a
- ld [wc0f0], a
- ld a, [wEngagedTrainerClass]
- ld b, a
- ld hl, EvilTrainerList
-.evilTrainerListLoop
- ld a, [hli]
- cp $ff
- jr z, .noEvilTrainer
- cp b
- jr nz, .evilTrainerListLoop
- ld a, MUSIC_MEET_EVIL_TRAINER
- jr .PlaySound
-.noEvilTrainer
- ld hl, FemaleTrainerList
-.femaleTrainerListLoop
- ld a, [hli]
- cp $ff
- jr z, .maleTrainer
- cp b
- jr nz, .femaleTrainerListLoop
- ld a, MUSIC_MEET_FEMALE_TRAINER
- jr .PlaySound
-.maleTrainer
- ld a, MUSIC_MEET_MALE_TRAINER
-.PlaySound
- ld [wc0ee], a
- jp PlaySound
-
-INCLUDE "data/trainer_types.asm"
-
-; checks if the player's coordinates match an arrow movement tile's coordinates
-; and if so, decodes the RLE movement data
-; b = player Y
-; c = player X
-DecodeArrowMovementRLE:: ; 3442 (0:3442)
- ld a, [hli]
- cp $ff
- ret z ; no match in the list
- cp b
- jr nz, .nextArrowMovementTileEntry1
- ld a, [hli]
- cp c
- jr nz, .nextArrowMovementTileEntry2
- ld a, [hli]
- ld d, [hl]
- ld e, a
- ld hl, wSimulatedJoypadStatesEnd
- call DecodeRLEList
- dec a
- ld [wSimulatedJoypadStatesIndex], a
- ret
-.nextArrowMovementTileEntry1
- inc hl
-.nextArrowMovementTileEntry2
- inc hl
- inc hl
- jr DecodeArrowMovementRLE
-
-FuncTX_ItemStoragePC:: ; 3460 (0:3460)
- call SaveScreenTilesToBuffer2
- ld b, BANK(PlayerPC)
- ld hl, PlayerPC
- jr bankswitchAndContinue
-
-FuncTX_BillsPC:: ; 346a (0:346a)
- call SaveScreenTilesToBuffer2
- ld b, BANK(BillsPC_)
- ld hl, BillsPC_
- jr bankswitchAndContinue
-
-FuncTX_SlotMachine:: ; 3474 (0:3474)
-; XXX find a better name for this function
-; special_F7
- ld b,BANK(CeladonPrizeMenu)
- ld hl,CeladonPrizeMenu
-bankswitchAndContinue:: ; 3479 (0:3479)
- call Bankswitch
- jp HoldTextDisplayOpen ; continue to main text-engine function
-
-FuncTX_PokemonCenterPC:: ; 347f (0:347f)
- ld b, BANK(ActivatePC)
- ld hl, ActivatePC
- jr bankswitchAndContinue
-
-StartSimulatingJoypadStates:: ; 3486 (0:3486)
- xor a
- ld [wOverrideSimulatedJoypadStatesMask], a
- ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1
- ld hl, wd730
- set 7, [hl]
- ret
-
-IsItemInBag:: ; 3493 (0:3493)
-; given an item_id in b
-; set zero flag if item isn't in player's bag
-; else reset zero flag
-; related to Pokémon Tower and ghosts
- predef IsItemInBag_
- ld a,b
- and a
- ret
-
-DisplayPokedex:: ; 349b (0:349b)
- ld [wd11e], a
- ld b, BANK(Func_7c18)
- ld hl, Func_7c18
- jp Bankswitch
-
-SetSpriteFacingDirectionAndDelay:: ; 34a6 (0:34a6)
- call SetSpriteFacingDirection
- ld c, $6
- jp DelayFrames
-
-SetSpriteFacingDirection:: ; 34ae (0:34ae)
- ld a, $9
- ld [H_SPRITEDATAOFFSET], a
- call GetPointerWithinSpriteStateData1
- ld a, [$ff8d]
- ld [hl], a
- ret
-
-SetSpriteImageIndexAfterSettingFacingDirection:: ; 34b9 (0:34b9)
- ld de, -7
- add hl, de
- ld [hl], a
- ret
-
-; tests if the player's coordinates are in a specified array
-; INPUT:
-; hl = address of array
-; OUTPUT:
-; [wWhichTrade] = if there is match, the matching array index
-; sets carry if the coordinates are in the array, clears carry if not
-ArePlayerCoordsInArray:: ; 34bf (0:34bf)
- ld a,[W_YCOORD]
- ld b,a
- ld a,[W_XCOORD]
- ld c,a
- ; fallthrough
-
-CheckCoords:: ; 34c7 (0:34c7)
- xor a
- ld [wWhichTrade],a
-.loop
- ld a,[hli]
- cp a,$ff ; reached terminator?
- jr z,.notInArray
- push hl
- ld hl,wWhichTrade
- inc [hl]
- pop hl
-.compareYCoord
- cp b
- jr z,.compareXCoord
- inc hl
- jr .loop
-.compareXCoord
- ld a,[hli]
- cp c
- jr nz,.loop
-.inArray
- scf
- ret
-.notInArray
- and a
- ret
-
-; tests if a boulder's coordinates are in a specified array
-; INPUT:
-; hl = address of array
-; [H_SPRITEINDEX] = index of boulder sprite
-; OUTPUT:
-; [wWhichTrade] = if there is match, the matching array index
-; sets carry if the coordinates are in the array, clears carry if not
-CheckBoulderCoords:: ; 34e4 (0:34e4)
- push hl
- ld hl, wSpriteStateData2 + $04
- ld a, [H_SPRITEINDEX]
- swap a
- ld d, $0
- ld e, a
- add hl, de
- ld a, [hli]
- sub $4 ; because sprite coordinates are offset by 4
- ld b, a
- ld a, [hl]
- sub $4 ; because sprite coordinates are offset by 4
- ld c, a
- pop hl
- jp CheckCoords
-
-GetPointerWithinSpriteStateData1:: ; 34fc (0:34fc)
- ld h, $c1
- jr _GetPointerWithinSpriteStateData
-
-GetPointerWithinSpriteStateData2:: ; 3500 (0:3500)
- ld h, $c2
-
-_GetPointerWithinSpriteStateData:
- ld a, [H_SPRITEDATAOFFSET]
- ld b, a
- ld a, [H_SPRITEINDEX]
- swap a
- add b
- ld l, a
- ret
-
-; decodes a $ff-terminated RLEncoded list
-; each entry is a pair of bytes <byte value> <repetitions>
-; the final $ff will be replicated in the output list and a contains the number of bytes written
-; de: input list
-; hl: output list
-DecodeRLEList:: ; 350c (0:350c)
- xor a
- ld [wRLEByteCount], a ; count written bytes here
-.listLoop
- ld a, [de]
- cp $ff
- jr z, .endOfList
- ld [H_DOWNARROWBLINKCNT1], a ; store byte value to be written
- inc de
- ld a, [de]
- ld b, $0
- ld c, a ; number of bytes to be written
- ld a, [wRLEByteCount]
- add c
- ld [wRLEByteCount], a ; update total number of written bytes
- ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
- call FillMemory ; write a c-times to output
- inc de
- jr .listLoop
-.endOfList
- ld a, $ff
- ld [hl], a ; write final $ff
- ld a, [wRLEByteCount]
- inc a ; include sentinel in counting
- ret
-
-; sets movement byte 1 for sprite [$FF8C] to $FE and byte 2 to [$FF8D]
-SetSpriteMovementBytesToFE:: ; 3533 (0:3533)
- push hl
- call GetSpriteMovementByte1Pointer
- ld [hl], $fe
- call GetSpriteMovementByte2Pointer
- ld a, [$ff8d]
- ld [hl], a
- pop hl
- ret
-
-; sets both movement bytes for sprite [$FF8C] to $FF
-SetSpriteMovementBytesToFF:: ; 3541 (0:3541)
- push hl
- call GetSpriteMovementByte1Pointer
- ld [hl],$FF
- call GetSpriteMovementByte2Pointer
- ld [hl],$FF ; prevent person from walking?
- pop hl
- ret
-
-; returns the sprite movement byte 1 pointer for sprite [$FF8C] in hl
-GetSpriteMovementByte1Pointer:: ; 354e (0:354e)
- ld h,$C2
- ld a,[H_SPRITEINDEX] ; the sprite to move
- swap a
- add a,6
- ld l,a
- ret
-
-; returns the sprite movement byte 2 pointer for sprite [$FF8C] in hl
-GetSpriteMovementByte2Pointer:: ; 3558 (0:3558)
- push de
- ld hl,W_MAPSPRITEDATA
- ld a,[$FF8C] ; the sprite to move
- dec a
- add a
- ld d,0
- ld e,a
- add hl,de
- pop de
- ret
-
-GetTrainerInformation:: ; 3566 (0:3566)
- call GetTrainerName
- ld a, [wLinkState]
- and a
- jr nz, .linkBattle
- ld a, Bank(TrainerPicAndMoneyPointers)
- call BankswitchHome
- ld a, [W_TRAINERCLASS] ; wd031
- dec a
- ld hl, TrainerPicAndMoneyPointers
- ld bc, $5
- call AddNTimes
- ld de, wTrainerPicPointer
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- ld de, wd046
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- jp BankswitchBack
-.linkBattle
- ld hl, wTrainerPicPointer
- ld de, RedPicFront
- ld [hl], e
- inc hl
- ld [hl], d
- ret
-
-GetTrainerName:: ; 359e (0:359e)
- ld b, BANK(GetTrainerName_)
- ld hl, GetTrainerName_
- jp Bankswitch
-
-
-HasEnoughMoney::
-; Check if the player has at least as much
-; money as the 3-byte BCD value at $ff9f.
- ld de, wPlayerMoney
- ld hl, $ff9f
- ld c, 3
- jp StringCmp
-
-HasEnoughCoins::
-; Check if the player has at least as many
-; coins as the 2-byte BCD value at $ffa0.
- ld de, wPlayerCoins
- ld hl, $ffa0
- ld c, 2
- jp StringCmp
-
-
-BankswitchHome:: ; 35d9 (0:35d9)
-; switches to bank # in a
-; Only use this when in the home bank!
- ld [wcf09],a
- ld a,[H_LOADEDROMBANK]
- ld [wcf08],a
- ld a,[wcf09]
- call BankswitchCommon
- ret
-
-BankswitchBack:: ; 35e8 (0:35e8)
-; returns from BankswitchHome
- ld a,[wcf08]
- call BankswitchCommon
- ret
-
-BankswitchCommon:: ; 3e7e (0:3e7e)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-Bankswitch:: ; 3e84 (0:3e84)
-; self-contained bankswitch, use this when not in the home bank
-; switches to the bank in b
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,b
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call .jumptoaddress
- pop bc
- ld a,b
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-.jumptoaddress
- jp [hl]
-
-; displays yes/no choice
-; yes -> set carry
-YesNoChoice:: ; 35ec (0:35ec)
- call SaveScreenTilesToBuffer1
- call InitYesNoTextBoxParameters
- jr DisplayYesNoChoice
-
-Func_35f4:: ; 35f4 (0:35f4)
- ld a, TWO_OPTION_MENU
- ld [wTextBoxID], a
- call InitYesNoTextBoxParameters
- jp DisplayTextBoxID
-
-InitYesNoTextBoxParameters:: ; 35ff (0:35ff)
- xor a ; YES_NO_MENU
- ld [wTwoOptionMenuID], a
- hlCoord 14, 7
- ld bc, $80f
- ret
-
-YesNoChoicePokeCenter:: ; 360a (0:360a)
- call SaveScreenTilesToBuffer1
- ld a, HEAL_CANCEL_MENU
- ld [wTwoOptionMenuID], a
- hlCoord 11, 6
- ld bc, $80c
- jr DisplayYesNoChoice
-
-Func_361a:: ; 361a (0:361a)
- call SaveScreenTilesToBuffer1
- ld a, WIDE_YES_NO_MENU
- ld [wTwoOptionMenuID], a
- hlCoord 12, 7
- ld bc, $080d
-DisplayYesNoChoice:: ; 3628 (0:3628)
- ld a, TWO_OPTION_MENU
- ld [wTextBoxID], a
- call DisplayTextBoxID
- jp LoadScreenTilesFromBuffer1
-
-; calculates the difference |a-b|, setting carry flag if a<b
-CalcDifference:: ; 3633 (0:3633)
- sub b
- ret nc
- cpl
- add $1
- scf
- ret
-
-MoveSprite:: ; 363a (0:363a)
-; move the sprite [$FF8C] with the movement pointed to by de
-; actually only copies the movement data to wcc5b for later
- call SetSpriteMovementBytesToFF
-MoveSprite_:: ; 363d (0:363d)
- push hl
- push bc
- call GetSpriteMovementByte1Pointer
- xor a
- ld [hl],a
- ld hl,wcc5b
- ld c,0
-
-.loop
- ld a,[de]
- ld [hli],a
- inc de
- inc c
- cp a,$FF ; have we reached the end of the movement data?
- jr nz,.loop
-
- ld a,c
- ld [wcf0f],a ; number of steps taken
-
- pop bc
- ld hl,wd730
- set 0,[hl]
- pop hl
- xor a
- ld [wOverrideSimulatedJoypadStatesMask],a
- ld [wSimulatedJoypadStatesEnd],a
- dec a
- ld [wJoyIgnore],a
- ld [wWastedByteCD3A],a
- ret
-
-; divides [$ffe5] by [$ffe6] and stores the quotient in [$ffe7]
-DivideBytes:: ; 366b (0:366b)
- push hl
- ld hl, $ffe7
- xor a
- ld [hld], a
- ld a, [hld]
- and a
- jr z, .done
- ld a, [hli]
-.loop
- sub [hl]
- jr c, .done
- inc hl
- inc [hl]
- dec hl
- jr .loop
-.done
- pop hl
- ret
-
-
-LoadFontTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, FontGraphics
- ld de, vFont
- ld bc, $400
- ld a, BANK(FontGraphics)
- jp FarCopyDataDouble ; if LCD is off, transfer all at once
-.on
- ld de, FontGraphics
- ld hl, vFont
- ld bc, BANK(FontGraphics) << 8 | $80
- jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank
-
-LoadTextBoxTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, TextBoxGraphics
- ld de, vChars2 + $600
- ld bc, $200
- ld a, BANK(TextBoxGraphics)
- jp FarCopyData2 ; if LCD is off, transfer all at once
-.on
- ld de, TextBoxGraphics
- ld hl, vChars2 + $600
- ld bc, BANK(TextBoxGraphics) << 8 | $20
- jp CopyVideoData ; if LCD is on, transfer during V-blank
-
-LoadHpBarAndStatusTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, HpBarAndStatusGraphics
- ld de, vChars2 + $620
- ld bc, $1e0
- ld a, BANK(HpBarAndStatusGraphics)
- jp FarCopyData2 ; if LCD is off, transfer all at once
-.on
- ld de, HpBarAndStatusGraphics
- ld hl, vChars2 + $620
- ld bc, BANK(HpBarAndStatusGraphics) << 8 | $1e
- jp CopyVideoData ; if LCD is on, transfer during V-blank
-
-
-UncompressSpriteFromDE:: ; 36eb (0:36eb)
-; Decompress pic at a:de.
- ld hl, W_SPRITEINPUTPTR
- ld [hl], e
- inc hl
- ld [hl], d
- jp UncompressSpriteData
-
-
-SaveScreenTilesToBuffer2:: ; 36f4 (0:36f4)
- ld hl, wTileMap
- ld de, wTileMapBackup2
- ld bc, $168
- call CopyData
- ret
-
-LoadScreenTilesFromBuffer2:: ; 3701 (0:3701)
- call LoadScreenTilesFromBuffer2DisableBGTransfer
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ret
-
-; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
-LoadScreenTilesFromBuffer2DisableBGTransfer:: ; 3709 (0:3709)
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ld hl, wTileMapBackup2
- ld de, wTileMap
- ld bc, $168
- call CopyData
- ret
-
-SaveScreenTilesToBuffer1:: ; 3719 (0:3719)
- ld hl, wTileMap
- ld de, wTileMapBackup
- ld bc, $168
- jp CopyData
-
-LoadScreenTilesFromBuffer1:: ; 3725 (0:3725)
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ld hl, wTileMapBackup
- ld de, wTileMap
- ld bc, $168
- call CopyData
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ret
-
-DelayFrames:: ; 3739 (0:3739)
-; wait n frames, where n is the value in c
- call DelayFrame
- dec c
- jr nz,DelayFrames
- ret
-
-PlaySoundWaitForCurrent:: ; 3740 (0:3740)
- push af
- call WaitForSoundToFinish
- pop af
- jp PlaySound
-
-; Wait for sound to finish playing
-WaitForSoundToFinish:: ; 3748 (0:3748)
- ld a, [wLowHealthAlarm]
- and $80
- ret nz
- push hl
-.asm_374f
- ld hl, wc02a
- xor a
- or [hl]
- inc hl
- or [hl]
- inc hl
- inc hl
- or [hl]
- jr nz, .asm_374f
- pop hl
- ret
-
-NamePointers:: ; 375d (0:375d)
- dw MonsterNames
- dw MoveNames
- dw UnusedNames
- dw ItemNames
- dw wPartyMonOT ; player's OT names list
- dw wEnemyMonOT ; enemy's OT names list
- dw TrainerNames
-
-GetName:: ; 376b (0:376b)
-; arguments:
-; [wd0b5] = which name
-; [wNameListType] = which list
-; [wPredefBank] = bank of list
-;
-; returns pointer to name in de
- ld a,[wd0b5]
- ld [wd11e],a
-
- ; TM names are separate from item names.
- ; BUG: This applies to all names instead of just items.
- cp HM_01
- jp nc, GetMachineName
-
- ld a,[H_LOADEDROMBANK]
- push af
- push hl
- push bc
- push de
- ld a,[wNameListType] ;List3759_entrySelector
- dec a
- jr nz,.otherEntries
- ;1 = MON_NAMES
- call GetMonName
- ld hl,11
- add hl,de
- ld e,l
- ld d,h
- jr .gotPtr
-.otherEntries ; $378d
- ;2-7 = OTHER ENTRIES
- ld a,[wPredefBank]
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ld a,[wNameListType] ;VariousNames' entryID
- dec a
- add a
- ld d,0
- ld e,a
- jr nc,.skip
- inc d
-.skip ; $37a0
- ld hl,NamePointers
- add hl,de
- ld a,[hli]
- ld [$ff96],a
- ld a,[hl]
- ld [$ff95],a
- ld a,[$ff95]
- ld h,a
- ld a,[$ff96]
- ld l,a
- ld a,[wd0b5]
- ld b,a
- ld c,0
-.nextName
- ld d,h
- ld e,l
-.nextChar
- ld a,[hli]
- cp a, "@"
- jr nz,.nextChar
- inc c ;entry counter
- ld a,b ;wanted entry
- cp c
- jr nz,.nextName
- ld h,d
- ld l,e
- ld de,wcd6d
- ld bc,$0014
- call CopyData
-.gotPtr ; $37cd
- ld a,e
- ld [wcf8d],a
- ld a,d
- ld [wcf8e],a
- pop de
- pop bc
- pop hl
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-GetItemPrice:: ; 37df (0:37df)
-; Stores item's price as BCD at hItemPrice (3 bytes)
-; Input: [wcf91] = item id
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wListMenuID]
- cp MOVESLISTMENU
- ld a, BANK(ItemPrices)
- jr nz, .asm_37ed
- ld a, $f ; hardcoded Bank
-.asm_37ed
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ld hl, wItemPrices
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [wcf91] ; a contains item id
- cp HM_01
- jr nc, .getTMPrice
- ld bc, $3
-.asm_3802
- add hl, bc
- dec a
- jr nz, .asm_3802
- dec hl
- ld a, [hld]
- ld [hItemPrice + 2], a
- ld a, [hld]
- ld [hItemPrice + 1], a
- ld a, [hl]
- ld [hItemPrice], a
- jr .asm_381c
-.getTMPrice
- ld a, Bank(GetMachinePrice)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- call GetMachinePrice
-.asm_381c
- ld de, hItemPrice
- pop af
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-; copies a string from [de] to [wcf4b]
-CopyStringToCF4B:: ; 3826 (0:3826)
- ld hl, wcf4b
- ; fall through
-
-; copies a string from [de] to [hl]
-CopyString:: ; 3829 (0:3829)
- ld a, [de]
- inc de
- ld [hli], a
- cp "@"
- jr nz, CopyString
- ret
-
-; this function is used when lower button sensitivity is wanted (e.g. menus)
-; OUTPUT: [hJoy5] = pressed buttons in usual format
-; there are two flags that control its functionality, [hJoy6] and [hJoy7]
-; there are esentially three modes of operation
-; 1. Get newly pressed buttons only
-; ([hJoy7] == 0, [hJoy6] == any)
-; Just copies [hJoyPressed] to [hJoy5].
-; 2. Get currently pressed buttons at low sample rate with delay
-; ([hJoy7] == 1, [hJoy6] != 0)
-; If the user holds down buttons for more than half a second,
-; report buttons as being pressed up to 12 times per second thereafter.
-; If the user holds down buttons for less than half a second,
-; report only one button press.
-; 3. Same as 2, but report no buttons as pressed if A or B is held down.
-; ([hJoy7] == 1, [hJoy6] == 0)
-JoypadLowSensitivity:: ; 3831 (0:3831)
- call Joypad
- ld a,[hJoy7] ; flag
- and a ; get all currently pressed buttons or only newly pressed buttons?
- ld a,[hJoyPressed] ; newly pressed buttons
- jr z,.storeButtonState
- ld a,[hJoyHeld] ; all currently pressed buttons
-.storeButtonState
- ld [hJoy5],a
- ld a,[hJoyPressed] ; newly pressed buttons
- and a ; have any buttons been newly pressed since last check?
- jr z,.noNewlyPressedButtons
-.newlyPressedButtons
- ld a,30 ; half a second delay
- ld [H_FRAMECOUNTER],a
- ret
-.noNewlyPressedButtons
- ld a,[H_FRAMECOUNTER]
- and a ; is the delay over?
- jr z,.delayOver
-.delayNotOver
- xor a
- ld [hJoy5],a ; report no buttons as pressed
- ret
-.delayOver
-; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed
- ld a,[hJoyHeld]
- and A_BUTTON | B_BUTTON
- jr z,.setShortDelay
- ld a,[hJoy6] ; flag
- and a
- jr nz,.setShortDelay
- xor a
- ld [hJoy5],a
-.setShortDelay
- ld a,5 ; 1/12 of a second delay
- ld [H_FRAMECOUNTER],a
- ret
-
-WaitForTextScrollButtonPress:: ; 3865 (0:3865)
- ld a, [H_DOWNARROWBLINKCNT1]
- push af
- ld a, [H_DOWNARROWBLINKCNT2]
- push af
- xor a
- ld [H_DOWNARROWBLINKCNT1], a
- ld a, $6
- ld [H_DOWNARROWBLINKCNT2], a
-.loop
- push hl
- ld a, [wTownMapSpriteBlinkingEnabled]
- and a
- jr z, .skipAnimation
- call TownMapSpriteBlinkingAnimation
-.skipAnimation
- hlCoord 18, 16
- call HandleDownArrowBlinkTiming
- pop hl
- call JoypadLowSensitivity
- predef CableClub_Run
- ld a, [hJoy5]
- and A_BUTTON | B_BUTTON
- jr z, .loop
- pop af
- ld [H_DOWNARROWBLINKCNT2], a
- pop af
- ld [H_DOWNARROWBLINKCNT1], a
- ret
-
-; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect
-ManualTextScroll:: ; 3898 (0:3898)
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- jr z, .inLinkBattle
- call WaitForTextScrollButtonPress
- ld a, (SFX_02_40 - SFX_Headers_02) / 3
- jp PlaySound
-.inLinkBattle
- ld c, $41
- jp DelayFrames
-
-; function to do multiplication
-; all values are big endian
-; INPUT
-; FF96-FF98 = multiplicand
-; FF99 = multiplier
-; OUTPUT
-; FF95-FF98 = product
-Multiply:: ; 38ac (0:38ac)
- push hl
- push bc
- callab _Multiply
- pop bc
- pop hl
- ret
-
-; function to do division
-; all values are big endian
-; INPUT
-; FF95-FF98 = dividend
-; FF99 = divisor
-; b = number of bytes in the dividend (starting from FF95)
-; OUTPUT
-; FF95-FF98 = quotient
-; FF99 = remainder
-Divide:: ; 38b9 (0:38b9)
- push hl
- push de
- push bc
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,Bank(_Divide)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- call _Divide
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- pop bc
- pop de
- pop hl
- ret
-
-; This function is used to wait a short period after printing a letter to the
-; screen unless the player presses the A/B button or the delay is turned off
-; through the [wd730] or [wd358] flags.
-PrintLetterDelay:: ; 38d3 (0:38d3)
- ld a,[wd730]
- bit 6,a
- ret nz
- ld a,[wd358]
- bit 1,a
- ret z
- push hl
- push de
- push bc
- ld a,[wd358]
- bit 0,a
- jr z,.waitOneFrame
- ld a,[W_OPTIONS]
- and $f
- ld [H_FRAMECOUNTER],a
- jr .checkButtons
-.waitOneFrame
- ld a,1
- ld [H_FRAMECOUNTER],a
-.checkButtons
- call Joypad
- ld a,[hJoyHeld]
-.checkAButton
- bit 0,a ; is the A button pressed?
- jr z,.checkBButton
- jr .endWait
-.checkBButton
- bit 1,a ; is the B button pressed?
- jr z,.buttonsNotPressed
-.endWait
- call DelayFrame
- jr .done
-.buttonsNotPressed ; if neither A nor B is pressed
- ld a,[H_FRAMECOUNTER]
- and a
- jr nz,.checkButtons
-.done
- pop bc
- pop de
- pop hl
- ret
-
-; Copies [hl, bc) to [de, bc - hl).
-; In other words, the source data is from hl up to but not including bc,
-; and the destination is de.
-CopyDataUntil:: ; 3913 (0:3913)
- ld a,[hli]
- ld [de],a
- inc de
- ld a,h
- cp b
- jr nz,CopyDataUntil
- ld a,l
- cp c
- jr nz,CopyDataUntil
- ret
-
-; Function to remove a pokemon from the party or the current box.
-; wWhichPokemon determines the pokemon.
-; [wcf95] == 0 specifies the party.
-; [wcf95] != 0 specifies the current box.
-RemovePokemon:: ; 391f (0:391f)
- ld hl, _RemovePokemon
- ld b, BANK(_RemovePokemon)
- jp Bankswitch
-
-AddPartyMon:: ; 3927 (0:3927)
- push hl
- push de
- push bc
- callba _AddPartyMon
- pop bc
- pop de
- pop hl
- ret
-
-; calculates all 5 stats of current mon and writes them to [de]
-CalcStats:: ; 3936 (0:3936)
- ld c, $0
-.statsLoop
- inc c
- call CalcStat
- ld a, [H_MULTIPLICAND+1]
- ld [de], a
- inc de
- ld a, [H_MULTIPLICAND+2]
- ld [de], a
- inc de
- ld a, c
- cp $5
- jr nz, .statsLoop
- ret
-
-; calculates stat c of current mon
-; c: stat to calc (HP=1,Atk=2,Def=3,Spd=4,Spc=5)
-; b: consider stat exp?
-; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c])
-CalcStat:: ; 394a (0:394a)
- push hl
- push de
- push bc
- ld a, b
- ld d, a
- push hl
- ld hl, W_MONHEADER
- ld b, $0
- add hl, bc
- ld a, [hl] ; read base value of stat
- ld e, a
- pop hl
- push hl
- sla c
- ld a, d
- and a
- jr z, .statExpDone ; consider stat exp?
- add hl, bc ; skip to corresponding stat exp value
-.statExpLoop ; calculates ceil(Sqrt(stat exp)) in b
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND+1], a
- inc b ; increment current stat exp bonus
- ld a, b
- cp $ff
- jr z, .statExpDone
- ld [H_MULTIPLICAND+2], a
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hld]
- ld d, a
- ld a, [$ff98]
- sub d
- ld a, [hli]
- ld d, a
- ld a, [$ff97]
- sbc d ; test if (current stat exp bonus)^2 < stat exp
- jr c, .statExpLoop
-.statExpDone
- srl c
- pop hl
- push bc
- ld bc, $b ; skip to stat IV values
- add hl, bc
- pop bc
- ld a, c
- cp $2
- jr z, .getAttackIV
- cp $3
- jr z, .getDefenseIV
- cp $4
- jr z, .getSpeedIV
- cp $5
- jr z, .getSpecialIV
-.getHpIV
- push bc
- ld a, [hl] ; Atk IV
- swap a
- and $1
- sla a
- sla a
- sla a
- ld b, a
- ld a, [hli] ; Def IV
- and $1
- sla a
- sla a
- add b
- ld b, a
- ld a, [hl] ; Spd IV
- swap a
- and $1
- sla a
- add b
- ld b, a
- ld a, [hl] ; Spc IV
- and $1
- add b ; HP IV: LSB of the other 4 IVs
- pop bc
- jr .calcStatFromIV
-.getAttackIV
- ld a, [hl]
- swap a
- and $f
- jr .calcStatFromIV
-.getDefenseIV
- ld a, [hl]
- and $f
- jr .calcStatFromIV
-.getSpeedIV
- inc hl
- ld a, [hl]
- swap a
- and $f
- jr .calcStatFromIV
-.getSpecialIV
- inc hl
- ld a, [hl]
- and $f
-.calcStatFromIV
- ld d, $0
- add e
- ld e, a
- jr nc, .noCarry
- inc d ; de = Base + IV
-.noCarry
- sla e
- rl d ; de = (Base + IV) * 2
- srl b
- srl b ; b = ceil(Sqrt(stat exp)) / 4
- ld a, b
- add e
- jr nc, .noCarry2
- inc d ; da = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4
-.noCarry2
- ld [H_MULTIPLICAND+2], a
- ld a, d
- ld [H_MULTIPLICAND+1], a
- xor a
- ld [H_MULTIPLICAND], a
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
- ld [H_MULTIPLIER], a
- call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level
- ld a, [H_MULTIPLICAND]
- ld [H_DIVIDEND], a
- ld a, [H_MULTIPLICAND+1]
- ld [H_DIVIDEND+1], a
- ld a, [H_MULTIPLICAND+2]
- ld [H_DIVIDEND+2], a
- ld a, $64
- ld [H_DIVISOR], a
- ld a, $3
- ld b, a
- call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100
- ld a, c
- cp $1
- ld a, $5
- jr nz, .notHPStat
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
- ld b, a
- ld a, [H_MULTIPLICAND+2]
- add b
- ld [H_MULTIPLICAND+2], a
- jr nc, .noCarry3
- ld a, [H_MULTIPLICAND+1]
- inc a
- ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level
-.noCarry3
- ld a, $a
-.notHPStat
- ld b, a
- ld a, [H_MULTIPLICAND+2]
- add b
- ld [H_MULTIPLICAND+2], a
- jr nc, .noCarry4
- ld a, [H_MULTIPLICAND+1]
- inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5
- ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10
-.noCarry4
- ld a, [H_MULTIPLICAND+1] ; check for overflow (>999)
- cp $4
- jr nc, .overflow
- cp $3
- jr c, .noOverflow
- ld a, [H_MULTIPLICAND+2]
- cp $e8
- jr c, .noOverflow
-.overflow
- ld a, $3 ; overflow: cap at 999
- ld [H_MULTIPLICAND+1], a
- ld a, $e7
- ld [H_MULTIPLICAND+2], a
-.noOverflow
- pop bc
- pop de
- pop hl
- ret
-
-AddEnemyMonToPlayerParty:: ; 3a53 (0:3a53)
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(_AddEnemyMonToPlayerParty)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- call _AddEnemyMonToPlayerParty
- pop bc
- ld a, b
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-Func_3a68:: ; 3a68 (0:3a68)
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(Func_f51e)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- call Func_f51e
- pop bc
- ld a, b
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- ret
-
-; skips a text entries, each of size $b (like trainer name, OT name, rival name, ...)
-; hl: base pointer, will be incremented by $b * a
-SkipFixedLengthTextEntries:: ; 3a7d (0:3a7d)
- and a
- ret z
- ld bc, $b
-.skipLoop
- add hl, bc
- dec a
- jr nz, .skipLoop
- ret
-
-AddNTimes:: ; 3a87 (0:3a87)
-; add bc to hl a times
- and a
- ret z
-.loop
- add hl,bc
- dec a
- jr nz,.loop
- ret
-
-; Compare strings, c bytes in length, at de and hl.
-; Often used to compare big endian numbers in battle calculations.
-StringCmp:: ; 3a8e (0:3a8e)
- ld a,[de]
- cp [hl]
- ret nz
- inc de
- inc hl
- dec c
- jr nz,StringCmp
- ret
-
-; INPUT:
-; a = oam block index (each block is 4 oam entries)
-; b = Y coordinate of upper left corner of sprite
-; c = X coordinate of upper left corner of sprite
-; de = base address of 4 tile number and attribute pairs
-WriteOAMBlock:: ; 3a97 (0:3a97)
- ld h,wOAMBuffer / $100
- swap a ; multiply by 16
- ld l,a
- call .writeOneEntry ; upper left
- push bc
- ld a,8
- add c
- ld c,a
- call .writeOneEntry ; upper right
- pop bc
- ld a,8
- add b
- ld b,a
- call .writeOneEntry ; lower left
- ld a,8
- add c
- ld c,a
- ; lower right
-.writeOneEntry
- ld [hl],b ; Y coordinate
- inc hl
- ld [hl],c ; X coordinate
- inc hl
- ld a,[de] ; tile number
- inc de
- ld [hli],a
- ld a,[de] ; attribute
- inc de
- ld [hli],a
- ret
-
-HandleMenuInput:: ; 3abe (0:3abe)
- xor a
- ld [wd09b],a
-
-HandleMenuInputPokemonSelection:: ; 3ac2 (0:3ac2)
- ld a,[H_DOWNARROWBLINKCNT1]
- push af
- ld a,[H_DOWNARROWBLINKCNT2]
- push af ; save existing values on stack
- xor a
- ld [H_DOWNARROWBLINKCNT1],a ; blinking down arrow timing value 1
- ld a,$06
- ld [H_DOWNARROWBLINKCNT2],a ; blinking down arrow timing value 2
-.loop1
- xor a
- ld [wPartyMonAnimCounter],a ; counter for pokemon shaking animation
- call PlaceMenuCursor
- call Delay3
-.loop2
- push hl
- ld a,[wd09b]
- and a ; is it a pokemon selection menu?
- jr z,.getJoypadState
- callba AnimatePartyMon ; shake mini sprite of selected pokemon
-.getJoypadState
- pop hl
- call JoypadLowSensitivity
- ld a,[hJoy5]
- and a ; was a key pressed?
- jr nz,.keyPressed
- push hl
- hlCoord 18, 11 ; coordinates of blinking down arrow in some menus
- call HandleDownArrowBlinkTiming ; blink down arrow (if any)
- pop hl
- ld a,[wMenuJoypadPollCount]
- dec a
- jr z,.giveUpWaiting
- jr .loop2
-.giveUpWaiting
-; if a key wasn't pressed within the specified number of checks
- pop af
- ld [H_DOWNARROWBLINKCNT2],a
- pop af
- ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
- xor a
- ld [wMenuWrappingEnabled],a ; disable menu wrapping
- ret
-.keyPressed
- xor a
- ld [wcc4b],a
- ld a,[hJoy5]
- ld b,a
- bit 6,a ; pressed Up key?
- jr z,.checkIfDownPressed
-.upPressed
- ld a,[wCurrentMenuItem] ; selected menu item
- and a ; already at the top of the menu?
- jr z,.alreadyAtTop
-.notAtTop
- dec a
- ld [wCurrentMenuItem],a ; move selected menu item up one space
- jr .checkOtherKeys
-.alreadyAtTop
- ld a,[wMenuWrappingEnabled]
- and a ; is wrapping around enabled?
- jr z,.noWrappingAround
- ld a,[wMaxMenuItem]
- ld [wCurrentMenuItem],a ; wrap to the bottom of the menu
- jr .checkOtherKeys
-.checkIfDownPressed
- bit 7,a
- jr z,.checkOtherKeys
-.downPressed
- ld a,[wCurrentMenuItem]
- inc a
- ld c,a
- ld a,[wMaxMenuItem]
- cp c
- jr nc,.notAtBottom
-.alreadyAtBottom
- ld a,[wMenuWrappingEnabled]
- and a ; is wrapping around enabled?
- jr z,.noWrappingAround
- ld c,$00 ; wrap from bottom to top
-.notAtBottom
- ld a,c
- ld [wCurrentMenuItem],a
-.checkOtherKeys
- ld a,[wMenuWatchedKeys]
- and b ; does the menu care about any of the pressed keys?
- jp z,.loop1
-.checkIfAButtonOrBButtonPressed
- ld a,[hJoy5]
- and A_BUTTON | B_BUTTON
- jr z,.skipPlayingSound
-.AButtonOrBButtonPressed
- push hl
- ld hl,wFlags_0xcd60
- bit 5,[hl]
- pop hl
- jr nz,.skipPlayingSound
- ld a,(SFX_02_40 - SFX_Headers_02) / 3
- call PlaySound ; play sound
-.skipPlayingSound
- pop af
- ld [H_DOWNARROWBLINKCNT2],a
- pop af
- ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
- xor a
- ld [wMenuWrappingEnabled],a ; disable menu wrapping
- ld a,[hJoy5]
- ret
-.noWrappingAround
- ld a,[wcc37]
- and a ; should we return if the user tried to go past the top or bottom?
- jr z,.checkOtherKeys
- jr .checkIfAButtonOrBButtonPressed
-
-PlaceMenuCursor:: ; 3b7c (0:3b7c)
- ld a,[wTopMenuItemY]
- and a ; is the y coordinate 0?
- jr z,.adjustForXCoord
- ld hl,wTileMap
- ld bc,SCREEN_WIDTH
-.topMenuItemLoop
- add hl,bc
- dec a
- jr nz,.topMenuItemLoop
-.adjustForXCoord
- ld a,[wTopMenuItemX]
- ld b,0
- ld c,a
- add hl,bc
- push hl
- ld a,[wLastMenuItem]
- and a ; was the previous menu id 0?
- jr z,.checkForArrow1
- push af
- ld a,[hFlags_0xFFF6]
- bit 1,a ; is the menu double spaced?
- jr z,.doubleSpaced1
- ld bc,20
- jr .getOldMenuItemScreenPosition
-.doubleSpaced1
- ld bc,40
-.getOldMenuItemScreenPosition
- pop af
-.oldMenuItemLoop
- add hl,bc
- dec a
- jr nz,.oldMenuItemLoop
-.checkForArrow1
- ld a,[hl]
- cp a,"▶" ; was an arrow next to the previously selected menu item?
- jr nz,.skipClearingArrow
-.clearArrow
- ld a,[wTileBehindCursor]
- ld [hl],a
-.skipClearingArrow
- pop hl
- ld a,[wCurrentMenuItem]
- and a
- jr z,.checkForArrow2
- push af
- ld a,[hFlags_0xFFF6]
- bit 1,a ; is the menu double spaced?
- jr z,.doubleSpaced2
- ld bc,20
- jr .getCurrentMenuItemScreenPosition
-.doubleSpaced2
- ld bc,40
-.getCurrentMenuItemScreenPosition
- pop af
-.currentMenuItemLoop
- add hl,bc
- dec a
- jr nz,.currentMenuItemLoop
-.checkForArrow2
- ld a,[hl]
- cp a,"▶" ; has the right arrow already been placed?
- jr z,.skipSavingTile ; if so, don't lose the saved tile
- ld [wTileBehindCursor],a ; save tile before overwriting with right arrow
-.skipSavingTile
- ld a,"▶" ; place right arrow
- ld [hl],a
- ld a,l
- ld [wMenuCursorLocation],a
- ld a,h
- ld [wMenuCursorLocation + 1],a
- ld a,[wCurrentMenuItem]
- ld [wLastMenuItem],a
- ret
-
-; This is used to mark a menu cursor other than the one currently being
-; manipulated. In the case of submenus, this is used to show the location of
-; the menu cursor in the parent menu. In the case of swapping items in list,
-; this is used to mark the item that was first chosen to be swapped.
-PlaceUnfilledArrowMenuCursor:: ; 3bec (0:3bec)
- ld b,a
- ld a,[wMenuCursorLocation]
- ld l,a
- ld a,[wMenuCursorLocation + 1]
- ld h,a
- ld [hl],$ec ; outline of right arrow
- ld a,b
- ret
-
-; Replaces the menu cursor with a blank space.
-EraseMenuCursor:: ; 3bf9 (0:3bf9)
- ld a,[wMenuCursorLocation]
- ld l,a
- ld a,[wMenuCursorLocation + 1]
- ld h,a
- ld [hl]," "
- ret
-
-; This toggles a blinking down arrow at hl on and off after a delay has passed.
-; This is often called even when no blinking is occurring.
-; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0.
-; The effect is that if the tile at hl is initialized with a down arrow,
-; this function will toggle that down arrow on and off, but if the tile isn't
-; initliazed with a down arrow, this function does nothing.
-; That allows this to be called without worrying about if a down arrow should
-; be blinking.
-HandleDownArrowBlinkTiming:: ; 3c04 (0:3c04)
- ld a,[hl]
- ld b,a
- ld a,$ee ; down arrow
- cp b
- jr nz,.downArrowOff
-.downArrowOn
- ld a,[H_DOWNARROWBLINKCNT1]
- dec a
- ld [H_DOWNARROWBLINKCNT1],a
- ret nz
- ld a,[H_DOWNARROWBLINKCNT2]
- dec a
- ld [H_DOWNARROWBLINKCNT2],a
- ret nz
- ld a," "
- ld [hl],a
- ld a,$ff
- ld [H_DOWNARROWBLINKCNT1],a
- ld a,$06
- ld [H_DOWNARROWBLINKCNT2],a
- ret
-.downArrowOff
- ld a,[H_DOWNARROWBLINKCNT1]
- and a
- ret z
- dec a
- ld [H_DOWNARROWBLINKCNT1],a
- ret nz
- dec a
- ld [H_DOWNARROWBLINKCNT1],a
- ld a,[H_DOWNARROWBLINKCNT2]
- dec a
- ld [H_DOWNARROWBLINKCNT2],a
- ret nz
- ld a,$06
- ld [H_DOWNARROWBLINKCNT2],a
- ld a,$ee ; down arrow
- ld [hl],a
- ret
-
-; The following code either enables or disables the automatic drawing of
-; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait
-; for a button press after displaying text (unless [wcc47] is set).
-
-EnableAutoTextBoxDrawing:: ; 3c3c (0:3c3c)
- xor a
- jr AutoTextBoxDrawingCommon
-
-DisableAutoTextBoxDrawing:: ; 3c3f (0:3c3f)
- ld a,$01
-
-AutoTextBoxDrawingCommon:: ; 3c41 (0:3c41)
- ld [wAutoTextBoxDrawingControl],a
- xor a
- ld [wDoNotWaitForButtonPressAfterDisplayingText],a ; make DisplayTextID wait for button press
- ret
-
-PrintText:: ; 3c49 (0:3c49)
-; Print text hl at (1, 14).
- push hl
- ld a,MESSAGE_BOX
- ld [wTextBoxID],a
- call DisplayTextBoxID
- call UpdateSprites
- call Delay3
- pop hl
-Func_3c59:: ; 3c59 (0:3c59)
- bcCoord 1, 14
- jp TextCommandProcessor
-
-
-PrintNumber:: ; 3c5f
-; Print the c-digit, b-byte value at de.
-; Allows 2 to 7 digits. For 1-digit numbers, add
-; the value to char "0" instead of calling PrintNumber.
-; Flags LEADING_ZEROES and LEFT_ALIGN can be given
-; in bits 7 and 6 of b respectively.
-LEADING_ZEROES EQU 7
-LEFT_ALIGN EQU 6
-
- push bc
- xor a
- ld [H_PASTLEADINGZEROES], a
- ld [H_NUMTOPRINT], a
- ld [H_NUMTOPRINT + 1], a
- ld a, b
- and $f
- cp 1
- jr z, .byte
- cp 2
- jr z, .word
-.long
- ld a, [de]
- ld [H_NUMTOPRINT], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 1], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
- jr .start
-
-.word
- ld a, [de]
- ld [H_NUMTOPRINT + 1], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
- jr .start
-
-.byte
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
-
-.start
- push de
-
- ld d, b
- ld a, c
- ld b, a
- xor a
- ld c, a
- ld a, b
-
- cp 2
- jr z, .tens
- cp 3
- jr z, .hundreds
- cp 4
- jr z, .thousands
- cp 5
- jr z, .ten_thousands
- cp 6
- jr z, .hundred_thousands
-
-print_digit: macro
-
-if (\1) / $10000
- ld a, \1 / $10000 % $100
-else xor a
-endc
- ld [H_POWEROFTEN + 0], a
-
-if (\1) / $100
- ld a, \1 / $100 % $100
-else xor a
-endc
- ld [H_POWEROFTEN + 1], a
-
- ld a, \1 / $1 % $100
- ld [H_POWEROFTEN + 2], a
-
- call .PrintDigit
- call .NextDigit
-endm
-
-.millions print_digit 1000000
-.hundred_thousands print_digit 100000
-.ten_thousands print_digit 10000
-.thousands print_digit 1000
-.hundreds print_digit 100
-
-.tens
- ld c, 0
- ld a, [H_NUMTOPRINT + 2]
-.mod
- cp 10
- jr c, .ok
- sub 10
- inc c
- jr .mod
-.ok
-
- ld b, a
- ld a, [H_PASTLEADINGZEROES]
- or c
- ld [H_PASTLEADINGZEROES], a
- jr nz, .past
- call .PrintLeadingZero
- jr .next
-.past
- ld a, "0"
- add c
- ld [hl], a
-.next
-
- call .NextDigit
-.ones
- ld a, "0"
- add b
- ld [hli], a
- pop de
- dec de
- pop bc
- ret
-
-.PrintDigit:
-; Divide by the current decimal place.
-; Print the quotient, and keep the modulus.
- ld c, 0
-.loop
- ld a, [H_POWEROFTEN]
- ld b, a
- ld a, [H_NUMTOPRINT]
- ld [H_SAVEDNUMTOPRINT], a
- cp b
- jr c, .underflow0
- sub b
- ld [H_NUMTOPRINT], a
- ld a, [H_POWEROFTEN + 1]
- ld b, a
- ld a, [H_NUMTOPRINT + 1]
- ld [H_SAVEDNUMTOPRINT + 1], a
- cp b
- jr nc, .noborrow1
-
- ld a, [H_NUMTOPRINT]
- or 0
- jr z, .underflow1
- dec a
- ld [H_NUMTOPRINT], a
- ld a, [H_NUMTOPRINT + 1]
-.noborrow1
-
- sub b
- ld [H_NUMTOPRINT + 1], a
- ld a, [H_POWEROFTEN + 2]
- ld b, a
- ld a, [H_NUMTOPRINT + 2]
- ld [H_SAVEDNUMTOPRINT + 2], a
- cp b
- jr nc, .noborrow2
-
- ld a, [H_NUMTOPRINT + 1]
- and a
- jr nz, .borrowed
-
- ld a, [H_NUMTOPRINT]
- and a
- jr z, .underflow2
- dec a
- ld [H_NUMTOPRINT], a
- xor a
-.borrowed
-
- dec a
- ld [H_NUMTOPRINT + 1], a
- ld a, [H_NUMTOPRINT + 2]
-.noborrow2
- sub b
- ld [H_NUMTOPRINT + 2], a
- inc c
- jr .loop
-
-.underflow2
- ld a, [H_SAVEDNUMTOPRINT + 1]
- ld [H_NUMTOPRINT + 1], a
-.underflow1
- ld a, [H_SAVEDNUMTOPRINT]
- ld [H_NUMTOPRINT], a
-.underflow0
- ld a, [H_PASTLEADINGZEROES]
- or c
- jr z, .PrintLeadingZero
-
- ld a, "0"
- add c
- ld [hl], a
- ld [H_PASTLEADINGZEROES], a
- ret
-
-.PrintLeadingZero:
- bit LEADING_ZEROES, d
- ret z
- ld [hl], "0"
- ret
-
-.NextDigit:
-; Increment unless the number is left-aligned,
-; leading zeroes are not printed, and no digits
-; have been printed yet.
- bit LEADING_ZEROES, d
- jr nz, .inc
- bit LEFT_ALIGN, d
- jr z, .inc
- ld a, [H_PASTLEADINGZEROES]
- and a
- ret z
-.inc
- inc hl
- ret
-
-
-CallFunctionInTable::
-JumpTable::
-; Call function a in jumptable hl.
-; de is not preserved.
- push hl
- push de
- push bc
- add a
- ld d, 0
- ld e, a
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, .returnAddress
- push de
- jp [hl]
-.returnAddress
- pop bc
- pop de
- pop hl
- ret
-
-
-IsInArray::
-; Search an array at hl for the value in a.
-; Entry size is de bytes.
-; Return count b and carry if found.
- ld b, 0
-
-IsInRestOfArray::
- ld c, a
-.loop
- ld a, [hl]
- cp -1
- jr z, .notfound
- cp c
- jr z, .found
- inc b
- add hl, de
- jr .loop
-
-.notfound
- and a
- ret
-
-.found
- scf
- ret
-
-
-RestoreScreenTilesAndReloadTilePatterns:: ; 3dbe (0:3dbe)
- call ClearSprites
- ld a, $1
- ld [wUpdateSpritesEnabled], a
- call ReloadMapSpriteTilePatterns
- call LoadScreenTilesFromBuffer2
- call LoadTextBoxTilePatterns
- call GoPAL_SET_CF1C
- jr Delay3
-
-
-GBPalWhiteOutWithDelay3::
- call GBPalWhiteOut
-
-Delay3::
-; The bg map is updated each frame in thirds.
-; Wait three frames to let the bg map fully update.
- ld c, 3
- jp DelayFrames
-
-GBPalNormal::
-; Reset BGP and OBP0.
- ld a, %11100100 ; 3210
- ld [rBGP], a
- ld a, %11010000 ; 3100
- ld [rOBP0], a
- ret
-
-GBPalWhiteOut::
-; White out all palettes.
- xor a
- ld [rBGP],a
- ld [rOBP0],a
- ld [rOBP1],a
- ret
-
-
-GoPAL_SET_CF1C:: ; 3ded (0:3ded)
- ld b,$ff
-GoPAL_SET:: ; 3def (0:3def)
- ld a,[wOnSGB]
- and a
- ret z
- predef_jump Func_71ddf
-
-GetHealthBarColor::
-; Return at hl the palette of
-; an HP bar e pixels long.
- ld a, e
- cp 27
- ld d, 0 ; green
- jr nc, .gotColor
- cp 10
- inc d ; yellow
- jr nc, .gotColor
- inc d ; red
-.gotColor
- ld [hl], d
- ret
-
-; Copy the current map's sprites' tile patterns to VRAM again after they have
-; been overwritten by other tile patterns.
-ReloadMapSpriteTilePatterns:: ; 3e08 (0:3e08)
- ld hl, wFontLoaded
- ld a, [hl]
- push af
- res 0, [hl]
- push hl
- xor a
- ld [W_SPRITESETID], a
- call DisableLCD
- callba InitMapSprites
- call EnableLCD
- pop hl
- pop af
- ld [hl], a
- call LoadPlayerSpriteGraphics
- call LoadFontTilePatterns
- jp UpdateSprites
-
-
-GiveItem::
-; Give player quantity c of item b,
-; and copy the item's name to wcf4b.
-; Return carry on success.
- ld a, b
- ld [wd11e], a
- ld [wcf91], a
- ld a, c
- ld [wcf96], a
- ld hl,wNumBagItems
- call AddItemToInventory
- ret nc
- call GetItemName
- call CopyStringToCF4B
- scf
- ret
-
-GivePokemon::
-; Give the player monster b at level c.
- ld a, b
- ld [wcf91], a
- ld a, c
- ld [W_CURENEMYLVL], a
- xor a
- ld [wcc49], a
- ld b, BANK(_GivePokemon)
- ld hl, _GivePokemon
- jp Bankswitch
-
-
-Random::
-; Return a random number in a.
-; For battles, use BattleRandom.
- push hl
- push de
- push bc
- callba Random_
- ld a, [hRandomAdd]
- pop bc
- pop de
- pop hl
- ret
-
-
-INCLUDE "home/predef.asm"
-
-
-Func_3ead:: ; 3ead (0:3ead)
- ld b, BANK(CinnabarGymQuiz_1eb0a)
- ld hl, CinnabarGymQuiz_1eb0a
- jp Bankswitch
-
-CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: ; 3eb5 (0:3eb5)
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [hJoyHeld]
- bit 0, a ; A button
- jr z, .nothingFound
-; A button is pressed
- ld a, Bank(CheckForHiddenObject)
- ld [MBC1RomBank], a
- ld [H_LOADEDROMBANK], a
- call CheckForHiddenObject
- ld a, [$ffee]
- and a
- jr nz, .hiddenObjectNotFound
- ld a, [wHiddenObjectFunctionRomBank]
- ld [MBC1RomBank], a
- ld [H_LOADEDROMBANK], a
- ld de, .returnAddress
- push de
- jp [hl]
-.returnAddress
- xor a
- jr .done
-.hiddenObjectNotFound
- callba PrintBookshelfText
- ld a, [$ffdb]
- and a
- jr z, .done
-.nothingFound
- ld a, $ff
-.done
- ld [$ffeb], a
- pop af
- ld [MBC1RomBank], a
- ld [H_LOADEDROMBANK], a
- ret
-
-PrintPredefTextID:: ; 3ef5 (0:3ef5)
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- ld hl, TextPredefs
- call SetMapTextPointer
- ld hl, wcf11
- set 0, [hl]
- call DisplayTextID
-
-RestoreMapTextPointer:: ; 3f05 (0:3f05)
- ld hl, W_MAPTEXTPTR
- ld a, [$ffec]
- ld [hli], a
- ld a, [$ffec + 1]
- ld [hl], a
- ret
-
-SetMapTextPointer:: ; 3f0f (0:3f0f)
- ld a, [W_MAPTEXTPTR]
- ld [$ffec], a
- ld a, [W_MAPTEXTPTR + 1]
- ld [$ffec + 1], a
- ld a, l
- ld [W_MAPTEXTPTR], a
- ld a, h
- ld [W_MAPTEXTPTR + 1], a
- ret
-
-TextPredefs::
- add_tx_pre CardKeySuccessText ; 01
- add_tx_pre CardKeyFailText ; 02
- add_tx_pre RedBedroomPC ; 03
- add_tx_pre RedBedroomSNESText ; 04
- add_tx_pre PushStartText ; 05
- add_tx_pre SaveOptionText ; 06
- add_tx_pre StrengthsAndWeaknessesText ; 07
- add_tx_pre OakLabEmailText ; 08
- add_tx_pre AerodactylFossilText ; 09
- add_tx_pre Route15UpstairsBinocularsText ; 0A
- add_tx_pre KabutopsFossilText ; 0B
- add_tx_pre GymStatueText1 ; 0C
- add_tx_pre GymStatueText2 ; 0D
- add_tx_pre BookcaseText ; 0E
- add_tx_pre ViridianCityPokecenterBenchGuyText ; 0F
- add_tx_pre PewterCityPokecenterBenchGuyText ; 10
- add_tx_pre CeruleanCityPokecenterBenchGuyText ; 11
- add_tx_pre LavenderCityPokecenterBenchGuyText ; 12
- add_tx_pre VermilionCityPokecenterBenchGuyText ; 13
- add_tx_pre CeladonCityPokecenterBenchGuyText ; 14
- add_tx_pre CeladonCityHotelText ; 15
- add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 16
- add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 17
- add_tx_pre SaffronCityPokecenterBenchGuyText ; 18
- add_tx_pre MtMoonPokecenterBenchGuyText ; 19
- add_tx_pre RockTunnelPokecenterBenchGuyText ; 1A
- add_tx_pre UnusedBenchGuyText1 ; 1B
- add_tx_pre UnusedBenchGuyText2 ; 1C
- add_tx_pre UnusedBenchGuyText3 ; 1D
- add_tx_pre TerminatorText_62508 ; 1E
- add_tx_pre PredefText1f ; 1F
- add_tx_pre ViridianSchoolNotebook ; 20
- add_tx_pre ViridianSchoolBlackboard ; 21
- add_tx_pre JustAMomentText ; 22
- add_tx_pre PredefText23 ; 23
- add_tx_pre FoundHiddenItemText ; 24
- add_tx_pre HiddenItemBagFullText ; 25
- add_tx_pre VermilionGymTrashText ; 26
- add_tx_pre IndigoPlateauHQText ; 27
- add_tx_pre GameCornerOutOfOrderText ; 28
- add_tx_pre GameCornerOutToLunchText ; 29
- add_tx_pre GameCornerSomeonesKeysText ; 2A
- add_tx_pre FoundHiddenCoinsText ; 2B
- add_tx_pre DroppedHiddenCoinsText ; 2C
- add_tx_pre BillsHouseMonitorText ; 2D
- add_tx_pre BillsHouseInitiatedText ; 2E
- add_tx_pre BillsHousePokemonList ; 2F
- add_tx_pre MagazinesText ; 30
- add_tx_pre CinnabarGymQuiz ; 31
- add_tx_pre GameCornerNoCoinsText ; 32
- add_tx_pre GameCornerCoinCaseText ; 33
- add_tx_pre LinkCableHelp ; 34
- add_tx_pre TMNotebook ; 35
- add_tx_pre FightingDojoText ; 36
- add_tx_pre FightingDojoText_52a10 ; 37
- add_tx_pre FightingDojoText_52a1d ; 38
- add_tx_pre NewBicycleText ; 39
- add_tx_pre IndigoPlateauStatues ; 3A
- add_tx_pre VermilionGymTrashSuccesText1 ; 3B
- add_tx_pre VermilionGymTrashSuccesText2 ; 3C
- add_tx_pre VermilionGymTrashSuccesText3 ; 3D
- add_tx_pre VermilionGymTrashFailText ; 3E
- add_tx_pre TownMapText ; 3F
- add_tx_pre BookOrSculptureText ; 40
- add_tx_pre ElevatorText ; 41
- add_tx_pre PokemonStuffText ; 42
+
+; The rst vectors are unused.
+SECTION "rst 00", ROM0 [$00]
+ rst $38
+SECTION "rst 08", ROM0 [$08]
+ rst $38
+SECTION "rst 10", ROM0 [$10]
+ rst $38
+SECTION "rst 18", ROM0 [$18]
+ rst $38
+SECTION "rst 20", ROM0 [$20]
+ rst $38
+SECTION "rst 28", ROM0 [$28]
+ rst $38
+SECTION "rst 30", ROM0 [$30]
+ rst $38
+SECTION "rst 38", ROM0 [$38]
+ rst $38
+
+; Hardware interrupts
+SECTION "vblank", ROM0 [$40]
+ jp VBlank
+SECTION "hblank", ROM0 [$48]
+ rst $38
+SECTION "timer", ROM0 [$50]
+ jp Timer
+SECTION "serial", ROM0 [$58]
+ jp Serial
+SECTION "joypad", ROM0 [$60]
+ reti
+
+
+SECTION "Home", ROM0
+
+DisableLCD::
+ xor a
+ ld [rIF], a
+ ld a, [rIE]
+ ld b, a
+ res 0, a
+ ld [rIE], a
+
+.wait
+ ld a, [rLY]
+ cp LY_VBLANK
+ jr nz, .wait
+
+ ld a, [rLCDC]
+ and $ff ^ rLCDC_ENABLE_MASK
+ ld [rLCDC], a
+ ld a, b
+ ld [rIE], a
+ ret
+
+EnableLCD::
+ ld a, [rLCDC]
+ set rLCDC_ENABLE, a
+ ld [rLCDC], a
+ ret
+
+ClearSprites::
+ xor a
+ ld hl, wOAMBuffer
+ ld b, 40 * 4
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+HideSprites::
+ ld a, 160
+ ld hl, wOAMBuffer
+ ld de, 4
+ ld b, 40
+.loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ ret
+
+INCLUDE "home/copy.asm"
+
+
+
+SECTION "Entry", ROM0 [$100]
+
+ nop
+ jp Start ; 01ab
+
+
+SECTION "Header", ROM0 [$104]
+
+ ; The header is generated by rgbfix.
+ ; The space here is allocated to prevent code from being overwritten.
+
+ ds $150 - $104
+
+
+
+SECTION "Main", ROM0
+
+Func_150:: ; 0150 (0:0150)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,b
+ call BankswitchCommon
+ ld a,[hli]
+ ld c,a
+ ld a,[hli]
+ ld b,a
+.loop
+ ld a,[hli]
+ ld d,a
+ ld a,$3
+.unknownloop
+ dec a
+ jr nz,.unknownloop
+
+ rept 7
+ call Func_199
+ call Func_1a5
+ endr
+
+ call Func_199
+ dec bc
+ ld a,c
+ or b
+ jr nz,.loop
+ pop af
+ call BankswitchCommon
+ ret
+
+Func_199:: ; 0199 (0:0199)
+ ld a,d
+ and $80
+ srl a
+ srl a
+ ld [rNR32],a
+ sla d
+ ret
+
+Func_1a5:: ; 01a5 (0:01a5)
+ ld a,$3
+.unknownloop2
+ dec a
+ jr nz,.unknownloop2
+ ret
+
+Start::
+ cp GBC
+ jr z, .gbc
+ xor a
+ jr .ok
+.gbc
+ ld a, $1
+.ok
+ ld [hGBC], a
+ jp Init
+
+Joypad:: ; 01b9
+ homecall_jump _Joypad
+
+ReadJoypad:: ; 01c8 (0:01c8)
+ homecall_jump ReadJoypad_
+
+INCLUDE "data/map_header_pointers.asm"
+INCLUDE "home/overworld.asm"
+
+
+CheckForUserInterruption:: ; 12f8 (0:12f8)
+; Return carry if Up+Select+B, Start or A are pressed in c frames.
+; Used only in the intro and title screen.
+ call DelayFrame
+
+ push bc
+ call JoypadLowSensitivity
+ pop bc
+
+ ld a, [hJoyHeld]
+ cp D_UP + SELECT + B_BUTTON
+ jr z, .input
+
+ ld a, [hJoy5]
+ and START | A_BUTTON
+ jr nz, .input
+
+ dec c
+ jr nz, CheckForUserInterruption
+
+ and a
+ ret
+
+.input
+ scf
+ ret
+
+; function to load position data for destination warp when switching maps
+; INPUT:
+; a = ID of destination warp within destination map
+LoadDestinationWarpPosition:: ; 1313 (0:1313)
+ ld b,a
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[wPredefParentBank]
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ld a,b
+ add a
+ add a
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld bc,4
+ ld de,wCurrentTileBlockMapViewPointer
+ call CopyData
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+
+DrawHPBar:: ; 1336 (0:1336)
+; 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 iz 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 W_MONHDEXNUM
+; INPUT:
+; [wWhichPokemon] = index of pokemon within party/box
+; [wcc49] = source
+; 00: player's party
+; 01: enemy's party
+; 02: current box
+; 03: daycare
+; OUTPUT:
+; [wcf91] = pokemon ID
+; wLoadedMon = base address of pokemon data
+; W_MONHDEXNUM = base address of base stats
+LoadMonData:: ; 1372 (0:1372)
+ ld hl, LoadMonData_
+ ld b, BANK(LoadMonData_)
+ jp Bankswitch
+
+
+Func_137a:: ; 137a (0:137a)
+; 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:: ; 1384 (0:1384)
+ ld a, 1
+ ld [W_SPRITEFLIPPED], a
+
+LoadFrontSpriteByMonIndex:: ; 1389 (0:1389)
+ 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, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(asm_3f0d0)
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ xor a
+ ld [$ffe1], a
+ call asm_3f0d0
+ xor a
+ ld [W_SPRITEFLIPPED], a
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+
+
+PlayCry:: ; 13d0 (0:13d0)
+; Play monster a's cry.
+ call GetCryData
+ call PlaySound
+ jp WaitForSoundToFinish
+
+GetCryData:: ; 13d9 (0:13d9)
+; 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 [wc0f1], a
+ ld a, [hl]
+ ld [wc0f2], a
+ call BankswitchBack
+
+ ; Cry headers have 3 channels,
+ ; and start from index $14,
+ ; so add 3 times the cry id.
+ ld a, b
+ ld c, $14
+ rlca ; * 2
+ add b
+ add c
+ ret
+
+
+DisplayPartyMenu:: ; 13fc (0:13fc)
+ ld a,[hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType],a
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ call PartyMenuInit
+ call DrawPartyMenu
+ jp HandlePartyMenuInput
+
+GoBackToPartyMenu:: ; 1411 (0:1411)
+ ld a,[hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType],a
+ call PartyMenuInit
+ call RedrawPartyMenu
+ jp HandlePartyMenuInput
+
+PartyMenuInit:: ; 1420 (0:1420)
+ ld a, 1 ; hardcoded bank
+ call BankswitchHome
+ call LoadHpBarAndStatusTilePatterns
+ ld hl, wd730
+ set 6, [hl] ; turn off letter printing delay
+ xor a
+ ld [wcc49], a
+ ld [wcc37], a
+ ld hl, wTopMenuItemY
+ inc a
+ ld [hli], a ; top menu item Y
+ xor a
+ ld [hli], a ; top menu item X
+ ld a, [wcc2b]
+ 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, [wd11f]
+ and a
+ ld a, A_BUTTON + B_BUTTON
+ jr z, .next
+ xor a
+ ld [wd11f], a
+ inc a
+.next
+ ld [hli], a ; menu watched keys
+ pop af
+ ld [hl], a ; old menu item ID
+ ret
+
+HandlePartyMenuInput:: ; 145a (0:145a)
+ ld a,1
+ ld [wMenuWrappingEnabled],a
+ ld a,$40
+ ld [wd09b],a
+ call HandleMenuInputPokemonSelection
+ call PlaceUnfilledArrowMenuCursor
+ ld b,a
+ xor a
+ ld [wd09b],a
+ ld a,[wCurrentMenuItem]
+ ld [wcc2b],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 [wd07d],a
+ call RedrawPartyMenu
+ jr HandlePartyMenuInput
+.handleSwap
+ ld a,[wCurrentMenuItem]
+ ld [wWhichPokemon],a
+ callba SwitchPartyMon
+ jr HandlePartyMenuInput
+
+DrawPartyMenu:: ; 14d4 (0:14d4)
+ ld hl, DrawPartyMenu_
+ jr DrawPartyMenuCommon
+
+RedrawPartyMenu:: ; 14d9 (0:14d9)
+ ld hl, RedrawPartyMenu_
+
+DrawPartyMenuCommon:: ; 14dc (0:14dc)
+ ld b, BANK(RedrawPartyMenu_)
+ jp Bankswitch
+
+; prints a pokemon's status condition
+; INPUT:
+; de = address of status condition
+; hl = destination address
+PrintStatusCondition:: ; 14e1 (0:14e1)
+ 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 ; 14f6
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(PrintStatusAilment)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call PrintStatusAilment ; print status condition
+ pop bc
+ ld a,b
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],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:: ; 150b (0:150b)
+ ld a,$6e ; ":L" tile ID
+ ld [hli],a
+ ld c,2 ; number of digits
+ ld a,[wLoadedMonLevel] ; level
+ cp a,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:: ; 151b (0:151b)
+ ld a,$6e ; ":L" tile ID
+ ld [hli],a
+ ld c,3 ; number of digits
+ ld a,[wLoadedMonLevel] ; level
+
+PrintLevelCommon:: ; 1523 (0:1523)
+ ld [wd11e],a
+ ld de,wd11e
+ ld b,$41 ; no leading zeroes, left-aligned, one byte
+ jp PrintNumber
+
+Func_152e:: ; 152e (0:152e)
+; Unused.
+ 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 W_MONHDEXNUM (W_MONHEADER)
+; INPUT:
+; [wd0b5] = pokemon ID
+GetMonHeader:: ; 1537 (0:1537)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(BaseStats)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],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 a,FOSSIL_KABUTOPS ; Kabutops fossil
+ jr z,.specialID
+ ld de,GhostPic
+ cp a,MON_GHOST ; Ghost
+ jr z,.specialID
+ ld de,FossilAerodactylPic
+ ld b,$77 ; size of Aerodactyl fossil sprite
+ cp a,FOSSIL_AERODACTYL ; Aerodactyl fossil
+ jr z,.specialID
+ cp a,MEW
+ jr z,.mew
+ predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
+ ld a,[wd11e]
+ dec a
+ ld bc,28
+ ld hl,BaseStats
+ call AddNTimes
+ ld de,W_MONHEADER
+ ld bc,28
+ call CopyData
+ jr .done
+.specialID
+ ld hl,W_MONHSPRITEDIM
+ 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,W_MONHEADER
+ ld bc,28
+ ld a,BANK(MewBaseStats)
+ call FarCopyData
+.done
+ ld a,[wd0b5]
+ ld [W_MONHDEXNUM],a
+ pop af
+ ld [wd11e],a
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; copy party pokemon's name to wcd6d
+GetPartyMonName2:: ; 15b4 (0:15b4)
+ ld a,[wWhichPokemon] ; index within party
+ ld hl,wPartyMonNicks
+
+; this is called more often
+GetPartyMonName:: ; 15ba (0:15ba)
+ push hl
+ push bc
+ call SkipFixedLengthTextEntries ; add 11 to hl, a times
+ ld de,wcd6d
+ push de
+ ld bc,11
+ call CopyData
+ pop de
+ pop bc
+ pop hl
+ ret
+
+; function to print a BCD (Binary-coded decimal) number
+; de = address of BCD number
+; hl = destination address
+; c = flags and length
+; bit 7: if set, do not print leading zeroes
+; if unset, print leading zeroes
+; bit 6: if set, left-align the string (do not pad empty digits with spaces)
+; if unset, right-align the string
+; bit 5: if set, print currency symbol at the beginning of the string
+; if unset, do not print the currency symbol
+; bits 0-4: length of BCD number in bytes
+; Note that bits 5 and 7 are modified during execution. The above reflects
+; their meaning at the beginning of the functions's execution.
+PrintBCDNumber:: ; 15cd (0:15cd)
+ ld b,c ; save flags in b
+ res 7,c
+ res 6,c
+ res 5,c ; c now holds the length
+ bit 5,b
+ jr z,.loop
+ bit 7,b
+ jr nz,.loop
+ ld [hl],"¥"
+ inc hl
+.loop
+ ld a,[de]
+ swap a
+ call PrintBCDDigit ; print upper digit
+ ld a,[de]
+ call PrintBCDDigit ; print lower digit
+ inc de
+ dec c
+ jr nz,.loop
+ bit 7,b ; were any non-zero digits printed?
+ jr z,.done ; if so, we are done
+.numberEqualsZero ; if every digit of the BCD number is zero
+ bit 6,b ; left or right alignment?
+ jr nz,.skipRightAlignmentAdjustment
+ dec hl ; if the string is right-aligned, it needs to be moved back one space
+.skipRightAlignmentAdjustment
+ bit 5,b
+ jr z,.skipCurrencySymbol
+ ld [hl],"¥"
+ inc hl
+.skipCurrencySymbol
+ ld [hl],"0"
+ call PrintLetterDelay
+ inc hl
+.done
+ ret
+
+PrintBCDDigit:: ; 1604 (0:1604)
+ and $f
+ and a
+ jr z,.zeroDigit
+.nonzeroDigit
+ bit 7,b ; have any non-space characters been printed?
+ jr z,.outputDigit
+; if bit 7 is set, then no numbers have been printed yet
+ bit 5,b ; print the currency symbol?
+ jr z,.skipCurrencySymbol
+ ld [hl],"¥"
+ inc hl
+ res 5,b
+.skipCurrencySymbol
+ res 7,b ; unset 7 to indicate that a nonzero digit has been reached
+.outputDigit
+ add a,"0"
+ ld [hli],a
+ jp PrintLetterDelay
+.zeroDigit
+ bit 7,b ; either printing leading zeroes or already reached a nonzero digit?
+ jr z,.outputDigit ; if so, print a zero digit
+ bit 6,b ; left or right alignment?
+ ret nz
+ inc hl ; if right-aligned, "print" a space by advancing the pointer
+ ret
+
+; uncompresses the front or back sprite of the specified mon
+; assumes the corresponding mon header is already loaded
+; hl contains offset to sprite pointer ($b for front or $d for back)
+UncompressMonSprite:: ; 1627 (0:1627)
+ ld bc,W_MONHEADER
+ add hl,bc
+ ld a,[hli]
+ ld [W_SPRITEINPUTPTR],a ; fetch sprite input pointer
+ ld a,[hl]
+ ld [W_SPRITEINPUTPTR+1],a
+; define (by index number) the bank that a pokemon's image is in
+; index = Mew, bank 1
+; index = Kabutops fossil, bank $B
+; index < $1F, bank 9
+; $1F ≤ index < $4A, bank $A
+; $4A ≤ index < $74, bank $B
+; $74 ≤ index < $99, bank $C
+; $99 ≤ index, bank $D
+ ld a,[wcf91] ; XXX name for this ram location
+ ld b,a
+ cp MEW
+ ld a,BANK(MewPicFront)
+ jr z,.GotBank
+ ld a,b
+ cp FOSSIL_KABUTOPS
+ ld a,BANK(FossilKabutopsPic)
+ jr z,.GotBank
+ ld a,b
+ cp TANGELA + 1
+ ld a,BANK(TangelaPicFront)
+ jr c,.GotBank
+ ld a,b
+ cp MOLTRES + 1
+ ld a,BANK(MoltresPicFront)
+ jr c,.GotBank
+ ld a,b
+ cp BEEDRILL + 2
+ ld a,BANK(BeedrillPicFront)
+ jr c,.GotBank
+ ld a,b
+ cp STARMIE + 1
+ ld a,BANK(StarmiePicFront)
+ jr c,.GotBank
+ ld a,BANK(VictreebelPicFront)
+.GotBank
+ jp UncompressSpriteData
+
+; de: destination location
+LoadMonFrontSprite:: ; 1665 (0:1665)
+ push de
+ ld hl, W_MONHFRONTSPRITE - W_MONHEADER
+ call UncompressMonSprite
+ ld hl, W_MONHSPRITEDIM
+ ld a, [hli]
+ ld c, a
+ pop de
+ ; fall through
+
+; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram
+; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers
+; de: destination location
+; a,c: sprite dimensions (in tiles of 8x8 each)
+LoadUncompressedSpriteData:: ; 1672 (0:1672)
+ push de
+ and $f
+ ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width
+ ld b, a
+ ld a, $7
+ sub b ; 7-w
+ inc a ; 8-w
+ srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up)
+ ld b, a
+ add a
+ add a
+ add a
+ sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles)
+ ld [H_SPRITEOFFSET], a
+ ld a, c
+ swap a
+ and $f
+ ld b, a
+ add a
+ add a
+ add a ; 8*tiles is height in bytes
+ ld [H_SPRITEHEIGHT], a ; $ff8c
+ ld a, $7
+ sub b ; 7-h ; skip for vertical center (in tiles, relative to current column)
+ ld b, a
+ ld a, [H_SPRITEOFFSET]
+ add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles)
+ add a
+ add a
+ add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes)
+ ld [H_SPRITEOFFSET], a
+ xor a
+ ld [$4000], a
+ ld hl, S_SPRITEBUFFER0
+ call ZeroSpriteBuffer ; zero buffer 0
+ ld de, S_SPRITEBUFFER1
+ ld hl, S_SPRITEBUFFER0
+ call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
+ ld hl, S_SPRITEBUFFER1
+ call ZeroSpriteBuffer ; zero buffer 1
+ ld de, S_SPRITEBUFFER2
+ ld hl, S_SPRITEBUFFER1
+ call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
+ pop de
+ jp InterlaceMergeSpriteBuffers
+
+; copies and aligns the sprite data properly inside the sprite buffer
+; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area
+AlignSpriteDataCentered:: ; 16c2 (0:16c2)
+ ld a, [H_SPRITEOFFSET]
+ ld b, $0
+ ld c, a
+ add hl, bc
+ ld a, [H_SPRITEWIDTH] ; $ff8b
+.columnLoop
+ push af
+ push hl
+ ld a, [H_SPRITEHEIGHT] ; $ff8c
+ ld c, a
+.columnInnerLoop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .columnInnerLoop
+ pop hl
+ ld bc, 7*8 ; 7 tiles
+ add hl, bc ; advance one full column
+ pop af
+ dec a
+ jr nz, .columnLoop
+ ret
+
+; fills the sprite buffer (pointed to in hl) with zeros
+ZeroSpriteBuffer:: ; 16df (0:16df)
+ ld bc, SPRITEBUFFERSIZE
+.nextByteLoop
+ xor a
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .nextByteLoop
+ ret
+
+; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2
+; in the resulting sprite, the rows of the two source sprites are interlaced
+; de: output address
+InterlaceMergeSpriteBuffers:: ; 16ea (0:16ea)
+ xor a
+ ld [$4000], a
+ push de
+ ld hl, S_SPRITEBUFFER2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2
+ ld de, S_SPRITEBUFFER1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1
+ ld bc, S_SPRITEBUFFER0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0
+ ld a, SPRITEBUFFERSIZE/2 ; $c4
+ ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
+.interlaceLoop
+ ld a, [de]
+ dec de
+ ld [hld], a ; write byte of source 2
+ ld a, [bc]
+ dec bc
+ ld [hld], a ; write byte of source 1
+ ld a, [de]
+ dec de
+ ld [hld], a ; write byte of source 2
+ ld a, [bc]
+ dec bc
+ ld [hld], a ; write byte of source 1
+ ld a, [H_SPRITEINTERLACECOUNTER] ; $ff8b
+ dec a
+ ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
+ jr nz, .interlaceLoop
+ ld a, [W_SPRITEFLIPPED]
+ and a
+ jr z, .notFlipped
+ ld bc, 2*SPRITEBUFFERSIZE
+ ld hl, S_SPRITEBUFFER1
+.swapLoop
+ swap [hl] ; if flipped swap nybbles in all bytes
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, .swapLoop
+.notFlipped
+ pop hl
+ ld de, S_SPRITEBUFFER1
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+
+INCLUDE "data/collision.asm"
+
+IsTilePassable:: ; 15c3 (0:15c3)
+; sets carry if tile is passable, resets carry otherwise
+ homecall_sf _IsTilePassable ; 1:4aaa
+ ret
+
+INCLUDE "home/copy2.asm"
+INCLUDE "home/text.asm"
+INCLUDE "home/vcopy.asm"
+INCLUDE "home/init.asm"
+INCLUDE "home/vblank.asm"
+INCLUDE "home/fade.asm"
+INCLUDE "home/serial.asm"
+INCLUDE "home/timer.asm"
+INCLUDE "home/audio.asm"
+
+
+UpdateSprites:: ; 2429 (0:2429)
+ ld a, [wUpdateSpritesEnabled]
+ dec a
+ ret nz
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(_UpdateSprites)
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ call _UpdateSprites
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+
+INCLUDE "data/mart_inventories.asm"
+
+TextScriptEndingChar:: ; 24d6 (0:24d6)
+ db "@"
+TextScriptEnd:: ; 24d7 (0:24d7)
+ ld hl,TextScriptEndingChar
+ ret
+
+ExclamationText:: ; 24db (0:24db)
+ TX_FAR _ExclamationText
+ db "@"
+
+GroundRoseText:: ; 24e0 (0:24e0)
+ TX_FAR _GroundRoseText
+ db "@"
+
+BoulderText:: ; 24e5 (0:24e5)
+ TX_FAR _BoulderText
+ db "@"
+
+MartSignText:: ; 24ea (0:24ea)
+ TX_FAR _MartSignText
+ db "@"
+
+PokeCenterSignText:: ; 24ef (0:24ef)
+ TX_FAR _PokeCenterSignText
+ db "@"
+
+Predef5CText:: ; 24f4 (0:24f4)
+; XXX better label (what does predef $5C do?)
+ db $08 ; asm
+ predef PickupItem
+ jp TextScriptEnd
+
+
+INCLUDE "home/pic.asm"
+
+
+ResetPlayerSpriteData:: ; 28a6 (0:28a6)
+ ld hl, wSpriteStateData1
+ call ResetPlayerSpriteData_ClearSpriteData
+ ld hl, wSpriteStateData2
+ call ResetPlayerSpriteData_ClearSpriteData
+ ld a, $1
+ ld [wSpriteStateData1], a
+ ld [wSpriteStateData2 + $0e], a
+ ld hl, wSpriteStateData1 + 4
+ ld [hl], $3c ; set Y screen pos
+ inc hl
+ inc hl
+ ld [hl], $40 ; set X screen pos
+ ret
+
+; overwrites sprite data with zeroes
+ResetPlayerSpriteData_ClearSpriteData:: ; 28c4 (0:28c4)
+ ld bc, $10
+ xor a
+ jp FillMemory
+
+Func_28cb:: ; 28cb (0:28cb)
+ ld a, [wMusicHeaderPointer]
+ and a
+ jr nz, .asm_28dc
+ ld a, [wd72c]
+ bit 1, a
+ ret nz
+ ld a, $77
+ ld [$ff24], a
+ ret
+.asm_28dc
+ ld a, [wcfc9]
+ and a
+ jr z, .asm_28e7
+ dec a
+ ld [wcfc9], a
+ ret
+.asm_28e7
+ ld a, [wcfc8]
+ ld [wcfc9], a
+ ld a, [$ff24]
+ and a
+ jr z, .asm_2903
+ ld b, a
+ and $f
+ dec a
+ ld c, a
+ ld a, b
+ and $f0
+ swap a
+ dec a
+ swap a
+ or c
+ ld [$ff24], a
+ ret
+.asm_2903
+ ld a, [wMusicHeaderPointer]
+ ld b, a
+ xor a
+ ld [wMusicHeaderPointer], a
+ ld a, $ff
+ ld [wc0ee], a
+ call PlaySound
+ ld a, [wc0f0]
+ ld [wc0ef], a
+ ld a, b
+ ld [wc0ee], a
+ jp PlaySound
+
+; this function is used to display sign messages, sprite dialog, etc.
+; INPUT: [$ff8c] = sprite ID or text ID
+DisplayTextID:: ; 2920 (0:2920)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ callba DisplayTextIDInit ; initialization
+ ld hl,wcf11
+ bit 0,[hl]
+ res 0,[hl]
+ jr nz,.skipSwitchToMapBank
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+.skipSwitchToMapBank
+ ld a,30 ; half a second
+ ld [H_FRAMECOUNTER],a ; used as joypad poll timer
+ ld hl,W_MAPTEXTPTR
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a ; hl = map text pointer
+ ld d,$00
+ ld a,[$ff8c] ; text ID
+ ld [wSpriteIndex],a
+ and a
+ jp z,DisplayStartMenu
+ cp a,$d3
+ jp z,DisplaySafariGameOverText
+ cp a,$d0
+ jp z,DisplayPokemonFaintedText
+ cp a,$d1
+ jp z,DisplayPlayerBlackedOutText
+ cp a,$d2
+ jp z,DisplayRepelWoreOffText
+ ld a,[W_NUMSPRITES]
+ ld e,a
+ ld a,[$ff8c] ; sprite ID
+ cp e
+ jr z,.spriteHandling
+ jr nc,.skipSpriteHandling
+.spriteHandling
+; get the text ID of the sprite
+ push hl
+ push de
+ push bc
+ callba UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction)
+ pop bc
+ pop de
+ ld hl,W_MAPSPRITEDATA ; NPC text entries
+ ld a,[$ff8c]
+ dec a
+ add a
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ inc hl
+ ld a,[hl] ; a = text ID of the sprite
+ pop hl
+.skipSpriteHandling
+; look up the address of the text in the map's text entries
+ dec a
+ ld e,a
+ sla e
+ add hl,de
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a ; hl = address of the text
+ ld a,[hl] ; a = first byte of text
+; check first byte of text for special cases
+ cp a,$fe ; Pokemart NPC
+ jp z,DisplayPokemartDialogue
+ cp a,$ff ; Pokemon Center NPC
+ jp z,DisplayPokemonCenterDialogue
+ cp a,$fc ; Item Storage PC
+ jp z,FuncTX_ItemStoragePC
+ cp a,$fd ; Bill's PC
+ jp z,FuncTX_BillsPC
+ cp a,$f9 ; Pokemon Center PC
+ jp z,FuncTX_PokemonCenterPC
+ cp a,$f5 ; Vending Machine
+ jr nz,.notVendingMachine
+ callba VendingMachineMenu ; jump banks to vending machine routine
+ jr AfterDisplayingTextID
+.notVendingMachine
+ cp a,$f7 ; slot machine
+ jp z,FuncTX_SlotMachine
+ cp a,$f6 ; cable connection NPC in Pokemon Center
+ jr nz,.notSpecialCase
+ callab CableClubNPC
+ jr AfterDisplayingTextID
+.notSpecialCase
+ call Func_3c59 ; display the text
+ ld a,[wDoNotWaitForButtonPressAfterDisplayingText]
+ and a
+ jr nz,HoldTextDisplayOpen
+
+AfterDisplayingTextID:: ; 29d6 (0:29d6)
+ ld a,[wcc47]
+ and a
+ jr nz,HoldTextDisplayOpen
+ call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text
+
+; loop to hold the dialogue box open as long as the player keeps holding down the A button
+HoldTextDisplayOpen:: ; 29df (0:29df)
+ call Joypad
+ ld a,[hJoyHeld]
+ bit 0,a ; is the A button being pressed?
+ jr nz,HoldTextDisplayOpen
+
+CloseTextDisplay:: ; 29e8 (0:29e8)
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ ld a,$90
+ ld [hWY],a ; move the window off the screen
+ call DelayFrame
+ call LoadGBPal
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a ; disable continuous WRAM to VRAM transfer each V-blank
+; loop to make sprites face the directions they originally faced before the dialogue
+ ld hl,wSpriteStateData2 + $19
+ ld c,$0f
+ ld de,$0010
+.restoreSpriteFacingDirectionLoop
+ ld a,[hl]
+ dec h
+ ld [hl],a
+ inc h
+ add hl,de
+ dec c
+ jr nz,.restoreSpriteFacingDirectionLoop
+ ld a,BANK(InitMapSprites)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
+ ld hl,wFontLoaded
+ res 0,[hl]
+ ld a,[wd732]
+ bit 3,a ; used fly warp
+ call z,LoadPlayerSpriteGraphics
+ call LoadCurrentMapView
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ jp UpdateSprites
+
+DisplayPokemartDialogue:: ; 2a2e (0:2a2e)
+ push hl
+ ld hl,PokemartGreetingText
+ call PrintText
+ pop hl
+ inc hl
+ call LoadItemList
+ ld a,$02
+ ld [wListMenuID],a ; selects between subtypes of menus
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,Bank(DisplayPokemartDialogue_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call DisplayPokemartDialogue_
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ jp AfterDisplayingTextID
+
+PokemartGreetingText:: ; 2a55 (0:2a55)
+ TX_FAR _PokemartGreetingText
+ db "@"
+
+LoadItemList:: ; 2a5a (0:2a5a)
+ ld a,$01
+ ld [wUpdateSpritesEnabled],a
+ ld a,h
+ ld [wd128],a
+ ld a,l
+ ld [wd129],a
+ ld de,wStringBuffer2 + 11
+.loop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ cp a,$ff
+ jr nz,.loop
+ ret
+
+DisplayPokemonCenterDialogue:: ; 2a72 (0:2a72)
+ xor a
+ ld [$ff8b],a
+ ld [$ff8c],a
+ ld [$ff8d],a
+ inc hl
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,Bank(DisplayPokemonCenterDialogue_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call DisplayPokemonCenterDialogue_
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ jp AfterDisplayingTextID
+
+DisplaySafariGameOverText:: ; 2a90 (0:2a90)
+ callab PrintSafariGameOverText
+ jp AfterDisplayingTextID
+
+DisplayPokemonFaintedText:: ; 2a9b (0:2a9b)
+ ld hl,PokemonFaintedText
+ call PrintText
+ jp AfterDisplayingTextID
+
+PokemonFaintedText:: ; 2aa4 (0:2aa4)
+ TX_FAR _PokemonFaintedText
+ db "@"
+
+DisplayPlayerBlackedOutText:: ; 2aa9 (0:2aa9)
+ ld hl,PlayerBlackedOutText
+ call PrintText
+ ld a,[wd732]
+ res 5,a ; reset forced to use bike bit
+ ld [wd732],a
+ jp HoldTextDisplayOpen
+
+PlayerBlackedOutText:: ; 2aba (0:2aba)
+ TX_FAR _PlayerBlackedOutText
+ db "@"
+
+DisplayRepelWoreOffText:: ; 2abf (0:2abf)
+ ld hl,RepelWoreOffText
+ call PrintText
+ jp AfterDisplayingTextID
+
+RepelWoreOffText:: ; 2ac8 (0:2ac8)
+ TX_FAR _RepelWoreOffText
+ db "@"
+
+INCLUDE "engine/menu/start_menu.asm"
+
+; function to count how many bits are set in a string of bytes
+; INPUT:
+; hl = address of string of bytes
+; b = length of string of bytes
+; OUTPUT:
+; [wd11e] = number of set bits
+CountSetBits:: ; 2b7f (0:2b7f)
+ ld c,0
+.loop
+ ld a,[hli]
+ ld e,a
+ ld d,8
+.innerLoop ; count how many bits are set in the current byte
+ srl e
+ ld a,0
+ adc c
+ ld c,a
+ dec d
+ jr nz,.innerLoop
+ dec b
+ jr nz,.loop
+ ld a,c
+ ld [wd11e],a ; store number of set bits
+ ret
+
+; subtracts the amount the player paid from their money
+; sets carry flag if there is enough money and unsets carry flag if not
+SubtractAmountPaidFromMoney:: ; 2b96 (0:2b96)
+ ld b,BANK(SubtractAmountPaidFromMoney_)
+ ld hl,SubtractAmountPaidFromMoney_
+ jp Bankswitch
+
+; adds the amount the player sold to their money
+AddAmountSoldToMoney:: ; 2b9e (0:2b9e)
+ ld de,wPlayerMoney + 2
+ ld hl,$ffa1 ; total price of items
+ ld c,3 ; length of money in bytes
+ predef AddBCDPredef ; add total price to money
+ ld a,MONEY_BOX
+ ld [wTextBoxID],a
+ call DisplayTextBoxID ; redraw money text box
+ ld a, (SFX_02_5a - SFX_Headers_02) / 3
+ call PlaySoundWaitForCurrent ; play sound
+ jp WaitForSoundToFinish ; wait until sound is done playing
+
+; function to remove an item (in varying quantities) from the player's bag or PC box
+; INPUT:
+; HL = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wWhichPokemon] = index (within the inventory) of the item to remove
+; [wcf96] = quantity to remove
+RemoveItemFromInventory:: ; 2bbb (0:2bbb)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(RemoveItemFromInventory_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call RemoveItemFromInventory_
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; function to add an item (in varying quantities) to the player's bag or PC box
+; INPUT:
+; HL = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wcf96] = item quantity
+; sets carry flag if successful, unsets carry flag if unsuccessful
+AddItemToInventory:: ; 2bcf (0:2bcf)
+ push bc
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(AddItemToInventory_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call AddItemToInventory_
+ pop bc
+ ld a,b
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ pop bc
+ ret
+
+; INPUT:
+; [wListMenuID] = list menu ID
+; [wList] = address of the list (2 bytes)
+DisplayListMenuID:: ; 2be6 (0:2be6)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer
+ ld a,1
+ ld [hJoy7],a ; joypad state update flag
+ ld a,[W_BATTLETYPE]
+ and a ; is it the Old Man battle?
+ jr nz,.specialBattleType
+ ld a,$01 ; hardcoded bank
+ jr .bankswitch
+.specialBattleType ; Old Man battle
+ ld a, Bank(DisplayBattleMenu)
+.bankswitch
+ call BankswitchHome
+ ld hl,wd730
+ set 6,[hl] ; turn off letter printing delay
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ ld [wd12a],a
+ ld a,[wList]
+ ld l,a
+ ld a,[wList + 1]
+ ld h,a ; hl = address of the list
+ ld a,[hl]
+ ld [wd12a],a ; [wd12a] = number of list entries
+ ld a,LIST_MENU_BOX
+ ld [wTextBoxID],a
+ call DisplayTextBoxID ; draw the menu text box
+ call UpdateSprites ; disable sprites behind the text box
+; the code up to .skipMovingSprites appears to be useless
+ hlCoord 4, 2 ; coordinates of upper left corner of menu text box
+ ld de,$090e ; height and width of menu text box
+ ld a,[wListMenuID]
+ and a ; is it a PC pokemon list?
+ jr nz,.skipMovingSprites
+ call UpdateSprites ; move sprites
+.skipMovingSprites
+ ld a,1 ; max menu item ID is 1 if the list has less than 2 entries
+ ld [wcc37],a
+ ld a,[wd12a]
+ cp a,2 ; does the list have less than 2 entries?
+ jr c,.setMenuVariables
+ ld a,2 ; max menu item ID is 2 if the list has at least 2 entries
+.setMenuVariables
+ ld [wMaxMenuItem],a
+ ld a,4
+ ld [wTopMenuItemY],a
+ ld a,5
+ ld [wTopMenuItemX],a
+ ld a,A_BUTTON | B_BUTTON | SELECT
+ ld [wMenuWatchedKeys],a
+ ld c,10
+ call DelayFrames
+
+DisplayListMenuIDLoop:: ; 2c53 (0:2c53)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a ; disable transfer
+ call PrintListMenuEntries
+ ld a,1
+ ld [H_AUTOBGTRANSFERENABLED],a ; enable transfer
+ call Delay3
+ ld a,[W_BATTLETYPE]
+ and a ; is it the Old Man battle?
+ jr z,.notOldManBattle
+.oldManBattle
+ ld a,"▶"
+ Coorda 5, 4 ; place menu cursor in front of first menu entry
+ ld c,80
+ call DelayFrames
+ xor a
+ ld [wCurrentMenuItem],a
+ hlCoord 5, 4
+ ld a,l
+ ld [wMenuCursorLocation],a
+ ld a,h
+ ld [wMenuCursorLocation + 1],a
+ jr .buttonAPressed
+.notOldManBattle
+ call LoadGBPal
+ call HandleMenuInput
+ push af
+ call PlaceMenuCursor
+ pop af
+ bit 0,a ; was the A button pressed?
+ jp z,.checkOtherKeys
+.buttonAPressed
+ ld a,[wCurrentMenuItem]
+ call PlaceUnfilledArrowMenuCursor
+ ld a,$01
+ ld [wd12e],a
+ ld [wd12d],a
+ xor a
+ ld [wcc37],a
+ ld a,[wCurrentMenuItem]
+ ld c,a
+ ld a,[wListScrollOffset]
+ add c
+ ld c,a
+ ld a,[wd12a] ; number of list entries
+ and a ; is the list empty?
+ jp z,ExitListMenu ; if so, exit the menu
+ dec a
+ cp c ; did the player select Cancel?
+ jp c,ExitListMenu ; if so, exit the menu
+ ld a,c
+ ld [wWhichPokemon],a
+ ld a,[wListMenuID]
+ cp a,ITEMLISTMENU
+ jr nz,.skipMultiplying
+; if it's an item menu
+ sla c ; item entries are 2 bytes long, so multiply by 2
+.skipMultiplying
+ ld a,[wList]
+ ld l,a
+ ld a,[wList + 1]
+ ld h,a
+ inc hl ; hl = beginning of list entries
+ ld b,0
+ add hl,bc
+ ld a,[hl]
+ ld [wcf91],a
+ ld a,[wListMenuID]
+ and a ; is it a PC pokemon list?
+ jr z,.pokemonList
+ push hl
+ call GetItemPrice
+ pop hl
+ ld a,[wListMenuID]
+ cp a,ITEMLISTMENU
+ jr nz,.skipGettingQuantity
+; if it's an item menu
+ inc hl
+ ld a,[hl] ; a = item quantity
+ ld [wcf97],a
+.skipGettingQuantity
+ ld a,[wcf91]
+ ld [wd0b5],a
+ ld a,BANK(ItemNames)
+ ld [wPredefBank],a
+ call GetName
+ jr .storeChosenEntry
+.pokemonList
+ ld hl,wPartyCount
+ ld a,[wList]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld hl,wPartyMonNicks
+ jr z,.getPokemonName
+ ld hl, wBoxMonNicks ; box pokemon names
+.getPokemonName
+ ld a,[wWhichPokemon]
+ call GetPartyMonName
+.storeChosenEntry ; store the menu entry that the player chose and return
+ ld de,wcd6d
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld a,$01
+ ld [wd12e],a
+ ld a,[wCurrentMenuItem]
+ ld [wd12d],a
+ xor a
+ ld [hJoy7],a ; joypad state update flag
+ ld hl,wd730
+ res 6,[hl] ; turn on letter printing delay
+ jp BankswitchBack
+.checkOtherKeys ; check B, SELECT, Up, and Down keys
+ bit 1,a ; was the B button pressed?
+ jp nz,ExitListMenu ; if so, exit the menu
+ bit 2,a ; was the select button pressed?
+ jp nz,HandleItemListSwapping ; if so, allow the player to swap menu entries
+ ld b,a
+ bit 7,b ; was Down pressed?
+ ld hl,wListScrollOffset
+ jr z,.upPressed
+.downPressed
+ ld a,[hl]
+ add a,3
+ ld b,a
+ ld a,[wd12a] ; number of list entries
+ cp b ; will going down scroll past the Cancel button?
+ jp c,DisplayListMenuIDLoop
+ inc [hl] ; if not, go down
+ jp DisplayListMenuIDLoop
+.upPressed
+ ld a,[hl]
+ and a
+ jp z,DisplayListMenuIDLoop
+ dec [hl]
+ jp DisplayListMenuIDLoop
+
+DisplayChooseQuantityMenu:: ; 2d57 (0:2d57)
+; text box dimensions/coordinates for just quantity
+ hlCoord 15, 9
+ ld b,1 ; height
+ ld c,3 ; width
+ ld a,[wListMenuID]
+ cp a,PRICEDITEMLISTMENU
+ jr nz,.drawTextBox
+; text box dimensions/coordinates for quantity and price
+ hlCoord 7, 9
+ ld b,1 ; height
+ ld c,11 ; width
+.drawTextBox
+ call TextBoxBorder
+ hlCoord 16, 10
+ ld a,[wListMenuID]
+ cp a,PRICEDITEMLISTMENU
+ jr nz,.printInitialQuantity
+ hlCoord 8, 10
+.printInitialQuantity
+ ld de,InitialQuantityText
+ call PlaceString
+ xor a
+ ld [wcf96],a ; initialize current quantity to 0
+ jp .incrementQuantity
+.waitForKeyPressLoop
+ call JoypadLowSensitivity
+ ld a,[hJoyPressed] ; newly pressed buttons
+ bit 0,a ; was the A button pressed?
+ jp nz,.buttonAPressed
+ bit 1,a ; was the B button pressed?
+ jp nz,.buttonBPressed
+ bit 6,a ; was Up pressed?
+ jr nz,.incrementQuantity
+ bit 7,a ; was Down pressed?
+ jr nz,.decrementQuantity
+ jr .waitForKeyPressLoop
+.incrementQuantity
+ ld a,[wcf97] ; max quantity
+ inc a
+ ld b,a
+ ld hl,wcf96 ; current quantity
+ inc [hl]
+ ld a,[hl]
+ cp b
+ jr nz,.handleNewQuantity
+; wrap to 1 if the player goes above the max quantity
+ ld a,1
+ ld [hl],a
+ jr .handleNewQuantity
+.decrementQuantity
+ ld hl,wcf96 ; current quantity
+ dec [hl]
+ jr nz,.handleNewQuantity
+; wrap to the max quantity if the player goes below 1
+ ld a,[wcf97] ; max quantity
+ ld [hl],a
+.handleNewQuantity
+ hlCoord 17, 10
+ ld a,[wListMenuID]
+ cp a,PRICEDITEMLISTMENU
+ jr nz,.printQuantity
+.printPrice
+ ld c,$03
+ ld a,[wcf96]
+ ld b,a
+ ld hl,$ff9f ; total price
+; initialize total price to 0
+ xor a
+ ld [hli],a
+ ld [hli],a
+ ld [hl],a
+.addLoop ; loop to multiply the individual price by the quantity to get the total price
+ ld de,$ffa1
+ ld hl,$ff8d
+ push bc
+ predef AddBCDPredef ; add the individual price to the current sum
+ pop bc
+ dec b
+ jr nz,.addLoop
+ ld a,[$ff8e]
+ and a ; should the price be halved (for selling items)?
+ jr z,.skipHalvingPrice
+ xor a
+ ld [$ffa2],a
+ ld [$ffa3],a
+ ld a,$02
+ ld [$ffa4],a
+ predef DivideBCDPredef3 ; halves the price
+; store the halved price
+ ld a,[$ffa2]
+ ld [$ff9f],a
+ ld a,[$ffa3]
+ ld [$ffa0],a
+ ld a,[$ffa4]
+ ld [$ffa1],a
+.skipHalvingPrice
+ hlCoord 12, 10
+ ld de,SpacesBetweenQuantityAndPriceText
+ call PlaceString
+ ld de,$ff9f ; total price
+ ld c,$a3
+ call PrintBCDNumber
+ hlCoord 9, 10
+.printQuantity
+ ld de,wcf96 ; current quantity
+ ld bc,$8102 ; print leading zeroes, 1 byte, 2 digits
+ call PrintNumber
+ jp .waitForKeyPressLoop
+.buttonAPressed ; the player chose to make the transaction
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ ret
+.buttonBPressed ; the player chose to cancel the transaction
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ ld a,$ff
+ ret
+
+InitialQuantityText:: ; 2e30 (0:2e30)
+ db "×01@"
+
+SpacesBetweenQuantityAndPriceText:: ; 2e34 (0:2e34)
+ db " @"
+
+ExitListMenu:: ; 2e3b (0:2e3b)
+ ld a,[wCurrentMenuItem]
+ ld [wd12d],a
+ ld a,$02
+ ld [wd12e],a
+ ld [wcc37],a
+ xor a
+ ld [hJoy7],a
+ ld hl,wd730
+ res 6,[hl]
+ call BankswitchBack
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ scf
+ ret
+
+PrintListMenuEntries:: ; 2e5a (0:2e5a)
+ hlCoord 5, 3
+ ld b,$09
+ ld c,$0e
+ call ClearScreenArea
+ ld a,[wList]
+ ld e,a
+ ld a,[wList + 1]
+ ld d,a
+ inc de ; de = beginning of list entries
+ ld a,[wListScrollOffset]
+ ld c,a
+ ld a,[wListMenuID]
+ cp a,ITEMLISTMENU
+ ld a,c
+ jr nz,.skipMultiplying
+; if it's an item menu
+; item entries are 2 bytes long, so multiply by 2
+ sla a
+ sla c
+.skipMultiplying
+ add e
+ ld e,a
+ jr nc,.noCarry
+ inc d
+.noCarry
+ hlCoord 6, 4 ; coordinates of first list entry name
+ ld b,4 ; print 4 names
+.loop
+ ld a,b
+ ld [wWhichPokemon],a
+ ld a,[de]
+ ld [wd11e],a
+ cp a,$ff
+ jp z,.printCancelMenuItem
+ push bc
+ push de
+ push hl
+ push hl
+ push de
+ ld a,[wListMenuID]
+ and a
+ jr z,.pokemonPCMenu
+ cp a,$01
+ jr z,.movesMenu
+.itemMenu
+ call GetItemName
+ jr .placeNameString
+.pokemonPCMenu
+ push hl
+ ld hl,wPartyCount
+ ld a,[wList]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld hl,wPartyMonNicks
+ jr z,.getPokemonName
+ ld hl, wBoxMonNicks ; box pokemon names
+.getPokemonName
+ ld a,[wWhichPokemon]
+ ld b,a
+ ld a,4
+ sub b
+ ld b,a
+ ld a,[wListScrollOffset]
+ add b
+ call GetPartyMonName
+ pop hl
+ jr .placeNameString
+.movesMenu
+ call GetMoveName
+.placeNameString
+ call PlaceString
+ pop de
+ pop hl
+ ld a,[wcf93]
+ and a ; should prices be printed?
+ jr z,.skipPrintingItemPrice
+.printItemPrice
+ push hl
+ ld a,[de]
+ ld de,ItemPrices
+ ld [wcf91],a
+ call GetItemPrice ; get price
+ pop hl
+ ld bc,20 + 5 ; 1 row down and 5 columns right
+ add hl,bc
+ ld c,$a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
+ call PrintBCDNumber
+.skipPrintingItemPrice
+ ld a,[wListMenuID]
+ and a
+ jr nz,.skipPrintingPokemonLevel
+.printPokemonLevel
+ ld a,[wd11e]
+ push af
+ push hl
+ ld hl,wPartyCount
+ ld a,[wList]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld a,$00
+ jr z,.next
+ ld a,$02
+.next
+ ld [wcc49],a
+ ld hl,wWhichPokemon
+ ld a,[hl]
+ ld b,a
+ ld a,$04
+ sub b
+ ld b,a
+ ld a,[wListScrollOffset]
+ add b
+ ld [hl],a
+ call LoadMonData ; load pokemon info
+ ld a,[wcc49]
+ and a ; is it a list of party pokemon or box pokemon?
+ jr z,.skipCopyingLevel
+.copyLevel
+ ld a,[wLoadedMonBoxLevel]
+ ld [wLoadedMonLevel],a
+.skipCopyingLevel
+ pop hl
+ ld bc,$001c
+ add hl,bc
+ call PrintLevel ; print level
+ pop af
+ ld [wd11e],a
+.skipPrintingPokemonLevel
+ pop hl
+ pop de
+ inc de
+ ld a,[wListMenuID]
+ cp a,ITEMLISTMENU
+ jr nz,.nextListEntry
+.printItemQuantity
+ ld a,[wd11e]
+ ld [wcf91],a
+ call IsKeyItem ; check if item is unsellable
+ ld a,[wd124]
+ and a ; is the item unsellable?
+ jr nz,.skipPrintingItemQuantity ; if so, don't print the quantity
+ push hl
+ ld bc,20 + 8 ; 1 row down and 8 columns right
+ add hl,bc
+ ld a,"×"
+ ld [hli],a
+ ld a,[wd11e]
+ push af
+ ld a,[de]
+ ld [wcf97],a
+ push de
+ ld de,wd11e
+ ld [de],a
+ ld bc,$0102
+ call PrintNumber
+ pop de
+ pop af
+ ld [wd11e],a
+ pop hl
+.skipPrintingItemQuantity
+ inc de
+ pop bc
+ inc c
+ push bc
+ inc c
+ ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
+ and a ; is an item being swapped?
+ jr z,.nextListEntry
+ sla a
+ cp c ; is it this item?
+ jr nz,.nextListEntry
+ dec hl
+ ld a,$ec ; unfilled right arrow menu cursor to indicate an item being swapped
+ ld [hli],a
+.nextListEntry
+ ld bc,2 * 20 ; 2 rows
+ add hl,bc
+ pop bc
+ inc c
+ dec b
+ jp nz,.loop
+ ld bc,-8
+ add hl,bc
+ ld a,$ee ; down arrow
+ ld [hl],a
+ ret
+.printCancelMenuItem
+ ld de,ListMenuCancelText
+ jp PlaceString
+
+ListMenuCancelText:: ; 2f97 (0:2f97)
+ db "CANCEL@"
+
+GetMonName:: ; 2f9e (0:2f9e)
+ push hl
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(MonsterNames) ; 07
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ld a,[wd11e]
+ dec a
+ ld hl,MonsterNames ; 421E
+ ld c,10
+ ld b,0
+ call AddNTimes
+ ld de,wcd6d
+ push de
+ ld bc,10
+ call CopyData
+ ld hl,wcd77
+ ld [hl], "@"
+ pop de
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ pop hl
+ ret
+
+GetItemName:: ; 2fcf (0:2fcf)
+; given an item ID at [wd11e], store the name of the item into a string
+; starting at wcd6d
+ push hl
+ push bc
+ ld a,[wd11e]
+ cp HM_01 ; is this a TM/HM?
+ jr nc,.Machine
+
+ ld [wd0b5],a
+ ld a,ITEM_NAME
+ ld [wNameListType],a
+ ld a,BANK(ItemNames)
+ ld [wPredefBank],a
+ call GetName
+ jr .Finish
+
+.Machine
+ call GetMachineName
+.Finish
+ ld de,wcd6d ; pointer to where item name is stored in RAM
+ pop bc
+ pop hl
+ ret
+
+GetMachineName:: ; 2ff3 (0:2ff3)
+; copies the name of the TM/HM in [wd11e] to wcd6d
+ push hl
+ push de
+ push bc
+ ld a,[wd11e]
+ push af
+ cp TM_01 ; is this a TM? [not HM]
+ jr nc,.WriteTM
+; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
+; TM printing code
+ add 5
+ ld [wd11e],a
+ ld hl,HiddenPrefix ; points to "HM"
+ ld bc,2
+ jr .WriteMachinePrefix
+.WriteTM
+ ld hl,TechnicalPrefix ; points to "TM"
+ ld bc,2
+.WriteMachinePrefix
+ ld de,wcd6d
+ call CopyData
+
+; now get the machine number and convert it to text
+ ld a,[wd11e]
+ sub TM_01 - 1
+ ld b,$F6 ; "0"
+.FirstDigit
+ sub 10
+ jr c,.SecondDigit
+ inc b
+ jr .FirstDigit
+.SecondDigit
+ add 10
+ push af
+ ld a,b
+ ld [de],a
+ inc de
+ pop af
+ ld b,$F6 ; "0"
+ add b
+ ld [de],a
+ inc de
+ ld a,"@"
+ ld [de],a
+
+ pop af
+ ld [wd11e],a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+TechnicalPrefix:: ; 303c (0:303c)
+ db "TM"
+HiddenPrefix:: ; 303e (0:303e)
+ db "HM"
+
+; sets carry if item is HM, clears carry if item is not HM
+; Input: a = item ID
+IsItemHM:: ; 3040 (0:3040)
+ cp a,HM_01
+ jr c,.notHM
+ cp a,TM_01
+ ret
+.notHM
+ and a
+ ret
+
+; sets carry if move is an HM, clears carry if move is not an HM
+; Input: a = move ID
+IsMoveHM:: ; 3049 (0:3049)
+ ld hl,HMMoves
+ ld de,1
+ jp IsInArray
+
+HMMoves:: ; 3052 (0:3052)
+ db CUT,FLY,SURF,STRENGTH,FLASH
+ db $ff ; terminator
+
+GetMoveName:: ; 3058 (0:3058)
+ push hl
+ ld a,MOVE_NAME
+ ld [wNameListType],a
+ ld a,[wd11e]
+ ld [wd0b5],a
+ ld a,BANK(MoveNames)
+ ld [wPredefBank],a
+ call GetName
+ ld de,wcd6d ; pointer to where move name is stored in RAM
+ pop hl
+ ret
+
+; reloads text box tile patterns, current map view, and tileset tile patterns
+ReloadMapData:: ; 3071 (0:3071)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call DisableLCD
+ call LoadTextBoxTilePatterns
+ call LoadCurrentMapView
+ call LoadTilesetTilePatternData
+ call EnableLCD
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; reloads tileset tile patterns
+ReloadTilesetTilePatterns:: ; 3090 (0:3090)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call DisableLCD
+ call LoadTilesetTilePatternData
+ call EnableLCD
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; shows the town map and lets the player choose a destination to fly to
+ChooseFlyDestination:: ; 30a9 (0:30a9)
+ ld hl,wd72e
+ res 4,[hl]
+ ld b, BANK(LoadTownMap_Fly)
+ ld hl, LoadTownMap_Fly
+ jp Bankswitch
+
+; causes the text box to close without waiting for a button press after displaying text
+DisableWaitingAfterTextDisplay:: ; 30b6 (0:30b6)
+ ld a,$01
+ ld [wDoNotWaitForButtonPressAfterDisplayingText],a
+ ret
+
+; uses an item
+; UseItem is used with dummy items to perform certain other functions as well
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wcd6a] = success
+; 00: unsucessful
+; 01: successful
+; 02: not able to be used right now, no extra menu displayed (only certain items use this)
+UseItem:: ; 30bc (0:30bc)
+ ld b,BANK(UseItem_)
+ ld hl,UseItem_
+ jp Bankswitch
+
+; confirms the item toss and then tosses the item
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wWhichPokemon] = index of item within inventory
+; [wcf96] = quantity to toss
+; OUTPUT:
+; clears carry flag if the item is tossed, sets carry flag if not
+TossItem:: ; 30c4 (0:30c4)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(TossItem_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call TossItem_
+ pop de
+ ld a,d
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; checks if an item is a key item
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wd124] = result
+; 00: item is not key item
+; 01: item is key item
+IsKeyItem:: ; 30d9 (0:30d9)
+ push hl
+ push de
+ push bc
+ callba IsKeyItem_
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; function to draw various text boxes
+; INPUT:
+; [wTextBoxID] = text box ID
+DisplayTextBoxID:: ; 30e8 (0:30e8)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,BANK(DisplayTextBoxID_)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call DisplayTextBoxID_
+ pop bc
+ ld a,b
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+; not zero if an NPC movement script is running, the player character is
+; automatically stepping down from a door, or joypad states are being simulated
+IsPlayerCharacterBeingControlledByGame:: ; 30fd (0:30fd)
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret nz
+ ld a, [wd736]
+ bit 1, a ; currently stepping down from door bit
+ ret nz
+ ld a, [wd730]
+ and $80
+ ret
+
+RunNPCMovementScript:: ; 310e (0:310e)
+ ld hl, wd736
+ bit 0, [hl]
+ res 0, [hl]
+ jr nz, .playerStepOutFromDoor
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret z
+ dec a
+ add a
+ ld d, 0
+ ld e, a
+ ld hl, .NPCMovementScriptPointerTables
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wNPCMovementScriptBank]
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ld a, [wNPCMovementScriptFunctionNum]
+ call CallFunctionInTable
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+.NPCMovementScriptPointerTables
+ dw ProfOakMovementScriptPointerTable
+ dw PewterMuseumGuyMovementScriptPointerTable
+ dw PewterGymGuyMovementScriptPointerTable
+.playerStepOutFromDoor
+ ld b, BANK(PlayerStepOutFromDoor)
+ ld hl, PlayerStepOutFromDoor
+ jp Bankswitch
+
+EndNPCMovementScript:: ; 314e (0:314e)
+ ld b, BANK(_EndNPCMovementScript)
+ ld hl, _EndNPCMovementScript
+ jp Bankswitch
+
+EmptyFunc2:: ; 3156 (0:3156)
+ ret
+
+; stores hl in [W_TRAINERHEADERPTR]
+StoreTrainerHeaderPointer:: ; 3157 (0:3157)
+ ld a, h
+ ld [W_TRAINERHEADERPTR], a
+ ld a, l
+ ld [W_TRAINERHEADERPTR+1], a
+ ret
+
+; executes the current map script from the function pointer array provided in hl.
+; a: map script index to execute (unless overridden by [wd733] bit 4)
+ExecuteCurMapScriptInTable:: ; 3160 (0:3160)
+ push af
+ push de
+ call StoreTrainerHeaderPointer
+ pop hl
+ pop af
+ push hl
+ ld hl, W_FLAGS_D733
+ bit 4, [hl]
+ res 4, [hl]
+ jr z, .useProvidedIndex ; test if map script index was overridden manually
+ ld a, [W_CURMAPSCRIPT]
+.useProvidedIndex
+ pop hl
+ ld [W_CURMAPSCRIPT], a
+ call CallFunctionInTable
+ ld a, [W_CURMAPSCRIPT]
+ ret
+
+LoadGymLeaderAndCityName:: ; 317f (0:317f)
+ push de
+ ld de, wGymCityName
+ ld bc, $11
+ call CopyData ; load city name
+ pop hl
+ ld de, wGymLeaderName
+ ld bc, $b
+ jp CopyData ; load gym leader name
+
+; reads specific information from trainer header (pointed to at W_TRAINERHEADERPTR)
+; a: offset in header data
+; 0 -> flag's bit (into wTrainerHeaderFlagBit)
+; 2 -> flag's byte ptr (into hl)
+; 4 -> before battle text (into hl)
+; 6 -> after battle text (into hl)
+; 8 -> end battle text (into hl)
+ReadTrainerHeaderInfo:: ; 3193 (0:3193)
+ push de
+ push af
+ ld d, $0
+ ld e, a
+ ld hl, W_TRAINERHEADERPTR
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a
+ add hl, de
+ pop af
+ and a
+ jr nz, .nonZeroOffset
+ ld a, [hl]
+ ld [wTrainerHeaderFlagBit], a ; store flag's bit
+ jr .done
+.nonZeroOffset
+ cp $2
+ jr z, .readPointer ; read flag's byte ptr
+ cp $4
+ jr z, .readPointer ; read before battle text
+ cp $6
+ jr z, .readPointer ; read after battle text
+ cp $8
+ jr z, .readPointer ; read end battle text
+ cp $a
+ jr nz, .done
+ ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?)
+ ld d, [hl]
+ ld e, a
+ jr .done
+.readPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.done
+ pop de
+ ret
+
+TrainerFlagAction::
+ predef_jump FlagActionPredef
+
+TalkToTrainer:: ; 31cc (0:31cc)
+ call StoreTrainerHeaderPointer
+ xor a
+ call ReadTrainerHeaderInfo ; read flag's bit
+ ld a, $2
+ call ReadTrainerHeaderInfo ; read flag's byte ptr
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ ld b, $2
+ call TrainerFlagAction ; read trainer's flag
+ ld a, c
+ and a
+ jr z, .trainerNotYetFought ; test trainer's flag
+ ld a, $6
+ call ReadTrainerHeaderInfo ; print after battle text
+ jp PrintText
+.trainerNotYetFought ; 0x31ed
+ ld a, $4
+ call ReadTrainerHeaderInfo ; print before battle text
+ call PrintText
+ ld a, $a
+ call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
+ push de
+ ld a, $8
+ call ReadTrainerHeaderInfo ; read end battle text
+ pop de
+ call SaveEndBattleTextPointers
+ ld hl, W_FLAGS_D733
+ set 4, [hl] ; activate map script index override (index is set below)
+ ld hl, wFlags_0xcd60
+ bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
+ ret nz
+; if the player talked to the trainer of his own volition
+ call EngageMapTrainer
+ ld hl, W_CURMAPSCRIPT
+ inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
+ jp StartTrainerBattle
+
+; checks if any trainers are seeing the player and wanting to fight
+CheckFightingMapTrainers:: ; 3219 (0:3219)
+ call CheckForEngagingTrainers
+ ld a, [wSpriteIndex]
+ cp $ff
+ jr nz, .trainerEngaging
+ xor a
+ ld [wSpriteIndex], a
+ ld [wTrainerHeaderFlagBit], a
+ ret
+.trainerEngaging
+ ld hl, W_FLAGS_D733
+ set 3, [hl]
+ ld [wcd4f], a
+ xor a
+ ld [wcd50], a
+ predef EmotionBubble
+ ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN
+ ld [wJoyIgnore], a
+ xor a
+ ldh [$b4], a
+ call TrainerWalkUpToPlayer_Bank0
+ ld hl, W_CURMAPSCRIPT
+ inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
+ ret
+
+; display the before battle text after the enemy trainer has walked up to the player's sprite
+DisplayEnemyTrainerTextAndStartBattle:: ; 324c (0:324c)
+ ld a, [wd730]
+ and $1
+ ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
+ ld [wJoyIgnore], a
+ ld a, [wSpriteIndex]
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ ; fall through
+
+StartTrainerBattle:: ; 325d (0:325d)
+ xor a
+ ld [wJoyIgnore], a
+ call InitBattleEnemyParameters
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, wd72e
+ set 1, [hl]
+ ld hl, W_CURMAPSCRIPT
+ inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
+ ret
+
+EndTrainerBattle:: ; 3275 (0:3275)
+ ld hl, wd126
+ set 5, [hl]
+ set 6, [hl]
+ ld hl, wd72d
+ res 7, [hl]
+ ld hl, wFlags_0xcd60
+ res 0, [hl] ; player is no longer engaged by any trainer
+ ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ cp $ff
+ jp z, ResetButtonPressedAndMapScript
+ ld a, $2
+ call ReadTrainerHeaderInfo
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ ld b, $1
+ call TrainerFlagAction ; flag trainer as fought
+ ld a, [W_ENEMYMONORTRAINERCLASS]
+ cp $c8
+ jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
+ ld hl, W_MISSABLEOBJECTLIST
+ ld de, $2
+ ld a, [wSpriteIndex]
+ call IsInArray ; search for sprite ID
+ inc hl
+ ld a, [hl]
+ ld [wcc4d], a ; load corresponding missable object index and remove it
+ predef HideObject
+.skipRemoveSprite
+ ld hl, wd730
+ bit 4, [hl]
+ res 4, [hl]
+ ret nz
+
+ResetButtonPressedAndMapScript:: ; 32c1 (0:32c1)
+ xor a
+ ld [wJoyIgnore], a
+ ld [hJoyHeld], a
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
+ ld [W_CURMAPSCRIPT], a ; reset battle status
+ ret
+
+; calls TrainerWalkUpToPlayer
+TrainerWalkUpToPlayer_Bank0:: ; 32cf (0:32cf)
+ ld b, BANK(TrainerWalkUpToPlayer)
+ ld hl, TrainerWalkUpToPlayer
+ jp Bankswitch
+
+; sets opponent type and mon set/lvl based on the engaging trainer data
+InitBattleEnemyParameters:: ; 32d7 (0:32d7)
+ ld a, [wEngagedTrainerClass]
+ ld [W_CUROPPONENT], a ; wd059
+ ld [W_ENEMYMONORTRAINERCLASS], a
+ cp $c8
+ ld a, [wEngagedTrainerSet] ; wcd2e
+ jr c, .noTrainer
+ ld [W_TRAINERNO], a ; wd05d
+ ret
+.noTrainer
+ ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
+ ret
+
+GetSpritePosition1:: ; 32ef (0:32ef)
+ ld hl, _GetSpritePosition1
+ jr asm_3301
+
+GetSpritePosition2:: ; 32f4 (0:32f4)
+ ld hl, _GetSpritePosition2
+ jr asm_3301 ; 0x32f7 $8
+
+SetSpritePosition1:: ; 32f9 (0:32f9)
+ ld hl, _SetSpritePosition1
+ jr asm_3301
+
+SetSpritePosition2:: ; 32fe (0:32fe)
+ ld hl, _SetSpritePosition2
+asm_3301:: ; 3301 (0:3301)
+ ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2)
+ jp Bankswitch ; indirect jump to one of the four functions
+
+CheckForEngagingTrainers:: ; 3306 (0:3306)
+ xor a
+ call ReadTrainerHeaderInfo ; read trainer flag's bit (unused)
+ ld d, h ; store trainer header address in de
+ ld e, l
+.trainerLoop
+ call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer
+ ld a, [de]
+ ld [wSpriteIndex], a ; store trainer flag's bit
+ ld [wTrainerHeaderFlagBit], a
+ cp $ff
+ ret z
+ ld a, $2
+ call ReadTrainerHeaderInfo ; read trainer flag's byte ptr
+ ld b, $2
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ call TrainerFlagAction ; read trainer flag
+ ld a, c
+ and a
+ jr nz, .trainerAlreadyFought
+ push hl
+ push de
+ push hl
+ xor a
+ call ReadTrainerHeaderInfo ; get trainer header pointer
+ inc hl
+ ld a, [hl] ; read trainer engage distance
+ pop hl
+ ld [wTrainerEngageDistance], a
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wTrainerSpriteOffset], a ; wWhichTrade
+ predef TrainerEngage
+ pop de
+ pop hl
+ ld a, [wTrainerSpriteOffset] ; wWhichTrade
+ and a
+ ret nz ; break if the trainer is engaging
+.trainerAlreadyFought
+ ld hl, $c
+ add hl, de
+ ld d, h
+ ld e, l
+ jr .trainerLoop
+
+; hl = text if the player wins
+; de = text if the player loses
+SaveEndBattleTextPointers:: ; 3354 (0:3354)
+ ld a, [H_LOADEDROMBANK]
+ ld [wEndBattleTextRomBank], a
+ ld a, h
+ ld [wEndBattleWinTextPointer], a
+ ld a, l
+ ld [wEndBattleWinTextPointer + 1], a
+ ld a, d
+ ld [wEndBattleLoseTextPointer], a
+ ld a, e
+ ld [wEndBattleLoseTextPointer + 1], a
+ ret
+
+; loads data of some trainer on the current map and plays pre-battle music
+; [wSpriteIndex]: sprite ID of trainer who is engaged
+EngageMapTrainer:: ; 336a (0:336a)
+ ld hl, W_MAPSPRITEEXTRADATA
+ ld d, $0
+ ld a, [wSpriteIndex]
+ dec a
+ add a
+ ld e, a
+ add hl, de ; seek to engaged trainer data
+ ld a, [hli] ; load trainer class
+ ld [wEngagedTrainerClass], a
+ ld a, [hl] ; load trainer mon set
+ ld [wEnemyMonAttackMod], a ; wcd2e
+ jp PlayTrainerMusic
+
+PrintEndBattleText:: ; 3381 (0:3381)
+ push hl
+ ld hl, wd72d
+ bit 7, [hl]
+ res 7, [hl]
+ pop hl
+ ret z
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wEndBattleTextRomBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ push hl
+ callba SaveTrainerName
+ ld hl, TrainerEndBattleText
+ call PrintText
+ pop hl
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ callba FreezeEnemyTrainerSprite
+ jp WaitForSoundToFinish
+
+GetSavedEndBattleTextPointer:: ; 33b7 (0:33b7)
+ ld a, [wBattleResult]
+ and a
+; won battle
+ jr nz, .lostBattle
+ ld a, [wEndBattleWinTextPointer]
+ ld h, a
+ ld a, [wEndBattleWinTextPointer + 1]
+ ld l, a
+ ret
+.lostBattle
+ ld a, [wEndBattleLoseTextPointer]
+ ld h, a
+ ld a, [wEndBattleLoseTextPointer + 1]
+ ld l, a
+ ret
+
+TrainerEndBattleText:: ; 33cf (0:33cf)
+ TX_FAR _TrainerNameText
+ db $08
+ call GetSavedEndBattleTextPointer
+ call TextCommandProcessor
+ jp TextScriptEnd
+
+; XXX unused?
+Func_33dd:: ; 33dd (0:33dd)
+ ld a, [wFlags_0xcd60]
+ bit 0, a
+ ret nz
+ call EngageMapTrainer
+ xor a
+ ret
+
+PlayTrainerMusic:: ; 33e8 (0:33e8)
+ ld a, [wEngagedTrainerClass]
+ cp $c8 + SONY1
+ ret z
+ cp $c8 + SONY2
+ ret z
+ cp $c8 + SONY3
+ ret z
+ ld a, [W_GYMLEADERNO] ; W_GYMLEADERNO
+ and a
+ ret nz
+ xor a
+ ld [wMusicHeaderPointer], a
+ ld a, $ff
+ call PlaySound ; stop music
+ ld a, BANK(Music_MeetEvilTrainer)
+ ld [wc0ef], a
+ ld [wc0f0], a
+ ld a, [wEngagedTrainerClass]
+ ld b, a
+ ld hl, EvilTrainerList
+.evilTrainerListLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .noEvilTrainer
+ cp b
+ jr nz, .evilTrainerListLoop
+ ld a, MUSIC_MEET_EVIL_TRAINER
+ jr .PlaySound
+.noEvilTrainer
+ ld hl, FemaleTrainerList
+.femaleTrainerListLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .maleTrainer
+ cp b
+ jr nz, .femaleTrainerListLoop
+ ld a, MUSIC_MEET_FEMALE_TRAINER
+ jr .PlaySound
+.maleTrainer
+ ld a, MUSIC_MEET_MALE_TRAINER
+.PlaySound
+ ld [wc0ee], a
+ jp PlaySound
+
+INCLUDE "data/trainer_types.asm"
+
+; checks if the player's coordinates match an arrow movement tile's coordinates
+; and if so, decodes the RLE movement data
+; b = player Y
+; c = player X
+DecodeArrowMovementRLE:: ; 3442 (0:3442)
+ ld a, [hli]
+ cp $ff
+ ret z ; no match in the list
+ cp b
+ jr nz, .nextArrowMovementTileEntry1
+ ld a, [hli]
+ cp c
+ jr nz, .nextArrowMovementTileEntry2
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+ ld hl, wSimulatedJoypadStatesEnd
+ call DecodeRLEList
+ dec a
+ ld [wSimulatedJoypadStatesIndex], a
+ ret
+.nextArrowMovementTileEntry1
+ inc hl
+.nextArrowMovementTileEntry2
+ inc hl
+ inc hl
+ jr DecodeArrowMovementRLE
+
+FuncTX_ItemStoragePC:: ; 3460 (0:3460)
+ call SaveScreenTilesToBuffer2
+ ld b, BANK(PlayerPC)
+ ld hl, PlayerPC
+ jr bankswitchAndContinue
+
+FuncTX_BillsPC:: ; 346a (0:346a)
+ call SaveScreenTilesToBuffer2
+ ld b, BANK(BillsPC_)
+ ld hl, BillsPC_
+ jr bankswitchAndContinue
+
+FuncTX_SlotMachine:: ; 3474 (0:3474)
+; XXX find a better name for this function
+; special_F7
+ ld b,BANK(CeladonPrizeMenu)
+ ld hl,CeladonPrizeMenu
+bankswitchAndContinue:: ; 3479 (0:3479)
+ call Bankswitch
+ jp HoldTextDisplayOpen ; continue to main text-engine function
+
+FuncTX_PokemonCenterPC:: ; 347f (0:347f)
+ ld b, BANK(ActivatePC)
+ ld hl, ActivatePC
+ jr bankswitchAndContinue
+
+StartSimulatingJoypadStates:: ; 3486 (0:3486)
+ xor a
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1
+ ld hl, wd730
+ set 7, [hl]
+ ret
+
+IsItemInBag:: ; 3493 (0:3493)
+; given an item_id in b
+; set zero flag if item isn't in player's bag
+; else reset zero flag
+; related to Pokémon Tower and ghosts
+ predef IsItemInBag_
+ ld a,b
+ and a
+ ret
+
+DisplayPokedex:: ; 349b (0:349b)
+ ld [wd11e], a
+ ld b, BANK(Func_7c18)
+ ld hl, Func_7c18
+ jp Bankswitch
+
+SetSpriteFacingDirectionAndDelay:: ; 34a6 (0:34a6)
+ call SetSpriteFacingDirection
+ ld c, $6
+ jp DelayFrames
+
+SetSpriteFacingDirection:: ; 34ae (0:34ae)
+ ld a, $9
+ ld [H_SPRITEDATAOFFSET], a
+ call GetPointerWithinSpriteStateData1
+ ld a, [$ff8d]
+ ld [hl], a
+ ret
+
+SetSpriteImageIndexAfterSettingFacingDirection:: ; 34b9 (0:34b9)
+ ld de, -7
+ add hl, de
+ ld [hl], a
+ ret
+
+; tests if the player's coordinates are in a specified array
+; INPUT:
+; hl = address of array
+; OUTPUT:
+; [wWhichTrade] = if there is match, the matching array index
+; sets carry if the coordinates are in the array, clears carry if not
+ArePlayerCoordsInArray:: ; 34bf (0:34bf)
+ ld a,[W_YCOORD]
+ ld b,a
+ ld a,[W_XCOORD]
+ ld c,a
+ ; fallthrough
+
+CheckCoords:: ; 34c7 (0:34c7)
+ xor a
+ ld [wWhichTrade],a
+.loop
+ ld a,[hli]
+ cp a,$ff ; reached terminator?
+ jr z,.notInArray
+ push hl
+ ld hl,wWhichTrade
+ inc [hl]
+ pop hl
+.compareYCoord
+ cp b
+ jr z,.compareXCoord
+ inc hl
+ jr .loop
+.compareXCoord
+ ld a,[hli]
+ cp c
+ jr nz,.loop
+.inArray
+ scf
+ ret
+.notInArray
+ and a
+ ret
+
+; tests if a boulder's coordinates are in a specified array
+; INPUT:
+; hl = address of array
+; [H_SPRITEINDEX] = index of boulder sprite
+; OUTPUT:
+; [wWhichTrade] = if there is match, the matching array index
+; sets carry if the coordinates are in the array, clears carry if not
+CheckBoulderCoords:: ; 34e4 (0:34e4)
+ push hl
+ ld hl, wSpriteStateData2 + $04
+ ld a, [H_SPRITEINDEX]
+ swap a
+ ld d, $0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ sub $4 ; because sprite coordinates are offset by 4
+ ld b, a
+ ld a, [hl]
+ sub $4 ; because sprite coordinates are offset by 4
+ ld c, a
+ pop hl
+ jp CheckCoords
+
+GetPointerWithinSpriteStateData1:: ; 34fc (0:34fc)
+ ld h, $c1
+ jr _GetPointerWithinSpriteStateData
+
+GetPointerWithinSpriteStateData2:: ; 3500 (0:3500)
+ ld h, $c2
+
+_GetPointerWithinSpriteStateData:
+ ld a, [H_SPRITEDATAOFFSET]
+ ld b, a
+ ld a, [H_SPRITEINDEX]
+ swap a
+ add b
+ ld l, a
+ ret
+
+; decodes a $ff-terminated RLEncoded list
+; each entry is a pair of bytes <byte value> <repetitions>
+; the final $ff will be replicated in the output list and a contains the number of bytes written
+; de: input list
+; hl: output list
+DecodeRLEList:: ; 350c (0:350c)
+ xor a
+ ld [wRLEByteCount], a ; count written bytes here
+.listLoop
+ ld a, [de]
+ cp $ff
+ jr z, .endOfList
+ ld [H_DOWNARROWBLINKCNT1], a ; store byte value to be written
+ inc de
+ ld a, [de]
+ ld b, $0
+ ld c, a ; number of bytes to be written
+ ld a, [wRLEByteCount]
+ add c
+ ld [wRLEByteCount], a ; update total number of written bytes
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ call FillMemory ; write a c-times to output
+ inc de
+ jr .listLoop
+.endOfList
+ ld a, $ff
+ ld [hl], a ; write final $ff
+ ld a, [wRLEByteCount]
+ inc a ; include sentinel in counting
+ ret
+
+; sets movement byte 1 for sprite [$FF8C] to $FE and byte 2 to [$FF8D]
+SetSpriteMovementBytesToFE:: ; 3533 (0:3533)
+ push hl
+ call GetSpriteMovementByte1Pointer
+ ld [hl], $fe
+ call GetSpriteMovementByte2Pointer
+ ld a, [$ff8d]
+ ld [hl], a
+ pop hl
+ ret
+
+; sets both movement bytes for sprite [$FF8C] to $FF
+SetSpriteMovementBytesToFF:: ; 3541 (0:3541)
+ push hl
+ call GetSpriteMovementByte1Pointer
+ ld [hl],$FF
+ call GetSpriteMovementByte2Pointer
+ ld [hl],$FF ; prevent person from walking?
+ pop hl
+ ret
+
+; returns the sprite movement byte 1 pointer for sprite [$FF8C] in hl
+GetSpriteMovementByte1Pointer:: ; 354e (0:354e)
+ ld h,$C2
+ ld a,[H_SPRITEINDEX] ; the sprite to move
+ swap a
+ add a,6
+ ld l,a
+ ret
+
+; returns the sprite movement byte 2 pointer for sprite [$FF8C] in hl
+GetSpriteMovementByte2Pointer:: ; 3558 (0:3558)
+ push de
+ ld hl,W_MAPSPRITEDATA
+ ld a,[$FF8C] ; the sprite to move
+ dec a
+ add a
+ ld d,0
+ ld e,a
+ add hl,de
+ pop de
+ ret
+
+GetTrainerInformation:: ; 3566 (0:3566)
+ call GetTrainerName
+ ld a, [wLinkState]
+ and a
+ jr nz, .linkBattle
+ ld a, Bank(TrainerPicAndMoneyPointers)
+ call BankswitchHome
+ ld a, [W_TRAINERCLASS] ; wd031
+ dec a
+ ld hl, TrainerPicAndMoneyPointers
+ ld bc, $5
+ call AddNTimes
+ ld de, wTrainerPicPointer
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld de, wd046
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ jp BankswitchBack
+.linkBattle
+ ld hl, wTrainerPicPointer
+ ld de, RedPicFront
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+GetTrainerName:: ; 359e (0:359e)
+ ld b, BANK(GetTrainerName_)
+ ld hl, GetTrainerName_
+ jp Bankswitch
+
+
+HasEnoughMoney::
+; Check if the player has at least as much
+; money as the 3-byte BCD value at $ff9f.
+ ld de, wPlayerMoney
+ ld hl, $ff9f
+ ld c, 3
+ jp StringCmp
+
+HasEnoughCoins::
+; Check if the player has at least as many
+; coins as the 2-byte BCD value at $ffa0.
+ ld de, wPlayerCoins
+ ld hl, $ffa0
+ ld c, 2
+ jp StringCmp
+
+
+BankswitchHome:: ; 35d9 (0:35d9)
+; switches to bank # in a
+; Only use this when in the home bank!
+ ld [wcf09],a
+ ld a,[H_LOADEDROMBANK]
+ ld [wcf08],a
+ ld a,[wcf09]
+ call BankswitchCommon
+ ret
+
+BankswitchBack:: ; 35e8 (0:35e8)
+; returns from BankswitchHome
+ ld a,[wcf08]
+ call BankswitchCommon
+ ret
+
+BankswitchCommon:: ; 3e7e (0:3e7e)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+Bankswitch:: ; 3e84 (0:3e84)
+; self-contained bankswitch, use this when not in the home bank
+; switches to the bank in b
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,b
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call .jumptoaddress
+ pop bc
+ ld a,b
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+.jumptoaddress
+ jp [hl]
+
+; displays yes/no choice
+; yes -> set carry
+YesNoChoice:: ; 35ec (0:35ec)
+ call SaveScreenTilesToBuffer1
+ call InitYesNoTextBoxParameters
+ jr DisplayYesNoChoice
+
+Func_35f4:: ; 35f4 (0:35f4)
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call InitYesNoTextBoxParameters
+ jp DisplayTextBoxID
+
+InitYesNoTextBoxParameters:: ; 35ff (0:35ff)
+ xor a ; YES_NO_MENU
+ ld [wTwoOptionMenuID], a
+ hlCoord 14, 7
+ ld bc, $80f
+ ret
+
+YesNoChoicePokeCenter:: ; 360a (0:360a)
+ call SaveScreenTilesToBuffer1
+ ld a, HEAL_CANCEL_MENU
+ ld [wTwoOptionMenuID], a
+ hlCoord 11, 6
+ ld bc, $80c
+ jr DisplayYesNoChoice
+
+Func_361a:: ; 361a (0:361a)
+ call SaveScreenTilesToBuffer1
+ ld a, WIDE_YES_NO_MENU
+ ld [wTwoOptionMenuID], a
+ hlCoord 12, 7
+ ld bc, $080d
+DisplayYesNoChoice:: ; 3628 (0:3628)
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ jp LoadScreenTilesFromBuffer1
+
+; calculates the difference |a-b|, setting carry flag if a<b
+CalcDifference:: ; 3633 (0:3633)
+ sub b
+ ret nc
+ cpl
+ add $1
+ scf
+ ret
+
+MoveSprite:: ; 363a (0:363a)
+; move the sprite [$FF8C] with the movement pointed to by de
+; actually only copies the movement data to wcc5b for later
+ call SetSpriteMovementBytesToFF
+MoveSprite_:: ; 363d (0:363d)
+ push hl
+ push bc
+ call GetSpriteMovementByte1Pointer
+ xor a
+ ld [hl],a
+ ld hl,wcc5b
+ ld c,0
+
+.loop
+ ld a,[de]
+ ld [hli],a
+ inc de
+ inc c
+ cp a,$FF ; have we reached the end of the movement data?
+ jr nz,.loop
+
+ ld a,c
+ ld [wcf0f],a ; number of steps taken
+
+ pop bc
+ ld hl,wd730
+ set 0,[hl]
+ pop hl
+ xor a
+ ld [wOverrideSimulatedJoypadStatesMask],a
+ ld [wSimulatedJoypadStatesEnd],a
+ dec a
+ ld [wJoyIgnore],a
+ ld [wWastedByteCD3A],a
+ ret
+
+; divides [$ffe5] by [$ffe6] and stores the quotient in [$ffe7]
+DivideBytes:: ; 366b (0:366b)
+ push hl
+ ld hl, $ffe7
+ xor a
+ ld [hld], a
+ ld a, [hld]
+ and a
+ jr z, .done
+ ld a, [hli]
+.loop
+ sub [hl]
+ jr c, .done
+ inc hl
+ inc [hl]
+ dec hl
+ jr .loop
+.done
+ pop hl
+ ret
+
+
+LoadFontTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, FontGraphics
+ ld de, vFont
+ ld bc, $400
+ ld a, BANK(FontGraphics)
+ jp FarCopyDataDouble ; if LCD is off, transfer all at once
+.on
+ ld de, FontGraphics
+ ld hl, vFont
+ ld bc, BANK(FontGraphics) << 8 | $80
+ jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank
+
+LoadTextBoxTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, TextBoxGraphics
+ ld de, vChars2 + $600
+ ld bc, $200
+ ld a, BANK(TextBoxGraphics)
+ jp FarCopyData2 ; if LCD is off, transfer all at once
+.on
+ ld de, TextBoxGraphics
+ ld hl, vChars2 + $600
+ ld bc, BANK(TextBoxGraphics) << 8 | $20
+ jp CopyVideoData ; if LCD is on, transfer during V-blank
+
+LoadHpBarAndStatusTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, HpBarAndStatusGraphics
+ ld de, vChars2 + $620
+ ld bc, $1e0
+ ld a, BANK(HpBarAndStatusGraphics)
+ jp FarCopyData2 ; if LCD is off, transfer all at once
+.on
+ ld de, HpBarAndStatusGraphics
+ ld hl, vChars2 + $620
+ ld bc, BANK(HpBarAndStatusGraphics) << 8 | $1e
+ jp CopyVideoData ; if LCD is on, transfer during V-blank
+
+
+UncompressSpriteFromDE:: ; 36eb (0:36eb)
+; Decompress pic at a:de.
+ ld hl, W_SPRITEINPUTPTR
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ jp UncompressSpriteData
+
+
+SaveScreenTilesToBuffer2:: ; 36f4 (0:36f4)
+ ld hl, wTileMap
+ ld de, wTileMapBackup2
+ ld bc, $168
+ call CopyData
+ ret
+
+LoadScreenTilesFromBuffer2:: ; 3701 (0:3701)
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ret
+
+; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
+LoadScreenTilesFromBuffer2DisableBGTransfer:: ; 3709 (0:3709)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, wTileMapBackup2
+ ld de, wTileMap
+ ld bc, $168
+ call CopyData
+ ret
+
+SaveScreenTilesToBuffer1:: ; 3719 (0:3719)
+ ld hl, wTileMap
+ ld de, wTileMapBackup
+ ld bc, $168
+ jp CopyData
+
+LoadScreenTilesFromBuffer1:: ; 3725 (0:3725)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, wTileMapBackup
+ ld de, wTileMap
+ ld bc, $168
+ call CopyData
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ret
+
+DelayFrames:: ; 3739 (0:3739)
+; wait n frames, where n is the value in c
+ call DelayFrame
+ dec c
+ jr nz,DelayFrames
+ ret
+
+PlaySoundWaitForCurrent:: ; 3740 (0:3740)
+ push af
+ call WaitForSoundToFinish
+ pop af
+ jp PlaySound
+
+; Wait for sound to finish playing
+WaitForSoundToFinish:: ; 3748 (0:3748)
+ ld a, [wLowHealthAlarm]
+ and $80
+ ret nz
+ push hl
+.asm_374f
+ ld hl, wc02a
+ xor a
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ inc hl
+ or [hl]
+ jr nz, .asm_374f
+ pop hl
+ ret
+
+NamePointers:: ; 375d (0:375d)
+ dw MonsterNames
+ dw MoveNames
+ dw UnusedNames
+ dw ItemNames
+ dw wPartyMonOT ; player's OT names list
+ dw wEnemyMonOT ; enemy's OT names list
+ dw TrainerNames
+
+GetName:: ; 376b (0:376b)
+; arguments:
+; [wd0b5] = which name
+; [wNameListType] = which list
+; [wPredefBank] = bank of list
+;
+; returns pointer to name in de
+ ld a,[wd0b5]
+ ld [wd11e],a
+
+ ; TM names are separate from item names.
+ ; BUG: This applies to all names instead of just items.
+ cp HM_01
+ jp nc, GetMachineName
+
+ ld a,[H_LOADEDROMBANK]
+ push af
+ push hl
+ push bc
+ push de
+ ld a,[wNameListType] ;List3759_entrySelector
+ dec a
+ jr nz,.otherEntries
+ ;1 = MON_NAMES
+ call GetMonName
+ ld hl,11
+ add hl,de
+ ld e,l
+ ld d,h
+ jr .gotPtr
+.otherEntries ; $378d
+ ;2-7 = OTHER ENTRIES
+ ld a,[wPredefBank]
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ld a,[wNameListType] ;VariousNames' entryID
+ dec a
+ add a
+ ld d,0
+ ld e,a
+ jr nc,.skip
+ inc d
+.skip ; $37a0
+ ld hl,NamePointers
+ add hl,de
+ ld a,[hli]
+ ld [$ff96],a
+ ld a,[hl]
+ ld [$ff95],a
+ ld a,[$ff95]
+ ld h,a
+ ld a,[$ff96]
+ ld l,a
+ ld a,[wd0b5]
+ ld b,a
+ ld c,0
+.nextName
+ ld d,h
+ ld e,l
+.nextChar
+ ld a,[hli]
+ cp a, "@"
+ jr nz,.nextChar
+ inc c ;entry counter
+ ld a,b ;wanted entry
+ cp c
+ jr nz,.nextName
+ ld h,d
+ ld l,e
+ ld de,wcd6d
+ ld bc,$0014
+ call CopyData
+.gotPtr ; $37cd
+ ld a,e
+ ld [wcf8d],a
+ ld a,d
+ ld [wcf8e],a
+ pop de
+ pop bc
+ pop hl
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+GetItemPrice:: ; 37df (0:37df)
+; Stores item's price as BCD at hItemPrice (3 bytes)
+; Input: [wcf91] = item id
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wListMenuID]
+ cp MOVESLISTMENU
+ ld a, BANK(ItemPrices)
+ jr nz, .asm_37ed
+ ld a, $f ; hardcoded Bank
+.asm_37ed
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ld hl, wItemPrices
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wcf91] ; a contains item id
+ cp HM_01
+ jr nc, .getTMPrice
+ ld bc, $3
+.asm_3802
+ add hl, bc
+ dec a
+ jr nz, .asm_3802
+ dec hl
+ ld a, [hld]
+ ld [hItemPrice + 2], a
+ ld a, [hld]
+ ld [hItemPrice + 1], a
+ ld a, [hl]
+ ld [hItemPrice], a
+ jr .asm_381c
+.getTMPrice
+ ld a, Bank(GetMachinePrice)
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ call GetMachinePrice
+.asm_381c
+ ld de, hItemPrice
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+
+; copies a string from [de] to [wcf4b]
+CopyStringToCF4B:: ; 3826 (0:3826)
+ ld hl, wcf4b
+ ; fall through
+
+; copies a string from [de] to [hl]
+CopyString:: ; 3829 (0:3829)
+ ld a, [de]
+ inc de
+ ld [hli], a
+ cp "@"
+ jr nz, CopyString
+ ret
+
+; this function is used when lower button sensitivity is wanted (e.g. menus)
+; OUTPUT: [hJoy5] = pressed buttons in usual format
+; there are two flags that control its functionality, [hJoy6] and [hJoy7]
+; there are esentially three modes of operation
+; 1. Get newly pressed buttons only
+; ([hJoy7] == 0, [hJoy6] == any)
+; Just copies [hJoyPressed] to [hJoy5].
+; 2. Get currently pressed buttons at low sample rate with delay
+; ([hJoy7] == 1, [hJoy6] != 0)
+; If the user holds down buttons for more than half a second,
+; report buttons as being pressed up to 12 times per second thereafter.
+; If the user holds down buttons for less than half a second,
+; report only one button press.
+; 3. Same as 2, but report no buttons as pressed if A or B is held down.
+; ([hJoy7] == 1, [hJoy6] == 0)
+JoypadLowSensitivity:: ; 3831 (0:3831)
+ call Joypad
+ ld a,[hJoy7] ; flag
+ and a ; get all currently pressed buttons or only newly pressed buttons?
+ ld a,[hJoyPressed] ; newly pressed buttons
+ jr z,.storeButtonState
+ ld a,[hJoyHeld] ; all currently pressed buttons
+.storeButtonState
+ ld [hJoy5],a
+ ld a,[hJoyPressed] ; newly pressed buttons
+ and a ; have any buttons been newly pressed since last check?
+ jr z,.noNewlyPressedButtons
+.newlyPressedButtons
+ ld a,30 ; half a second delay
+ ld [H_FRAMECOUNTER],a
+ ret
+.noNewlyPressedButtons
+ ld a,[H_FRAMECOUNTER]
+ and a ; is the delay over?
+ jr z,.delayOver
+.delayNotOver
+ xor a
+ ld [hJoy5],a ; report no buttons as pressed
+ ret
+.delayOver
+; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed
+ ld a,[hJoyHeld]
+ and A_BUTTON | B_BUTTON
+ jr z,.setShortDelay
+ ld a,[hJoy6] ; flag
+ and a
+ jr nz,.setShortDelay
+ xor a
+ ld [hJoy5],a
+.setShortDelay
+ ld a,5 ; 1/12 of a second delay
+ ld [H_FRAMECOUNTER],a
+ ret
+
+WaitForTextScrollButtonPress:: ; 3865 (0:3865)
+ ld a, [H_DOWNARROWBLINKCNT1]
+ push af
+ ld a, [H_DOWNARROWBLINKCNT2]
+ push af
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld a, $6
+ ld [H_DOWNARROWBLINKCNT2], a
+.loop
+ push hl
+ ld a, [wTownMapSpriteBlinkingEnabled]
+ and a
+ jr z, .skipAnimation
+ call TownMapSpriteBlinkingAnimation
+.skipAnimation
+ hlCoord 18, 16
+ call HandleDownArrowBlinkTiming
+ pop hl
+ call JoypadLowSensitivity
+ predef CableClub_Run
+ ld a, [hJoy5]
+ and A_BUTTON | B_BUTTON
+ jr z, .loop
+ pop af
+ ld [H_DOWNARROWBLINKCNT2], a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1], a
+ ret
+
+; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect
+ManualTextScroll:: ; 3898 (0:3898)
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .inLinkBattle
+ call WaitForTextScrollButtonPress
+ ld a, (SFX_02_40 - SFX_Headers_02) / 3
+ jp PlaySound
+.inLinkBattle
+ ld c, $41
+ jp DelayFrames
+
+; function to do multiplication
+; all values are big endian
+; INPUT
+; FF96-FF98 = multiplicand
+; FF99 = multiplier
+; OUTPUT
+; FF95-FF98 = product
+Multiply:: ; 38ac (0:38ac)
+ push hl
+ push bc
+ callab _Multiply
+ pop bc
+ pop hl
+ ret
+
+; function to do division
+; all values are big endian
+; INPUT
+; FF95-FF98 = dividend
+; FF99 = divisor
+; b = number of bytes in the dividend (starting from FF95)
+; OUTPUT
+; FF95-FF98 = quotient
+; FF99 = remainder
+Divide:: ; 38b9 (0:38b9)
+ push hl
+ push de
+ push bc
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,Bank(_Divide)
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ call _Divide
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; This function is used to wait a short period after printing a letter to the
+; screen unless the player presses the A/B button or the delay is turned off
+; through the [wd730] or [wd358] flags.
+PrintLetterDelay:: ; 38d3 (0:38d3)
+ ld a,[wd730]
+ bit 6,a
+ ret nz
+ ld a,[wd358]
+ bit 1,a
+ ret z
+ push hl
+ push de
+ push bc
+ ld a,[wd358]
+ bit 0,a
+ jr z,.waitOneFrame
+ ld a,[W_OPTIONS]
+ and $f
+ ld [H_FRAMECOUNTER],a
+ jr .checkButtons
+.waitOneFrame
+ ld a,1
+ ld [H_FRAMECOUNTER],a
+.checkButtons
+ call Joypad
+ ld a,[hJoyHeld]
+.checkAButton
+ bit 0,a ; is the A button pressed?
+ jr z,.checkBButton
+ jr .endWait
+.checkBButton
+ bit 1,a ; is the B button pressed?
+ jr z,.buttonsNotPressed
+.endWait
+ call DelayFrame
+ jr .done
+.buttonsNotPressed ; if neither A nor B is pressed
+ ld a,[H_FRAMECOUNTER]
+ and a
+ jr nz,.checkButtons
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; Copies [hl, bc) to [de, bc - hl).
+; In other words, the source data is from hl up to but not including bc,
+; and the destination is de.
+CopyDataUntil:: ; 3913 (0:3913)
+ ld a,[hli]
+ ld [de],a
+ inc de
+ ld a,h
+ cp b
+ jr nz,CopyDataUntil
+ ld a,l
+ cp c
+ jr nz,CopyDataUntil
+ ret
+
+; Function to remove a pokemon from the party or the current box.
+; wWhichPokemon determines the pokemon.
+; [wcf95] == 0 specifies the party.
+; [wcf95] != 0 specifies the current box.
+RemovePokemon:: ; 391f (0:391f)
+ ld hl, _RemovePokemon
+ ld b, BANK(_RemovePokemon)
+ jp Bankswitch
+
+AddPartyMon:: ; 3927 (0:3927)
+ push hl
+ push de
+ push bc
+ callba _AddPartyMon
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; calculates all 5 stats of current mon and writes them to [de]
+CalcStats:: ; 3936 (0:3936)
+ ld c, $0
+.statsLoop
+ inc c
+ call CalcStat
+ ld a, [H_MULTIPLICAND+1]
+ ld [de], a
+ inc de
+ ld a, [H_MULTIPLICAND+2]
+ ld [de], a
+ inc de
+ ld a, c
+ cp $5
+ jr nz, .statsLoop
+ ret
+
+; calculates stat c of current mon
+; c: stat to calc (HP=1,Atk=2,Def=3,Spd=4,Spc=5)
+; b: consider stat exp?
+; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c])
+CalcStat:: ; 394a (0:394a)
+ push hl
+ push de
+ push bc
+ ld a, b
+ ld d, a
+ push hl
+ ld hl, W_MONHEADER
+ ld b, $0
+ add hl, bc
+ ld a, [hl] ; read base value of stat
+ ld e, a
+ pop hl
+ push hl
+ sla c
+ ld a, d
+ and a
+ jr z, .statExpDone ; consider stat exp?
+ add hl, bc ; skip to corresponding stat exp value
+.statExpLoop ; calculates ceil(Sqrt(stat exp)) in b
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld [H_MULTIPLICAND+1], a
+ inc b ; increment current stat exp bonus
+ ld a, b
+ cp $ff
+ jr z, .statExpDone
+ ld [H_MULTIPLICAND+2], a
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hld]
+ ld d, a
+ ld a, [$ff98]
+ sub d
+ ld a, [hli]
+ ld d, a
+ ld a, [$ff97]
+ sbc d ; test if (current stat exp bonus)^2 < stat exp
+ jr c, .statExpLoop
+.statExpDone
+ srl c
+ pop hl
+ push bc
+ ld bc, $b ; skip to stat IV values
+ add hl, bc
+ pop bc
+ ld a, c
+ cp $2
+ jr z, .getAttackIV
+ cp $3
+ jr z, .getDefenseIV
+ cp $4
+ jr z, .getSpeedIV
+ cp $5
+ jr z, .getSpecialIV
+.getHpIV
+ push bc
+ ld a, [hl] ; Atk IV
+ swap a
+ and $1
+ sla a
+ sla a
+ sla a
+ ld b, a
+ ld a, [hli] ; Def IV
+ and $1
+ sla a
+ sla a
+ add b
+ ld b, a
+ ld a, [hl] ; Spd IV
+ swap a
+ and $1
+ sla a
+ add b
+ ld b, a
+ ld a, [hl] ; Spc IV
+ and $1
+ add b ; HP IV: LSB of the other 4 IVs
+ pop bc
+ jr .calcStatFromIV
+.getAttackIV
+ ld a, [hl]
+ swap a
+ and $f
+ jr .calcStatFromIV
+.getDefenseIV
+ ld a, [hl]
+ and $f
+ jr .calcStatFromIV
+.getSpeedIV
+ inc hl
+ ld a, [hl]
+ swap a
+ and $f
+ jr .calcStatFromIV
+.getSpecialIV
+ inc hl
+ ld a, [hl]
+ and $f
+.calcStatFromIV
+ ld d, $0
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d ; de = Base + IV
+.noCarry
+ sla e
+ rl d ; de = (Base + IV) * 2
+ srl b
+ srl b ; b = ceil(Sqrt(stat exp)) / 4
+ ld a, b
+ add e
+ jr nc, .noCarry2
+ inc d ; da = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4
+.noCarry2
+ ld [H_MULTIPLICAND+2], a
+ ld a, d
+ ld [H_MULTIPLICAND+1], a
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld [H_MULTIPLIER], a
+ call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level
+ ld a, [H_MULTIPLICAND]
+ ld [H_DIVIDEND], a
+ ld a, [H_MULTIPLICAND+1]
+ ld [H_DIVIDEND+1], a
+ ld a, [H_MULTIPLICAND+2]
+ ld [H_DIVIDEND+2], a
+ ld a, $64
+ ld [H_DIVISOR], a
+ ld a, $3
+ ld b, a
+ call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100
+ ld a, c
+ cp $1
+ ld a, $5
+ jr nz, .notHPStat
+ ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld b, a
+ ld a, [H_MULTIPLICAND+2]
+ add b
+ ld [H_MULTIPLICAND+2], a
+ jr nc, .noCarry3
+ ld a, [H_MULTIPLICAND+1]
+ inc a
+ ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level
+.noCarry3
+ ld a, $a
+.notHPStat
+ ld b, a
+ ld a, [H_MULTIPLICAND+2]
+ add b
+ ld [H_MULTIPLICAND+2], a
+ jr nc, .noCarry4
+ ld a, [H_MULTIPLICAND+1]
+ inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5
+ ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10
+.noCarry4
+ ld a, [H_MULTIPLICAND+1] ; check for overflow (>999)
+ cp $4
+ jr nc, .overflow
+ cp $3
+ jr c, .noOverflow
+ ld a, [H_MULTIPLICAND+2]
+ cp $e8
+ jr c, .noOverflow
+.overflow
+ ld a, $3 ; overflow: cap at 999
+ ld [H_MULTIPLICAND+1], a
+ ld a, $e7
+ ld [H_MULTIPLICAND+2], a
+.noOverflow
+ pop bc
+ pop de
+ pop hl
+ ret
+
+AddEnemyMonToPlayerParty:: ; 3a53 (0:3a53)
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(_AddEnemyMonToPlayerParty)
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ call _AddEnemyMonToPlayerParty
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+
+Func_3a68:: ; 3a68 (0:3a68)
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(Func_f51e)
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ call Func_f51e
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ ret
+
+; skips a text entries, each of size $b (like trainer name, OT name, rival name, ...)
+; hl: base pointer, will be incremented by $b * a
+SkipFixedLengthTextEntries:: ; 3a7d (0:3a7d)
+ and a
+ ret z
+ ld bc, $b
+.skipLoop
+ add hl, bc
+ dec a
+ jr nz, .skipLoop
+ ret
+
+AddNTimes:: ; 3a87 (0:3a87)
+; add bc to hl a times
+ and a
+ ret z
+.loop
+ add hl,bc
+ dec a
+ jr nz,.loop
+ ret
+
+; Compare strings, c bytes in length, at de and hl.
+; Often used to compare big endian numbers in battle calculations.
+StringCmp:: ; 3a8e (0:3a8e)
+ ld a,[de]
+ cp [hl]
+ ret nz
+ inc de
+ inc hl
+ dec c
+ jr nz,StringCmp
+ ret
+
+; INPUT:
+; a = oam block index (each block is 4 oam entries)
+; b = Y coordinate of upper left corner of sprite
+; c = X coordinate of upper left corner of sprite
+; de = base address of 4 tile number and attribute pairs
+WriteOAMBlock:: ; 3a97 (0:3a97)
+ ld h,wOAMBuffer / $100
+ swap a ; multiply by 16
+ ld l,a
+ call .writeOneEntry ; upper left
+ push bc
+ ld a,8
+ add c
+ ld c,a
+ call .writeOneEntry ; upper right
+ pop bc
+ ld a,8
+ add b
+ ld b,a
+ call .writeOneEntry ; lower left
+ ld a,8
+ add c
+ ld c,a
+ ; lower right
+.writeOneEntry
+ ld [hl],b ; Y coordinate
+ inc hl
+ ld [hl],c ; X coordinate
+ inc hl
+ ld a,[de] ; tile number
+ inc de
+ ld [hli],a
+ ld a,[de] ; attribute
+ inc de
+ ld [hli],a
+ ret
+
+HandleMenuInput:: ; 3abe (0:3abe)
+ xor a
+ ld [wd09b],a
+
+HandleMenuInputPokemonSelection:: ; 3ac2 (0:3ac2)
+ ld a,[H_DOWNARROWBLINKCNT1]
+ push af
+ ld a,[H_DOWNARROWBLINKCNT2]
+ push af ; save existing values on stack
+ xor a
+ ld [H_DOWNARROWBLINKCNT1],a ; blinking down arrow timing value 1
+ ld a,$06
+ ld [H_DOWNARROWBLINKCNT2],a ; blinking down arrow timing value 2
+.loop1
+ xor a
+ ld [wPartyMonAnimCounter],a ; counter for pokemon shaking animation
+ call PlaceMenuCursor
+ call Delay3
+.loop2
+ push hl
+ ld a,[wd09b]
+ and a ; is it a pokemon selection menu?
+ jr z,.getJoypadState
+ callba AnimatePartyMon ; shake mini sprite of selected pokemon
+.getJoypadState
+ pop hl
+ call JoypadLowSensitivity
+ ld a,[hJoy5]
+ and a ; was a key pressed?
+ jr nz,.keyPressed
+ push hl
+ hlCoord 18, 11 ; coordinates of blinking down arrow in some menus
+ call HandleDownArrowBlinkTiming ; blink down arrow (if any)
+ pop hl
+ ld a,[wMenuJoypadPollCount]
+ dec a
+ jr z,.giveUpWaiting
+ jr .loop2
+.giveUpWaiting
+; if a key wasn't pressed within the specified number of checks
+ pop af
+ ld [H_DOWNARROWBLINKCNT2],a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
+ xor a
+ ld [wMenuWrappingEnabled],a ; disable menu wrapping
+ ret
+.keyPressed
+ xor a
+ ld [wcc4b],a
+ ld a,[hJoy5]
+ ld b,a
+ bit 6,a ; pressed Up key?
+ jr z,.checkIfDownPressed
+.upPressed
+ ld a,[wCurrentMenuItem] ; selected menu item
+ and a ; already at the top of the menu?
+ jr z,.alreadyAtTop
+.notAtTop
+ dec a
+ ld [wCurrentMenuItem],a ; move selected menu item up one space
+ jr .checkOtherKeys
+.alreadyAtTop
+ ld a,[wMenuWrappingEnabled]
+ and a ; is wrapping around enabled?
+ jr z,.noWrappingAround
+ ld a,[wMaxMenuItem]
+ ld [wCurrentMenuItem],a ; wrap to the bottom of the menu
+ jr .checkOtherKeys
+.checkIfDownPressed
+ bit 7,a
+ jr z,.checkOtherKeys
+.downPressed
+ ld a,[wCurrentMenuItem]
+ inc a
+ ld c,a
+ ld a,[wMaxMenuItem]
+ cp c
+ jr nc,.notAtBottom
+.alreadyAtBottom
+ ld a,[wMenuWrappingEnabled]
+ and a ; is wrapping around enabled?
+ jr z,.noWrappingAround
+ ld c,$00 ; wrap from bottom to top
+.notAtBottom
+ ld a,c
+ ld [wCurrentMenuItem],a
+.checkOtherKeys
+ ld a,[wMenuWatchedKeys]
+ and b ; does the menu care about any of the pressed keys?
+ jp z,.loop1
+.checkIfAButtonOrBButtonPressed
+ ld a,[hJoy5]
+ and A_BUTTON | B_BUTTON
+ jr z,.skipPlayingSound
+.AButtonOrBButtonPressed
+ push hl
+ ld hl,wFlags_0xcd60
+ bit 5,[hl]
+ pop hl
+ jr nz,.skipPlayingSound
+ ld a,(SFX_02_40 - SFX_Headers_02) / 3
+ call PlaySound ; play sound
+.skipPlayingSound
+ pop af
+ ld [H_DOWNARROWBLINKCNT2],a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
+ xor a
+ ld [wMenuWrappingEnabled],a ; disable menu wrapping
+ ld a,[hJoy5]
+ ret
+.noWrappingAround
+ ld a,[wcc37]
+ and a ; should we return if the user tried to go past the top or bottom?
+ jr z,.checkOtherKeys
+ jr .checkIfAButtonOrBButtonPressed
+
+PlaceMenuCursor:: ; 3b7c (0:3b7c)
+ ld a,[wTopMenuItemY]
+ and a ; is the y coordinate 0?
+ jr z,.adjustForXCoord
+ ld hl,wTileMap
+ ld bc,SCREEN_WIDTH
+.topMenuItemLoop
+ add hl,bc
+ dec a
+ jr nz,.topMenuItemLoop
+.adjustForXCoord
+ ld a,[wTopMenuItemX]
+ ld b,0
+ ld c,a
+ add hl,bc
+ push hl
+ ld a,[wLastMenuItem]
+ and a ; was the previous menu id 0?
+ jr z,.checkForArrow1
+ push af
+ ld a,[hFlags_0xFFF6]
+ bit 1,a ; is the menu double spaced?
+ jr z,.doubleSpaced1
+ ld bc,20
+ jr .getOldMenuItemScreenPosition
+.doubleSpaced1
+ ld bc,40
+.getOldMenuItemScreenPosition
+ pop af
+.oldMenuItemLoop
+ add hl,bc
+ dec a
+ jr nz,.oldMenuItemLoop
+.checkForArrow1
+ ld a,[hl]
+ cp a,"▶" ; was an arrow next to the previously selected menu item?
+ jr nz,.skipClearingArrow
+.clearArrow
+ ld a,[wTileBehindCursor]
+ ld [hl],a
+.skipClearingArrow
+ pop hl
+ ld a,[wCurrentMenuItem]
+ and a
+ jr z,.checkForArrow2
+ push af
+ ld a,[hFlags_0xFFF6]
+ bit 1,a ; is the menu double spaced?
+ jr z,.doubleSpaced2
+ ld bc,20
+ jr .getCurrentMenuItemScreenPosition
+.doubleSpaced2
+ ld bc,40
+.getCurrentMenuItemScreenPosition
+ pop af
+.currentMenuItemLoop
+ add hl,bc
+ dec a
+ jr nz,.currentMenuItemLoop
+.checkForArrow2
+ ld a,[hl]
+ cp a,"▶" ; has the right arrow already been placed?
+ jr z,.skipSavingTile ; if so, don't lose the saved tile
+ ld [wTileBehindCursor],a ; save tile before overwriting with right arrow
+.skipSavingTile
+ ld a,"▶" ; place right arrow
+ ld [hl],a
+ ld a,l
+ ld [wMenuCursorLocation],a
+ ld a,h
+ ld [wMenuCursorLocation + 1],a
+ ld a,[wCurrentMenuItem]
+ ld [wLastMenuItem],a
+ ret
+
+; This is used to mark a menu cursor other than the one currently being
+; manipulated. In the case of submenus, this is used to show the location of
+; the menu cursor in the parent menu. In the case of swapping items in list,
+; this is used to mark the item that was first chosen to be swapped.
+PlaceUnfilledArrowMenuCursor:: ; 3bec (0:3bec)
+ ld b,a
+ ld a,[wMenuCursorLocation]
+ ld l,a
+ ld a,[wMenuCursorLocation + 1]
+ ld h,a
+ ld [hl],$ec ; outline of right arrow
+ ld a,b
+ ret
+
+; Replaces the menu cursor with a blank space.
+EraseMenuCursor:: ; 3bf9 (0:3bf9)
+ ld a,[wMenuCursorLocation]
+ ld l,a
+ ld a,[wMenuCursorLocation + 1]
+ ld h,a
+ ld [hl]," "
+ ret
+
+; This toggles a blinking down arrow at hl on and off after a delay has passed.
+; This is often called even when no blinking is occurring.
+; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0.
+; The effect is that if the tile at hl is initialized with a down arrow,
+; this function will toggle that down arrow on and off, but if the tile isn't
+; initliazed with a down arrow, this function does nothing.
+; That allows this to be called without worrying about if a down arrow should
+; be blinking.
+HandleDownArrowBlinkTiming:: ; 3c04 (0:3c04)
+ ld a,[hl]
+ ld b,a
+ ld a,$ee ; down arrow
+ cp b
+ jr nz,.downArrowOff
+.downArrowOn
+ ld a,[H_DOWNARROWBLINKCNT1]
+ dec a
+ ld [H_DOWNARROWBLINKCNT1],a
+ ret nz
+ ld a,[H_DOWNARROWBLINKCNT2]
+ dec a
+ ld [H_DOWNARROWBLINKCNT2],a
+ ret nz
+ ld a," "
+ ld [hl],a
+ ld a,$ff
+ ld [H_DOWNARROWBLINKCNT1],a
+ ld a,$06
+ ld [H_DOWNARROWBLINKCNT2],a
+ ret
+.downArrowOff
+ ld a,[H_DOWNARROWBLINKCNT1]
+ and a
+ ret z
+ dec a
+ ld [H_DOWNARROWBLINKCNT1],a
+ ret nz
+ dec a
+ ld [H_DOWNARROWBLINKCNT1],a
+ ld a,[H_DOWNARROWBLINKCNT2]
+ dec a
+ ld [H_DOWNARROWBLINKCNT2],a
+ ret nz
+ ld a,$06
+ ld [H_DOWNARROWBLINKCNT2],a
+ ld a,$ee ; down arrow
+ ld [hl],a
+ ret
+
+; The following code either enables or disables the automatic drawing of
+; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait
+; for a button press after displaying text (unless [wcc47] is set).
+
+EnableAutoTextBoxDrawing:: ; 3c3c (0:3c3c)
+ xor a
+ jr AutoTextBoxDrawingCommon
+
+DisableAutoTextBoxDrawing:: ; 3c3f (0:3c3f)
+ ld a,$01
+
+AutoTextBoxDrawingCommon:: ; 3c41 (0:3c41)
+ ld [wAutoTextBoxDrawingControl],a
+ xor a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText],a ; make DisplayTextID wait for button press
+ ret
+
+PrintText:: ; 3c49 (0:3c49)
+; Print text hl at (1, 14).
+ push hl
+ ld a,MESSAGE_BOX
+ ld [wTextBoxID],a
+ call DisplayTextBoxID
+ call UpdateSprites
+ call Delay3
+ pop hl
+Func_3c59:: ; 3c59 (0:3c59)
+ bcCoord 1, 14
+ jp TextCommandProcessor
+
+
+PrintNumber:: ; 3c5f
+; Print the c-digit, b-byte value at de.
+; Allows 2 to 7 digits. For 1-digit numbers, add
+; the value to char "0" instead of calling PrintNumber.
+; Flags LEADING_ZEROES and LEFT_ALIGN can be given
+; in bits 7 and 6 of b respectively.
+LEADING_ZEROES EQU 7
+LEFT_ALIGN EQU 6
+
+ push bc
+ xor a
+ ld [H_PASTLEADINGZEROES], a
+ ld [H_NUMTOPRINT], a
+ ld [H_NUMTOPRINT + 1], a
+ ld a, b
+ and $f
+ cp 1
+ jr z, .byte
+ cp 2
+ jr z, .word
+.long
+ ld a, [de]
+ ld [H_NUMTOPRINT], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 1], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+ jr .start
+
+.word
+ ld a, [de]
+ ld [H_NUMTOPRINT + 1], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+ jr .start
+
+.byte
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+
+.start
+ push de
+
+ ld d, b
+ ld a, c
+ ld b, a
+ xor a
+ ld c, a
+ ld a, b
+
+ cp 2
+ jr z, .tens
+ cp 3
+ jr z, .hundreds
+ cp 4
+ jr z, .thousands
+ cp 5
+ jr z, .ten_thousands
+ cp 6
+ jr z, .hundred_thousands
+
+print_digit: macro
+
+if (\1) / $10000
+ ld a, \1 / $10000 % $100
+else xor a
+endc
+ ld [H_POWEROFTEN + 0], a
+
+if (\1) / $100
+ ld a, \1 / $100 % $100
+else xor a
+endc
+ ld [H_POWEROFTEN + 1], a
+
+ ld a, \1 / $1 % $100
+ ld [H_POWEROFTEN + 2], a
+
+ call .PrintDigit
+ call .NextDigit
+endm
+
+.millions print_digit 1000000
+.hundred_thousands print_digit 100000
+.ten_thousands print_digit 10000
+.thousands print_digit 1000
+.hundreds print_digit 100
+
+.tens
+ ld c, 0
+ ld a, [H_NUMTOPRINT + 2]
+.mod
+ cp 10
+ jr c, .ok
+ sub 10
+ inc c
+ jr .mod
+.ok
+
+ ld b, a
+ ld a, [H_PASTLEADINGZEROES]
+ or c
+ ld [H_PASTLEADINGZEROES], a
+ jr nz, .past
+ call .PrintLeadingZero
+ jr .next
+.past
+ ld a, "0"
+ add c
+ ld [hl], a
+.next
+
+ call .NextDigit
+.ones
+ ld a, "0"
+ add b
+ ld [hli], a
+ pop de
+ dec de
+ pop bc
+ ret
+
+.PrintDigit:
+; Divide by the current decimal place.
+; Print the quotient, and keep the modulus.
+ ld c, 0
+.loop
+ ld a, [H_POWEROFTEN]
+ ld b, a
+ ld a, [H_NUMTOPRINT]
+ ld [H_SAVEDNUMTOPRINT], a
+ cp b
+ jr c, .underflow0
+ sub b
+ ld [H_NUMTOPRINT], a
+ ld a, [H_POWEROFTEN + 1]
+ ld b, a
+ ld a, [H_NUMTOPRINT + 1]
+ ld [H_SAVEDNUMTOPRINT + 1], a
+ cp b
+ jr nc, .noborrow1
+
+ ld a, [H_NUMTOPRINT]
+ or 0
+ jr z, .underflow1
+ dec a
+ ld [H_NUMTOPRINT], a
+ ld a, [H_NUMTOPRINT + 1]
+.noborrow1
+
+ sub b
+ ld [H_NUMTOPRINT + 1], a
+ ld a, [H_POWEROFTEN + 2]
+ ld b, a
+ ld a, [H_NUMTOPRINT + 2]
+ ld [H_SAVEDNUMTOPRINT + 2], a
+ cp b
+ jr nc, .noborrow2
+
+ ld a, [H_NUMTOPRINT + 1]
+ and a
+ jr nz, .borrowed
+
+ ld a, [H_NUMTOPRINT]
+ and a
+ jr z, .underflow2
+ dec a
+ ld [H_NUMTOPRINT], a
+ xor a
+.borrowed
+
+ dec a
+ ld [H_NUMTOPRINT + 1], a
+ ld a, [H_NUMTOPRINT + 2]
+.noborrow2
+ sub b
+ ld [H_NUMTOPRINT + 2], a
+ inc c
+ jr .loop
+
+.underflow2
+ ld a, [H_SAVEDNUMTOPRINT + 1]
+ ld [H_NUMTOPRINT + 1], a
+.underflow1
+ ld a, [H_SAVEDNUMTOPRINT]
+ ld [H_NUMTOPRINT], a
+.underflow0
+ ld a, [H_PASTLEADINGZEROES]
+ or c
+ jr z, .PrintLeadingZero
+
+ ld a, "0"
+ add c
+ ld [hl], a
+ ld [H_PASTLEADINGZEROES], a
+ ret
+
+.PrintLeadingZero:
+ bit LEADING_ZEROES, d
+ ret z
+ ld [hl], "0"
+ ret
+
+.NextDigit:
+; Increment unless the number is left-aligned,
+; leading zeroes are not printed, and no digits
+; have been printed yet.
+ bit LEADING_ZEROES, d
+ jr nz, .inc
+ bit LEFT_ALIGN, d
+ jr z, .inc
+ ld a, [H_PASTLEADINGZEROES]
+ and a
+ ret z
+.inc
+ inc hl
+ ret
+
+
+CallFunctionInTable::
+JumpTable::
+; Call function a in jumptable hl.
+; de is not preserved.
+ push hl
+ push de
+ push bc
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .returnAddress
+ push de
+ jp [hl]
+.returnAddress
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+IsInArray::
+; Search an array at hl for the value in a.
+; Entry size is de bytes.
+; Return count b and carry if found.
+ ld b, 0
+
+IsInRestOfArray::
+ ld c, a
+.loop
+ ld a, [hl]
+ cp -1
+ jr z, .notfound
+ cp c
+ jr z, .found
+ inc b
+ add hl, de
+ jr .loop
+
+.notfound
+ and a
+ ret
+
+.found
+ scf
+ ret
+
+InitMapSprites:: ; 3dba (0:3dba)
+ ld hl, _InitMapSprites ; 1401b (5:401b)
+ ld b,BANK(_InitMapSprites)
+ jp Bankswitch
+
+RestoreScreenTilesAndReloadTilePatterns:: ; 3dbe (0:3dbe)
+ call ClearSprites
+ ld a, $1
+ ld [wUpdateSpritesEnabled], a
+ call ReloadMapSpriteTilePatterns
+ call LoadScreenTilesFromBuffer2
+ call LoadTextBoxTilePatterns
+ call GoPAL_SET_CF1C
+ jr Delay3
+
+
+GBPalWhiteOutWithDelay3::
+ call GBPalWhiteOut
+
+Delay3::
+; The bg map is updated each frame in thirds.
+; Wait three frames to let the bg map fully update.
+ ld c, 3
+ jp DelayFrames
+
+GBPalNormal::
+; Reset BGP and OBP0.
+ ld a, %11100100 ; 3210
+ ld [rBGP], a
+ ld a, %11010000 ; 3100
+ ld [rOBP0], a
+ ret
+
+GBPalWhiteOut::
+; White out all palettes.
+ xor a
+ ld [rBGP],a
+ ld [rOBP0],a
+ ld [rOBP1],a
+ ret
+
+
+GoPAL_SET_CF1C:: ; 3ded (0:3ded)
+ ld b,$ff
+GoPAL_SET:: ; 3def (0:3def)
+ ld a,[wOnSGB]
+ and a
+ ret z
+ predef_jump Func_71ddf
+
+GetHealthBarColor::
+; Return at hl the palette of
+; an HP bar e pixels long.
+ ld a, e
+ cp 27
+ ld d, 0 ; green
+ jr nc, .gotColor
+ cp 10
+ inc d ; yellow
+ jr nc, .gotColor
+ inc d ; red
+.gotColor
+ ld [hl], d
+ ret
+
+; Copy the current map's sprites' tile patterns to VRAM again after they have
+; been overwritten by other tile patterns.
+ReloadMapSpriteTilePatterns:: ; 3e08 (0:3e08)
+ ld hl, wFontLoaded
+ ld a, [hl]
+ push af
+ res 0, [hl]
+ push hl
+ xor a
+ ld [W_SPRITESETID], a
+ call DisableLCD
+ callba InitMapSprites
+ call EnableLCD
+ pop hl
+ pop af
+ ld [hl], a
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ jp UpdateSprites
+
+
+GiveItem::
+; Give player quantity c of item b,
+; and copy the item's name to wcf4b.
+; Return carry on success.
+ ld a, b
+ ld [wd11e], a
+ ld [wcf91], a
+ ld a, c
+ ld [wcf96], a
+ ld hl,wNumBagItems
+ call AddItemToInventory
+ ret nc
+ call GetItemName
+ call CopyStringToCF4B
+ scf
+ ret
+
+GivePokemon::
+; Give the player monster b at level c.
+ ld a, b
+ ld [wcf91], a
+ ld a, c
+ ld [W_CURENEMYLVL], a
+ xor a
+ ld [wcc49], a
+ ld b, BANK(_GivePokemon)
+ ld hl, _GivePokemon
+ jp Bankswitch
+
+
+Random::
+; Return a random number in a.
+; For battles, use BattleRandom.
+ push hl
+ push de
+ push bc
+ callba Random_
+ ld a, [hRandomAdd]
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+INCLUDE "home/predef.asm"
+
+
+Func_3ead:: ; 3ead (0:3ead)
+ ld b, BANK(CinnabarGymQuiz_1eb0a)
+ ld hl, CinnabarGymQuiz_1eb0a
+ jp Bankswitch
+
+CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: ; 3eb5 (0:3eb5)
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [hJoyHeld]
+ bit 0, a ; A button
+ jr z, .nothingFound
+; A button is pressed
+ ld a, Bank(CheckForHiddenObject)
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ call CheckForHiddenObject
+ ld a, [$ffee]
+ and a
+ jr nz, .hiddenObjectNotFound
+ ld a, [wHiddenObjectFunctionRomBank]
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ ld de, .returnAddress
+ push de
+ jp [hl]
+.returnAddress
+ xor a
+ jr .done
+.hiddenObjectNotFound
+ callba PrintBookshelfText
+ ld a, [$ffdb]
+ and a
+ jr z, .done
+.nothingFound
+ ld a, $ff
+.done
+ ld [$ffeb], a
+ pop af
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ ret
+
+PrintPredefTextID:: ; 3ef5 (0:3ef5)
+ ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ ld hl, TextPredefs
+ call SetMapTextPointer
+ ld hl, wcf11
+ set 0, [hl]
+ call DisplayTextID
+
+RestoreMapTextPointer:: ; 3f05 (0:3f05)
+ ld hl, W_MAPTEXTPTR
+ ld a, [$ffec]
+ ld [hli], a
+ ld a, [$ffec + 1]
+ ld [hl], a
+ ret
+
+SetMapTextPointer:: ; 3f0f (0:3f0f)
+ ld a, [W_MAPTEXTPTR]
+ ld [$ffec], a
+ ld a, [W_MAPTEXTPTR + 1]
+ ld [$ffec + 1], a
+ ld a, l
+ ld [W_MAPTEXTPTR], a
+ ld a, h
+ ld [W_MAPTEXTPTR + 1], a
+ ret
+
+TextPredefs::
+ add_tx_pre CardKeySuccessText ; 01
+ add_tx_pre CardKeyFailText ; 02
+ add_tx_pre RedBedroomPC ; 03
+ add_tx_pre RedBedroomSNESText ; 04
+ add_tx_pre PushStartText ; 05
+ add_tx_pre SaveOptionText ; 06
+ add_tx_pre StrengthsAndWeaknessesText ; 07
+ add_tx_pre OakLabEmailText ; 08
+ add_tx_pre AerodactylFossilText ; 09
+ add_tx_pre Route15UpstairsBinocularsText ; 0A
+ add_tx_pre KabutopsFossilText ; 0B
+ add_tx_pre GymStatueText1 ; 0C
+ add_tx_pre GymStatueText2 ; 0D
+ add_tx_pre BookcaseText ; 0E
+ add_tx_pre ViridianCityPokecenterBenchGuyText ; 0F
+ add_tx_pre PewterCityPokecenterBenchGuyText ; 10
+ add_tx_pre CeruleanCityPokecenterBenchGuyText ; 11
+ add_tx_pre LavenderCityPokecenterBenchGuyText ; 12
+ add_tx_pre VermilionCityPokecenterBenchGuyText ; 13
+ add_tx_pre CeladonCityPokecenterBenchGuyText ; 14
+ add_tx_pre CeladonCityHotelText ; 15
+ add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 16
+ add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 17
+ add_tx_pre SaffronCityPokecenterBenchGuyText ; 18
+ add_tx_pre MtMoonPokecenterBenchGuyText ; 19
+ add_tx_pre RockTunnelPokecenterBenchGuyText ; 1A
+ add_tx_pre UnusedBenchGuyText1 ; 1B
+ add_tx_pre UnusedBenchGuyText2 ; 1C
+ add_tx_pre UnusedBenchGuyText3 ; 1D
+ add_tx_pre TerminatorText_62508 ; 1E
+ add_tx_pre PredefText1f ; 1F
+ add_tx_pre ViridianSchoolNotebook ; 20
+ add_tx_pre ViridianSchoolBlackboard ; 21
+ add_tx_pre JustAMomentText ; 22
+ add_tx_pre PredefText23 ; 23
+ add_tx_pre FoundHiddenItemText ; 24
+ add_tx_pre HiddenItemBagFullText ; 25
+ add_tx_pre VermilionGymTrashText ; 26
+ add_tx_pre IndigoPlateauHQText ; 27
+ add_tx_pre GameCornerOutOfOrderText ; 28
+ add_tx_pre GameCornerOutToLunchText ; 29
+ add_tx_pre GameCornerSomeonesKeysText ; 2A
+ add_tx_pre FoundHiddenCoinsText ; 2B
+ add_tx_pre DroppedHiddenCoinsText ; 2C
+ add_tx_pre BillsHouseMonitorText ; 2D
+ add_tx_pre BillsHouseInitiatedText ; 2E
+ add_tx_pre BillsHousePokemonList ; 2F
+ add_tx_pre MagazinesText ; 30
+ add_tx_pre CinnabarGymQuiz ; 31
+ add_tx_pre GameCornerNoCoinsText ; 32
+ add_tx_pre GameCornerCoinCaseText ; 33
+ add_tx_pre LinkCableHelp ; 34
+ add_tx_pre TMNotebook ; 35
+ add_tx_pre FightingDojoText ; 36
+ add_tx_pre FightingDojoText_52a10 ; 37
+ add_tx_pre FightingDojoText_52a1d ; 38
+ add_tx_pre NewBicycleText ; 39
+ add_tx_pre IndigoPlateauStatues ; 3A
+ add_tx_pre VermilionGymTrashSuccesText1 ; 3B
+ add_tx_pre VermilionGymTrashSuccesText2 ; 3C
+ add_tx_pre VermilionGymTrashSuccesText3 ; 3D
+ add_tx_pre VermilionGymTrashFailText ; 3E
+ add_tx_pre TownMapText ; 3F
+ add_tx_pre BookOrSculptureText ; 40
+ add_tx_pre ElevatorText ; 41
+ add_tx_pre PokemonStuffText ; 42
diff --git a/home/audio.asm b/home/audio.asm
index 9210924c..e062c8da 100644
--- a/home/audio.asm
+++ b/home/audio.asm
@@ -1,183 +1,186 @@
-PlayDefaultMusic:: ; 2307 (0:2307)
- call WaitForSoundToFinish
- xor a
- ld c, a
- ld d, a
- ld [wcfca], a
- jr asm_2324
-
-Func_2312:: ; 2312 (0:2312)
- ld c, $a
- ld d, $0
- ld a, [wd72e]
- bit 5, a
- jr z, asm_2324
- xor a
- ld [wcfca], a
- ld c, $8
- ld d, c
-asm_2324:: ; 2324 (0:2324)
- ld a, [wWalkBikeSurfState]
- and a
- jr z, .asm_2343
- cp $2
- jr z, .asm_2332
- ld a, MUSIC_BIKE_RIDING
- jr .asm_2334
-.asm_2332
- ld a, MUSIC_SURFING
-.asm_2334
- ld b, a
- ld a, d
- and a
- ld a, BANK(Music_BikeRiding)
- jr nz, .asm_233e
- ld [wc0ef], a
-.asm_233e
- ld [wc0f0], a
- jr .asm_234c
-.asm_2343
- ld a, [wd35b]
- ld b, a
- call Func_2385
- jr c, .asm_2351
-.asm_234c
- ld a, [wcfca]
- cp b
- ret z
-.asm_2351
- ld a, c
- ld [wMusicHeaderPointer], a
- ld a, b
- ld [wcfca], a
- ld [wc0ee], a
- jp PlaySound
-
-Func_235f:: ; 235f (0:235f)
- ld a, [wc0ef]
- ld b, a
- cp BANK(Music2_UpdateMusic)
- jr nz, .checkForBank08
-.bank02
- ld hl, Music2_UpdateMusic
- jr .asm_2378
-.checkForBank08
- cp BANK(Music8_UpdateMusic)
- jr nz, .bank1F
-.bank08
- ld hl, Music8_UpdateMusic
- jr .asm_2378
-.bank1F
- ld hl, Music1f_UpdateMusic
-.asm_2378
- ld c, $6
-.asm_237a
- push bc
- push hl
- call Bankswitch
- pop hl
- pop bc
- dec c
- jr nz, .asm_237a
- ret
-
-Func_2385:: ; 2385 (0:2385)
- ld a, [wd35c]
- ld e, a
- ld a, [wc0ef]
- cp e
- jr nz, .asm_2394
- ld [wc0f0], a
- and a
- ret
-.asm_2394
- ld a, c
- and a
- ld a, e
- jr nz, .asm_239c
- ld [wc0ef], a
-.asm_239c
- ld [wc0f0], a
- scf
- ret
-
-PlayMusic:: ; 23a1 (0:23a1)
- ld b, a
- ld [wc0ee], a
- xor a
- ld [wMusicHeaderPointer], a
- ld a, c
- ld [wc0ef], a
- ld [wc0f0], a
- ld a, b
-
-; plays music specified by a. If value is $ff, music is stopped
-PlaySound:: ; 23b1 (0:23b1)
- push hl
- push de
- push bc
- ld b, a
- ld a, [wc0ee]
- and a
- jr z, .asm_23c8
- xor a
- ld [wc02a], a
- ld [wc02b], a
- ld [wc02c], a
- ld [wc02d], a
-.asm_23c8
- ld a, [wMusicHeaderPointer]
- and a
- jr z, .asm_23e3
- ld a, [wc0ee]
- and a
- jr z, .asm_2425
- xor a
- ld [wc0ee], a
- ld a, [wcfca]
- cp $ff
- jr nz, .asm_2414
- xor a
- ld [wMusicHeaderPointer], a
-.asm_23e3
- xor a
- ld [wc0ee], a
- ld a, [H_LOADEDROMBANK]
- ld [$ffb9], a
- ld a, [wc0ef]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- cp BANK(Func_9876)
- jr nz, .checkForBank08
-.bank02
- ld a, b
- call Func_9876
- jr .asm_240b
-.checkForBank08
- cp BANK(Func_22035)
- jr nz, .bank1F
-.bank08
- ld a, b
- call Func_22035
- jr .asm_240b
-.bank1F
- ld a, b
- call Func_7d8ea
-.asm_240b
- ld a, [$ffb9]
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- jr .asm_2425
-.asm_2414
- ld a, b
- ld [wcfca], a
- ld a, [wMusicHeaderPointer]
- ld [wcfc8], a
- ld [wcfc9], a
- ld a, b
- ld [wMusicHeaderPointer], a
-.asm_2425
- pop bc
- pop de
- pop hl
- ret
+PlayDefaultMusic:: ; 2307 (0:2307)
+ call WaitForSoundToFinish
+ xor a
+ ld c, a
+ ld d, a
+ ld [wcfca], a
+ jr asm_2324
+
+Func_2312:: ; 2312 (0:2312)
+ ld c, $a
+ ld d, $0
+ ld a, [wd72e]
+ bit 5, a
+ jr z, asm_2324
+ xor a
+ ld [wcfca], a
+ ld c, $8
+ ld d, c
+asm_2324:: ; 2324 (0:2324)
+ ld a, [wWalkBikeSurfState]
+ and a
+ jr z, .asm_2343
+ cp $2
+ jr z, .asm_2332
+ ld a, MUSIC_BIKE_RIDING
+ jr .asm_2334
+.asm_2332
+ ld a, MUSIC_SURFING
+.asm_2334
+ ld b, a
+ ld a, d
+ and a
+ ld a, BANK(Music_BikeRiding)
+ jr nz, .asm_233e
+ ld [wc0ef], a
+.asm_233e
+ ld [wc0f0], a
+ jr .asm_234c
+.asm_2343
+ ld a, [wd35b]
+ ld b, a
+ call Func_2385
+ jr c, .asm_2351
+.asm_234c
+ ld a, [wcfca]
+ cp b
+ ret z
+.asm_2351
+ ld a, c
+ ld [wMusicHeaderPointer], a
+ ld a, b
+ ld [wcfca], a
+ ld [wc0ee], a
+ jp PlaySound
+
+Func_235f:: ; 235f (0:235f)
+ ld a, [wc0ef]
+ ld b, a
+ cp BANK(Music2_UpdateMusic)
+ jr nz, .checkForBank08
+.bank02
+ ld hl, Music2_UpdateMusic
+ jr .asm_2378
+.checkForBank08
+ cp BANK(Music8_UpdateMusic)
+ jr nz, .bank1F
+.bank08
+ ld hl, Music8_UpdateMusic
+ jr .asm_2378
+.bank1F
+ ld hl, Music1f_UpdateMusic
+.asm_2378
+ ld c, $6
+.asm_237a
+ push bc
+ push hl
+ call Bankswitch
+ pop hl
+ pop bc
+ dec c
+ jr nz, .asm_237a
+ ret
+
+Func_2385:: ; 2385 (0:2385)
+ ld a, [wd35c]
+ ld e, a
+ ld a, [wc0ef]
+ cp e
+ jr nz, .asm_2394
+ ld [wc0f0], a
+ and a
+ ret
+.asm_2394
+ ld a, c
+ and a
+ ld a, e
+ jr nz, .asm_239c
+ ld [wc0ef], a
+.asm_239c
+ ld [wc0f0], a
+ scf
+ ret
+
+PlayMusic:: ; 23a1 (0:23a1)
+ ld b, a
+ ld [wc0ee], a
+ xor a
+ ld [wMusicHeaderPointer], a
+ ld a, c
+ ld [wc0ef], a
+ ld [wc0f0], a
+ ld a, b
+
+StopAllMusic:: ; 2233 (0:2233)
+ ld a,$FF
+ ld [wc0ee],a
+; plays music specified by a. If value is $ff, music is stopped
+PlaySound:: ; 23b1 (0:23b1)
+ push hl
+ push de
+ push bc
+ ld b, a
+ ld a, [wc0ee]
+ and a
+ jr z, .asm_23c8
+ xor a
+ ld [wc02a], a
+ ld [wc02b], a
+ ld [wc02c], a
+ ld [wc02d], a
+.asm_23c8
+ ld a, [wMusicHeaderPointer]
+ and a
+ jr z, .asm_23e3
+ ld a, [wc0ee]
+ and a
+ jr z, .asm_2425
+ xor a
+ ld [wc0ee], a
+ ld a, [wcfca]
+ cp $ff
+ jr nz, .asm_2414
+ xor a
+ ld [wMusicHeaderPointer], a
+.asm_23e3
+ xor a
+ ld [wc0ee], a
+ ld a, [H_LOADEDROMBANK]
+ ld [$ffb9], a
+ ld a, [wc0ef]
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ cp BANK(Func_9876)
+ jr nz, .checkForBank08
+.bank02
+ ld a, b
+ call Func_9876
+ jr .asm_240b
+.checkForBank08
+ cp BANK(Func_22035)
+ jr nz, .bank1F
+.bank08
+ ld a, b
+ call Func_22035
+ jr .asm_240b
+.bank1F
+ ld a, b
+ call Func_7d8ea
+.asm_240b
+ ld a, [$ffb9]
+ ld [H_LOADEDROMBANK], a
+ ld [$2000], a
+ jr .asm_2425
+.asm_2414
+ ld a, b
+ ld [wcfca], a
+ ld a, [wMusicHeaderPointer]
+ ld [wcfc8], a
+ ld [wcfc9], a
+ ld a, b
+ ld [wMusicHeaderPointer], a
+.asm_2425
+ pop bc
+ pop de
+ pop hl
+ ret
diff --git a/home/init.asm b/home/init.asm
index cc89ad34..701a4bb8 100644
--- a/home/init.asm
+++ b/home/init.asm
@@ -1,137 +1,136 @@
-SoftReset::
- call StopAllSounds
- call GBPalWhiteOut
- ld c, $20
- call DelayFrames
- ; fallthrough
-
-Init::
-; Program init.
-
-rLCDC_DEFAULT EQU %11100011
-; * LCD enabled
-; * Window tile map at $9C00
-; * Window display enabled
-; * BG and window tile data at $8800
-; * BG tile map at $9800
-; * 8x8 OBJ size
-; * OBJ display enabled
-; * BG display enabled
-
- di
-
- xor a
- ld [rIF], a
- ld [rIE], a
- ld [$ff43], a
- ld [$ff42], a
- ld [rSB], a
- ld [rSC], a
- ld [$ff4b], a
- ld [$ff4a], a
- ld [$ff06], a
- ld [$ff07], a
- ld [$ff47], a
- ld [$ff48], a
- ld [$ff49], a
-
- ld a, rLCDC_ENABLE_MASK
- ld [rLCDC], a
- call DisableLCD
-
- ld sp, wStack
-
- ld hl, $c000 ; start of WRAM
- ld bc, $2000 ; size of WRAM
-.loop
- ld [hl], 0
- inc hl
- dec bc
- ld a, b
- or c
- jr nz, .loop
-
- call ClearVram
-
- ld hl, $ff80
- ld bc, $ffff - $ff80
- call FillMemory
-
- call ClearSprites
-
- ld a, Bank(WriteDMACodeToHRAM)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- call WriteDMACodeToHRAM
-
- xor a
- ld [hTilesetType], a
- ld [$ff41], a
- ld [hSCX], a
- ld [hSCY], a
- ld [$ff0f], a
- ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL
- ld [rIE], a
-
- ld a, 144 ; move the window off-screen
- ld [hWY], a
- ld [rWY], a
- ld a, 7
- ld [rWX], a
-
- ld a, CONNECTION_NOT_ESTABLISHED
- ld [hSerialConnectionStatus], a
-
- ld h, vBGMap0 / $100
- call ClearBgMap
- ld h, vBGMap1 / $100
- call ClearBgMap
-
- ld a, rLCDC_DEFAULT
- ld [rLCDC], a
- ld a, 16
- ld [hSoftReset], a
- call StopAllSounds
-
- ei
-
- predef LoadSGB
-
- ld a, BANK(SFX_1f_67)
- ld [wc0ef], a
- ld [wc0f0], a
- ld a, $9c
- ld [$ffbd], a
- xor a
- ld [$ffbc], a
- dec a
- ld [wUpdateSpritesEnabled], a
-
- predef PlayIntro
-
- call DisableLCD
- call ClearVram
- call GBPalNormal
- call ClearSprites
- ld a, rLCDC_DEFAULT
- ld [rLCDC], a
-
- jp SetDefaultNamesBeforeTitlescreen
-
-ClearVram:
- ld hl, $8000
- ld bc, $2000
- xor a
- jp FillMemory
-
-
-StopAllSounds::
- ld a, BANK(Music2_UpdateMusic)
- ld [wc0ef], a
- ld [wc0f0], a
- xor a
- ld [wMusicHeaderPointer], a
- ld [wc0ee], a
- ld [wcfca], a
- dec a
- jp PlaySound
+SoftReset::
+ call StopAllSounds
+ call GBPalWhiteOut
+ ld c, $20
+ call DelayFrames
+ ; fallthrough
+
+Init::
+; Program init.
+
+rLCDC_DEFAULT EQU %11100011
+; * LCD enabled
+; * Window tile map at $9C00
+; * Window display enabled
+; * BG and window tile data at $8800
+; * BG tile map at $9800
+; * 8x8 OBJ size
+; * OBJ display enabled
+; * BG display enabled
+
+ di
+
+ xor a
+ ld [rIF], a
+ ld [rIE], a
+ ld [$ff43], a
+ ld [$ff42], a
+ ld [rSB], a
+ ld [rSC], a
+ ld [$ff4b], a
+ ld [$ff4a], a
+ ld [$ff06], a
+ ld [$ff07], a
+ ld [$ff47], a
+ ld [$ff48], a
+ ld [$ff49], a
+
+ ld a, rLCDC_ENABLE_MASK
+ ld [rLCDC], a
+ call DisableLCD
+
+ ld sp, wStack
+
+ ld hl, $c000 ; start of WRAM
+ ld bc, $2000 ; size of WRAM
+.loop
+ ld [hl], 0
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+
+ call ClearVram
+
+ ld hl, $ff80
+ ld bc, $ffff - $ff80
+ call FillMemory
+
+ call ClearSprites
+
+ ld a, Bank(WriteDMACodeToHRAM)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call WriteDMACodeToHRAM
+
+ xor a
+ ld [hTilesetType], a
+ ld [$ff41], a
+ ld [hSCX], a
+ ld [hSCY], a
+ ld [$ff0f], a
+ ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL
+ ld [rIE], a
+
+ ld a, 144 ; move the window off-screen
+ ld [hWY], a
+ ld [rWY], a
+ ld a, 7
+ ld [rWX], a
+
+ ld a, CONNECTION_NOT_ESTABLISHED
+ ld [hSerialConnectionStatus], a
+
+ ld h, vBGMap0 / $100
+ call ClearBgMap
+ ld h, vBGMap1 / $100
+ call ClearBgMap
+
+ ld a, rLCDC_DEFAULT
+ ld [rLCDC], a
+ ld a, 16
+ ld [hSoftReset], a
+ call StopAllSounds
+
+ ei
+
+ predef LoadSGB
+
+ ld a, BANK(SFX_1f_67)
+ ld [wc0ef], a
+ ld [wc0f0], a
+ ld a, $9c
+ ld [$ffbd], a
+ xor a
+ ld [$ffbc], a
+ dec a
+ ld [wUpdateSpritesEnabled], a
+
+ predef PlayIntro
+
+ call DisableLCD
+ call ClearVram
+ call GBPalNormal
+ call ClearSprites
+ ld a, rLCDC_DEFAULT
+ ld [rLCDC], a
+
+ jp SetDefaultNamesBeforeTitlescreen
+
+ClearVram:
+ ld hl, $8000
+ ld bc, $2000
+ xor a
+ jp FillMemory
+
+
+StopAllSounds::
+ ld a, BANK(Music2_UpdateMusic)
+ ld [wc0ef], a
+ ld [wc0f0], a
+ xor a
+ ld [wMusicHeaderPointer], a
+ ld [wc0ee], a
+ ld [wcfca], a
+ jp StopAllMusic
diff --git a/home/overworld.asm b/home/overworld.asm
index 0a92355c..3309f1cc 100644
--- a/home/overworld.asm
+++ b/home/overworld.asm
@@ -1,2225 +1,2293 @@
-EnterMap:: ; 01d7 (0:01d7)
-; Load a new map.
- ld a, $ff
- ld [wJoyIgnore], a
- call LoadMapData
- callba ClearVariablesAfterLoadingMapData
- ld hl, wd72c
- bit 0, [hl] ; has the player already made 3 steps since the last battle?
- jr z, .skipGivingThreeStepsOfNoRandomBattles
- ld a, 3 ; minimum number of steps between battles
- ld [wNumberOfNoRandomBattleStepsLeft], a
-.skipGivingThreeStepsOfNoRandomBattles
- ld hl, wd72e
- bit 5, [hl] ; did a battle happen immediately before this?
- res 5, [hl] ; unset the "battle just happened" flag
- call z, ResetUsingStrengthOutOfBattleBit
- call nz, MapEntryAfterBattle
- ld hl, wd732
- ld a, [hl]
- and 1 << 4 | 1 << 3 ; fly warp or dungeon warp
- jr z, .didNotEnterUsingFlyWarpOrDungeonWarp
- callba EnterMapAnim
- call UpdateSprites
- ld hl, wd732
- res 3, [hl]
- ld hl, wd72e
- res 4, [hl]
- call Func_342a
-.didNotEnterUsingFlyWarpOrDungeonWarp
- callba CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road
- ld hl, wd732
- bit 4, [hl]
- res 4, [hl]
- ld hl, wd72d
- res 5, [hl]
- call UpdateSprites
- ld hl, wd126
- set 5, [hl]
- set 6, [hl]
- xor a
- ld [wJoyIgnore], a
-
-OverworldLoop:: ; 0242 (0:0242)
- call DelayFrame
-OverworldLoopLessDelay:: ; 0245 (0:0245)
- call DelayFrame
- call Func_342a
- call LoadGBPal
- ld a,[wWalkCounter]
- and a
- jp nz,.moveAhead ; if the player sprite has not yet completed the walking animation
- call JoypadOverworld ; get joypad state (which is possibly simulated)
- callba SafariZoneCheck
- ld a,[wSafariZoneGameOver]
- and a
- jp nz,WarpFound2
- ld hl,wd72d
- bit 3,[hl]
- res 3,[hl]
- jp nz,WarpFound2
- ld a,[wd732]
- and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
- jp nz,HandleFlyWarpOrDungeonWarp
- ld a,[W_CUROPPONENT]
- and a
- jp nz,.newBattle
- ld a,[wd730]
- bit 7,a ; are we simulating button presses?
- jr z,.notSimulating
- ld a,[hJoyHeld]
- jr .checkIfStartIsPressed
-.notSimulating
- ld a,[hJoyPressed]
-.checkIfStartIsPressed
- bit 3,a ; start button
- jr z,.startButtonNotPressed
-; if START is pressed
- xor a
- ld [hSpriteIndexOrTextID],a ; start menu text ID
- jp .displayDialogue
-.startButtonNotPressed
- bit 0,a ; A button
- jp z,.checkIfDownButtonIsPressed
-; if A is pressed
- ld a,[wd730]
- bit 2,a
- jp nz,.noDirectionButtonsPressed
- call IsPlayerCharacterBeingControlledByGame
- jr nz,.checkForOpponent
- call CheckForHiddenObjectOrBookshelfOrCardKeyDoor
- ld a,[$ffeb]
- and a
- jp z,OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found
- xor a
- ld [wd436],a ; new yellow address
- call IsSpriteOrSignInFrontOfPlayer
- call Func_0ffe
- ld a,[hSpriteIndexOrTextID]
- and a
- jp z,OverworldLoop
-.displayDialogue
- predef GetTileAndCoordsInFrontOfPlayer
- call UpdateSprites
- ld a,[wFlags_0xcd60]
- bit 2,a
- jr nz,.checkForOpponent
- bit 0,a
- jr nz,.checkForOpponent
- aCoord 8, 9
- ld [wcf0e],a
- call DisplayTextID ; display either the start menu or the NPC/sign text
- ld a,[wcc47]
- and a
- jr z,.checkForOpponent
- xor a
- ld [wcc47],a
- jp EnterMap
-; predef LoadSAV
-; ld a,[W_CURMAP]
-; ld [wDestinationMap],a
-; call SpecialWarpIn
-; ld a,[W_CURMAP]
-; call SwitchToMapRomBank ; switch to the ROM bank of the current map
-; ld hl,W_CURMAPTILESET
-; set 7,[hl]
-.checkForOpponent
- ld a,[W_CUROPPONENT]
- and a
- jp nz,.newBattle
- jp OverworldLoop
-.noDirectionButtonsPressed
- call UpdateSprites ; 231c
- ld hl,wFlags_0xcd60
- res 2,[hl]
- xor a
- ld [wd435], a
- ld a, $1
- ld a,$01
- ld [wcc4b],a
- ld a,[wd528] ; the direction that was pressed last time
- and a
- jr z, .overworldloop
-; if a direction was pressed last time
- ld [wd529],a ; save the last direction
- xor a
- ld [wd528],a ; zero the direction
-.overworldloop
- jp OverworldLoop
-.checkIfDownButtonIsPressed
- ld a,[hJoyHeld] ; current joypad state
- bit 7,a ; down button
- jr z,.checkIfUpButtonIsPressed
- ld a,$01
- ld [wSpriteStateData1 + 3],a
- ld a,$04
- jr .handleDirectionButtonPress
-.checkIfUpButtonIsPressed
- bit 6,a ; up button
- jr z,.checkIfLeftButtonIsPressed
- ld a,$ff
- ld [wSpriteStateData1 + 3],a
- ld a,$08
- jr .handleDirectionButtonPress
-.checkIfLeftButtonIsPressed
- bit 5,a ; left button
- jr z,.checkIfRightButtonIsPressed
- ld a,$ff
- ld [wSpriteStateData1 + 5],a
- ld a,$02
- jr .handleDirectionButtonPress
-.checkIfRightButtonIsPressed
- bit 4,a ; right button
- jr z,.noDirectionButtonsPressed
- ld a,$01
- ld [wSpriteStateData1 + 5],a
-.handleDirectionButtonPress
- ld [wd52a],a ; new direction
- ld a,[wd730]
- bit 7,a ; are we simulating button presses?
- jr nz,.noDirectionChange ; ignore direction changes if we are
- ld a,[wcc4b]
- and a
- jr z,.noDirectionChange
- ld a,[wd52a] ; new direction
- ld b,a
- ld a,[wd529] ; old direction
- cp b
- jr z,.noDirectionChange
- ld a,$8
- ld [wd434],a
-; unlike in red/blue, yellow does not have the 180 degrees odd code
- ld hl,wFlags_0xcd60
- set 2,[hl]
- xor a
- ld [wcc4b],a
- ld a,[wd52a]
- ld [wd528],a
- call NewBattle
- jp c,.battleOccurred
- jp OverworldLoop
-.noDirectionChange
- ld a,[wd52a] ; current direction
- ld [wd528],a ; save direction
- call UpdateSprites
- ld a,[wWalkBikeSurfState]
- cp a,$02 ; surfing
- jr z,.surfing
-; not surfing
- call CollisionCheckOnLand
- jr nc,.noCollision
-; collision occurred
- push hl
- ld hl,wd736
- bit 2,[hl] ; standing on warp flag
- pop hl
- jp z,OverworldLoop
-; collision occurred while standing on a warp
- push hl
- call ExtraWarpCheck ; sets carry if there is a potential to warp
- pop hl
- jp c,CheckWarpsCollision
- jp OverworldLoop
-.surfing
- call CollisionCheckOnWater
- jp c,OverworldLoop
-.noCollision
- ld a,$08
- ld [wWalkCounter],a
- callab Func_fcc08
- jr .moveAhead2
-.moveAhead
- call IsSpinning
- call UpdateSprites ; move sprites
-.moveAhead2
- ld hl,wFlags_0xcd60
- res 2,[hl]
- xor a
- ld [wd435],a
- call DoBikeSpeedup
- call AdvancePlayerSprite
- ld a,[wWalkCounter]
- and a
- jp nz,CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works)
-; walking animation finished
- call StepCountCheck
- ld a,[wd790]
- bit 7,a ; in the safari zone?
- jr z,.notSafariZone
- callba SafariZoneCheckSteps
- ld a,[wSafariZoneGameOver]
- and a
- jp nz,WarpFound2
-.notSafariZone
- ld a,[W_ISINBATTLE]
- and a
- jp nz,CheckWarpsNoCollision
- predef ApplyOutOfBattlePoisonDamage ; also increment daycare mon exp
- ld a,[wd12d]
- and a
- jp nz,HandleBlackOut ; if all pokemon fainted
-.newBattle
- call NewBattle
- ld hl,wd736
- res 2,[hl] ; standing on warp flag
- jp nc,CheckWarpsNoCollision ; check for warps if there was no battle
-.battleOccurred
- ld hl,wd72d
- res 6,[hl]
- ld hl,W_FLAGS_D733
- res 3,[hl]
- ld hl,wd126
- set 5,[hl]
- set 6,[hl]
- xor a
- ld [hJoyHeld],a
- ld a,[W_CURMAP]
- cp a,CINNABAR_GYM
- jr nz,.notCinnabarGym
- ld hl,wd79b
- set 7,[hl]
-.notCinnabarGym
- ld hl,wd72e
- set 5,[hl]
- ld a,[W_CURMAP]
- cp a,OAKS_LAB
- jp z,.noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab
- callab AnyPartyAlive
- ld a,d
- and a
- jr z,.allPokemonFainted
-.noFaintCheck
- ld c,$0a
- call DelayFrames
- jp EnterMap
-;.allPokemonFainted
-; ld a,$ff
-; ld [W_ISINBATTLE],a
-; call RunMapScript
-; jp HandleBlackOut
-
-StepCountCheck:: ; 0457 (0:0457)
- ld a,[wd730]
- bit 7,a
- jr nz,.doneStepCounting ; if button presses are being simulated, don't count steps
-; step counting
- ld hl,wStepCounter
- dec [hl]
- ld a,[wd72c]
- bit 0,a
- jr z,.doneStepCounting
- ld hl,wNumberOfNoRandomBattleStepsLeft
- dec [hl]
- jr nz,.doneStepCounting
- ld hl,wd72c
- res 0,[hl] ; indicate that the player has stepped thrice since the last battle
-.doneStepCounting
- ret
-
-; function to determine if there will be a battle and execute it (either a trainer battle or wild battle)
-; sets carry if a battle occurred and unsets carry if not
-NewBattle:: ; 0480 (0:0480)
- ld a,[wd72d]
- bit 4,a
- jr nz,.noBattle
- call IsPlayerCharacterBeingControlledByGame
- jr nz,.noBattle ; no battle if the player character is under the game's control
- ld a,[wd72e]
- bit 4,a
- jr nz,.noBattle
- ld b, BANK(InitBattle)
- ld hl, InitBattle ; 3d:5ff2
- jp Bankswitch
-.noBattle
- and a
- ret
-
-DoBikeSpeedup:: ; 049d (0:049d)
- ld a,[wWalkBikeSurfState]
- dec a ; riding a bike?
- ret nz
- ld a,[wd736]
- bit 6,a
- ret nz
- ld a,[wNPCMovementScriptPointerTableNum]
- and a
- ret nz
- ld a,[W_CURMAP]
- cp ROUTE_17 ; cycling road
- jr nz,.goFaster
- ld a,[hJoyHeld]
- and a,D_UP | D_LEFT | D_RIGHT
- ret nz
-.goFaster
- call AdvancePlayerSprite
- ret
-
-; check if the player has stepped onto a warp after having not collided
-CheckWarpsNoCollision:: ; 04bd (0:04bd)
- ld a,[wNumberOfWarps]
- and a
- jp z,CheckMapConnections
- ld b,0
- ld a,[wNumberOfWarps]
- ld c,a
- ld a,[W_YCOORD]
- ld d,a
- ld a,[W_XCOORD]
- ld e,a
- ld hl,wWarpEntries
-CheckWarpsNoCollisionLoop:: ; 04d5 (0:04d5)
- ld a,[hli] ; check if the warp's Y position matches
- cp d
- jr nz,CheckWarpsNoCollisionRetry1
- ld a,[hli] ; check if the warp's X position matches
- cp e
- jr nz,CheckWarpsNoCollisionRetry2
-; if a match was found
- push hl
- push bc
- ld hl,wd736
- set 2,[hl] ; standing on warp flag
- callba IsPlayerStandingOnDoorTileOrWarpTile
- pop bc
- pop hl
- jr c,WarpFound1 ; jump if standing on door or warp
- push hl
- push bc
- call ExtraWarpCheck
- pop bc
- pop hl
- jr nc,CheckWarpsNoCollisionRetry2
-; if the extra check passed
- ld a,[W_FLAGS_D733]
- bit 2,a
- jr nz,WarpFound1
- push de
- push bc
- call Joypad
- pop bc
- pop de
- ld a,[hJoyHeld]
- and a,D_DOWN | D_UP | D_LEFT | D_RIGHT
- jr z,CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp
- jr WarpFound1
-
-CheckWarpsNoCollisionRetry1:: ; 050f (0:050f)
- inc hl
-CheckWarpsNoCollisionRetry2:: ; 0510 (0:0510)
- inc hl
- inc hl
-ContinueCheckWarpsNoCollisionLoop:: ; 0512 (0:0512)
- inc b ; increment warp number
- dec c ; decrement number of warps
- jp nz,CheckWarpsNoCollisionLoop
- jp CheckMapConnections
-
-; check if the player has stepped onto a warp after having collided
-CheckWarpsCollision:: ; 0706 (0:0706)
- ld a,[wNumberOfWarps]
- ld c,a
- ld hl,wWarpEntries
-.loop
- ld a,[hli] ; Y coordinate of warp
- ld b,a
- ld a,[W_YCOORD]
- cp b
- jr nz,.retry1
- ld a,[hli] ; X coordinate of warp
- ld b,a
- ld a,[W_XCOORD]
- cp b
- jr nz,.retry2
- ld a,[hli]
- ld [wDestinationWarpID],a
- ld a,[hl]
- ld [$ff8b],a ; save target map
- jr WarpFound2
-.retry1
- inc hl
-.retry2
- inc hl
- inc hl
- dec c
- jr nz,.loop
- jp OverworldLoop
-
-WarpFound1:: ; 0735 (0:0735)
- ld a,[hli]
- ld [wDestinationWarpID],a
- ld a,[hli]
- ld [$ff8b],a ; save target map
-
-WarpFound2:: ; 073c (0:073c)
- ld a,[wNumberOfWarps]
- sub c
- ld [wd73b],a ; save ID of used warp
- ld a,[W_CURMAP]
- ld [wd73c],a
- call CheckIfInOutsideMap
- jr nz,.indoorMaps
-; this is for handling "outside" maps that can't have the 0xFF destination map
- ld a,[W_CURMAP]
- ld [wLastMap],a
- ld a,[W_CURMAPWIDTH]
- ld [wd366],a
- ld a,[$ff8b] ; destination map number
- ld [W_CURMAP],a ; change current map to destination map
- cp a,ROCK_TUNNEL_1
- jr nz,.notRockTunnel
- ld a,$06
- ld [wMapPalOffset],a
- call GBFadeOutToBlack
-.notRockTunnel
- callab Func_fc5fa ; 3f:45fa
- call PlayMapChangeSound
- jr .done
-; for maps that can have the 0xFF destination map, which means to return to the outside map; not all these maps are necessarily indoors, though
-.indoorMaps
- ld a,[$ff8b] ; destination map
- cp a,$ff
- jr z,.goBackOutside
-; if not going back to the previous map
- ld [W_CURMAP],a ; current map number
- callba IsPlayerStandingOnWarpPadOrHole
- ld a,[wcd5b]
- dec a ; is the player on a warp pad?
- jr nz,.notWarpPad
-; if the player is on a warp pad
- call LeaveMapAnim
- ld hl,wd732
- set 3,[hl]
- jr .skipMapChangeSound
-.notWarpPad
- call PlayMapChangeSound
-.skipMapChangeSound
- ld hl,wd736
- res 0,[hl]
- res 1,[hl]
- callab Func_fc65b ; 3f:465b
- jr .done
-.goBackOutside
- callab Func_fc69a ; 3f:469a
- ; continue from here
- ld a,[wLastMap]
- ld [W_CURMAP],a
- call PlayMapChangeSound
- xor a
- ld [wMapPalOffset],a
-.done
- ld hl,wd736
- set 0,[hl] ; have the player's sprite step out from the door (if there is one)
- call IgnoreInputForHalfSecond
- jp EnterMap
-
-; if no matching warp was found
-CheckMapConnections:: ; 05db (0:05db)
-.checkWestMap
- ld a,[W_XCOORD]
- cp a,$ff
- jr nz,.checkEastMap
- ld a,[W_MAPCONN3PTR]
- ld [W_CURMAP],a
- ld a,[wd38f] ; new X coordinate upon entering west map
- ld [W_XCOORD],a
- ld a,[W_YCOORD]
- ld c,a
- ld a,[wd38e] ; Y adjustment upon entering west map
- add c
- ld c,a
- ld [W_YCOORD],a
- ld a,[wd390] ; pointer to upper left corner of map without adjustment for Y position
- ld l,a
- ld a,[wd391]
- ld h,a
- srl c
- jr z,.savePointer1
-.pointerAdjustmentLoop1
- ld a,[wd38d] ; width of connected map
- add a,$06
- ld e,a
- ld d,$00
- ld b,$00
- add hl,de
- dec c
- jr nz,.pointerAdjustmentLoop1
-.savePointer1
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
- jp .loadNewMap
-.checkEastMap
- ld b,a
- ld a,[wd525] ; map width
- cp b
- jr nz,.checkNorthMap
- ld a,[W_MAPCONN4PTR]
- ld [W_CURMAP],a
- ld a,[wd39a] ; new X coordinate upon entering east map
- ld [W_XCOORD],a
- ld a,[W_YCOORD]
- ld c,a
- ld a,[wd399] ; Y adjustment upon entering east map
- add c
- ld c,a
- ld [W_YCOORD],a
- ld a,[wd39b] ; pointer to upper left corner of map without adjustment for Y position
- ld l,a
- ld a,[wd39c]
- ld h,a
- srl c
- jr z,.savePointer2
-.pointerAdjustmentLoop2
- ld a,[wd398]
- add a,$06
- ld e,a
- ld d,$00
- ld b,$00
- add hl,de
- dec c
- jr nz,.pointerAdjustmentLoop2
-.savePointer2
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
- jp .loadNewMap
-.checkNorthMap
- ld a,[W_YCOORD]
- cp a,$ff
- jr nz,.checkSouthMap
- ld a,[W_MAPCONN1PTR]
- ld [W_CURMAP],a
- ld a,[wd378] ; new Y coordinate upon entering north map
- ld [W_YCOORD],a
- ld a,[W_XCOORD]
- ld c,a
- ld a,[wd379] ; X adjustment upon entering north map
- add c
- ld c,a
- ld [W_XCOORD],a
- ld a,[wd37a] ; pointer to upper left corner of map without adjustment for X position
- ld l,a
- ld a,[wd37b]
- ld h,a
- ld b,$00
- srl c
- add hl,bc
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
- jp .loadNewMap
-.checkSouthMap
- ld b,a
- ld a,[wd524]
- cp b
- jr nz,.didNotEnterConnectedMap
- ld a,[W_MAPCONN2PTR]
- ld [W_CURMAP],a
- ld a,[wd383] ; new Y coordinate upon entering south map
- ld [W_YCOORD],a
- ld a,[W_XCOORD]
- ld c,a
- ld a,[wd384] ; X adjustment upon entering south map
- add c
- ld c,a
- ld [W_XCOORD],a
- ld a,[wd385] ; pointer to upper left corner of map without adjustment for X position
- ld l,a
- ld a,[wd386]
- ld h,a
- ld b,$00
- srl c
- add hl,bc
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
-.loadNewMap ; load the connected map that was entered
- call LoadMapHeader
- call Func_2312 ; music
- ld b,$09
- call GoPAL_SET
-; Since the sprite set shouldn't change, this will just update VRAM slots at
-; $C2XE without loading any tile patterns.
- callba InitMapSprites
- call LoadTileBlockMap
- jp OverworldLoopLessDelay
-.didNotEnterConnectedMap
- jp OverworldLoop
-
-; function to play a sound when changing maps
-PlayMapChangeSound:: ; 08c9 (0:08c9)
- aCoord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on
- cp a,$0b ; door tile in tileset 0
- jr nz,.didNotGoThroughDoor
- ld a,(SFX_02_57 - SFX_Headers_02) / 3
- jr .playSound
-.didNotGoThroughDoor
- ld a,(SFX_02_5c - SFX_Headers_02) / 3
-.playSound
- call PlaySound
- ld a,[wMapPalOffset]
- and a
- ret nz
- jp GBFadeOutToBlack
-
-CheckIfInOutsideMap:: ; 08e1 (0:08e1)
-; If the player is in an outside map (a town or route), set the z flag
- ld a, [W_CURMAPTILESET]
- and a ; most towns/routes have tileset 0 (OVERWORLD)
- ret z
- cp PLATEAU ; Route 23 / Indigo Plateau
- ret
-
-; this function is an extra check that sometimes has to pass in order to warp, beyond just standing on a warp
-; the "sometimes" qualification is necessary because of CheckWarpsNoCollision's behavior
-; depending on the map, either "function 1" or "function 2" is used for the check
-; "function 1" passes when the player is at the edge of the map and is facing towards the outside of the map
-; "function 2" passes when the the tile in front of the player is among a certain set
-; sets carry if the check passes, otherwise clears carry
-ExtraWarpCheck:: ; 08e9 (0:08e9)
- ld a, [W_CURMAP]
- cp SS_ANNE_3
- jr z, .useFunction1
- cp ROCKET_HIDEOUT_1
- jr z, .useFunction2
- cp ROCKET_HIDEOUT_2
- jr z, .useFunction2
- cp ROCKET_HIDEOUT_4
- jr z, .useFunction2
- cp ROCK_TUNNEL_1
- jr z, .useFunction2
- ld a, [W_CURMAPTILESET]
- and a ; outside tileset (OVERWORLD)
- jr z, .useFunction2
- cp SHIP ; S.S. Anne tileset
- jr z, .useFunction2
- cp SHIP_PORT ; Vermilion Port tileset
- jr z, .useFunction2
- cp PLATEAU ; Indigo Plateau tileset
- jr z, .useFunction2
-.useFunction1
- ld hl, IsPlayerFacingEdgeOfMap
- jr .doBankswitch
-.useFunction2
- ld hl, IsWarpTileInFrontOfPlayer
-.doBankswitch
- ld b, BANK(IsWarpTileInFrontOfPlayer)
- jp Bankswitch
-
-MapEntryAfterBattle:: ; 091f (0:091f)
- callba IsPlayerStandingOnWarp ; for enabling warp testing after collisions
- ld a,[wMapPalOffset]
- and a
- jp z,GBFadeInFromWhite
- jp LoadGBPal
-
-HandleBlackOut::
-; For when all the player's pokemon faint.
-; Does not print the "blacked out" message.
-
- call GBFadeOutToBlack
- ld a, $08
- call StopMusic
- ld hl, wd72e
- res 5, [hl]
- ld a, Bank(ResetStatusAndHalveMoneyOnBlackout) ; also Bank(SpecialWarpIn) and Bank(SpecialEnterMap)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- call ResetStatusAndHalveMoneyOnBlackout
- call SpecialWarpIn
- call Func_2312
- jp SpecialEnterMap
-
-StopMusic::
- ld [wMusicHeaderPointer], a
- ld a, $ff
- ld [wc0ee], a
- call PlaySound
-.wait
- ld a, [wMusicHeaderPointer]
- and a
- jr nz, .wait
- jp StopAllSounds
-
-HandleFlyWarpOrDungeonWarp:: ; 0794 (0:0794)
- call UpdateSprites
- call Delay3
- xor a
- ld [wBattleResult], a
- ld [wWalkBikeSurfState], a
- ld [W_ISINBATTLE], a
- ld [wMapPalOffset], a
- ld hl, wd732
- set 2, [hl] ; fly warp or dungeon warp
- res 5, [hl] ; forced to ride bike
- call LeaveMapAnim
- ld a, Bank(SpecialWarpIn)
- ld [H_LOADEDROMBANK], a
- ld [$2000], a
- call SpecialWarpIn
- jp SpecialEnterMap
-
-LeaveMapAnim:: ; 07bc (0:07bc)
- ld b, BANK(_LeaveMapAnim)
- ld hl, _LeaveMapAnim
- jp Bankswitch
-
-LoadPlayerSpriteGraphics::
-; Load sprite graphics based on whether the player is standing, biking, or surfing.
-
- ; 0: standing
- ; 1: biking
- ; 2: surfing
-
- ld a, [wWalkBikeSurfState]
- dec a
- jr z, .ridingBike
-
- ld a, [hTilesetType]
- and a
- jr nz, .determineGraphics
- jr .startWalking
-
-.ridingBike
- ; If the bike can't be used,
- ; start walking instead.
- call IsBikeRidingAllowed
- jr c, .determineGraphics
-
-.startWalking
- xor a
- ld [wWalkBikeSurfState], a
- ld [wWalkBikeSurfStateCopy], a
- jp LoadWalkingPlayerSpriteGraphics
-
-.determineGraphics
- ld a, [wWalkBikeSurfState]
- and a
- jp z, LoadWalkingPlayerSpriteGraphics
- dec a
- jp z, LoadBikePlayerSpriteGraphics
- dec a
- jp z, LoadSurfingPlayerSpriteGraphics
- jp LoadWalkingPlayerSpriteGraphics
-
-IsBikeRidingAllowed::
-; The bike can be used on Route 23 and Indigo Plateau,
-; or maps with tilesets in BikeRidingTilesets.
-; Return carry if biking is allowed.
-
- ld a, [W_CURMAP]
- cp ROUTE_23
- jr z, .allowed
- cp INDIGO_PLATEAU
- jr z, .allowed
-
- ld a, [W_CURMAPTILESET]
- ld b, a
- ld hl, BikeRidingTilesets
-.loop
- ld a, [hli]
- cp b
- jr z, .allowed
- inc a
- jr nz, .loop
- and a
- ret
-
-.allowed
- scf
- ret
-
-INCLUDE "data/bike_riding_tilesets.asm"
-
-; load the tile pattern data of the current tileset into VRAM
-LoadTilesetTilePatternData:: ; 09e8 (0:09e8)
- ld a,[W_TILESETGFXPTR]
- ld l,a
- ld a,[W_TILESETGFXPTR + 1]
- ld h,a
- ld de,vTileset
- ld bc,$600
- ld a,[W_TILESETBANK]
- jp FarCopyData2
-
-; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8
-; it can also load partial tile maps of connected maps into a border of length 3 around the current map
-LoadTileBlockMap:: ; 09fc (0:09fc)
-; fill C6E8-CBFB with the background tile
- ld hl,wOverworldMap
- ld a,[wd3ad] ; background tile number
- ld d,a
- ld bc,$0514
-.backgroundTileLoop
- ld a,d
- ld [hli],a
- dec bc
- ld a,c
- or b
- jr nz,.backgroundTileLoop
-; load tile map of current map (made of tile block IDs)
-; a 3-byte border at the edges of the map is kept so that there is space for map connections
- ld hl,wOverworldMap
- ld a,[W_CURMAPWIDTH]
- ld [$ff8c],a
- add a,$06 ; border (east and west)
- ld [$ff8b],a ; map width + border
- ld b,$00
- ld c,a
-; make space for north border (next 3 lines)
- add hl,bc
- add hl,bc
- add hl,bc
- ld c,$03
- add hl,bc ; this puts us past the (west) border
- ld a,[W_MAPDATAPTR] ; tile map pointer
- ld e,a
- ld a,[W_MAPDATAPTR + 1]
- ld d,a ; de = tile map pointer
- ld a,[W_CURMAPHEIGHT]
- ld b,a
-.rowLoop ; copy one row each iteration
- push hl
- ld a,[$ff8c] ; map width (without border)
- ld c,a
-.rowInnerLoop
- ld a,[de]
- inc de
- ld [hli],a
- dec c
- jr nz,.rowInnerLoop
-; add the map width plus the border to the base address of the current row to get the next row's address
- pop hl
- ld a,[$ff8b] ; map width + border
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- dec b
- jr nz,.rowLoop
-.northConnection
- ld a,[W_MAPCONN1PTR]
- cp a,$ff
- jr z,.southConnection
- call SwitchToMapRomBank
- ld a,[wd372]
- ld l,a
- ld a,[wd373]
- ld h,a
- ld a,[wd374]
- ld e,a
- ld a,[wd375]
- ld d,a
- ld a,[wd376]
- ld [$ff8b],a
- ld a,[wd377]
- ld [$ff8c],a
- call LoadNorthSouthConnectionsTileMap
-.southConnection
- ld a,[W_MAPCONN2PTR]
- cp a,$ff
- jr z,.westConnection
- call SwitchToMapRomBank
- ld a,[wd37d]
- ld l,a
- ld a,[wd37e]
- ld h,a
- ld a,[wd37f]
- ld e,a
- ld a,[wd380]
- ld d,a
- ld a,[wd381]
- ld [$ff8b],a
- ld a,[wd382]
- ld [$ff8c],a
- call LoadNorthSouthConnectionsTileMap
-.westConnection
- ld a,[W_MAPCONN3PTR]
- cp a,$ff
- jr z,.eastConnection
- call SwitchToMapRomBank
- ld a,[wd388]
- ld l,a
- ld a,[wd389]
- ld h,a
- ld a,[wd38a]
- ld e,a
- ld a,[wd38b]
- ld d,a
- ld a,[wd38c]
- ld b,a
- ld a,[wd38d]
- ld [$ff8b],a
- call LoadEastWestConnectionsTileMap
-.eastConnection
- ld a,[W_MAPCONN4PTR]
- cp a,$ff
- jr z,.done
- call SwitchToMapRomBank
- ld a,[wd393]
- ld l,a
- ld a,[wd394]
- ld h,a
- ld a,[wd395]
- ld e,a
- ld a,[wd396]
- ld d,a
- ld a,[wd397]
- ld b,a
- ld a,[wd398]
- ld [$ff8b],a
- call LoadEastWestConnectionsTileMap
-.done
- ret
-
-LoadNorthSouthConnectionsTileMap:: ; 0ade (0:0ade)
- ld c,$03
-.loop
- push de
- push hl
- ld a,[$ff8b] ; width of connection
- ld b,a
-.innerLoop
- ld a,[hli]
- ld [de],a
- inc de
- dec b
- jr nz,.innerLoop
- pop hl
- pop de
- ld a,[$ff8c] ; width of connected map
- add l
- ld l,a
- jr nc,.noCarry1
- inc h
-.noCarry1
- ld a,[W_CURMAPWIDTH]
- add a,$06
- add e
- ld e,a
- jr nc,.noCarry2
- inc d
-.noCarry2
- dec c
- jr nz,.loop
- ret
-
-LoadEastWestConnectionsTileMap:: ; 0b02 (0:0b02)
- push hl
- push de
- ld c,$03
-.innerLoop
- ld a,[hli]
- ld [de],a
- inc de
- dec c
- jr nz,.innerLoop
- pop de
- pop hl
- ld a,[$ff8b] ; width of connected map
- add l
- ld l,a
- jr nc,.noCarry1
- inc h
-.noCarry1
- ld a,[W_CURMAPWIDTH]
- add a,$06
- add e
- ld e,a
- jr nc,.noCarry2
- inc d
-.noCarry2
- dec b
- jr nz,LoadEastWestConnectionsTileMap
- ret
-
-; function to check if there is a sign or sprite in front of the player
-; if so, it is stored in [hSpriteIndexOrTextID]
-; if not, [hSpriteIndexOrTextID] is set to 0
-IsSpriteOrSignInFrontOfPlayer:: ; 0b23 (0:0b23)
- xor a
- ld [hSpriteIndexOrTextID],a
- ld a,[wd4b0] ; number of signs in the map
- and a
- jr z,.extendRangeOverCounter
-; if there are signs
- predef GetTileAndCoordsInFrontOfPlayer ; get the coordinates in front of the player in de
- ld hl,wd4b1 ; start of sign coordinates
- ld a,[wd4b0] ; number of signs in the map
- ld b,a
- ld c,$00
-.signLoop
- inc c
- ld a,[hli] ; sign Y
- cp d
- jr z,.yCoordMatched
- inc hl
- jr .retry
-.yCoordMatched
- ld a,[hli] ; sign X
- cp e
- jr nz,.retry
-.xCoordMatched
-; found sign
- push hl
- push bc
- ld hl,wd4d1 ; start of sign text ID's
- ld b,$00
- dec c
- add hl,bc
- ld a,[hl]
- ld [hSpriteIndexOrTextID],a ; store sign text ID
- pop bc
- pop hl
- ret
-.retry
- dec b
- jr nz,.signLoop
-; check if the player is front of a counter in a pokemon center, pokemart, etc. and if so, extend the range at which he can talk to the NPC
-.extendRangeOverCounter
- predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player in c
- ld hl,W_TILESETTALKINGOVERTILES ; list of tiles that extend talking range (counter tiles)
- ld b,$03
- ld d,$20 ; talking range in pixels (long range)
-.counterTilesLoop
- ld a,[hli]
- cp c
- jr z,IsSpriteInFrontOfPlayer2 ; jumps if the tile in front of the player is a counter tile
- dec b
- jr nz,.counterTilesLoop
-
-; part of the above function, but sometimes its called on its own, when signs are irrelevant
-; the caller must zero [hSpriteIndexOrTextID]
-IsSpriteInFrontOfPlayer:: ; 0b6b (0:0b6b)
- ld d,$10 ; talking range in pixels (normal range)
-IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
- ld bc,$3c40 ; Y and X position of player sprite
- ld a,[wSpriteStateData1 + 9] ; direction the player is facing
-.checkIfPlayerFacingUp
- cp a,$04
- jr nz,.checkIfPlayerFacingDown
-; facing up
- ld a,b
- sub d
- ld b,a
- ld a,$08
- jr .doneCheckingDirection
-.checkIfPlayerFacingDown
- cp a,$00
- jr nz,.checkIfPlayerFacingRight
-; facing down
- ld a,b
- add d
- ld b,a
- ld a,$04
- jr .doneCheckingDirection
-.checkIfPlayerFacingRight
- cp a,$0c
- jr nz,.playerFacingLeft
-; facing right
- ld a,c
- add d
- ld c,a
- ld a,$01
- jr .doneCheckingDirection
-.playerFacingLeft
-; facing left
- ld a,c
- sub d
- ld c,a
- ld a,$02
-.doneCheckingDirection
- ld [wd52a],a
- ld a,[W_NUMSPRITES] ; number of sprites
- and a
- ret z
-; if there are sprites
- ld hl,wSpriteStateData1 + $10
- ld d,a
- ld e,$01
-.spriteLoop
- push hl
- ld a,[hli] ; image (0 if no sprite)
- and a
- jr z,.nextSprite
- inc l
- ld a,[hli] ; sprite visibility
- inc a
- jr z,.nextSprite
- inc l
- ld a,[hli] ; Y location
- cp b
- jr nz,.nextSprite
- inc l
- ld a,[hl] ; X location
- cp c
- jr z,.foundSpriteInFrontOfPlayer
-.nextSprite
- pop hl
- ld a,l
- add a,$10
- ld l,a
- inc e
- dec d
- jr nz,.spriteLoop
- ret
-.foundSpriteInFrontOfPlayer
- pop hl
- ld a,l
- and a,$f0
- inc a
- ld l,a
- set 7,[hl]
- ld a,e
- ld [hSpriteIndexOrTextID],a
- ret
-
-; function to check if the player will jump down a ledge and check if the tile ahead is passable (when not surfing)
-; sets the carry flag if there is a collision, and unsets it if there isn't a collision
-CollisionCheckOnLand:: ; 0bd1 (0:0bd1)
- ld a,[wd736]
- bit 6,a ; is the player jumping?
- jr nz,.noCollision
-; if not jumping a ledge
- ld a,[wSimulatedJoypadStatesIndex]
- and a
- jr nz,.noCollision ; no collisions when the player's movements are being controlled by the game
- ld a,[wd52a] ; the direction that the player is trying to go in
- ld d,a
- ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
- and d ; check if a sprite is in the direction the player is trying to go
- jr nz,.collision
- xor a
- ld [hSpriteIndexOrTextID],a
- call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision?
- ld a,[hSpriteIndexOrTextID]
- and a ; was there a sprite collision?
- jr nz,.collision
-; if no sprite collision
- ld hl,TilePairCollisionsLand
- call CheckForJumpingAndTilePairCollisions
- jr c,.collision
- call CheckTilePassable
- jr nc,.noCollision
-.collision
- ld a,[wc02a]
- cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
- jr z,.setCarry
- ld a,(SFX_02_5b - SFX_Headers_02) / 3
- call PlaySound ; play collision sound (if it's not already playing)
-.setCarry
- scf
- ret
-.noCollision
- and a
- ret
-
-; function that checks if the tile in front of the player is passable
-; clears carry if it is, sets carry if not
-CheckTilePassable:: ; 0c10 (0:0c10)
- predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player
- ld a,[wTileInFrontOfPlayer] ; tile in front of player
- ld c,a
- ld hl,W_TILESETCOLLISIONPTR ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl now points to passable tiles
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.tileNotPassable
- cp c
- ret z
- jr .loop
-.tileNotPassable
- scf
- ret
-
-; check if the player is going to jump down a small ledge
-; and check for collisions that only occur between certain pairs of tiles
-; Input: hl - address of directional collision data
-; sets carry if there is a collision and unsets carry if not
-CheckForJumpingAndTilePairCollisions:: ; 0c2a (0:0c2a)
- push hl
- predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player
- push de
- push bc
- callba HandleLedges ; check if the player is trying to jump a ledge
- pop bc
- pop de
- pop hl
- and a
- ld a,[wd736]
- bit 6,a ; is the player jumping?
- ret nz
-; if not jumping
-
-CheckForTilePairCollisions2:: ; 0c44 (0:0c44)
- aCoord 8, 9 ; tile the player is on
- ld [wcf0e],a
-
-CheckForTilePairCollisions:: ; 0c4a (0:0c4a)
- ld a,[wTileInFrontOfPlayer]
- ld c,a
-.tilePairCollisionLoop
- ld a,[W_CURMAPTILESET] ; tileset number
- ld b,a
- ld a,[hli]
- cp a,$ff
- jr z,.noMatch
- cp b
- jr z,.tilesetMatches
- inc hl
-.retry
- inc hl
- jr .tilePairCollisionLoop
-.tilesetMatches
- ld a,[wcf0e] ; tile the player is on
- ld b,a
- ld a,[hl]
- cp b
- jr z,.currentTileMatchesFirstInPair
- inc hl
- ld a,[hl]
- cp b
- jr z,.currentTileMatchesSecondInPair
- jr .retry
-.currentTileMatchesFirstInPair
- inc hl
- ld a,[hl]
- cp c
- jr z,.foundMatch
- jr .tilePairCollisionLoop
-.currentTileMatchesSecondInPair
- dec hl
- ld a,[hli]
- cp c
- inc hl
- jr nz,.tilePairCollisionLoop
-.foundMatch
- scf
- ret
-.noMatch
- and a
- ret
-
-; FORMAT: tileset number, tile 1, tile 2
-; terminated by 0xFF
-; these entries indicate that the player may not cross between tile 1 and tile 2
-; it's mainly used to simulate differences in elevation
-
-TilePairCollisionsLand:: ; 0c7e (0:0c7e)
- db CAVERN, $20, $05
- db CAVERN, $41, $05
- db FOREST, $30, $2E
- db CAVERN, $2A, $05
- db CAVERN, $05, $21
- db FOREST, $52, $2E
- db FOREST, $55, $2E
- db FOREST, $56, $2E
- db FOREST, $20, $2E
- db FOREST, $5E, $2E
- db FOREST, $5F, $2E
- db $FF
-
-TilePairCollisionsWater:: ; 0ca0 (0:0ca0)
- db FOREST, $14, $2E
- db FOREST, $48, $2E
- db CAVERN, $14, $05
- db $FF
-
-; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character
-LoadCurrentMapView:: ; 0caa (0:0caa)
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,[W_TILESETBANK] ; tile data ROM bank
- ld [H_LOADEDROMBANK],a
- ld [$2000],a ; switch to ROM bank that contains tile data
- ld a,[wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view
- ld e,a
- ld a,[wCurrentTileBlockMapViewPointer + 1]
- ld d,a
- ld hl,wTileMapBackup
- ld b,$05
-.rowLoop ; each loop iteration fills in one row of tile blocks
- push hl
- push de
- ld c,$06
-.rowInnerLoop ; loop to draw each tile block of the current row
- push bc
- push de
- push hl
- ld a,[de]
- ld c,a ; tile block number
- call DrawTileBlock
- pop hl
- pop de
- pop bc
- inc hl
- inc hl
- inc hl
- inc hl
- inc de
- dec c
- jr nz,.rowInnerLoop
-; update tile block map pointer to next row's address
- pop de
- ld a,[W_CURMAPWIDTH]
- add a,$06
- add e
- ld e,a
- jr nc,.noCarry
- inc d
-.noCarry
-; update tile map pointer to next row's address
- pop hl
- ld a,$60
- add l
- ld l,a
- jr nc,.noCarry2
- inc h
-.noCarry2
- dec b
- jr nz,.rowLoop
- ld hl,wTileMapBackup
- ld bc,$0000
-.adjustForYCoordWithinTileBlock
- ld a,[W_YBLOCKCOORD]
- and a
- jr z,.adjustForXCoordWithinTileBlock
- ld bc,$0030
- add hl,bc
-.adjustForXCoordWithinTileBlock
- ld a,[W_XBLOCKCOORD]
- and a
- jr z,.copyToVisibleAreaBuffer
- ld bc,$0002
- add hl,bc
-.copyToVisibleAreaBuffer
- ld de,wTileMap ; base address for the tiles that are directly transfered to VRAM during V-blank
- ld b,$12
-.rowLoop2
- ld c,$14
-.rowInnerLoop2
- ld a,[hli]
- ld [de],a
- inc de
- dec c
- jr nz,.rowInnerLoop2
- ld a,$04
- add l
- ld l,a
- jr nc,.noCarry3
- inc h
-.noCarry3
- dec b
- jr nz,.rowLoop2
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a ; restore previous ROM bank
- ret
-
-AdvancePlayerSprite:: ; 0b7f (0:0b7f)
- ld a,[wUpdateSpritesEnabled]
- push af
- ld a,$FF
- ld [wUpdateSpritesEnabled],a
- ld hl, _AdvancePlayerSorite ; 3c:410c
- ld b, BANK(_AdvancePlayerSprite)
- call Bankswitch
- pop af
- ld [wUpdateSpritesEnabled],a
- ret
-
-; the following four functions are used to move the pointer to the upper left
-; corner of the tile block map in the direction of motion
-
-MoveTileBlockMapPointerEast:: ; 0e65 (0:0e65)
- ld a,[de]
- add a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- inc a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerWest:: ; 0e6f (0:0e6f)
- ld a,[de]
- sub a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- dec a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerSouth:: ; 0e79 (0:0e79)
- add a,$06
- ld b,a
- ld a,[de]
- add b
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- inc a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerNorth:: ; 0e85 (0:0e85)
- add a,$06
- ld b,a
- ld a,[de]
- sub b
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- dec a
- ld [de],a
- ret
-
-; the following 6 functions are used to tell the V-blank handler to redraw
-; the portion of the map that was newly exposed due to the player's movement
-
-ScheduleNorthRowRedraw:: ; 0e91 (0:0e91)
- hlCoord 0, 0
- call CopyToScreenEdgeTiles
- ld a,[wMapViewVRAMPointer]
- ld [H_SCREENEDGEREDRAWADDR],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [H_SCREENEDGEREDRAWADDR + 1],a
- ld a,REDRAWROW
- ld [H_SCREENEDGEREDRAW],a
- ret
-
-CopyToScreenEdgeTiles:: ; 0ea6 (0:0ea6)
- ld de,wScreenEdgeTiles
- ld c,2 * 20
-.loop
- ld a,[hli]
- ld [de],a
- inc de
- dec c
- jr nz,.loop
- ret
-
-ScheduleSouthRowRedraw:: ; 0eb2 (0:0eb2)
- hlCoord 0, 16
- call CopyToScreenEdgeTiles
- ld a,[wMapViewVRAMPointer]
- ld l,a
- ld a,[wMapViewVRAMPointer + 1]
- ld h,a
- ld bc,$0200
- add hl,bc
- ld a,h
- and a,$03
- or a,$98
- ld [H_SCREENEDGEREDRAWADDR + 1],a
- ld a,l
- ld [H_SCREENEDGEREDRAWADDR],a
- ld a,REDRAWROW
- ld [H_SCREENEDGEREDRAW],a
- ret
-
-ScheduleEastColumnRedraw:: ; 0ed3 (0:0ed3)
- hlCoord 18, 0
- call ScheduleColumnRedrawHelper
- ld a,[wMapViewVRAMPointer]
- ld c,a
- and a,$e0
- ld b,a
- ld a,c
- add a,18
- and a,$1f
- or b
- ld [H_SCREENEDGEREDRAWADDR],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [H_SCREENEDGEREDRAWADDR + 1],a
- ld a,REDRAWCOL
- ld [H_SCREENEDGEREDRAW],a
- ret
-
-ScheduleColumnRedrawHelper:: ; 0ef2 (0:0ef2)
- ld de,wScreenEdgeTiles
- ld c,$12
-.loop
- ld a,[hli]
- ld [de],a
- inc de
- ld a,[hl]
- ld [de],a
- inc de
- ld a,19
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- dec c
- jr nz,.loop
- ret
-
-ScheduleWestColumnRedraw:: ; 0f08 (0:0f08)
- hlCoord 0, 0
- call ScheduleColumnRedrawHelper
- ld a,[wMapViewVRAMPointer]
- ld [H_SCREENEDGEREDRAWADDR],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [H_SCREENEDGEREDRAWADDR + 1],a
- ld a,REDRAWCOL
- ld [H_SCREENEDGEREDRAW],a
- ret
-
-; function to write the tiles that make up a tile block to memory
-; Input: c = tile block ID, hl = destination address
-DrawTileBlock:: ; 0f1d (0:0f1d)
- push hl
- ld a,[W_TILESETBLOCKSPTR] ; pointer to tiles
- ld l,a
- ld a,[W_TILESETBLOCKSPTR + 1]
- ld h,a
- ld a,c
- swap a
- ld b,a
- and a,$f0
- ld c,a
- ld a,b
- and a,$0f
- ld b,a ; bc = tile block ID * 0x10
- add hl,bc
- ld d,h
- ld e,l ; de = address of the tile block's tiles
- pop hl
- ld c,$04 ; 4 loop iterations
-.loop ; each loop iteration, write 4 tile numbers
- push bc
- ld a,[de]
- ld [hli],a
- inc de
- ld a,[de]
- ld [hli],a
- inc de
- ld a,[de]
- ld [hli],a
- inc de
- ld a,[de]
- ld [hl],a
- inc de
- ld bc,$0015
- add hl,bc
- pop bc
- dec c
- jr nz,.loop
- ret
-
-; function to update joypad state and simulate button presses
-JoypadOverworld:: ; 0f4d (0:0f4d)
- xor a
- ld [wSpriteStateData1 + 3],a
- ld [wSpriteStateData1 + 5],a
- call RunMapScript
- call Joypad
- ld a,[W_FLAGS_D733]
- bit 3,a ; check if a trainer wants a challenge
- jr nz,.notForcedDownwards
- ld a,[W_CURMAP]
- cp a,ROUTE_17 ; Cycling Road
- jr nz,.notForcedDownwards
- ld a,[hJoyHeld]
- and a,D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
- jr nz,.notForcedDownwards
- ld a,D_DOWN
- ld [hJoyHeld],a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press
-.notForcedDownwards
- ld a,[wd730]
- bit 7,a
- ret z
-; if simulating button presses
- ld a,[hJoyHeld]
- ld b,a
- ld a,[wOverrideSimulatedJoypadStatesMask] ; bit mask for button presses that override simulated ones
- and b
- ret nz ; return if the simulated button presses are overridden
- ld hl,wSimulatedJoypadStatesIndex
- dec [hl]
- ld a,[hl]
- cp a,$ff
- jr z,.doneSimulating ; if the end of the simulated button presses has been reached
- ld hl,wSimulatedJoypadStatesEnd
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- ld a,[hl]
- ld [hJoyHeld],a ; store simulated button press in joypad state
- and a
- ret nz
- ld [hJoyPressed],a
- ld [hJoyReleased],a
- ret
-; if done simulating button presses
-.doneSimulating
- xor a
- ld [wWastedByteCD3A],a
- ld [wSimulatedJoypadStatesIndex],a
- ld [wSimulatedJoypadStatesEnd],a
- ld [wJoyIgnore],a
- ld [hJoyHeld],a
- ld hl,wd736
- ld a,[hl]
- and a,$f8
- ld [hl],a
- ld hl,wd730
- res 7,[hl]
- ret
-
-; function to check the tile ahead to determine if the character should get on land or keep surfing
-; sets carry if there is a collision and clears carry otherwise
-; It seems that this function has a bug in it, but due to luck, it doesn't
-; show up. After detecting a sprite collision, it jumps to the code that
-; checks if the next tile is passable instead of just directly jumping to the
-; "collision detected" code. However, it doesn't store the next tile in c,
-; so the old value of c is used. 2429 is always called before this function,
-; and 2429 always sets c to 0xF0. There is no 0xF0 background tile, so it
-; is considered impassable and it is detected as a collision.
-CollisionCheckOnWater:: ; 0fb7 (0:0fb7)
- ld a,[wd730]
- bit 7,a
- jp nz,.noCollision ; return and clear carry if button presses are being simulated
- ld a,[wd52a] ; the direction that the player is trying to go in
- ld d,a
- ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
- and d ; check if a sprite is in the direction the player is trying to go
- jr nz,.checkIfNextTileIsPassable ; bug?
- ld hl,TilePairCollisionsWater
- call CheckForJumpingAndTilePairCollisions
- jr c,.collision
- predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player (puts it in c and [wTileInFrontOfPlayer])
- ld a,[wTileInFrontOfPlayer] ; tile in front of player
- cp a,$14 ; water tile
- jr z,.noCollision ; keep surfing if it's a water tile
- cp a,$32 ; either the left tile of the S.S. Anne boarding platform or the tile on eastern coastlines (depending on the current tileset)
- jr z,.checkIfVermilionDockTileset
- cp a,$48 ; tile on right on coast lines in Safari Zone
- jr z,.noCollision ; keep surfing
-; check if the [land] tile in front of the player is passable
-.checkIfNextTileIsPassable
- ld hl,W_TILESETCOLLISIONPTR ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.collision
- cp c
- jr z,.stopSurfing ; stop surfing if the tile is passable
- jr .loop
-.collision
- ld a,[wc02a]
- cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
- jr z,.setCarry
- ld a,(SFX_02_5b - SFX_Headers_02) / 3
- call PlaySound ; play collision sound (if it's not already playing)
-.setCarry
- scf
- jr .done
-.noCollision
- and a
-.done
- ret
-.stopSurfing
- xor a
- ld [wWalkBikeSurfState],a
- call LoadPlayerSpriteGraphics
- call PlayDefaultMusic
- jr .noCollision
-.checkIfVermilionDockTileset
- ld a, [W_CURMAPTILESET] ; tileset
- cp SHIP_PORT ; Vermilion Dock tileset
- jr nz, .noCollision ; keep surfing if it's not the boarding platform tile
- jr .stopSurfing ; if it is the boarding platform tile, stop surfing
-
-; function to run the current map's script
-RunMapScript:: ; 101b (0:101b)
- push hl
- push de
- push bc
- callba TryPushingBoulder
- ld a,[wFlags_0xcd60]
- bit 1,a ; play boulder dust animation
- jr z,.afterBoulderEffect
- callba DoBoulderDustAnimation
-.afterBoulderEffect
- pop bc
- pop de
- pop hl
- call RunNPCMovementScript
- ld a,[W_CURMAP] ; current map number
- call SwitchToMapRomBank ; change to the ROM bank the map's data is in
- ld hl,W_MAPSCRIPTPTR
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld de,.return
- push de
- jp [hl] ; jump to script
-.return
- ret
-
-LoadWalkingPlayerSpriteGraphics:: ; 104d (0:104d)
- ld de,RedSprite ; $4180
- ld hl,vNPCSprites
- jr LoadPlayerSpriteGraphicsCommon
-
-LoadSurfingPlayerSpriteGraphics:: ; 1055 (0:1055)
- ld de,SeelSprite
- ld hl,vNPCSprites
- jr LoadPlayerSpriteGraphicsCommon
-
-LoadBikePlayerSpriteGraphics:: ; 105d (0:105d)
- ld de,RedCyclingSprite
- ld hl,vNPCSprites
-
-LoadPlayerSpriteGraphicsCommon:: ; 1063 (0:1063)
- push de
- push hl
- ld bc,(BANK(RedSprite) << 8) + $0c
- call CopyVideoData
- pop hl
- pop de
- ld a,$c0
- add e
- ld e,a
- jr nc,.noCarry
- inc d
-.noCarry
- set 3,h
- ld bc,$050c
- jp CopyVideoData
-
-; function to load data from the map header
-LoadMapHeader:: ; 107c (0:107c)
- callba MarkTownVisitedAndLoadMissableObjects
- ld a,[W_CURMAPTILESET]
- ld [wd119],a
- ld a,[W_CURMAP]
- call SwitchToMapRomBank
- ld a,[W_CURMAPTILESET]
- ld b,a
- res 7,a
- ld [W_CURMAPTILESET],a
- ld [$ff8b],a
- bit 7,b
- ret nz
- ld hl,MapHeaderPointers
- ld a,[W_CURMAP]
- sla a
- jr nc,.noCarry1
- inc h
-.noCarry1
- add l
- ld l,a
- jr nc,.noCarry2
- inc h
-.noCarry2
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl = base of map header
-; copy the first 10 bytes (the fixed area) of the map data to D367-D370
- ld de,W_CURMAPTILESET
- ld c,$0a
-.copyFixedHeaderLoop
- ld a,[hli]
- ld [de],a
- inc de
- dec c
- jr nz,.copyFixedHeaderLoop
-; initialize all the connected maps to disabled at first, before loading the actual values
- ld a,$ff
- ld [W_MAPCONN1PTR],a
- ld [W_MAPCONN2PTR],a
- ld [W_MAPCONN3PTR],a
- ld [W_MAPCONN4PTR],a
-; copy connection data (if any) to WRAM
- ld a,[W_MAPCONNECTIONS]
- ld b,a
-.checkNorth
- bit 3,b
- jr z,.checkSouth
- ld de,W_MAPCONN1PTR
- call CopyMapConnectionHeader
-.checkSouth
- bit 2,b
- jr z,.checkWest
- ld de,W_MAPCONN2PTR
- call CopyMapConnectionHeader
-.checkWest
- bit 1,b
- jr z,.checkEast
- ld de,W_MAPCONN3PTR
- call CopyMapConnectionHeader
-.checkEast
- bit 0,b
- jr z,.getObjectDataPointer
- ld de,W_MAPCONN4PTR
- call CopyMapConnectionHeader
-.getObjectDataPointer
- ld a,[hli]
- ld [wd3a9],a
- ld a,[hli]
- ld [wd3aa],a
- push hl
- ld a,[wd3a9]
- ld l,a
- ld a,[wd3aa]
- ld h,a ; hl = base of object data
- ld de,wd3ad ; background tile ID
- ld a,[hli]
- ld [de],a ; save background tile ID
-.loadWarpData
- ld a,[hli]
- ld [wNumberOfWarps],a
- and a
- jr z,.loadSignData
- ld c,a
- ld de,wWarpEntries
-.warpLoop ; one warp per loop iteration
- ld b,$04
-.warpInnerLoop
- ld a,[hli]
- ld [de],a
- inc de
- dec b
- jr nz,.warpInnerLoop
- dec c
- jr nz,.warpLoop
-.loadSignData
- ld a,[hli] ; number of signs
- ld [wd4b0],a ; save the number of signs
- and a ; are there any signs?
- jr z,.loadSpriteData ; if not, skip this
- ld c,a
- ld de,wd4d1 ; base address of sign text IDs
- ld a,d
- ld [$ff95],a
- ld a,e
- ld [$ff96],a
- ld de,wd4b1 ; base address of sign coordinates
-.signLoop
- ld a,[hli]
- ld [de],a
- inc de
- ld a,[hli]
- ld [de],a
- inc de
- push de
- ld a,[$ff95]
- ld d,a
- ld a,[$ff96]
- ld e,a
- ld a,[hli]
- ld [de],a
- inc de
- ld a,d
- ld [$ff95],a
- ld a,e
- ld [$ff96],a
- pop de
- dec c
- jr nz,.signLoop
-.loadSpriteData
- ld a,[wd72e]
- bit 5,a ; did a battle happen immediately before this?
- jp nz,.finishUp ; if so, skip this because battles don't destroy this data
- ld a,[hli]
- ld [W_NUMSPRITES],a ; save the number of sprites
- push hl
-; zero C110-C1FF and C210-C2FF
- ld hl,wSpriteStateData1 + $10
- ld de,wSpriteStateData2 + $10
- xor a
- ld b,$f0
-.zeroSpriteDataLoop
- ld [hli],a
- ld [de],a
- inc e
- dec b
- jr nz,.zeroSpriteDataLoop
-; initialize all C100-C1FF sprite entries to disabled (other than player's)
- ld hl,wSpriteStateData1 + $12
- ld de,$0010
- ld c,$0f
-.disableSpriteEntriesLoop
- ld [hl],$ff
- add hl,de
- dec c
- jr nz,.disableSpriteEntriesLoop
- pop hl
- ld de,wSpriteStateData1 + $10
- ld a,[W_NUMSPRITES] ; number of sprites
- and a ; are there any sprites?
- jp z,.finishUp ; if there are no sprites, skip the rest
- ld b,a
- ld c,$00
-.loadSpriteLoop
- ld a,[hli]
- ld [de],a ; store picture ID at C1X0
- inc d
- ld a,$04
- add e
- ld e,a
- ld a,[hli]
- ld [de],a ; store Y position at C2X4
- inc e
- ld a,[hli]
- ld [de],a ; store X position at C2X5
- inc e
- ld a,[hli]
- ld [de],a ; store movement byte 1 at C2X6
- ld a,[hli]
- ld [$ff8d],a ; save movement byte 2
- ld a,[hli]
- ld [$ff8e],a ; save text ID and flags byte
- push bc
- push hl
- ld b,$00
- ld hl,W_MAPSPRITEDATA
- add hl,bc
- ld a,[$ff8d]
- ld [hli],a ; store movement byte 2 in byte 0 of sprite entry
- ld a,[$ff8e]
- ld [hl],a ; this appears pointless, since the value is overwritten immediately after
- ld a,[$ff8e]
- ld [$ff8d],a
- and a,$3f
- ld [hl],a ; store text ID in byte 1 of sprite entry
- pop hl
- ld a,[$ff8d]
- bit 6,a
- jr nz,.trainerSprite
- bit 7,a
- jr nz,.itemBallSprite
- jr .regularSprite
-.trainerSprite
- ld a,[hli]
- ld [$ff8d],a ; save trainer class
- ld a,[hli]
- ld [$ff8e],a ; save trainer number (within class)
- push hl
- ld hl,W_MAPSPRITEEXTRADATA
- add hl,bc
- ld a,[$ff8d]
- ld [hli],a ; store trainer class in byte 0 of the entry
- ld a,[$ff8e]
- ld [hl],a ; store trainer number in byte 1 of the entry
- pop hl
- jr .nextSprite
-.itemBallSprite
- ld a,[hli]
- ld [$ff8d],a ; save item number
- push hl
- ld hl,W_MAPSPRITEEXTRADATA
- add hl,bc
- ld a,[$ff8d]
- ld [hli],a ; store item number in byte 0 of the entry
- xor a
- ld [hl],a ; zero byte 1, since it is not used
- pop hl
- jr .nextSprite
-.regularSprite
- push hl
- ld hl,W_MAPSPRITEEXTRADATA
- add hl,bc
-; zero both bytes, since regular sprites don't use this extra space
- xor a
- ld [hli],a
- ld [hl],a
- pop hl
-.nextSprite
- pop bc
- dec d
- ld a,$0a
- add e
- ld e,a
- inc c
- inc c
- dec b
- jp nz,.loadSpriteLoop
-.finishUp
- predef LoadTilesetHeader
- callab LoadWildData
- pop hl ; restore hl from before going to the warp/sign/sprite data (this value was saved for seemingly no purpose)
- ld a,[W_CURMAPHEIGHT] ; map height in 4x4 tile blocks
- add a ; double it
- ld [wd524],a ; store map height in 2x2 tile blocks
- ld a,[W_CURMAPWIDTH] ; map width in 4x4 tile blocks
- add a ; double it
- ld [wd525],a ; map width in 2x2 tile blocks
- ld a,[W_CURMAP]
- ld c,a
- ld b,$00
- ld a,[H_LOADEDROMBANK]
- push af
- ld a, BANK(MapSongBanks)
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ld hl, MapSongBanks
- add hl,bc
- add hl,bc
- ld a,[hli]
- ld [wd35b],a ; music 1
- ld a,[hl]
- ld [wd35c],a ; music 2
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; function to copy map connection data from ROM to WRAM
-; Input: hl = source, de = destination
-CopyMapConnectionHeader:: ; 1238 (0:1238)
- ld c,$0b
-.loop
- ld a,[hli]
- ld [de],a
- inc de
- dec c
- jr nz,.loop
- ret
-
-; function to load map data
-LoadMapData:: ; 1241 (0:1241)
- ld a,[H_LOADEDROMBANK]
- push af
- call DisableLCD
- ld a,$98
- ld [wMapViewVRAMPointer + 1],a
- xor a
- ld [wMapViewVRAMPointer],a
- ld [hSCY],a
- ld [hSCX],a
- ld [wWalkCounter],a
- ld [wd119],a
- ld [wWalkBikeSurfStateCopy],a
- ld [W_SPRITESETID],a
- call LoadTextBoxTilePatterns
- call LoadMapHeader
- callba InitMapSprites ; load tile pattern data for sprites
- call LoadTileBlockMap
- call LoadTilesetTilePatternData
- call LoadCurrentMapView
-; copy current map view to VRAM
- ld hl,wTileMap
- ld de,vBGMap0
- ld b,18
-.vramCopyLoop
- ld c,20
-.vramCopyInnerLoop
- ld a,[hli]
- ld [de],a
- inc e
- dec c
- jr nz,.vramCopyInnerLoop
- ld a,32 - 20
- add e
- ld e,a
- jr nc,.noCarry
- inc d
-.noCarry
- dec b
- jr nz,.vramCopyLoop
- ld a,$01
- ld [wUpdateSpritesEnabled],a
- call EnableLCD
- ld b,$09
- call GoPAL_SET
- call LoadPlayerSpriteGraphics
- ld a,[wd732]
- and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
- jr nz,.restoreRomBank
- ld a,[W_FLAGS_D733]
- bit 1,a
- jr nz,.restoreRomBank
- call Func_235f ; music related
- call Func_2312 ; music related
-.restoreRomBank
- pop af
- ld [H_LOADEDROMBANK],a
- ld [$2000],a
- ret
-
-; function to switch to the ROM bank that a map is stored in
-; Input: a = map number
-SwitchToMapRomBank:: ; 12bc (0:12bc)
- push hl
- push bc
- ld c,a
- ld b,$00
- ld a,Bank(MapHeaderBanks)
- call BankswitchHome ; switch to ROM bank 3
- ld hl,MapHeaderBanks
- add hl,bc
- ld a,[hl]
- ld [$ffe8],a ; save map ROM bank
- call BankswitchBack
- ld a,[$ffe8]
- ld [H_LOADEDROMBANK],a
- ld [$2000],a ; switch to map ROM bank
- pop bc
- pop hl
- ret
-
-IgnoreInputForHalfSecond: ; 12da (0:12da)
- ld a, 30
- ld [wIgnoreInputCounter], a
- ld hl, wd730
- ld a, [hl]
- or $26
- ld [hl], a ; set ignore input bit
- ret
-
-ResetUsingStrengthOutOfBattleBit: ; 12e7 (0:12e7)
- ld hl, wd728
- res 0, [hl]
- ret
-
-ForceBikeOrSurf:: ; 12ed (0:12ed)
- ld b, BANK(RedSprite)
- ld hl, LoadPlayerSpriteGraphics
- call Bankswitch
- jp PlayDefaultMusic ; update map/player state?
-
-; Handle the player jumping down
-; a ledge in the overworld.
-HandleMidJump:: ; 0fe1 (0:0fe1)
- ld a,[wd736]
- bit 7,a ; jumping down a ledge?
- ret z
- ld b, BANK(_HandleMidJump)
- ld hl, _HandleMidJump
- jp Bankswitch
-
-IsSpinning:: ; 0ff0 (0:0ff0)
- ld a,[wd736]
- bit 7,a
- ret z ; no spinning
- ld b, BANK(LoadSpinnerArrowTiles); spin while moving
- ld hl,LoadSpinnerArrowTiles ; 11:5077
- jp Bankswitch
-
-Func_0ffe:: ; 0ffe (0:0ffe)
- ld hl, Func_fcf0c ; 3f:4f0c
- ld b, BANK(Func_fcf0c)
- jp Bankswitch
+EnterMap:: ; 01d7 (0:01d7)
+; Load a new map.
+ ld a, $ff
+ ld [wJoyIgnore], a
+ call LoadMapData
+ callba ClearVariablesAfterLoadingMapData
+ ld hl, wd72c
+ bit 0, [hl] ; has the player already made 3 steps since the last battle?
+ jr z, .skipGivingThreeStepsOfNoRandomBattles
+ ld a, 3 ; minimum number of steps between battles
+ ld [wNumberOfNoRandomBattleStepsLeft], a
+.skipGivingThreeStepsOfNoRandomBattles
+ ld hl, wd72e
+ bit 5, [hl] ; did a battle happen immediately before this?
+ res 5, [hl] ; unset the "battle just happened" flag
+ call z, ResetUsingStrengthOutOfBattleBit
+ call nz, MapEntryAfterBattle
+ ld hl, wd732
+ ld a, [hl]
+ and 1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jr z, .didNotEnterUsingFlyWarpOrDungeonWarp
+ callba EnterMapAnim
+ call UpdateSprites
+ ld hl, wd732
+ res 3, [hl]
+ ld hl, wd72e
+ res 4, [hl]
+ call Func_342a
+.didNotEnterUsingFlyWarpOrDungeonWarp
+ callba CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road
+ ld hl, wd732
+ bit 4, [hl]
+ res 4, [hl]
+ ld hl, wd72d
+ res 5, [hl]
+ call UpdateSprites
+ ld hl, wd126
+ set 5, [hl]
+ set 6, [hl]
+ xor a
+ ld [wJoyIgnore], a
+
+OverworldLoop:: ; 0242 (0:0242)
+ call DelayFrame
+OverworldLoopLessDelay:: ; 0245 (0:0245)
+ call DelayFrame
+ call Func_342a
+ call LoadGBPal
+ ld a,[wWalkCounter]
+ and a
+ jp nz,.moveAhead ; if the player sprite has not yet completed the walking animation
+ call JoypadOverworld ; get joypad state (which is possibly simulated)
+ callba SafariZoneCheck
+ ld a,[wSafariZoneGameOver]
+ and a
+ jp nz,WarpFound2
+ ld hl,wd72d
+ bit 3,[hl]
+ res 3,[hl]
+ jp nz,WarpFound2
+ ld a,[wd732]
+ and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jp nz,HandleFlyWarpOrDungeonWarp
+ ld a,[W_CUROPPONENT]
+ and a
+ jp nz,.newBattle
+ ld a,[wd730]
+ bit 7,a ; are we simulating button presses?
+ jr z,.notSimulating
+ ld a,[hJoyHeld]
+ jr .checkIfStartIsPressed
+.notSimulating
+ ld a,[hJoyPressed]
+.checkIfStartIsPressed
+ bit 3,a ; start button
+ jr z,.startButtonNotPressed
+; if START is pressed
+ xor a
+ ld [hSpriteIndexOrTextID],a ; start menu text ID
+ jp .displayDialogue
+.startButtonNotPressed
+ bit 0,a ; A button
+ jp z,.checkIfDownButtonIsPressed
+; if A is pressed
+ ld a,[wd730]
+ bit 2,a
+ jp nz,.noDirectionButtonsPressed
+ call IsPlayerCharacterBeingControlledByGame
+ jr nz,.checkForOpponent
+ call CheckForHiddenObjectOrBookshelfOrCardKeyDoor
+ ld a,[$ffeb]
+ and a
+ jp z,OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found
+ xor a
+ ld [wd436],a ; new yellow address
+ call IsSpriteOrSignInFrontOfPlayer
+ call Func_0ffe
+ ld a,[hSpriteIndexOrTextID]
+ and a
+ jp z,OverworldLoop
+.displayDialogue
+ predef GetTileAndCoordsInFrontOfPlayer
+ call UpdateSprites
+ ld a,[wFlags_0xcd60]
+ bit 2,a
+ jr nz,.checkForOpponent
+ bit 0,a
+ jr nz,.checkForOpponent
+ aCoord 8, 9
+ ld [wcf0e],a
+ call DisplayTextID ; display either the start menu or the NPC/sign text
+ ld a,[wcc47]
+ and a
+ jr z,.checkForOpponent
+ xor a
+ ld [wcc47],a
+ jp EnterMap
+; predef LoadSAV
+; ld a,[W_CURMAP]
+; ld [wDestinationMap],a
+; call SpecialWarpIn
+; ld a,[W_CURMAP]
+; call SwitchToMapRomBank ; switch to the ROM bank of the current map
+; ld hl,W_CURMAPTILESET
+; set 7,[hl]
+.checkForOpponent
+ ld a,[W_CUROPPONENT]
+ and a
+ jp nz,.newBattle
+ jp OverworldLoop
+.noDirectionButtonsPressed
+ call UpdateSprites ; 231c
+ ld hl,wFlags_0xcd60
+ res 2,[hl]
+ xor a
+ ld [wd435], a
+ ld a, $1
+ ld a,$01
+ ld [wcc4b],a
+ ld a,[wd528] ; the direction that was pressed last time
+ and a
+ jr z, .overworldloop
+; if a direction was pressed last time
+ ld [wd529],a ; save the last direction
+ xor a
+ ld [wd528],a ; zero the direction
+.overworldloop
+ jp OverworldLoop
+.checkIfDownButtonIsPressed
+ ld a,[hJoyHeld] ; current joypad state
+ bit 7,a ; down button
+ jr z,.checkIfUpButtonIsPressed
+ ld a,$01
+ ld [wSpriteStateData1 + 3],a
+ ld a,$04
+ jr .handleDirectionButtonPress
+.checkIfUpButtonIsPressed
+ bit 6,a ; up button
+ jr z,.checkIfLeftButtonIsPressed
+ ld a,$ff
+ ld [wSpriteStateData1 + 3],a
+ ld a,$08
+ jr .handleDirectionButtonPress
+.checkIfLeftButtonIsPressed
+ bit 5,a ; left button
+ jr z,.checkIfRightButtonIsPressed
+ ld a,$ff
+ ld [wSpriteStateData1 + 5],a
+ ld a,$02
+ jr .handleDirectionButtonPress
+.checkIfRightButtonIsPressed
+ bit 4,a ; right button
+ jr z,.noDirectionButtonsPressed
+ ld a,$01
+ ld [wSpriteStateData1 + 5],a
+.handleDirectionButtonPress
+ ld [wd52a],a ; new direction
+ ld a,[wd730]
+ bit 7,a ; are we simulating button presses?
+ jr nz,.noDirectionChange ; ignore direction changes if we are
+ ld a,[wcc4b]
+ and a
+ jr z,.noDirectionChange
+ ld a,[wd52a] ; new direction
+ ld b,a
+ ld a,[wd529] ; old direction
+ cp b
+ jr z,.noDirectionChange
+ ld a,$8
+ ld [wd434],a
+; unlike in red/blue, yellow does not have the 180 degrees odd code
+ ld hl,wFlags_0xcd60
+ set 2,[hl]
+ xor a
+ ld [wcc4b],a
+ ld a,[wd52a]
+ ld [wd528],a
+ call NewBattle
+ jp c,.battleOccurred
+ jp OverworldLoop
+.noDirectionChange
+ ld a,[wd52a] ; current direction
+ ld [wd528],a ; save direction
+ call UpdateSprites
+ ld a,[wWalkBikeSurfState]
+ cp a,$02 ; surfing
+ jr z,.surfing
+; not surfing
+ call CollisionCheckOnLand
+ jr nc,.noCollision
+; collision occurred
+ push hl
+ ld hl,wd736
+ bit 2,[hl] ; standing on warp flag
+ pop hl
+ jp z,OverworldLoop
+; collision occurred while standing on a warp
+ push hl
+ call ExtraWarpCheck ; sets carry if there is a potential to warp
+ pop hl
+ jp c,CheckWarpsCollision
+ jp OverworldLoop
+.surfing
+ call CollisionCheckOnWater
+ jp c,OverworldLoop
+.noCollision
+ ld a,$08
+ ld [wWalkCounter],a
+ callab Func_fcc08
+ jr .moveAhead2
+.moveAhead
+ call IsSpinning
+ call UpdateSprites ; move sprites
+.moveAhead2
+ ld hl,wFlags_0xcd60
+ res 2,[hl]
+ xor a
+ ld [wd435],a
+ call DoBikeSpeedup
+ call AdvancePlayerSprite
+ ld a,[wWalkCounter]
+ and a
+ jp nz,CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works)
+; walking animation finished
+ call StepCountCheck
+ ld a,[wd790]
+ bit 7,a ; in the safari zone?
+ jr z,.notSafariZone
+ callba SafariZoneCheckSteps
+ ld a,[wSafariZoneGameOver]
+ and a
+ jp nz,WarpFound2
+.notSafariZone
+ ld a,[W_ISINBATTLE]
+ and a
+ jp nz,CheckWarpsNoCollision
+ predef ApplyOutOfBattlePoisonDamage ; also increment daycare mon exp
+ ld a,[wd12d]
+ and a
+ jp nz,HandleBlackOut ; if all pokemon fainted
+.newBattle
+ call NewBattle
+ ld hl,wd736
+ res 2,[hl] ; standing on warp flag
+ jp nc,CheckWarpsNoCollision ; check for warps if there was no battle
+.battleOccurred
+ ld hl,wd72d
+ res 6,[hl]
+ ld hl,W_FLAGS_D733
+ res 3,[hl]
+ ld hl,wd126
+ set 5,[hl]
+ set 6,[hl]
+ xor a
+ ld [hJoyHeld],a
+ ld a,[W_CURMAP]
+ cp a,CINNABAR_GYM
+ jr nz,.notCinnabarGym
+ ld hl,wd79b
+ set 7,[hl]
+.notCinnabarGym
+ ld hl,wd72e
+ set 5,[hl]
+ ld a,[W_CURMAP]
+ cp a,OAKS_LAB
+ jp z,.noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab
+ callab AnyPartyAlive
+ ld a,d
+ and a
+ jr z,.allPokemonFainted
+.noFaintCheck
+ ld c,$0a
+ call DelayFrames
+ jp EnterMap
+;.allPokemonFainted
+; ld a,$ff
+; ld [W_ISINBATTLE],a
+; call RunMapScript
+; jp HandleBlackOut
+
+StepCountCheck:: ; 0457 (0:0457)
+ ld a,[wd730]
+ bit 7,a
+ jr nz,.doneStepCounting ; if button presses are being simulated, don't count steps
+; step counting
+ ld hl,wStepCounter
+ dec [hl]
+ ld a,[wd72c]
+ bit 0,a
+ jr z,.doneStepCounting
+ ld hl,wNumberOfNoRandomBattleStepsLeft
+ dec [hl]
+ jr nz,.doneStepCounting
+ ld hl,wd72c
+ res 0,[hl] ; indicate that the player has stepped thrice since the last battle
+.doneStepCounting
+ ret
+
+; function to determine if there will be a battle and execute it (either a trainer battle or wild battle)
+; sets carry if a battle occurred and unsets carry if not
+NewBattle:: ; 0480 (0:0480)
+ ld a,[wd72d]
+ bit 4,a
+ jr nz,.noBattle
+ call IsPlayerCharacterBeingControlledByGame
+ jr nz,.noBattle ; no battle if the player character is under the game's control
+ ld a,[wd72e]
+ bit 4,a
+ jr nz,.noBattle
+ ld b, BANK(InitBattle)
+ ld hl, InitBattle ; 3d:5ff2
+ jp Bankswitch
+.noBattle
+ and a
+ ret
+
+DoBikeSpeedup:: ; 049d (0:049d)
+ ld a,[wWalkBikeSurfState]
+ dec a ; riding a bike?
+ ret nz
+ ld a,[wd736]
+ bit 6,a
+ ret nz
+ ld a,[wNPCMovementScriptPointerTableNum]
+ and a
+ ret nz
+ ld a,[W_CURMAP]
+ cp ROUTE_17 ; cycling road
+ jr nz,.goFaster
+ ld a,[hJoyHeld]
+ and a,D_UP | D_LEFT | D_RIGHT
+ ret nz
+.goFaster
+ call AdvancePlayerSprite
+ ret
+
+; check if the player has stepped onto a warp after having not collided
+CheckWarpsNoCollision:: ; 04bd (0:04bd)
+ ld a,[wNumberOfWarps]
+ and a
+ jp z,CheckMapConnections
+ ld b,0
+ ld a,[wNumberOfWarps]
+ ld c,a
+ ld a,[W_YCOORD]
+ ld d,a
+ ld a,[W_XCOORD]
+ ld e,a
+ ld hl,wWarpEntries
+CheckWarpsNoCollisionLoop:: ; 04d5 (0:04d5)
+ ld a,[hli] ; check if the warp's Y position matches
+ cp d
+ jr nz,CheckWarpsNoCollisionRetry1
+ ld a,[hli] ; check if the warp's X position matches
+ cp e
+ jr nz,CheckWarpsNoCollisionRetry2
+; if a match was found
+ push hl
+ push bc
+ ld hl,wd736
+ set 2,[hl] ; standing on warp flag
+ callba IsPlayerStandingOnDoorTileOrWarpTile
+ pop bc
+ pop hl
+ jr c,WarpFound1 ; jump if standing on door or warp
+ push hl
+ push bc
+ call ExtraWarpCheck
+ pop bc
+ pop hl
+ jr nc,CheckWarpsNoCollisionRetry2
+; if the extra check passed
+ ld a,[W_FLAGS_D733]
+ bit 2,a
+ jr nz,WarpFound1
+ push de
+ push bc
+ call Joypad
+ pop bc
+ pop de
+ ld a,[hJoyHeld]
+ and a,D_DOWN | D_UP | D_LEFT | D_RIGHT
+ jr z,CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp
+ jr WarpFound1
+
+CheckWarpsNoCollisionRetry1:: ; 050f (0:050f)
+ inc hl
+CheckWarpsNoCollisionRetry2:: ; 0510 (0:0510)
+ inc hl
+ inc hl
+ContinueCheckWarpsNoCollisionLoop:: ; 0512 (0:0512)
+ inc b ; increment warp number
+ dec c ; decrement number of warps
+ jp nz,CheckWarpsNoCollisionLoop
+ jp CheckMapConnections
+
+; check if the player has stepped onto a warp after having collided
+CheckWarpsCollision:: ; 051a (0:051a)
+ ld a,[wNumberOfWarps]
+ ld c,a
+ ld hl,wWarpEntries
+.loop
+ ld a,[hli] ; Y coordinate of warp
+ ld b,a
+ ld a,[W_YCOORD]
+ cp b
+ jr nz,.retry1
+ ld a,[hli] ; X coordinate of warp
+ ld b,a
+ ld a,[W_XCOORD]
+ cp b
+ jr nz,.retry2
+ ld a,[hli]
+ ld [wDestinationWarpID],a
+ ld a,[hl]
+ ld [$ff8b],a ; save target map
+ jr WarpFound2
+.retry1
+ inc hl
+.retry2
+ inc hl
+ inc hl
+ dec c
+ jr nz,.loop
+ jp OverworldLoop
+
+WarpFound1:: ; 0543 (0:0543)
+ ld a,[hli]
+ ld [wDestinationWarpID],a
+ ld a,[hli]
+ ld [$ff8b],a ; save target map
+
+WarpFound2:: ; 054a (0:054a)
+ ld a,[wNumberOfWarps]
+ sub c
+ ld [wd73b],a ; save ID of used warp
+ ld a,[W_CURMAP]
+ ld [wd73c],a
+ call CheckIfInOutsideMap
+ jr nz,.indoorMaps
+; this is for handling "outside" maps that can't have the 0xFF destination map
+ ld a,[W_CURMAP]
+ ld [wLastMap],a
+ ld a,[W_CURMAPWIDTH]
+ ld [wd366],a
+ ld a,[$ff8b] ; destination map number
+ ld [W_CURMAP],a ; change current map to destination map
+ cp a,ROCK_TUNNEL_1
+ jr nz,.notRockTunnel
+ ld a,$06
+ ld [wMapPalOffset],a
+ call GBFadeOutToBlack
+.notRockTunnel
+ callab Func_fc5fa ; 3f:45fa
+ call PlayMapChangeSound
+ jr .done
+; for maps that can have the 0xFF destination map, which means to return to the outside map; not all these maps are necessarily indoors, though
+.indoorMaps
+ ld a,[$ff8b] ; destination map
+ cp a,$ff
+ jr z,.goBackOutside
+; if not going back to the previous map
+ ld [W_CURMAP],a ; current map number
+ callba IsPlayerStandingOnWarpPadOrHole
+ ld a,[wcd5b]
+ dec a ; is the player on a warp pad?
+ jr nz,.notWarpPad
+; if the player is on a warp pad
+ call LeaveMapAnim
+ ld hl,wd732
+ set 3,[hl]
+ jr .skipMapChangeSound
+.notWarpPad
+ call PlayMapChangeSound
+.skipMapChangeSound
+ ld hl,wd736
+ res 0,[hl]
+ res 1,[hl]
+ callab Func_fc65b ; 3f:465b
+ jr .done
+.goBackOutside
+ callab Func_fc69a ; 3f:469a
+ ld a,[wLastMap]
+ ld [W_CURMAP],a
+ call PlayMapChangeSound
+ xor a
+ ld [wMapPalOffset],a
+.done
+ ld hl,wd736
+ set 0,[hl] ; have the player's sprite step out from the door (if there is one)
+ call IgnoreInputForHalfSecond
+ jp EnterMap
+
+; if no matching warp was found
+CheckMapConnections:: ; 05db (0:05db)
+.checkWestMap
+ ld a,[W_XCOORD]
+ cp a,$ff
+ jr nz,.checkEastMap
+ ld a,[W_MAPCONN3PTR]
+ ld [W_CURMAP],a
+ ld a,[wd38f] ; new X coordinate upon entering west map
+ ld [W_XCOORD],a
+ ld a,[W_YCOORD]
+ ld c,a
+ ld a,[wd38e] ; Y adjustment upon entering west map
+ add c
+ ld c,a
+ ld [W_YCOORD],a
+ ld a,[wd390] ; pointer to upper left corner of map without adjustment for Y position
+ ld l,a
+ ld a,[wd391]
+ ld h,a
+ srl c
+ jr z,.savePointer1
+.pointerAdjustmentLoop1
+ ld a,[wd38d] ; width of connected map
+ add a,$06
+ ld e,a
+ ld d,$00
+ ld b,$00
+ add hl,de
+ dec c
+ jr nz,.pointerAdjustmentLoop1
+.savePointer1
+ ld a,l
+ ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
+ ld a,h
+ ld [wCurrentTileBlockMapViewPointer + 1],a
+ jp .loadNewMap
+.checkEastMap
+ ld b,a
+ ld a,[wd525] ; map width
+ cp b
+ jr nz,.checkNorthMap
+ ld a,[W_MAPCONN4PTR]
+ ld [W_CURMAP],a
+ ld a,[wd39a] ; new X coordinate upon entering east map
+ ld [W_XCOORD],a
+ ld a,[W_YCOORD]
+ ld c,a
+ ld a,[wd399] ; Y adjustment upon entering east map
+ add c
+ ld c,a
+ ld [W_YCOORD],a
+ ld a,[wd39b] ; pointer to upper left corner of map without adjustment for Y position
+ ld l,a
+ ld a,[wd39c]
+ ld h,a
+ srl c
+ jr z,.savePointer2
+.pointerAdjustmentLoop2
+ ld a,[wd398]
+ add a,$06
+ ld e,a
+ ld d,$00
+ ld b,$00
+ add hl,de
+ dec c
+ jr nz,.pointerAdjustmentLoop2
+.savePointer2
+ ld a,l
+ ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
+ ld a,h
+ ld [wCurrentTileBlockMapViewPointer + 1],a
+ jp .loadNewMap
+.checkNorthMap
+ ld a,[W_YCOORD]
+ cp a,$ff
+ jr nz,.checkSouthMap
+ ld a,[W_MAPCONN1PTR]
+ ld [W_CURMAP],a
+ ld a,[wd378] ; new Y coordinate upon entering north map
+ ld [W_YCOORD],a
+ ld a,[W_XCOORD]
+ ld c,a
+ ld a,[wd379] ; X adjustment upon entering north map
+ add c
+ ld c,a
+ ld [W_XCOORD],a
+ ld a,[wd37a] ; pointer to upper left corner of map without adjustment for X position
+ ld l,a
+ ld a,[wd37b]
+ ld h,a
+ ld b,$00
+ srl c
+ add hl,bc
+ ld a,l
+ ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
+ ld a,h
+ ld [wCurrentTileBlockMapViewPointer + 1],a
+ jp .loadNewMap
+.checkSouthMap
+ ld b,a
+ ld a,[wd524]
+ cp b
+ jr nz,.didNotEnterConnectedMap
+ ld a,[W_MAPCONN2PTR]
+ ld [W_CURMAP],a
+ ld a,[wd383] ; new Y coordinate upon entering south map
+ ld [W_YCOORD],a
+ ld a,[W_XCOORD]
+ ld c,a
+ ld a,[wd384] ; X adjustment upon entering south map
+ add c
+ ld c,a
+ ld [W_XCOORD],a
+ ld a,[wd385] ; pointer to upper left corner of map without adjustment for X position
+ ld l,a
+ ld a,[wd386]
+ ld h,a
+ ld b,$00
+ srl c
+ add hl,bc
+ ld a,l
+ ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
+ ld a,h
+ ld [wCurrentTileBlockMapViewPointer + 1],a
+.loadNewMap ; 06ce (0:06ce)
+; load the connected map that was entered
+ ld hl,[wd430]
+ set 4,[hl]
+ ld a,$2
+ ld [wd431],a
+ call LoadMapHeader ; 0dab (0:0dab)
+ call Func_2312 ; music
+ ld b,$09
+ call GoPAL_SET
+; Since the sprite set shouldn't change, this will just update VRAM slots at
+; $C2XE without loading any tile patterns.
+ call InitMapSprites
+ call LoadTileBlockMap
+ jp OverworldLoopLessDelay
+.didNotEnterConnectedMap
+ jp OverworldLoop
+
+; function to play a sound when changing maps
+PlayMapChangeSound:: ; 06ef (0:06ef)
+ ld a,[W_CURMAPTILESET]
+ cp FACILITY
+ jr z,.didNotGoThroughDoor
+ cp CEMETERY
+ jr z,.didNotGoThroughDoor
+ cp UNDERGROUND
+ jr nz,.didNotGoThroughDoor
+ aCoord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on
+ cp a,$0b ; door tile in tileset 0
+ jr nz,.didNotGoThroughDoor
+ ld a,(SFX_02_57 - SFX_Headers_02) / 3
+ jr .playSound
+.didNotGoThroughDoor
+ ld a,(SFX_02_5c - SFX_Headers_02) / 3
+.playSound
+ call PlaySound
+ ld a,[wMapPalOffset]
+ and a
+ ret nz
+ jp GBFadeOutToBlack
+
+CheckIfInOutsideMap:: ; 0712 (0:0712)
+; If the player is in an outside map (a town or route), set the z flag
+ ld a, [W_CURMAPTILESET]
+ and a ; most towns/routes have tileset 0 (OVERWORLD)
+ ret z
+ cp PLATEAU ; Route 23 / Indigo Plateau
+ ret
+
+; this function is an extra check that sometimes has to pass in order to warp, beyond just standing on a warp
+; the "sometimes" qualification is necessary because of CheckWarpsNoCollision's behavior
+; depending on the map, either "function 1" or "function 2" is used for the check
+; "function 1" passes when the player is at the edge of the map and is facing towards the outside of the map
+; "function 2" passes when the the tile in front of the player is among a certain set
+; sets carry if the check passes, otherwise clears carry
+ExtraWarpCheck:: ; 071a (0:071a)
+ ld a, [W_CURMAP]
+ cp SS_ANNE_3
+ jr z, .useFunction1
+ cp ROCKET_HIDEOUT_1
+ jr z, .useFunction2
+ cp ROCKET_HIDEOUT_2
+ jr z, .useFunction2
+ cp ROCKET_HIDEOUT_4
+ jr z, .useFunction2
+ cp ROCK_TUNNEL_1
+ jr z, .useFunction2
+ ld a, [W_CURMAPTILESET]
+ and a ; outside tileset (OVERWORLD)
+ jr z, .useFunction2
+ cp SHIP ; S.S. Anne tileset
+ jr z, .useFunction2
+ cp SHIP_PORT ; Vermilion Port tileset
+ jr z, .useFunction2
+ cp PLATEAU ; Indigo Plateau tileset
+ jr z, .useFunction2
+.useFunction1
+ ld hl, IsPlayerFacingEdgeOfMap
+ jr .doBankswitch
+.useFunction2
+ ld hl, IsWarpTileInFrontOfPlayer
+.doBankswitch
+ ld b, BANK(IsWarpTileInFrontOfPlayer)
+ jp Bankswitch
+
+MapEntryAfterBattle:: ; 0750 (0:0750)
+ callba IsPlayerStandingOnWarp ; for enabling warp testing after collisions
+ ld a,[wMapPalOffset]
+ and a
+ jp z,GBFadeInFromWhite
+ jp LoadGBPal
+
+HandleBlackOut:: ; 0762 (0:0762)
+; For when all the player's pokemon faint.
+; Does not print the "blacked out" message.
+
+ call GBFadeOutToBlack
+ ld a, $08
+ call StopMusic
+ ld hl, wd72e
+ res 5, [hl]
+ callsb ResetStatusAndHalveMoneyOnBlackout ; also Bank(SpecialWarpIn) and Bank(SpecialEnterMap)
+ callab Func_f0274 ; 3c:4274
+ call SpecialWarpIn
+ call Func_2312
+ jp SpecialEnterMap
+
+StopMusic:: ; 0788 (0:0788)
+ ld [wMusicHeaderPointer], a
+ call StopAllMusic
+.wait
+ ld a, [wMusicHeaderPointer]
+ and a
+ jr nz, .wait
+ jp StopAllSounds
+
+HandleFlyWarpOrDungeonWarp:: ; 0794 (0:0794)
+ call UpdateSprites
+ call Delay3
+ xor a
+ ld [wBattleResult], a
+ ld [wWalkBikeSurfState], a
+ ld [W_ISINBATTLE], a
+ ld [wMapPalOffset], a
+ ld hl, wd732
+ set 2, [hl] ; fly warp or dungeon warp
+ res 5, [hl] ; forced to ride bike
+ call LeaveMapAnim
+ call LoadPlayerSpriteGraphics
+ callsb SpecialWarpIn
+ jp SpecialEnterMap
+
+LeaveMapAnim:: ; 07bc (0:07bc)
+ ld b, BANK(_LeaveMapAnim)
+ ld hl, _LeaveMapAnim
+ jp Bankswitch
+
+Func_07c4:: ; 07c4 (0:07c4)
+ ld a, [wWalkBikeSurfState]
+ and a
+ ret z
+ xor a
+ ld [wWalkBikeSurfState],a
+ ld hl,wd732
+ bit 4,[hl]
+ ret z
+ call PlayDefaultMusic
+ ret
+
+LoadPlayerSpriteGraphics:: ; 07d7 (0:07d7)
+; Load sprite graphics based on whether the player is standing, biking, or surfing.
+
+ ; 0: standing
+ ; 1: biking
+ ; 2: surfing
+
+ ld a, [wWalkBikeSurfState]
+ dec a
+ jr z, .ridingBike
+
+ ld a, [hTilesetType]
+ and a
+ jr nz, .determineGraphics
+ jr .startWalking
+
+.ridingBike
+ ; If the bike can't be used,
+ ; start walking instead.
+ call IsBikeRidingAllowed
+ jr c, .determineGraphics
+
+.startWalking
+ xor a
+ ld [wWalkBikeSurfState], a
+ ld [wWalkBikeSurfStateCopy], a
+ jp LoadWalkingPlayerSpriteGraphics
+
+.determineGraphics
+ ld a, [wWalkBikeSurfState]
+ and a
+ jp z, LoadWalkingPlayerSpriteGraphics
+ dec a
+ jp z, LoadBikePlayerSpriteGraphics
+ dec a
+ jp z, LoadSurfingPlayerSpriteGraphics
+ jp LoadWalkingPlayerSpriteGraphics
+
+IsBikeRidingAllowed:: ; 0805 (0:0805)
+; The bike can be used on Route 23 and Indigo Plateau,
+; or maps with tilesets in BikeRidingTilesets.
+; Return carry if biking is allowed.
+
+ ld a, [W_CURMAP]
+ cp ROUTE_23
+ jr z, .allowed
+ cp INDIGO_PLATEAU
+ jr z, .allowed
+
+ ld a, [W_CURMAPTILESET]
+ ld b, a
+ ld hl, BikeRidingTilesets
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .allowed
+ inc a
+ jr nz, .loop
+ and a
+ ret
+
+.allowed
+ scf
+ ret
+
+INCLUDE "data/bike_riding_tilesets.asm"
+
+; load the tile pattern data of the current tileset into VRAM
+LoadTilesetTilePatternData:: ; 0828 (0:0828)
+ ld a,[W_TILESETGFXPTR]
+ ld l,a
+ ld a,[W_TILESETGFXPTR + 1]
+ ld h,a
+ ld de,vTileset
+ ld bc,$600
+ ld a,[W_TILESETBANK]
+ jp FarCopyData2
+
+; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8
+; it can also load partial tile maps of connected maps into a border of length 3 around the current map
+LoadTileBlockMap:: ; 083c (0:083c)
+; fill C6E8-CBFB with the background tile
+ ld hl,wOverworldMap
+ ld bc,$0514
+ ld a,[wd3ad] ; background tile number
+ call FillMemory
+; load tile map of current map (made of tile block IDs)
+; a 3-byte border at the edges of the map is kept so that there is space for map connections
+ ld hl,wOverworldMap
+ ld a,[W_CURMAPWIDTH]
+ ld [$ff8c],a
+ add a,$06 ; border (east and west)
+ ld [$ff8b],a ; map width + border
+ ld b,$00
+ ld c,a
+; make space for north border (next 3 lines)
+ add hl,bc
+ add hl,bc
+ add hl,bc
+ ld c,$03
+ add hl,bc ; this puts us past the (west) border
+ ld a,[W_MAPDATAPTR] ; tile map pointer
+ ld e,a
+ ld a,[W_MAPDATAPTR + 1]
+ ld d,a ; de = tile map pointer
+ ld a,[W_CURMAPHEIGHT]
+ ld b,a
+.rowLoop ; copy one row each iteration
+ push hl
+ ld a,[$ff8c] ; map width (without border)
+ ld c,a
+.rowInnerLoop
+ ld a,[de]
+ inc de
+ ld [hli],a
+ dec c
+ jr nz,.rowInnerLoop
+; add the map width plus the border to the base address of the current row to get the next row's address
+ pop hl
+ ld a,[$ff8b] ; map width + border
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ dec b
+ jr nz,.rowLoop
+.northConnection
+ ld a,[W_MAPCONN1PTR]
+ cp a,$ff
+ jr z,.southConnection
+ call SwitchToMapRomBank
+ ld a,[wd372]
+ ld l,a
+ ld a,[wd373]
+ ld h,a
+ ld a,[wd374]
+ ld e,a
+ ld a,[wd375]
+ ld d,a
+ ld a,[wd376]
+ ld [$ff8b],a
+ ld a,[wd377]
+ ld [$ff8c],a
+ call LoadNorthSouthConnectionsTileMap
+.southConnection
+ ld a,[W_MAPCONN2PTR]
+ cp a,$ff
+ jr z,.westConnection
+ call SwitchToMapRomBank
+ ld a,[wd37d]
+ ld l,a
+ ld a,[wd37e]
+ ld h,a
+ ld a,[wd37f]
+ ld e,a
+ ld a,[wd380]
+ ld d,a
+ ld a,[wd381]
+ ld [$ff8b],a
+ ld a,[wd382]
+ ld [$ff8c],a
+ call LoadNorthSouthConnectionsTileMap
+.westConnection
+ ld a,[W_MAPCONN3PTR]
+ cp a,$ff
+ jr z,.eastConnection
+ call SwitchToMapRomBank
+ ld a,[wd388]
+ ld l,a
+ ld a,[wd389]
+ ld h,a
+ ld a,[wd38a]
+ ld e,a
+ ld a,[wd38b]
+ ld d,a
+ ld a,[wd38c]
+ ld b,a
+ ld a,[wd38d]
+ ld [$ff8b],a
+ call LoadEastWestConnectionsTileMap
+.eastConnection
+ ld a,[W_MAPCONN4PTR]
+ cp a,$ff
+ jr z,.done
+ call SwitchToMapRomBank
+ ld a,[wd393]
+ ld l,a
+ ld a,[wd394]
+ ld h,a
+ ld a,[wd395]
+ ld e,a
+ ld a,[wd396]
+ ld d,a
+ ld a,[wd397]
+ ld b,a
+ ld a,[wd398]
+ ld [$ff8b],a
+ call LoadEastWestConnectionsTileMap
+.done
+ ret
+
+LoadNorthSouthConnectionsTileMap:: ; 0919 (0:0919)
+ ld c,$03
+.loop
+ push de
+ push hl
+ ld a,[$ff8b] ; width of connection
+ ld b,a
+.innerLoop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec b
+ jr nz,.innerLoop
+ pop hl
+ pop de
+ ld a,[$ff8c] ; width of connected map
+ add l
+ ld l,a
+ jr nc,.noCarry1
+ inc h
+.noCarry1
+ ld a,[W_CURMAPWIDTH]
+ add a,$06
+ add e
+ ld e,a
+ jr nc,.noCarry2
+ inc d
+.noCarry2
+ dec c
+ jr nz,.loop
+ ret
+
+LoadEastWestConnectionsTileMap:: ; 093d (0:093d)
+ push hl
+ push de
+ ld c,$03
+.innerLoop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec c
+ jr nz,.innerLoop
+ pop de
+ pop hl
+ ld a,[$ff8b] ; width of connected map
+ add l
+ ld l,a
+ jr nc,.noCarry1
+ inc h
+.noCarry1
+ ld a,[W_CURMAPWIDTH]
+ add a,$06
+ add e
+ ld e,a
+ jr nc,.noCarry2
+ inc d
+.noCarry2
+ dec b
+ jr nz,LoadEastWestConnectionsTileMap
+ ret
+
+; function to check if there is a sign or sprite in front of the player
+; if so, carry is set. otherwise, carry is cleared
+IsSpriteOrSignInFrontOfPlayer:: ; 095e (0:095e)
+ xor a
+ ld [hSpriteIndexOrTextID],a
+ ld a,[wd4b0] ; number of signs in the map
+ and a
+ jr z,.extendRangeOverCounter
+; if there are signs
+ predef GetTileAndCoordsInFrontOfPlayer ; get the coordinates in front of the player in de
+ call SignLoop
+ ret c
+.extendRangeOverCounter
+; check if the player is front of a counter in a pokemon center, pokemart, etc. and if so, extend the range at which he can talk to the NPC
+ predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player in c
+ ld hl,W_TILESETTALKINGOVERTILES ; list of tiles that extend talking range (counter tiles)
+ ld b,$03
+ ld d,$20 ; talking range in pixels (long range)
+.counterTilesLoop
+ ld a,[hli]
+ cp c
+ jr z,IsSpriteInFrontOfPlayer2 ; jumps if the tile in front of the player is a counter tile
+ dec b
+ jr nz,.counterTilesLoop
+
+; sets carry flag if a sprite is in front of the player, resets if not
+IsSpriteInFrontOfPlayer:: ; 0983 (0:0983)
+ ld d,$10 ; talking range in pixels (normal range)
+IsSpriteInFrontOfPlayer2:: ; 0985 (0:0985)
+ ld bc,$3c40 ; Y and X position of player sprite
+ ld a,[wSpriteStateData1 + 9] ; direction the player is facing
+.checkIfPlayerFacingUp
+ cp a,$04
+ jr nz,.checkIfPlayerFacingDown
+; facing up
+ ld a,b
+ sub d
+ ld b,a
+ ld a,$08
+ jr .doneCheckingDirection
+.checkIfPlayerFacingDown
+ cp a,$00
+ jr nz,.checkIfPlayerFacingRight
+; facing down
+ ld a,b
+ add d
+ ld b,a
+ ld a,$04
+ jr .doneCheckingDirection
+.checkIfPlayerFacingRight
+ cp a,$0c
+ jr nz,.playerFacingLeft
+; facing right
+ ld a,c
+ add d
+ ld c,a
+ ld a,$01
+ jr .doneCheckingDirection
+.playerFacingLeft
+; facing left
+ ld a,c
+ sub d
+ ld c,a
+ ld a,$02
+.doneCheckingDirection
+ ld [wd52a],a
+ ld hl,wSpriteStateData1 + $10
+; yellow does not have the "if sprites are existant" check
+ ld e,$01
+ ld d,$f
+.spriteLoop
+ push hl
+ ld a,[hli] ; image (0 if no sprite)
+ and a
+ jr z,.nextSprite
+ inc l
+ ld a,[hli] ; sprite visibility
+ inc a
+ jr z,.nextSprite
+ inc l
+ ld a,[hli] ; Y location
+ cp b
+ jr nz,.nextSprite
+ inc l
+ ld a,[hl] ; X location
+ cp c
+ jr z,.foundSpriteInFrontOfPlayer
+.nextSprite
+ pop hl
+ ld a,l
+ add a,$10
+ ld l,a
+ inc e
+ dec d
+ jr nz,.spriteLoop
+ xor a
+ ret
+.foundSpriteInFrontOfPlayer
+ pop hl
+ ld a,l
+ and a,$f0
+ inc a
+ ld l,a
+ set 7,[hl]
+ ld a,e
+ ld [hSpriteIndexOrTextID],a
+ ld a,[hSpriteIndexOrTextID] ; possible useless read because a already has the value of the read address
+ cp a,$f
+ jr nz,.dontwritetowd436
+ ld a,$FF
+ ld [wd436],a
+.dontwritetowd436
+ scf
+ ret
+
+SignLoop:: ; 09f2 (0:09f2)
+; search if a player is facing a sign
+ ld hl,wd4b1 ; start of sign coordinates
+ ld a,[wd4b0] ; number of signs in the map
+ ld b,a
+ ld c,$00
+.signLoop
+ inc c
+ ld a,[hli] ; sign Y
+ cp d
+ jr z,.yCoordMatched
+ inc hl
+ jr .retry
+.yCoordMatched
+ ld a,[hli] ; sign X
+ cp e
+ jr nz,.retry
+.xCoordMatched
+; found sign
+ push hl
+ push bc
+ ld hl,wd4d1 ; start of sign text ID's
+ ld b,$00
+ dec c
+ add hl,bc
+ ld a,[hl]
+ ld [hSpriteIndexOrTextID],a ; store sign text ID
+ pop bc
+ pop hl
+ scf
+ ret
+.retry
+ dec b
+ jr nz,.signLoop
+ xor a
+ ret
+
+; function to check if the player will jump down a ledge and check if the tile ahead is passable (when not surfing)
+; sets the carry flag if there is a collision, and unsets it if there isn't a collision
+CollisionCheckOnLand:: ; 0a1c (0:0a1c)
+ ld a,[wd736]
+ bit 6,a ; is the player jumping?
+ jr nz,.noCollision
+; if not jumping a ledge
+ ld a,[wSimulatedJoypadStatesIndex]
+ and a
+ jr nz,.noCollision ; no collisions when the player's movements are being controlled by the game
+ ld a,[wd52a] ; the direction that the player is trying to go in
+ ld d,a
+ ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
+ and d ; check if a sprite is in the direction the player is trying to go
+ nop ; ??? why is this in the code
+ jr nz,.collision
+ xor a
+ ld [hSpriteIndexOrTextID],a
+ call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision?
+ jr nc,.asm_0a5c
+ res 7,[hl]
+ ld a,[hSpriteIndexOrTextID]
+ and a ; was there a sprite collision?
+ jr z,.asm_0a5c
+; if no sprite collision
+ cp $f
+ jr nz,.collision
+ call CheckForJumpingAndTilePairCollisions
+ jr nz,.collision
+ ld a,[hJoyHeld]
+ and $2
+ jr nz,.asm_0a5c
+ ld hl,wd435
+ ld a,[hl]
+ and a
+ jr z,.asm_0a5c
+ dec [hl]
+ jr nz,.collision
+.asm_0a5c
+ ld hl,TilePairCollisionsLand
+ call CheckForJumpingAndTilePairCollisions
+ jr c,.collision
+ call CheckTilePassable
+ jr nc,.noCollision
+.collision
+ ld a,[wc02a]
+ cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
+ jr z,.setCarry
+ ld a,(SFX_02_5b - SFX_Headers_02) / 3
+ call PlaySound ; play collision sound (if it's not already playing)
+.setCarry
+ scf
+ ret
+.noCollision
+ and a
+ ret
+
+; function that checks if the tile in front of the player is passable
+; clears carry if it is, sets carry if not
+CheckTilePassable:: ; 0a79 (0:0a79)
+ predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player
+ ld a,[wTileInFrontOfPlayer] ; tile in front of player
+ ld c,a
+ call IsTilePassable
+ ret
+
+; check if the player is going to jump down a small ledge
+; and check for collisions that only occur between certain pairs of tiles
+; Input: hl - address of directional collision data
+; sets carry if there is a collision and unsets carry if not
+CheckForJumpingAndTilePairCollisions:: ; 0a86 (0:0a86)
+ push hl
+ predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player
+ push de
+ push bc
+ callba HandleLedges ; check if the player is trying to jump a ledge
+ pop bc
+ pop de
+ pop hl
+ and a
+ ld a,[wd736]
+ bit 6,a ; is the player jumping?
+ ret nz
+; if not jumping
+
+CheckForTilePairCollisions2:: ; 0aa0 (0:0aa0)
+ aCoord 8, 9 ; tile the player is on
+ ld [wcf0e],a
+
+CheckForTilePairCollisions:: ; 0aa6 (0:0aa6)
+ ld a,[wTileInFrontOfPlayer]
+ ld c,a
+.tilePairCollisionLoop
+ ld a,[W_CURMAPTILESET] ; tileset number
+ ld b,a
+ ld a,[hli]
+ cp a,$ff
+ jr z,.noMatch
+ cp b
+ jr z,.tilesetMatches
+ inc hl
+.retry
+ inc hl
+ jr .tilePairCollisionLoop
+.tilesetMatches
+ ld a,[wcf0e] ; tile the player is on
+ ld b,a
+ ld a,[hl]
+ cp b
+ jr z,.currentTileMatchesFirstInPair
+ inc hl
+ ld a,[hl]
+ cp b
+ jr z,.currentTileMatchesSecondInPair
+ jr .retry
+.currentTileMatchesFirstInPair
+ inc hl
+ ld a,[hl]
+ cp c
+ jr z,.foundMatch
+ jr .tilePairCollisionLoop
+.currentTileMatchesSecondInPair
+ dec hl
+ ld a,[hli]
+ cp c
+ inc hl
+ jr nz,.tilePairCollisionLoop
+.foundMatch
+ scf
+ ret
+.noMatch
+ and a
+ ret
+
+; FORMAT: tileset number, tile 1, tile 2
+; terminated by 0xFF
+; these entries indicate that the player may not cross between tile 1 and tile 2
+; it's mainly used to simulate differences in elevation
+
+TilePairCollisionsLand:: ; 0ada (0:0ada)
+ db CAVERN, $20, $05
+ db CAVERN, $41, $05
+ db FOREST, $30, $2E
+ db CAVERN, $2A, $05
+ db CAVERN, $05, $21
+ db FOREST, $52, $2E
+ db FOREST, $55, $2E
+ db FOREST, $56, $2E
+ db FOREST, $20, $2E
+ db FOREST, $5E, $2E
+ db FOREST, $5F, $2E
+ db $FF
+
+TilePairCollisionsWater:: ; 0afc (0:0afc)
+ db FOREST, $14, $2E
+ db FOREST, $48, $2E
+ db CAVERN, $14, $05
+ db $FF
+
+; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character
+LoadCurrentMapView:: ; 0b06 (0:0b06)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[W_TILESETBANK] ; tile data ROM bank
+ call BankswitchCommon ; switch to ROM bank that contains tile data
+ ld a,[wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view
+ ld e,a
+ ld a,[wCurrentTileBlockMapViewPointer + 1]
+ ld d,a
+ ld hl,wTileMapBackup
+ ld b,$05
+.rowLoop ; each loop iteration fills in one row of tile blocks
+ push hl
+ push de
+ ld c,$06
+.rowInnerLoop ; loop to draw each tile block of the current row
+ push bc
+ push de
+ push hl
+ ld a,[de]
+ ld c,a ; tile block number
+ call DrawTileBlock
+ pop hl
+ pop de
+ pop bc
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ inc de
+ dec c
+ jr nz,.rowInnerLoop
+; update tile block map pointer to next row's address
+ pop de
+ ld a,[W_CURMAPWIDTH]
+ add a,$06
+ add e
+ ld e,a
+ jr nc,.noCarry
+ inc d
+.noCarry
+; update tile map pointer to next row's address
+ pop hl
+ ld a,$60
+ add l
+ ld l,a
+ jr nc,.noCarry2
+ inc h
+.noCarry2
+ dec b
+ jr nz,.rowLoop
+ ld hl,wTileMapBackup
+ ld bc,$0000
+.adjustForYCoordWithinTileBlock
+ ld a,[W_YBLOCKCOORD]
+ and a
+ jr z,.adjustForXCoordWithinTileBlock
+ ld bc,$0030
+ add hl,bc
+.adjustForXCoordWithinTileBlock
+ ld a,[W_XBLOCKCOORD]
+ and a
+ jr z,.copyToVisibleAreaBuffer
+ ld bc,$0002
+ add hl,bc
+.copyToVisibleAreaBuffer
+ ld de,wTileMap ; base address for the tiles that are directly transfered to VRAM during V-blank
+ ld b,$12
+.rowLoop2
+ ld c,$14
+.rowInnerLoop2
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec c
+ jr nz,.rowInnerLoop2
+ ld a,$04
+ add l
+ ld l,a
+ jr nc,.noCarry3
+ inc h
+.noCarry3
+ dec b
+ jr nz,.rowLoop2
+ pop af
+ call BankswitchCommon ; restore previous ROM bank
+ ret
+
+AdvancePlayerSprite:: ; 0b7f (0:0b7f)
+ ld a,[wUpdateSpritesEnabled]
+ push af
+ ld a,$FF
+ ld [wUpdateSpritesEnabled],a
+ ld hl, _AdvancePlayerSorite ; 3c:410c
+ ld b, BANK(_AdvancePlayerSprite)
+ call Bankswitch
+ pop af
+ ld [wUpdateSpritesEnabled],a
+ ret
+
+; the following 6 functions are used to tell the V-blank handler to redraw
+; the portion of the map that was newly exposed due to the player's movement
+
+ScheduleNorthRowRedraw:: ; 0b95 (0:0b95)
+ hlCoord 0, 0
+ call CopyToScreenEdgeTiles
+ ld a,[wMapViewVRAMPointer]
+ ld [H_SCREENEDGEREDRAWADDR],a
+ ld a,[wMapViewVRAMPointer + 1]
+ ld [H_SCREENEDGEREDRAWADDR + 1],a
+ ld a,REDRAWROW
+ ld [H_SCREENEDGEREDRAW],a
+ ret
+
+CopyToScreenEdgeTiles:: ; 0baa (0:0baa)
+ ld de,wScreenEdgeTiles
+ ld c,2 * 20
+.loop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec c
+ jr nz,.loop
+ ret
+
+ScheduleSouthRowRedraw:: ; 0bb6 (0:0bb6)
+ hlCoord 0, 16
+ call CopyToScreenEdgeTiles
+ ld a,[wMapViewVRAMPointer]
+ ld l,a
+ ld a,[wMapViewVRAMPointer + 1]
+ ld h,a
+ ld bc,$0200
+ add hl,bc
+ ld a,h
+ and a,$03
+ or a,$98
+ ld [H_SCREENEDGEREDRAWADDR + 1],a
+ ld a,l
+ ld [H_SCREENEDGEREDRAWADDR],a
+ ld a,REDRAWROW
+ ld [H_SCREENEDGEREDRAW],a
+ ret
+
+ScheduleEastColumnRedraw:: ; 0bd6 (0:0bd7)
+ hlCoord 18, 0
+ call ScheduleColumnRedrawHelper
+ ld a,[wMapViewVRAMPointer]
+ ld c,a
+ and a,$e0
+ ld b,a
+ ld a,c
+ add a,18
+ and a,$1f
+ or b
+ ld [H_SCREENEDGEREDRAWADDR],a
+ ld a,[wMapViewVRAMPointer + 1]
+ ld [H_SCREENEDGEREDRAWADDR + 1],a
+ ld a,REDRAWCOL
+ ld [H_SCREENEDGEREDRAW],a
+ ret
+
+ScheduleColumnRedrawHelper:: ; 0bf6 (0:0bf6)
+ ld de,wScreenEdgeTiles
+ ld c,$12
+.loop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ ld a,[hl]
+ ld [de],a
+ inc de
+ ld a,19
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ dec c
+ jr nz,.loop
+ ret
+
+ScheduleWestColumnRedraw:: ; 0c0c (0:0c0c)
+ hlCoord 0, 0
+ call ScheduleColumnRedrawHelper
+ ld a,[wMapViewVRAMPointer]
+ ld [H_SCREENEDGEREDRAWADDR],a
+ ld a,[wMapViewVRAMPointer + 1]
+ ld [H_SCREENEDGEREDRAWADDR + 1],a
+ ld a,REDRAWCOL
+ ld [H_SCREENEDGEREDRAW],a
+ ret
+
+; function to write the tiles that make up a tile block to memory
+; Input: c = tile block ID, hl = destination address
+DrawTileBlock:: ; 0c21 (0:0c21)
+ push hl
+ ld a,[W_TILESETBLOCKSPTR] ; pointer to tiles
+ ld l,a
+ ld a,[W_TILESETBLOCKSPTR + 1]
+ ld h,a
+ ld a,c
+ swap a
+ ld b,a
+ and a,$f0
+ ld c,a
+ ld a,b
+ and a,$0f
+ ld b,a ; bc = tile block ID * 0x10
+ add hl,bc
+ ld d,h
+ ld e,l ; de = address of the tile block's tiles
+ pop hl
+ ld c,$04 ; 4 loop iterations
+.loop ; each loop iteration, write 4 tile numbers
+ push bc
+ ld a,[de]
+ ld [hli],a
+ inc de
+ ld a,[de]
+ ld [hli],a
+ inc de
+ ld a,[de]
+ ld [hli],a
+ inc de
+ ld a,[de]
+ ld [hl],a
+ inc de
+ ld bc,$0015
+ add hl,bc
+ pop bc
+ dec c
+ jr nz,.loop
+ ret
+
+; function to update joypad state and simulate button presses
+JoypadOverworld:: ; 0c51 (0:0c51)
+ xor a
+ ld [wSpriteStateData1 + 3],a
+ ld [wSpriteStateData1 + 5],a
+ call RunMapScript
+ call Joypad
+ call ForceBikeDown
+ call AreInputsSimulated
+ ret
+
+ForceBikeDown:: ; 0c65 (0:0c65)
+ ld a,[W_FLAGS_D733]
+ bit 3,a ; check if a trainer wants a challenge
+ ret nz
+ ld a,[W_CURMAP]
+ cp a,ROUTE_17 ; Cycling Road
+ ret nz
+ ld a,[hJoyHeld]
+ and a,D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
+ jr nz,.notForcedDownwards
+ ld a,D_DOWN
+ ld [hJoyHeld],a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press
+ ret
+
+AreInputsSimulated:: ; 0c7b (0:0c7b)
+ ld a,[wd730]
+ bit 7,a
+ ret z
+; if simulating button presses
+ ld a,[hJoyHeld]
+ ld b,a
+ ld a,[wOverrideSimulatedJoypadStatesMask] ; bit mask for button presses that override simulated ones
+ and b
+ ret nz ; return if the simulated button presses are overridden
+ call GetSimulatedInput
+ jr nc,.doneSimulating
+ ld [hJoyHeld],a ; store simulated button press in joypad state
+ and a
+ ret nz
+ ld [hJoyPressed],a
+ ld [hJoyReleased],a
+ ret
+
+; if done simulating button presses
+.doneSimulating
+ xor a
+ ld [wWastedByteCD3A],a
+ ld [wSimulatedJoypadStatesIndex],a
+ ld [wSimulatedJoypadStatesEnd],a
+ ld [wJoyIgnore],a
+ ld [hJoyHeld],a
+ ld hl,wd736
+ ld a,[hl]
+ and a,$f8
+ ld [hl],a
+ ld hl,wd730
+ res 7,[hl]
+ ret
+
+GetSimulatedInput:: ; 0cb3 (0:0cb3)
+ ld hl,wSimulatedJoypadStatesIndex
+ dec [hl]
+ ld a,[hl]
+ cp a,$ff
+ jr z,.endofsimulatedinputs ; if the end of the simulated button presses has been reached
+ push de
+ ld e,a
+ ld d,$0
+ ld hl,wSimulatedJoypadStatesEnd
+ add hl,de
+ ld a,[hl]
+ pop de
+ scf
+ ret
+.endofsimulatedinputs
+ and a
+ ret
+
+
+; function to check the tile ahead to determine if the character should get on land or keep surfing
+; sets carry if there is a collision and clears carry otherwise
+; It seems that this function has a bug in it, but due to luck, it doesn't
+; show up. After detecting a sprite collision, it jumps to the code that
+; checks if the next tile is passable instead of just directly jumping to the
+; "collision detected" code. However, it doesn't store the next tile in c,
+; so the old value of c is used. 2429 is always called before this function,
+; and 2429 always sets c to 0xF0. There is no 0xF0 background tile, so it
+; is considered impassable and it is detected as a collision.
+CollisionCheckOnWater:: ; 0cca (0:0cca)
+ ld a,[wd730]
+ bit 7,a
+ jp nz,.noCollision ; return and clear carry if button presses are being simulated
+ ld a,[wd52a] ; the direction that the player is trying to go in
+ ld d,a
+ ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
+ and d ; check if a sprite is in the direction the player is trying to go
+ jr nz,.checkIfNextTileIsPassable ; bug?
+ ld hl,TilePairCollisionsWater
+ call CheckForJumpingAndTilePairCollisions
+ jr c,.collision
+ predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player (puts it in c and [wTileInFrontOfPlayer])
+ callab IsNextTileShoreOrWater ; 3:6808
+ jr c,.noCollsion
+ ld a,[wTileInFrontOfPlayer] ; tile in front of player
+ ld c,a
+ call IsTilePassable
+ jr nc,.stopSurfing
+.collision
+ ld a,[wc02a]
+ cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
+ jr z,.setCarry
+ ld a,(SFX_02_5b - SFX_Headers_02) / 3
+ call PlaySound ; play collision sound (if it's not already playing)
+.setCarry
+ scf
+ jr .done
+.checkIfVermilionDockTileset
+ ld a, [W_CURMAPTILESET] ; tileset
+ cp SHIP_PORT ; Vermilion Dock tileset
+ jr nz, .noCollision ; keep surfing if it's not the boarding platform tile
+ jr .stopSurfing ; if it is the boarding platform tile, stop surfing
+.stopSurfing ; based game freak
+ ld a,$3
+ ld [wd431],a
+ ld hl,wd430
+ set 5,[hl]
+ xor a
+ ld [wWalkBikeSurfState],a
+ call LoadPlayerSpriteGraphics
+ call PlayDefaultMusic
+ jr .noCollision
+.noCollision ; ...and they do the same mistake twice
+ and a
+.done
+ ret
+
+; function to run the current map's script
+RunMapScript:: ; 0d2c (0:0d2c)
+ push hl
+ push de
+ push bc
+ callba TryPushingBoulder
+ ld a,[wFlags_0xcd60]
+ bit 1,a ; play boulder dust animation
+ jr z,.afterBoulderEffect
+ callba DoBoulderDustAnimation
+.afterBoulderEffect
+ pop bc
+ pop de
+ pop hl
+ call RunNPCMovementScript
+ ld a,[W_CURMAP] ; current map number
+ call SwitchToMapRomBank ; change to the ROM bank the map's data is in
+ ld hl,W_MAPSCRIPTPTR
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld de,.return
+ push de
+ jp [hl] ; jump to script
+.return
+ ret
+
+Func_0d5e:: ; 0d5e (0:0d5e)
+; new sprite copy stuff
+ xor a
+ ld [wd473],a
+ ld b,BANK(RedSprite)
+ ld de,RedSprite ; $4180
+ jr LoadPlayerSpriteGraphicsCommon
+
+Func_0d69:: ; 0d69 (0:0d69)
+ ld a,[wd473]
+ and a
+ jr z,.asm_0d75
+ dec a
+ jr z,.asm_0d83
+ dec a
+ jr z,.asm_0d7c
+.asm_0d75
+ ld a,[wd472]
+ bit 6,a
+ jr z,LoadSurfingPlayerSpriteGraphics
+.asm_0d7c
+ ld b,BANK(Pointer_fedef)
+ ld de,Pointer_fedef ; 3f:6def
+ jr LoadPlayerSpriteGraphicsCommon
+
+LoadSurfingPlayerSpriteGraphics:: ; 0d83 (0:0d83)
+ ld b,BANK(RedSprite) ; not sure, but probably same bank (5)
+ ld de,SeelSprite
+ jr LoadPlayerSpriteGraphicsCommon
+
+LoadBikePlayerSpriteGraphics:: ; 0d8a (0:0d8a)
+ ld de,RedCyclingSprite
+LoadPlayerSpriteGraphicsCommon:: ; 0d8f (0:0d8f)
+ ld hl,vNPCSprites
+ push de
+ push hl
+ ld c, $c
+ call CopyVideoData
+ pop hl
+ pop de
+ ld a,$c0
+ add e
+ ld e,a
+ jr nc,.noCarry
+ inc d
+.noCarry
+ set 3,h
+ ld c,$c
+ jp CopyVideoData
+
+; function to load data from the map header
+LoadMapHeader:: ; 0dab (0:0dab)
+ callba MarkTownVisitedAndLoadMissableObjects
+ jr .asm_0dbd
+ callba Func_f0a55 ; 3c:4a55
+.asm_0dbd
+ ld a,[W_CURMAPTILESET]
+ ld [wd119],a
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ ld a,[W_CURMAPTILESET]
+ ld b,a
+ res 7,a
+ ld [W_CURMAPTILESET],a
+ ld [$ff8b],a
+ bit 7,b
+ ret nz
+ call GetMapHeaderPointer
+; copy the first 10 bytes (the fixed area) of the map data to D367-D370
+ ld de,W_CURMAPTILESET
+ ld c,$0a
+.copyFixedHeaderLoop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec c
+ jr nz,.copyFixedHeaderLoop
+; initialize all the connected maps to disabled at first, before loading the actual values
+ ld a,$ff
+ ld [W_MAPCONN1PTR],a
+ ld [W_MAPCONN2PTR],a
+ ld [W_MAPCONN3PTR],a
+ ld [W_MAPCONN4PTR],a
+; copy connection data (if any) to WRAM
+ ld a,[W_MAPCONNECTIONS]
+ ld b,a
+.checkNorth
+ bit 3,b
+ jr z,.checkSouth
+ ld de,W_MAPCONN1PTR
+ call CopyMapConnectionHeader
+.checkSouth
+ bit 2,b
+ jr z,.checkWest
+ ld de,W_MAPCONN2PTR
+ call CopyMapConnectionHeader
+.checkWest
+ bit 1,b
+ jr z,.checkEast
+ ld de,W_MAPCONN3PTR
+ call CopyMapConnectionHeader
+.checkEast
+ bit 0,b
+ jr z,.getObjectDataPointer
+ ld de,W_MAPCONN4PTR
+ call CopyMapConnectionHeader
+.getObjectDataPointer
+ ld a,[hli]
+ ld [wd3a9],a
+ ld a,[hli]
+ ld [wd3aa],a
+ push hl
+ ld a,[wd3a9]
+ ld l,a
+ ld a,[wd3aa]
+ ld h,a ; hl = base of object data
+ ld de,wd3ad ; background tile ID
+ ld a,[hli]
+ ld [de],a ; save background tile ID
+.loadWarpData
+ ld a,[hli]
+ ld [wNumberOfWarps],a
+ and a
+ jr z,.loadSignData
+ ld c,a
+ ld de,wWarpEntries
+.warpLoop ; one warp per loop iteration
+ ld b,$04
+.warpInnerLoop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec b
+ jr nz,.warpInnerLoop
+ dec c
+ jr nz,.warpLoop
+.loadSignData
+ ld a,[hli] ; number of signs
+ ld [wd4b0],a ; save the number of signs
+ and a ; are there any signs?
+ jr z,.loadSpriteData ; if not, skip this
+ call CopySignData ; 0eb3 (0:0eb3)
+.loadSpriteData
+ ld a,[wd72e]
+ bit 5,a ; did a battle happen immediately before this?
+ jp nz,.finishUp ; if so, skip this because battles don't destroy this data
+ call InitSprites
+.finishUp
+ predef LoadTilesetHeader
+ ld a,[wd72e]
+ bit 5,a ; did a battle happen immediately before this?
+ jr nz,.asm_0e73
+ callab Func_fc4fa ; 3f:44fa
+ callab LoadWildData
+ pop hl ; restore hl from before going to the warp/sign/sprite data (this value was saved for seemingly no purpose)
+ ld a,[W_CURMAPHEIGHT] ; map height in 4x4 tile blocks
+ add a ; double it
+ ld [wd524],a ; store map height in 2x2 tile blocks
+ ld a,[W_CURMAPWIDTH] ; map width in 4x4 tile blocks
+ add a ; double it
+ ld [wd525],a ; map width in 2x2 tile blocks
+ ld a,[W_CURMAP]
+ ld c,a
+ ld b,$00
+ ld a,[H_LOADEDROMBANK]
+ push af
+ switchbank MapSongBanks
+ ld hl, MapSongBanks ; 3f:4000
+ add hl,bc
+ add hl,bc
+ ld a,[hli]
+ ld [wd35b],a ; music 1
+ ld a,[hl]
+ ld [wd35c],a ; music 2
+ pop af
+ call BankswitchCommon
+ ret
+
+; function to copy map connection data from ROM to WRAM
+; Input: hl = source, de = destination
+CopyMapConnectionHeader:: ; 1238 (0:1238)
+ ld c,$0b
+.loop
+ ld a,[hli]
+ ld [de],a
+ inc de
+ dec c
+ jr nz,.loop
+ ret
+
+CopySignData:: ; 0eb3 (0:0eb3)
+ ld de,wd4b1 ; start of sign coords
+ ld bc,wd4d1 ; start of sign text ids
+ ld a,[wd4b0] ; number of signs
+.signcopyloop
+ push af
+ ld a,[hli]
+ ld [de],a ; copy y coord
+ inc de
+ ld a,[hli]
+ ld [de],a ; copy x coord
+ inc de
+ ld a,[hli]
+ ld [bc],a ; copy sign text id
+ inc bc
+ pop af
+ dec a
+ jr nz,.signcopyloop
+ ret
+
+; function to load map data
+LoadMapData:: ; 1241 (0:1241)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ call DisableLCD
+ call ResetMapVariables
+ call LoadTextBoxTilePatterns
+ call LoadMapHeader
+ call InitMapSprites ; load tile pattern data for sprites
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld a,$01
+ ld [wUpdateSpritesEnabled],a
+ call EnableLCD
+ ld b,$09
+ call GoPAL_SET
+ call LoadPlayerSpriteGraphics
+ ld a,[wd732]
+ and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jr nz,.restoreRomBank
+ ld a,[W_FLAGS_D733]
+ bit 1,a
+ jr nz,.restoreRomBank
+ call Func_235f ; music related
+ call Func_2312 ; music related
+.restoreRomBank
+ pop af
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a
+ ret
+
+LoadScreenRelatedData:: ; 0f0c (0:0f0c)
+ call LoadTileBlockMap
+ call LoadTilesetTilePatternData
+ call LoadCurrentMapView
+ ret
+
+Func_0f16:: ; 0f16 (0:0f16)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ call DisableLCD
+ call ResetMapVariables
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld de,vBGMap1
+ call CopyMapViewToVRAM2
+ call EnableLCD
+ call ReloadMapSpriteTilePatterns
+ pop af
+ call BankswitchCommon
+ jr .asm_0f4d
+Func_0f3d:: ; 0f3d (0:0f3d)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call LoadTileBlockMap
+ pop af
+ call BankswitchCommon
+.asm_0f4d
+ ld hl, Func_f02da
+ ld b,BANK(Func_f02da) ; 3c:42da
+ jp Bankswitch
+ ret ; useless?
+
+ResetMapVariables:: ; 0f56 (0:0f56)
+ ld a,$98
+ ld [wMapViewVRAMPointer + 1],a
+ xor a
+ ld [wMapViewVRAMPointer],a
+ ld [hSCY],a
+ ld [hSCX],a
+ ld [wWalkCounter],a
+ ld [wd119],a
+ ld [W_SPRITESETID],a
+ ld [wWalkBikeSurfStateCopy],a
+ ret
+
+CopyMapViewToVRAM:: ; 0f70 (0:0f70)
+; copy current map view to VRAM
+ ld de,vBGMap0
+CopyMapViewToVRAM2: ; 0f73 (0:0f73)
+ ld hl,wTileMap
+ ld b,18
+.vramCopyLoop
+ ld c,20
+.vramCopyInnerLoop
+ ld a,[hli]
+ ld [de],a
+ inc e
+ dec c
+ jr nz,.vramCopyInnerLoop
+ ld a,32 - 20 ; total vram map width in tiles - screen width in tiles
+ add e
+ ld e,a
+ jr nc,.noCarry
+ inc d
+.noCarry
+ dec b
+ jr nz,.vramCopyLoop
+ ret
+
+; function to switch to the ROM bank that a map is stored in
+; Input: a = map number
+SwitchToMapRomBank:: ; 0f8b (0:0f8b)
+ push hl
+ push bc
+ ld c,a
+ ld b,$00
+ ld a,BANK(MapHeaderBanks)
+ call BankswitchHome ; switch to ROM bank 3F
+ ld hl,MapHeaderBanks
+ add hl,bc
+ ld a,[hl]
+ ld [$ffe8],a ; save map ROM bank
+ call BankswitchCommon
+ pop bc
+ pop hl
+ ret
+
+GetMapHeaderPointer:: ; 0fa7 (0:0fa7)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ switchbank Pointer_fc1f2 ; 3f:41f2
+ push de
+ ld a,[W_CURMAP]
+ ld e,a
+ ld d,$0
+ ld hl,Pointer_fc1f2
+ add hl,de
+ add hl,de
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ pop de
+ pop af
+ jp BankswitchCommon
+
+IgnoreInputForHalfSecond: ; 0fc3 (0:0fc3)
+ ld a, 30
+ ld [wIgnoreInputCounter], a
+ ld hl, wd730
+ ld a, [hl]
+ or $26
+ ld [hl], a ; set ignore input bit
+ ret
+
+ResetUsingStrengthOutOfBattleBit: ; 0fd0 (0:0fd0)
+ ld hl, wd728
+ res 0, [hl]
+ ret
+
+ForceBikeOrSurf:: ; 0fd6 (0:0fd6)
+ ld b, BANK(RedSprite)
+ ld hl, LoadPlayerSpriteGraphics
+ call Bankswitch
+ jp PlayDefaultMusic ; update map/player state?
+
+; Handle the player jumping down
+; a ledge in the overworld.
+HandleMidJump:: ; 0fe1 (0:0fe1)
+ ld a,[wd736]
+ bit 7,a ; jumping down a ledge?
+ ret z
+ ld b, BANK(_HandleMidJump)
+ ld hl, _HandleMidJump
+ jp Bankswitch
+
+IsSpinning:: ; 0ff0 (0:0ff0)
+ ld a,[wd736]
+ bit 7,a
+ ret z ; no spinning
+ ld b, BANK(LoadSpinnerArrowTiles); spin while moving
+ ld hl,LoadSpinnerArrowTiles ; 11:5077
+ jp Bankswitch
+
+Func_0ffe:: ; 0ffe (0:0ffe)
+ ld hl, Func_fcf0c ; 3f:4f0c
+ ld b, BANK(Func_fcf0c)
+ jp Bankswitch
+
+InitSprites:: ; 1006 (0:1006)
+ ld a,[hli]
+ ld [W_NUMSPRITES],a ; save the number of sprites
+ push hl
+ push hl
+ push de
+ push bc
+ call ZeroSpriteStateData
+ call DisableRegularSprites
+ ld hl,W_MAPSPRITEDATA
+ ld bc,$20
+ xor a
+ call FillMemory
+ pop bc
+ pop de
+ pop hl
+ ld a,[W_NUMSPRITES]
+ and a ; are sprites existant?
+ ret z ; don't copy sprite data if not
+ ld b,a
+ ld c,$0
+ ld de,wSpriteStateData1 + $10
+; copy sprite stuff?
+.loadSpriteLoop
+ ld a,[hli]
+ ld [de],a ; store picture ID at C1X0
+ inc d
+ ld a,$04
+ add e
+ ld e,a
+ ld a,[hli]
+ ld [de],a ; store Y position at C2X4
+ inc e
+ ld a,[hli]
+ ld [de],a ; store X position at C2X5
+ inc e
+ ld a,[hli]
+ ld [de],a ; store movement byte 1 at C2X6
+ ld a,[hli]
+ ld [$ff8d],a ; save movement byte 2
+ ld a,[hli]
+ ld [$ff8e],a ; save text ID and flags byte
+ push bc
+ call LoadSprite
+ pop bc
+ dec d
+ ld a,e
+ add a,$a
+ ld e,a
+ inc c
+ inc c
+ dec b
+ jr nz,.loadSpriteLoop
+ ret
+
+ZeroSpriteStateData:: ; 1050 (0:1050)
+; zero C110-C1EF and C210-C2EF
+; C1F0-C1FF and C2F0-C2FF is probably used for Pikachu
+ ld hl,wSpriteStateData1 + $10
+ ld de,wSpriteStateData2 + $10
+ xor a
+ ld b,$e0
+.loop
+ ld [hli],a
+ ld [de],a
+ inc e
+ dec b
+ jr nz,.loop
+ ret
+
+DisableRegularSprites:: ; 1060 (0:1060)
+; initialize all C100-C1FF sprite entries to disabled (other than player's and pikachu)
+ ld hl,wSpriteStateData1 + $12
+ ld de,$10
+ ld c,$e
+.loop
+ ld [hl],$ff
+ add hl,de
+ dec c
+ jr nz,.loop
+ ret
+
+LoadSprite:: ; 106f (0:106f)
+ push hl
+ ld b,$0
+ ld hl,W_MAPSPRITEDATA
+ add hl,bc
+ ld a,[$ff8d]
+ ld [hli],a ; store movement byte 2 in byte 0 of sprite entry
+ ld a,[$ff8e]
+ ld [hl],a ; this appears pointless, since the value is overwritten immediately after
+ ld a,[$ff8e]
+ ld [$ff8d],a
+ and a,$3f
+ ld [hl],a ; store text ID in byte 1 of sprite entry
+ pop hl
+ ld a,[$ff8d]
+ bit 6,a
+ jr nz,.trainerSprite
+ bit 7,a
+ jr nz,.itemBallSprite
+; for regular sprites
+ push hl
+ ld hl,W_MAPSPRITEEXTRADATA
+ add hl,bc
+; zero both bytes, since regular sprites don't use this extra space
+ xor a
+ ld [hli],a
+ ld [hl],a
+ pop hl
+ ret
+
+.trainerSprite
+ ld a,[hli]
+ ld [$ff8d],a ; save trainer class
+ ld a,[hli]
+ ld [$ff8e],a ; save trainer number (within class)
+ push hl
+ ld hl,W_MAPSPRITEEXTRADATA
+ add hl,bc
+ ld a,[$ff8d]
+ ld [hli],a ; store trainer class in byte 0 of the entry
+ ld a,[$ff8e]
+ ld [hl],a ; store trainer number in byte 1 of the entry
+ pop hl
+ ret
+
+.itemBallSprite
+ ld a,[hli]
+ ld [$ff8d],a ; save item number
+ push hl
+ ld hl,W_MAPSPRITEEXTRADATA
+ add hl,bc
+ ld a,[$ff8d]
+ ld [hli],a ; store item number in byte 0 of the entry
+ xor a
+ ld [hl],a ; zero byte 1, since it is not used
+ pop hl
+ ret ; end of home/overworld.asm = 10b9 (0:10b9) \ No newline at end of file
diff --git a/macros.asm b/macros.asm
index 4a97e236..0f79fa74 100644
--- a/macros.asm
+++ b/macros.asm
@@ -1,569 +1,600 @@
-
-text EQUS "db $00," ; Start writing text.
-next EQUS "db $4e," ; Move a line down.
-line EQUS "db $4f," ; Start writing at the bottom line.
-para EQUS "db $51," ; Start a new paragraph.
-cont EQUS "db $55," ; Scroll to the next line.
-done EQUS "db $57" ; End a text box.
-prompt EQUS "db $58" ; Prompt the player to end a text box (initiating some other event).
-
-page EQUS "db $49," ; Start a new Pokedex page.
-dex EQUS "db $5f, $50" ; End a Pokedex entry.
-
-
-percent EQUS "* $ff / 100"
-
-
-; Constant enumeration is useful for monsters, items, moves, etc.
-const_def: MACRO
-const_value = 0
-ENDM
-
-const: MACRO
-\1 EQU const_value
-const_value = const_value + 1
-ENDM
-
-
-homecall_jump: MACRO
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(\1)
- call BankswitchCommon
- call \1
- pop af
- jp BankswitchCommon
- ENDM
-
-callba: MACRO
- ld b, BANK(\1)
- ld hl, \1
- call Bankswitch
- ENDM
-
-callab: MACRO
- ld hl, \1
- ld b, BANK(\1)
- call Bankswitch
- ENDM
-
-bcd2: MACRO
- dn ((\1) / 1000) % 10, ((\1) / 100) % 10
- dn ((\1) / 10) % 10, (\1) % 10
- ENDM
-
-bcd3: MACRO
- dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
- dn ((\1) / 1000) % 10, ((\1) / 100) % 10
- dn ((\1) / 10) % 10, (\1) % 10
- ENDM
-
-coins equs "bcd2"
-money equs "bcd3"
-
-;\1 = X
-;\2 = Y
-hlCoord: MACRO
- ld hl, wTileMap + 20 * \2 + \1
- ENDM
-
-;\1 = X
-;\2 = Y
-deCoord: MACRO
- ld de, wTileMap + 20 * \2 + \1
- ENDM
-
-;\1 = X
-;\2 = Y
-bcCoord: MACRO
- ld bc, wTileMap + 20 * \2 + \1
- ENDM
-
-;\1 = X
-;\2 = Y
-aCoord: MACRO
- ld a, [wTileMap + 20 * \2 + \1]
- ENDM
-
-;\1 = X
-;\2 = Y
-Coorda: MACRO
- ld [wTileMap + 20 * \2 + \1], a
- ENDM
-
-;\1 = X
-;\2 = Y
-dwCoord: MACRO
- dw wTileMap + 20 * \2 + \1
- ENDM
-
-;\1 = Map Width
-;\2 = Rows above (Y-blocks)
-;\3 = X movement (X-blocks)
-EVENT_DISP: MACRO
- dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
- db \2,\3 ;Y,X
- ENDM
-
-FLYWARP_DATA: MACRO
- EVENT_DISP \1,\2,\3
- db ((\2) & $01) ;sub-block Y
- db ((\3) & $01) ;sub-block X
- ENDM
-
-; external map entry macro
-EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
-; the appearance of towns and routes in the town map, indexed by map id
- ; nybble: y-coordinate
- ; nybble: x-coordinate
- ; word : pointer to map name
- db (\1 + (\2 << 4))
- dw \3
- ENDM
-
-; internal map entry macro
-IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
-; the appearance of buildings and dungeons in the town map
- ; byte : maximum map id subject to this rule
- ; nybble: y-coordinate
- ; nybble: x-coordinate
- ; word : pointer to map name
- db \1
- db \2 + \3 << 4
- dw \4
- ENDM
-
-; tilesets' headers macro
-tileset: MACRO
- db BANK(\2) ; BANK(GFX)
- dw \1, \2, \3 ; Block, GFX, Coll
- db \4, \5, \6 ; counter tiles
- db \7 ; grass tile
- db \8 ; permission (indoor, cave, outdoor)
- ENDM
-
-INDOOR EQU 0
-CAVE EQU 1
-OUTDOOR EQU 2
-
-; macro for two nibbles
-dn: MACRO
- db (\1 << 4 | \2)
- ENDM
-
-; macro for putting a byte then a word
-dbw: MACRO
- db \1
- dw \2
- ENDM
-
-; data format macros
-RGB: MACRO
- dw (\3 << 10 | \2 << 5 | \1)
- ENDM
-
-; text macros
-TX_NUM: MACRO
-; print a big-endian decimal number.
-; \1: address to read from
-; \2: number of bytes to read
-; \3: number of digits to display
- db $09
- dw \1
- db \2 << 4 | \3
- ENDM
-
-TX_FAR: MACRO
- db $17
- dw \1
- db BANK(\1)
- ENDM
-
-; text engine command $1
-TX_RAM: MACRO
-; prints text to screen
-; \1: RAM address to read from
- db $1
- dw \1
- ENDM
-
-TX_BCD: MACRO
- db $2
- dw \1
- db \2
- ENDM
-
-; Predef macro.
-add_predef: MACRO
-\1Predef::
- db BANK(\1)
- dw \1
- ENDM
-
-predef_id: MACRO
- ld a, (\1Predef - PredefPointers) / 3
- ENDM
-
-predef: MACRO
- predef_id \1
- call Predef
- ENDM
-
-predef_jump: MACRO
- predef_id \1
- jp Predef
- ENDM
-
-
-add_tx_pre: MACRO
-\1_id:: dw \1
-ENDM
-
-tx_pre_id: MACRO
- ld a, (\1_id - TextPredefs) / 2
-ENDM
-
-tx_pre: MACRO
- tx_pre_id \1
- call PrintPredefTextID
-ENDM
-
-tx_pre_jump: MACRO
- tx_pre_id \1
- jp PrintPredefTextID
-ENDM
-
-
-;1_channel EQU $00
-;2_channels EQU $40
-;3_channels EQU $80
-;4_channels EQU $C0
-
-CH0 EQU 0
-CH1 EQU 1
-CH2 EQU 2
-CH3 EQU 3
-CH4 EQU 4
-CH5 EQU 5
-CH6 EQU 6
-CH7 EQU 7
-
-unknownsfx0x10: MACRO
- db $10
- db \1
-ENDM
-
-unknownsfx0x20: MACRO
- db $20 | \1
- db \2
- db \3
- db \4
-ENDM
-
-unknownnoise0x20: MACRO
- db $20 | \1
- db \2
- db \3
-ENDM
-
-;format: pitch length (in 16ths)
-C_: MACRO
- db $00 | (\1 - 1)
-ENDM
-
-C#: MACRO
- db $10 | (\1 - 1)
-ENDM
-
-D_: MACRO
- db $20 | (\1 - 1)
-ENDM
-
-D#: MACRO
- db $30 | (\1 - 1)
-ENDM
-
-E_: MACRO
- db $40 | (\1 - 1)
-ENDM
-
-F_: MACRO
- db $50 | (\1 - 1)
-ENDM
-
-F#: MACRO
- db $60 | (\1 - 1)
-ENDM
-
-G_: MACRO
- db $70 | (\1 - 1)
-ENDM
-
-G#: MACRO
- db $80 | (\1 - 1)
-ENDM
-
-A_: MACRO
- db $90 | (\1 - 1)
-ENDM
-
-A#: MACRO
- db $A0 | (\1 - 1)
-ENDM
-
-B_: MACRO
- db $B0 | (\1 - 1)
-ENDM
-
-;format: instrument length (in 16ths)
-snare1: MACRO
- db $B0 | (\1 - 1)
- db $01
-ENDM
-
-snare2: MACRO
- db $B0 | (\1 - 1)
- db $02
-ENDM
-
-snare3: MACRO
- db $B0 | (\1 - 1)
- db $03
-ENDM
-
-snare4: MACRO
- db $B0 | (\1 - 1)
- db $04
-ENDM
-
-snare5: MACRO
- db $B0 | (\1 - 1)
- db $05
-ENDM
-
-triangle1: MACRO
- db $B0 | (\1 - 1)
- db $06
-ENDM
-
-triangle2: MACRO
- db $B0 | (\1 - 1)
- db $07
-ENDM
-
-snare6: MACRO
- db $B0 | (\1 - 1)
- db $08
-ENDM
-
-snare7: MACRO
- db $B0 | (\1 - 1)
- db $09
-ENDM
-
-snare8: MACRO
- db $B0 | (\1 - 1)
- db $0A
-ENDM
-
-snare9: MACRO
- db $B0 | (\1 - 1)
- db $0B
-ENDM
-
-cymbal1: MACRO
- db $B0 | (\1 - 1)
- db $0C
-ENDM
-
-cymbal2: MACRO
- db $B0 | (\1 - 1)
- db $0D
-ENDM
-
-cymbal3: MACRO
- db $B0 | (\1 - 1)
- db $0E
-ENDM
-
-mutedsnare1: MACRO
- db $B0 | (\1 - 1)
- db $0F
-ENDM
-
-triangle3: MACRO
- db $B0 | (\1 - 1)
- db $10
-ENDM
-
-mutedsnare2: MACRO
- db $B0 | (\1 - 1)
- db $11
-ENDM
-
-mutedsnare3: MACRO
- db $B0 | (\1 - 1)
- db $12
-ENDM
-
-mutedsnare4: MACRO
- db $B0 | (\1 - 1)
- db $13
-ENDM
-
-;format: rest length (in 16ths)
-rest: MACRO
- db $C0 | (\1 - 1)
-ENDM
-
-; format: notetype speed, volume, fade
-notetype: MACRO
- db $D0 | \1
- db (\2 << 4) | \3
-ENDM
-
-dspeed: MACRO
- db $D0 | \1
-ENDM
-
-octave: MACRO
- db $E8 - \1
-ENDM
-
-toggleperfectpitch: MACRO
- db $E8
-ENDM
-
-;format: vibrato delay, rate, depth
-vibrato: MACRO
- db $EA
- db \1
- db (\2 << 4) | \3
-ENDM
-
-pitchbend: MACRO
- db $EB
- db \1
- db \2
-ENDM
-
-duty: MACRO
- db $EC
- db \1
-ENDM
-
-tempo: MACRO
- db $ED
- db \1 / $100
- db \1 % $100
-ENDM
-
-stereopanning: MACRO
- db $EE
- db \1
-ENDM
-
-volume: MACRO
- db $F0
- db (\1 << 4) | \2
-ENDM
-
-executemusic: MACRO
- db $F8
-ENDM
-
-dutycycle: MACRO
- db $FC
- db \1
-ENDM
-
-;format: callchannel address
-callchannel: MACRO
- db $FD
- dw \1
-ENDM
-
-;format: loopchannel count, address
-loopchannel: MACRO
- db $FE
- db \1
- dw \2
-ENDM
-
-endchannel: MACRO
- db $FF
-ENDM
-
-
-;\1 (byte) = connected map id
-;\2 (byte) = connected map width
-;\3 (byte) = connected map height
-;\4 (byte) = x movement of connection strip
-;\5 (byte) = connection strip offset
-;\6 (byte) = width of connection strip
-;\7 (word) = connected map blocks pointer
-NORTH_MAP_CONNECTION: MACRO
- db \1 ; map id
- dw \7 + (\2 * (\3 - 3)) + \5; "Connection Strip" location
- dw wOverworldMap + 3 + \4 ; current map position
- db \6 ; width of connection strip
- db \2 ; map width
- db (\3 * 2) - 1 ; y alignment (y coordinate of player when entering map)
- db (\4 - \5) * -2 ; x alignment (x coordinate of player when entering map)
- dw wOverworldMap + 1 + (\3 * (\2 + 6)) ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = connected map id
-;\2 (byte) = connected map width
-;\3 (byte) = x movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (byte) = width of connection strip
-;\6 (word) = connected map blocks pointer
-;\7 (byte) = current map width
-;\8 (byte) = current map height
-SOUTH_MAP_CONNECTION: MACRO
- db \1 ; map id
- dw \6 + \4 ; "Conection Strip" location
- dw wOverworldMap + 3 + (\8 + 3) * (\7 + 6) + \3 ; current map positoin
- db \5 ; width of connection strip
- db \2 ; map width
- db 0 ; y alignment (y coordinate of player when entering map)
- db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
- dw wOverworldMap + 7 + \2 ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = connected map id
-;\2 (byte) = connected map width
-;\3 (byte) = y movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (byte) = height of connection strip
-;\6 (word) = connected map blocks pointer
-;\7 (byte) = current map width
-EAST_MAP_CONNECTION: MACRO
- db \1 ; map id
- dw \6 + (\2 * \4) ; "Connection Strip" location
- dw wOverworldMap - 3 + (\7 + 6) * (\3 + 4) ; current map position
- db \5 ; height of connection strip
- db \2 ; map width
- db (\3 - \4) * -2 ; y alignment
- db 0 ; x alignment
- dw wOverworldMap + 7 + \2 ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = connected map id
-;\2 (byte) = connected map width
-;\3 (byte) = y movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (byte) = height of connection strip
-;\6 (word) = connected map blocks pointer
-;\7 (byte) = current map width
-WEST_MAP_CONNECTION: MACRO
- db \1 ; map id
- dw \6 + (\2 * \4) + \2 - 3 ; "Connection Strip" location
- dw wOverworldMap + (\7 + 6) * (\3 + 3) ; current map position
- db \5 ; height of connection strip
- db \2 ; map width
- db (\3 - \4) * -2 ; y alignment
- db (\2 * 2) - 1 ; x alignment
- dw wOverworldMap + 6 + (2 * \2) ; window (position of the upper left block after entring the map)
-ENDM
+
+text EQUS "db $00," ; Start writing text.
+next EQUS "db $4e," ; Move a line down.
+line EQUS "db $4f," ; Start writing at the bottom line.
+para EQUS "db $51," ; Start a new paragraph.
+cont EQUS "db $55," ; Scroll to the next line.
+done EQUS "db $57" ; End a text box.
+prompt EQUS "db $58" ; Prompt the player to end a text box (initiating some other event).
+
+page EQUS "db $49," ; Start a new Pokedex page.
+dex EQUS "db $5f, $50" ; End a Pokedex entry.
+
+
+percent EQUS "* $ff / 100"
+
+
+; Constant enumeration is useful for monsters, items, moves, etc.
+const_def: MACRO
+const_value = 0
+ENDM
+
+const: MACRO
+\1 EQU const_value
+const_value = const_value + 1
+ENDM
+
+
+homecall_jump: MACRO
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(\1)
+ call BankswitchCommon
+ call \1
+ pop af
+ jp BankswitchCommon
+ ENDM
+
+homecall: MACRO
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(\1)
+ call BankswitchCommon
+ call \1
+ pop af
+ call BankswitchCommon
+ ENDM
+
+homecall_sf: MACRO ; homecall but save flags by popping into bc instead of af
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(\1)
+ call BankswitchCommon
+ call \1
+ pop bc
+ ld a,b
+ call BankswitchCommon
+ ENDM
+
+switchbank: MACRO
+ ld a, BANK(\1)
+ call BankswitchCommon
+ ENDM
+
+callsb: MACRO
+ ld a, BANK(\1)
+ call BankswitchCommon
+ call \1
+
+callba: MACRO
+ ld b, BANK(\1)
+ ld hl, \1
+ call Bankswitch
+ ENDM
+
+callab: MACRO
+ ld hl, \1
+ ld b, BANK(\1)
+ call Bankswitch
+ ENDM
+
+bcd2: MACRO
+ dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+ dn ((\1) / 10) % 10, (\1) % 10
+ ENDM
+
+bcd3: MACRO
+ dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
+ dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+ dn ((\1) / 10) % 10, (\1) % 10
+ ENDM
+
+coins equs "bcd2"
+money equs "bcd3"
+
+;\1 = X
+;\2 = Y
+hlCoord: MACRO
+ ld hl, wTileMap + 20 * \2 + \1
+ ENDM
+
+;\1 = X
+;\2 = Y
+deCoord: MACRO
+ ld de, wTileMap + 20 * \2 + \1
+ ENDM
+
+;\1 = X
+;\2 = Y
+bcCoord: MACRO
+ ld bc, wTileMap + 20 * \2 + \1
+ ENDM
+
+;\1 = X
+;\2 = Y
+aCoord: MACRO
+ ld a, [wTileMap + 20 * \2 + \1]
+ ENDM
+
+;\1 = X
+;\2 = Y
+Coorda: MACRO
+ ld [wTileMap + 20 * \2 + \1], a
+ ENDM
+
+;\1 = X
+;\2 = Y
+dwCoord: MACRO
+ dw wTileMap + 20 * \2 + \1
+ ENDM
+
+;\1 = Map Width
+;\2 = Rows above (Y-blocks)
+;\3 = X movement (X-blocks)
+EVENT_DISP: MACRO
+ dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
+ db \2,\3 ;Y,X
+ ENDM
+
+FLYWARP_DATA: MACRO
+ EVENT_DISP \1,\2,\3
+ db ((\2) & $01) ;sub-block Y
+ db ((\3) & $01) ;sub-block X
+ ENDM
+
+; external map entry macro
+EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
+; the appearance of towns and routes in the town map, indexed by map id
+ ; nybble: y-coordinate
+ ; nybble: x-coordinate
+ ; word : pointer to map name
+ db (\1 + (\2 << 4))
+ dw \3
+ ENDM
+
+; internal map entry macro
+IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
+; the appearance of buildings and dungeons in the town map
+ ; byte : maximum map id subject to this rule
+ ; nybble: y-coordinate
+ ; nybble: x-coordinate
+ ; word : pointer to map name
+ db \1
+ db \2 + \3 << 4
+ dw \4
+ ENDM
+
+; tilesets' headers macro
+tileset: MACRO
+ db BANK(\2) ; BANK(GFX)
+ dw \1, \2, \3 ; Block, GFX, Coll
+ db \4, \5, \6 ; counter tiles
+ db \7 ; grass tile
+ db \8 ; permission (indoor, cave, outdoor)
+ ENDM
+
+INDOOR EQU 0
+CAVE EQU 1
+OUTDOOR EQU 2
+
+; macro for two nibbles
+dn: MACRO
+ db (\1 << 4 | \2)
+ ENDM
+
+; macro for putting a byte then a word
+dbw: MACRO
+ db \1
+ dw \2
+ ENDM
+
+; data format macros
+RGB: MACRO
+ dw (\3 << 10 | \2 << 5 | \1)
+ ENDM
+
+; text macros
+TX_NUM: MACRO
+; print a big-endian decimal number.
+; \1: address to read from
+; \2: number of bytes to read
+; \3: number of digits to display
+ db $09
+ dw \1
+ db \2 << 4 | \3
+ ENDM
+
+TX_FAR: MACRO
+ db $17
+ dw \1
+ db BANK(\1)
+ ENDM
+
+; text engine command $1
+TX_RAM: MACRO
+; prints text to screen
+; \1: RAM address to read from
+ db $1
+ dw \1
+ ENDM
+
+TX_BCD: MACRO
+ db $2
+ dw \1
+ db \2
+ ENDM
+
+; Predef macro.
+add_predef: MACRO
+\1Predef::
+ db BANK(\1)
+ dw \1
+ ENDM
+
+predef_id: MACRO
+ ld a, (\1Predef - PredefPointers) / 3
+ ENDM
+
+predef: MACRO
+ predef_id \1
+ call Predef
+ ENDM
+
+predef_jump: MACRO
+ predef_id \1
+ jp Predef
+ ENDM
+
+
+add_tx_pre: MACRO
+\1_id:: dw \1
+ENDM
+
+tx_pre_id: MACRO
+ ld a, (\1_id - TextPredefs) / 2
+ENDM
+
+tx_pre: MACRO
+ tx_pre_id \1
+ call PrintPredefTextID
+ENDM
+
+tx_pre_jump: MACRO
+ tx_pre_id \1
+ jp PrintPredefTextID
+ENDM
+
+
+;1_channel EQU $00
+;2_channels EQU $40
+;3_channels EQU $80
+;4_channels EQU $C0
+
+CH0 EQU 0
+CH1 EQU 1
+CH2 EQU 2
+CH3 EQU 3
+CH4 EQU 4
+CH5 EQU 5
+CH6 EQU 6
+CH7 EQU 7
+
+unknownsfx0x10: MACRO
+ db $10
+ db \1
+ENDM
+
+unknownsfx0x20: MACRO
+ db $20 | \1
+ db \2
+ db \3
+ db \4
+ENDM
+
+unknownnoise0x20: MACRO
+ db $20 | \1
+ db \2
+ db \3
+ENDM
+
+;format: pitch length (in 16ths)
+C_: MACRO
+ db $00 | (\1 - 1)
+ENDM
+
+C#: MACRO
+ db $10 | (\1 - 1)
+ENDM
+
+D_: MACRO
+ db $20 | (\1 - 1)
+ENDM
+
+D#: MACRO
+ db $30 | (\1 - 1)
+ENDM
+
+E_: MACRO
+ db $40 | (\1 - 1)
+ENDM
+
+F_: MACRO
+ db $50 | (\1 - 1)
+ENDM
+
+F#: MACRO
+ db $60 | (\1 - 1)
+ENDM
+
+G_: MACRO
+ db $70 | (\1 - 1)
+ENDM
+
+G#: MACRO
+ db $80 | (\1 - 1)
+ENDM
+
+A_: MACRO
+ db $90 | (\1 - 1)
+ENDM
+
+A#: MACRO
+ db $A0 | (\1 - 1)
+ENDM
+
+B_: MACRO
+ db $B0 | (\1 - 1)
+ENDM
+
+;format: instrument length (in 16ths)
+snare1: MACRO
+ db $B0 | (\1 - 1)
+ db $01
+ENDM
+
+snare2: MACRO
+ db $B0 | (\1 - 1)
+ db $02
+ENDM
+
+snare3: MACRO
+ db $B0 | (\1 - 1)
+ db $03
+ENDM
+
+snare4: MACRO
+ db $B0 | (\1 - 1)
+ db $04
+ENDM
+
+snare5: MACRO
+ db $B0 | (\1 - 1)
+ db $05
+ENDM
+
+triangle1: MACRO
+ db $B0 | (\1 - 1)
+ db $06
+ENDM
+
+triangle2: MACRO
+ db $B0 | (\1 - 1)
+ db $07
+ENDM
+
+snare6: MACRO
+ db $B0 | (\1 - 1)
+ db $08
+ENDM
+
+snare7: MACRO
+ db $B0 | (\1 - 1)
+ db $09
+ENDM
+
+snare8: MACRO
+ db $B0 | (\1 - 1)
+ db $0A
+ENDM
+
+snare9: MACRO
+ db $B0 | (\1 - 1)
+ db $0B
+ENDM
+
+cymbal1: MACRO
+ db $B0 | (\1 - 1)
+ db $0C
+ENDM
+
+cymbal2: MACRO
+ db $B0 | (\1 - 1)
+ db $0D
+ENDM
+
+cymbal3: MACRO
+ db $B0 | (\1 - 1)
+ db $0E
+ENDM
+
+mutedsnare1: MACRO
+ db $B0 | (\1 - 1)
+ db $0F
+ENDM
+
+triangle3: MACRO
+ db $B0 | (\1 - 1)
+ db $10
+ENDM
+
+mutedsnare2: MACRO
+ db $B0 | (\1 - 1)
+ db $11
+ENDM
+
+mutedsnare3: MACRO
+ db $B0 | (\1 - 1)
+ db $12
+ENDM
+
+mutedsnare4: MACRO
+ db $B0 | (\1 - 1)
+ db $13
+ENDM
+
+;format: rest length (in 16ths)
+rest: MACRO
+ db $C0 | (\1 - 1)
+ENDM
+
+; format: notetype speed, volume, fade
+notetype: MACRO
+ db $D0 | \1
+ db (\2 << 4) | \3
+ENDM
+
+dspeed: MACRO
+ db $D0 | \1
+ENDM
+
+octave: MACRO
+ db $E8 - \1
+ENDM
+
+toggleperfectpitch: MACRO
+ db $E8
+ENDM
+
+;format: vibrato delay, rate, depth
+vibrato: MACRO
+ db $EA
+ db \1
+ db (\2 << 4) | \3
+ENDM
+
+pitchbend: MACRO
+ db $EB
+ db \1
+ db \2
+ENDM
+
+duty: MACRO
+ db $EC
+ db \1
+ENDM
+
+tempo: MACRO
+ db $ED
+ db \1 / $100
+ db \1 % $100
+ENDM
+
+stereopanning: MACRO
+ db $EE
+ db \1
+ENDM
+
+volume: MACRO
+ db $F0
+ db (\1 << 4) | \2
+ENDM
+
+executemusic: MACRO
+ db $F8
+ENDM
+
+dutycycle: MACRO
+ db $FC
+ db \1
+ENDM
+
+;format: callchannel address
+callchannel: MACRO
+ db $FD
+ dw \1
+ENDM
+
+;format: loopchannel count, address
+loopchannel: MACRO
+ db $FE
+ db \1
+ dw \2
+ENDM
+
+endchannel: MACRO
+ db $FF
+ENDM
+
+
+;\1 (byte) = connected map id
+;\2 (byte) = connected map width
+;\3 (byte) = connected map height
+;\4 (byte) = x movement of connection strip
+;\5 (byte) = connection strip offset
+;\6 (byte) = width of connection strip
+;\7 (word) = connected map blocks pointer
+NORTH_MAP_CONNECTION: MACRO
+ db \1 ; map id
+ dw \7 + (\2 * (\3 - 3)) + \5; "Connection Strip" location
+ dw wOverworldMap + 3 + \4 ; current map position
+ db \6 ; width of connection strip
+ db \2 ; map width
+ db (\3 * 2) - 1 ; y alignment (y coordinate of player when entering map)
+ db (\4 - \5) * -2 ; x alignment (x coordinate of player when entering map)
+ dw wOverworldMap + 1 + (\3 * (\2 + 6)) ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = connected map id
+;\2 (byte) = connected map width
+;\3 (byte) = x movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (byte) = width of connection strip
+;\6 (word) = connected map blocks pointer
+;\7 (byte) = current map width
+;\8 (byte) = current map height
+SOUTH_MAP_CONNECTION: MACRO
+ db \1 ; map id
+ dw \6 + \4 ; "Conection Strip" location
+ dw wOverworldMap + 3 + (\8 + 3) * (\7 + 6) + \3 ; current map positoin
+ db \5 ; width of connection strip
+ db \2 ; map width
+ db 0 ; y alignment (y coordinate of player when entering map)
+ db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
+ dw wOverworldMap + 7 + \2 ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = connected map id
+;\2 (byte) = connected map width
+;\3 (byte) = y movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (byte) = height of connection strip
+;\6 (word) = connected map blocks pointer
+;\7 (byte) = current map width
+EAST_MAP_CONNECTION: MACRO
+ db \1 ; map id
+ dw \6 + (\2 * \4) ; "Connection Strip" location
+ dw wOverworldMap - 3 + (\7 + 6) * (\3 + 4) ; current map position
+ db \5 ; height of connection strip
+ db \2 ; map width
+ db (\3 - \4) * -2 ; y alignment
+ db 0 ; x alignment
+ dw wOverworldMap + 7 + \2 ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = connected map id
+;\2 (byte) = connected map width
+;\3 (byte) = y movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (byte) = height of connection strip
+;\6 (word) = connected map blocks pointer
+;\7 (byte) = current map width
+WEST_MAP_CONNECTION: MACRO
+ db \1 ; map id
+ dw \6 + (\2 * \4) + \2 - 3 ; "Connection Strip" location
+ dw wOverworldMap + (\7 + 6) * (\3 + 3) ; current map position
+ db \5 ; height of connection strip
+ db \2 ; map width
+ db (\3 - \4) * -2 ; y alignment
+ db (\2 * 2) - 1 ; x alignment
+ dw wOverworldMap + 6 + (2 * \2) ; window (position of the upper left block after entring the map)
+ENDM
diff --git a/main.asm b/main.asm
index 2a1e066a..3bbb41c8 100755
--- a/main.asm
+++ b/main.asm
@@ -1,6684 +1,6684 @@
-INCLUDE "constants.asm"
-
-NPC_SPRITES_1 EQU $4
-NPC_SPRITES_2 EQU $5
-
-GFX EQU $4
-
-PICS_1 EQU $9
-PICS_2 EQU $A
-PICS_3 EQU $B
-PICS_4 EQU $C
-PICS_5 EQU $D
-
-
-INCLUDE "home.asm"
-
-
-SECTION "bank1",ROMX,BANK[$1]
-
-INCLUDE "data/facing.asm"
-
-ResetStatusAndHalveMoneyOnBlackout::
-; Reset player status on blackout.
- xor a
- ld [wBattleResult], a
- ld [wWalkBikeSurfState], a
- ld [W_ISINBATTLE], a
- ld [wMapPalOffset], a
- ld [wNPCMovementScriptFunctionNum], a
- ld [hJoyHeld], a
- ld [wNPCMovementScriptPointerTableNum], a
- ld [wFlags_0xcd60], a
-
- ld [$ff9f], a
- ld [$ff9f + 1], a
- ld [$ff9f + 2], a
- call HasEnoughMoney
- jr c, .lostmoney ; never happens
-
- ; Halve the player's money.
- ld a, [wPlayerMoney]
- ld [$ff9f], a
- ld a, [wPlayerMoney + 1]
- ld [$ff9f + 1], a
- ld a, [wPlayerMoney + 2]
- ld [$ff9f + 2], a
- xor a
- ld [$ffa2], a
- ld [$ffa3], a
- ld a, 2
- ld [$ffa4], a
- predef DivideBCDPredef3
- ld a, [$ffa2]
- ld [wPlayerMoney], a
- ld a, [$ffa2 + 1]
- ld [wPlayerMoney + 1], a
- ld a, [$ffa2 + 2]
- ld [wPlayerMoney + 2], a
-
-.lostmoney
- ld hl, wd732
- set 2, [hl]
- res 3, [hl]
- set 6, [hl]
- ld a, %11111111
- ld [wJoyIgnore], a
- predef_jump HealParty
-
-
-MewPicFront:: INCBIN "pic/bmon/mew.pic"
-MewPicBack:: INCBIN "pic/monback/mewb.pic"
-INCLUDE "data/baseStats/mew.asm"
-
-INCLUDE "engine/battle/safari_zone.asm"
-
-INCLUDE "engine/titlescreen.asm"
-
-NintenText: db "NINTEN@"
-SonyText: db "SONY@"
-
-
-LoadMonData_:
-; Load monster [wWhichPokemon] from list [wcc49]:
-; 0: partymon
-; 1: enemymon
-; 2: boxmon
-; 3: daycaremon
-; Return monster id at wcf91 and its data at wLoadedMon.
-; Also load base stats at W_MONHDEXNUM for convenience.
-
- ld a, [wDayCareMonSpecies]
- ld [wcf91], a
- ld a, [wcc49]
- cp 3
- jr z, .GetMonHeader
-
- ld a, [wWhichPokemon]
- ld e, a
- callab GetMonSpecies
-
-.GetMonHeader
- ld a, [wcf91]
- ld [wd0b5], a ; input for GetMonHeader
- call GetMonHeader
-
- ld hl, wPartyMons
- ld bc, wPartyMon2 - wPartyMon1
- ld a, [wcc49]
- cp 1
- jr c, .getMonEntry
-
- ld hl, wEnemyMons
- jr z, .getMonEntry
-
- cp 2
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1
- jr z, .getMonEntry
-
- ld hl, wDayCareMon
- jr .copyMonData
-
-.getMonEntry
- ld a, [wWhichPokemon]
- call AddNTimes
-
-.copyMonData
- ld de, wLoadedMon
- ld bc, wPartyMon2 - wPartyMon1
- jp CopyData
-
-
-INCLUDE "data/item_prices.asm"
-INCLUDE "text/item_names.asm"
-
-UnusedNames:
- db "かみなりバッヂ@"
- db "かいがらバッヂ@"
- db "おじぞうバッヂ@"
- db "はやぶさバッヂ@"
- db "ひんやりバッヂ@"
- db "なかよしバッヂ@"
- db "バラバッヂ@"
- db "ひのたまバッヂ@"
- db "ゴールドバッヂ@"
- db "たまご@"
- db "ひよこ@"
- db "ブロンズ@"
- db "シルバー@"
- db "ゴールド@"
- db "プチキャプテン@"
- db "キャプテン@"
- db "プチマスター@"
- db "マスター@"
- db "エクセレント"
-
-INCLUDE "engine/overworld/oam.asm"
-INCLUDE "engine/oam_dma.asm"
-
-PrintWaitingText:
- hlCoord 3, 10
- ld b, $1
- ld c, $b
- ld a, [W_ISINBATTLE]
- and a
- jr z, .asm_4c17
- call TextBoxBorder
- jr .asm_4c1a
-.asm_4c17
- call CableClub_TextBoxBorder
-.asm_4c1a
- hlCoord 4, 11
- ld de, WaitingText
- call PlaceString
- ld c, 50
- jp DelayFrames
-
-WaitingText:
- db "Waiting...!@"
-
-
-_UpdateSprites: ; 4c34 (1:4c34)
- ld h, $c1
- inc h
- ld a, $e ; wSpriteStateData2 + $0e
-.spriteLoop
- ld l, a
- sub $e
- ld c, a
- ld [H_CURRENTSPRITEOFFSET], a
- ld a, [hl]
- and a
- jr z, .skipSprite ; tests $c2Xe
- push hl
- push de
- push bc
- call .updateCurrentSprite
- pop bc
- pop de
- pop hl
-.skipSprite
- ld a, l
- add $10 ; move to next sprite
- cp $e ; test for overflow (back at $0e)
- jr nz, .spriteLoop
- ret
-.updateCurrentSprite ; 4c54 (1:4c54)
- cp $1
- jp nz, UpdateNonPlayerSprite
- jp UpdatePlayerSprite
-
-UpdateNonPlayerSprite:
- dec a
- swap a
- ld [$ff93], a ; $10 * sprite#
- ld a, [wNPCMovementScriptSpriteOffset] ; some sprite offset?
- ld b, a
- ld a, [H_CURRENTSPRITEOFFSET]
- cp b
- jr nz, .unequal
- jp Func_5236
-.unequal
- jp Func_4ed1
-
-; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET)
-; is going to collide with another sprite by looping over the other sprites.
-; The current sprite's offset will be labelled with i (e.g. $c1i0).
-; The loop sprite's offset will labelled with j (e.g. $c1j0).
-;
-; Note that the Y coordinate of the sprite (in [$c1k4]) is one of the following
-; 9 values when the sprite is aligned with the grid: $fc, $0c, $1c, $2c, ..., $7c.
-; The reason that 4 is added below to the coordinate is to make it align with a
-; multiple of $10 to make comparisons easier.
-DetectCollisionBetweenSprites:
- nop
-
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- add wSpriteStateData1 % $100
- ld l, a
-
- ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused)
- and a ; is this sprite slot slot used?
- ret z ; return if not used
-
- ld a, l
- add 3
- ld l, a
-
- ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1)
- call SetSpriteCollisionValues
-
- ld a, [hli] ; a = [$C1i4] (Y screen coordinate)
- add 4 ; align with multiple of $10
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving south or
-; subtract 7 from a if moving north.
- add b
- and $f0
- or c
-
- ld [$ff90], a ; store Y coordinate adjusted for direction of movement
-
- ld a, [hli] ; a = [$c1i5] (delta X) (-1, 0, or 1)
- call SetSpriteCollisionValues
- ld a, [hl] ; a = [$C1i6] (X screen coordinate)
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving east or
-; subtract 7 from a if moving west.
- add b
- and $f0
- or c
-
- ld [$ff91], a ; store X coordinate adjusted for direction of movement
-
- ld a, l
- add 7
- ld l, a
-
- xor a
- ld [hld], a ; zero [$c1id] XXX what's [$c1id] for?
- ld [hld], a ; zero [$c1ic] (directions in which collisions occurred)
-
- ld a, [$ff91]
- ld [hld], a ; [$c1ib] = adjusted X coordiate
- ld a, [$ff90]
- ld [hl], a ; [$c1ia] = adjusted Y coordinate
-
- xor a ; zero the loop counter
-
-.loop
- ld [$ff8f], a ; store loop counter
- swap a
- ld e, a
- ld a, [H_CURRENTSPRITEOFFSET]
- cp e ; does the loop sprite match the current sprite?
- jp z, .next ; go to the next sprite if they match
-
- ld d, h
- ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused)
- and a ; is this sprite slot slot used?
- jp z, .next ; go the next sprite if not used
-
- inc e
- inc e
- ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen)
- inc a
- jp z, .next ; go the next sprite if offscreen
-
- ld a, [H_CURRENTSPRITEOFFSET]
- add 10
- ld l, a
-
- inc e
- ld a, [de] ; a = [$c1j3] (delta Y)
- call SetSpriteCollisionValues
-
- inc e
- ld a, [de] ; a = [$C1j4] (Y screen coordinate)
- add 4 ; align with multiple of $10
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving south or
-; subtract 7 from a if moving north.
- add b
- and $f0
- or c
-
- sub [hl] ; subtract the adjusted Y coordinate of sprite i ([$c1ia]) from that of sprite j
-
-; calculate the absolute value of the difference to get the distance
- jr nc, .noCarry1
- cpl
- inc a
-.noCarry1
- ld [$ff90], a ; store the distance between the two sprites' adjusted Y values
-
-; Use the carry flag set by the above subtraction to determine which sprite's
-; Y coordinate is larger. This information is used later to set [$c1ic],
-; which stores which direction the collision occurred in.
-; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2.
-; If sprite i's Y is larger, set lowest 2 bits of c to 10.
-; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01.
- push af
- rl c
- pop af
- ccf
- rl c
-
-; If sprite i's delta Y is 0, then b = 7, else b = 9.
- ld b, 7
- ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate)
- and $f
- jr z, .next1
- ld b, 9
-
-.next1
- ld a, [$ff90] ; a = distance between adjusted Y coordinates
- sub b
- ld [$ff92], a ; store distance adjusted using sprite i's direction
- ld a, b
- ld [$ff90], a ; store 7 or 9 depending on sprite i's delta Y
- jr c, .checkXDistance
-
-; If sprite j's delta Y is 0, then b = 7, else b = 9.
- ld b, 7
- dec e
- ld a, [de] ; a = [$c1j3] (delta Y)
- inc e
- and a
- jr z, .next2
- ld b, 9
-
-.next2
- ld a, [$ff92] ; a = distance adjusted using sprite i's direction
- sub b ; adjust distance using sprite j's direction
- jr z, .checkXDistance
- jr nc, .next ; go to next sprite if distance is still positive after both adjustments
-
-.checkXDistance
- inc e
- inc l
- ld a, [de] ; a = [$c1j5] (delta X)
-
- push bc
-
- call SetSpriteCollisionValues
- inc e
- ld a, [de] ; a = [$c1j6] (X screen coordinate)
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving east or
-; subtract 7 from a if moving west.
- add b
- and $f0
- or c
-
- pop bc
-
- sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j
-
-; calculate the absolute value of the difference to get the distance
- jr nc, .noCarry2
- cpl
- inc a
-.noCarry2
- ld [$ff91], a ; store the distance between the two sprites' adjusted X values
-
-; Use the carry flag set by the above subtraction to determine which sprite's
-; X coordinate is larger. This information is used later to set [$c1ic],
-; which stores which direction the collision occurred in.
-; The following 5 lines set the lowest 2 bits of c.
-; If sprite i's X is larger, set lowest 2 bits of c to 10.
-; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01.
- push af
- rl c
- pop af
- ccf
- rl c
-
-; If sprite i's delta X is 0, then b = 7, else b = 9.
- ld b, 7
- ld a, [hl] ; a = [$c1ib] (adjusted X coordinate)
- and $f
- jr z, .next3
- ld b, 9
-
-.next3
- ld a, [$ff91] ; a = distance between adjusted X coordinates
- sub b
- ld [$ff92], a ; store distance adjusted using sprite i's direction
- ld a, b
- ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X
- jr c, .collision
-
-; If sprite j's delta X is 0, then b = 7, else b = 9.
- ld b, 7
- dec e
- ld a, [de] ; a = [$c1j5] (delta X)
- inc e
- and a
- jr z, .next4
- ld b, 9
-
-.next4
- ld a, [$ff92] ; a = distance adjusted using sprite i's direction
- sub b ; adjust distance using sprite j's direction
- jr z, .collision
- jr nc, .next ; go to next sprite if distance is still positive after both adjustments
-
-.collision
- ld a, [$ff91] ; a = 7 or 9 depending on sprite i's delta X
- ld b, a
- ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y
- inc l
-
-; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100.
-; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa)
- cp b
- jr c, .next5
- ld b, %1100
- jr .next6
-.next5
- ld b, %0011
-
-.next6
- ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis)
- and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above
- or [hl] ; or with existing collision direction bits in [$c1ic]
- ld [hl], a ; store new value
- ld a, c ; useless code because a is overwritten before being used again
-
-; set bit in [$c1ie] or [$c1if] to indicate which sprite the collision occurred with
- inc l
- inc l
- ld a, [$ff8f] ; a = loop counter
- ld de, SpriteCollisionBitTable
- add a
- add e
- ld e, a
- jr nc, .noCarry3
- inc d
-.noCarry3
- ld a, [de]
- or [hl]
- ld [hli], a
- inc de
- ld a, [de]
- or [hl]
- ld [hl], a
-
-.next
- ld a, [$ff8f] ; a = loop counter
- inc a
- cp $10
- jp nz, .loop
- ret
-
-; takes delta X or delta Y in a
-; b = delta X/Y
-; c = 0 if delta X/Y is 0
-; c = 7 if delta X/Y is 1
-; c = 9 if delta X/Y is -1
-SetSpriteCollisionValues:
- and a
- ld b, 0
- ld c, 0
- jr z, .done
- ld c, 9
- cp -1
- jr z, .ok
- ld c, 7
- ld a, 0
-.ok
- ld b, a
-.done
- ret
-
-SpriteCollisionBitTable:
- db %00000000,%00000001
- db %00000000,%00000010
- db %00000000,%00000100
- db %00000000,%00001000
- db %00000000,%00010000
- db %00000000,%00100000
- db %00000000,%01000000
- db %00000000,%10000000
- db %00000001,%00000000
- db %00000010,%00000000
- db %00000100,%00000000
- db %00001000,%00000000
- db %00010000,%00000000
- db %00100000,%00000000
- db %01000000,%00000000
- db %10000000,%00000000
-
-TestBattle:
- ret
-
-.loop
- call GBPalNormal
-
- ; Don't mess around
- ; with obedience.
- ld a, %10000000 ; EARTHBADGE
- ld [W_OBTAINEDBADGES], a
-
- ld hl, W_FLAGS_D733
- set 0, [hl]
-
- ; Reset the party.
- ld hl, wPartyCount
- xor a
- ld [hli], a
- dec a
- ld [hl], a
-
- ; Give the player a
- ; level 20 Rhydon.
- ld a, RHYDON
- ld [wcf91], a
- ld a, 20
- ld [W_CURENEMYLVL], a
- xor a
- ld [wcc49], a
- ld [W_CURMAP], a
- call AddPartyMon
-
- ; Fight against a
- ; level 20 Rhydon.
- ld a, RHYDON
- ld [W_CUROPPONENT], a
-
- predef InitOpponent
-
- ; When the battle ends,
- ; do it all again.
- ld a, 1
- ld [wUpdateSpritesEnabled], a
- ld [H_AUTOBGTRANSFERENABLED], a
- jr .loop
-
-INCLUDE "engine/overworld/item.asm"
-INCLUDE "engine/overworld/movement.asm"
-
-INCLUDE "engine/cable_club.asm"
-
-LoadTrainerInfoTextBoxTiles: ; 5ae6 (1:5ae6)
- ld de, TrainerInfoTextBoxTileGraphics ; $7b98
- ld hl, vChars2 + $760
- ld bc, (BANK(TrainerInfoTextBoxTileGraphics) << 8) +$09
- jp CopyVideoData
-
-INCLUDE "engine/menu/main_menu.asm"
-
-INCLUDE "engine/oak_speech.asm"
-
-SpecialWarpIn: ; 62ce (1:62ce)
- call LoadSpecialWarpData
- predef LoadTilesetHeader
- ld hl,wd732
- bit 2,[hl] ; dungeon warp or fly warp?
- res 2,[hl]
- jr z,.next
-; if dungeon warp or fly warp
- ld a,[wDestinationMap]
- jr .next2
-.next
- bit 1,[hl]
- jr z,.next3
- call EmptyFunc
-.next3
- ld a,0
-.next2
- ld b,a
- ld a,[wd72d]
- and a
- jr nz,.next4
- ld a,b
-.next4
- ld hl,wd732
- bit 4,[hl] ; dungeon warp?
- ret nz
-; if not dungeon warp
- ld [wLastMap],a
- ret
-
-; gets the map ID, tile block map view pointer, tileset, and coordinates
-LoadSpecialWarpData: ; 62ff (1:62ff)
- ld a, [wd72d]
- cp BATTLE_CENTER
- jr nz, .notBattleCenter
- ld hl, BattleCenterSpec1
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right
- jr z, .copyWarpData
- ld hl, BattleCenterSpec2
- jr .copyWarpData
-.notBattleCenter
- cp TRADE_CENTER
- jr nz, .notTradeCenter
- ld hl, TradeCenterSpec1
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- jr z, .copyWarpData
- ld hl, TradeCenterSpec2
- jr .copyWarpData
-.notTradeCenter
- ld a, [wd732]
- bit 1, a
- jr nz, .notFirstMap
- bit 2, a
- jr nz, .notFirstMap
- ld hl, FirstMapSpec
-.copyWarpData
- ld de, W_CURMAP
- ld c, $7
-.copyWarpDataLoop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyWarpDataLoop
- ld a, [hli]
- ld [W_CURMAPTILESET], a
- xor a
- jr .done
-.notFirstMap
- ld a, [wLastMap]
- ld hl, wd732
- bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
- jr nz, .usedDunegonWarp
- bit 6, [hl] ; return to last pokemon center (or player's house)?
- res 6, [hl]
- jr z, .otherDestination
-; return to last pokemon center or player's house
- ld a, [wLastBlackoutMap]
- jr .usedFlyWarp
-.usedDunegonWarp
- ld hl, wd72d
- res 4, [hl]
- ld a, [wDungeonWarpDestinationMap]
- ld b, a
- ld [W_CURMAP], a
- ld a, [wWhichDungeonWarp]
- ld c, a
- ld hl, DungeonWarpList
- ld de, $0
- ld a, $6
- ld [wd12f], a
-.dungeonWarpListLoop
- ld a, [hli]
- cp b
- jr z, .matchedDungeonWarpDestinationMap
- inc hl
- jr .nextDungeonWarp
-.matchedDungeonWarpDestinationMap
- ld a, [hli]
- cp c
- jr z, .matchedDungeonWarpID
-.nextDungeonWarp
- ld a, [wd12f]
- add e
- ld e, a
- jr .dungeonWarpListLoop
-.matchedDungeonWarpID
- ld hl, DungeonWarpData
- add hl, de
- jr .copyWarpData2
-.otherDestination
- ld a, [wDestinationMap]
-.usedFlyWarp
- ld b, a
- ld [W_CURMAP], a
- ld hl, FlyWarpDataPtr
-.flyWarpDataPtrLoop
- ld a, [hli]
- inc hl
- cp b
- jr z, .foundFlyWarpMatch
- inc hl
- inc hl
- jr .flyWarpDataPtrLoop
-.foundFlyWarpMatch
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.copyWarpData2
- ld de, wCurrentTileBlockMapViewPointer
- ld c, $6
-.copyWarpDataLoop2
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyWarpDataLoop2
- xor a ; OVERWORLD
- ld [W_CURMAPTILESET], a
-.done
- ld [wYOffsetSinceLastSpecialWarp], a
- ld [wXOffsetSinceLastSpecialWarp], a
- ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps
- ld [wDestinationWarpID], a
- ret
-
-INCLUDE "data/special_warps.asm"
-
-; This function appears to never be used.
-; It is likely a debugging feature to give the player Tsunekazu Ishihara's
-; favorite Pokemon. This is indicated by the overpowered Exeggutor, which
-; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC
-; interview on February 8, 2000.
-; "Exeggutor is my favorite. That's because I was always using this character
-; while I was debugging the program."
-; http://www.ign.com/articles/2000/02/09/abc-news-pokamon-chat-transcript
-
-SetIshiharaTeam: ; 64ca (1:64ca)
- ld de, IshiharaTeam
-.loop
- ld a, [de]
- cp $ff
- ret z
- ld [wcf91], a
- inc de
- ld a, [de]
- ld [W_CURENEMYLVL], a
- inc de
- call AddPartyMon
- jr .loop
-
-IshiharaTeam: ; 64df (1:64df)
- db EXEGGUTOR,90
- db MEW,20
- db JOLTEON,56
- db DUGTRIO,56
- db ARTICUNO,57
- db $FF
-
-EmptyFunc: ; 64ea (1:64ea)
- ret
-
-INCLUDE "engine/menu/naming_screen.asm"
-
-INCLUDE "engine/oak_speech2.asm"
-
-; subtracts the amount the player paid from their money
-; sets carry flag if there is enough money and unsets carry flag if not
-SubtractAmountPaidFromMoney_: ; 6b21 (1:6b21)
- ld de,wPlayerMoney
- ld hl,$ff9f ; total price of items
- ld c,3 ; length of money in bytes
- call StringCmp
- ret c
- ld de,wPlayerMoney + 2
- ld hl,$ffa1 ; total price of items
- ld c,3 ; length of money in bytes
- predef SubBCDPredef ; subtract total price from money
- ld a,MONEY_BOX
- ld [wTextBoxID],a
- call DisplayTextBoxID ; redraw money text box
- and a
- ret
-
-HandleItemListSwapping: ; 6b44 (1:6b44)
- ld a,[wListMenuID]
- cp a,ITEMLISTMENU
- jp nz,DisplayListMenuIDLoop ; only rearrange item list menus
- push hl
- ld hl,wList
- ld a,[hli]
- ld h,[hl]
- ld l,a
- inc hl ; hl = beginning of list entries
- ld a,[wCurrentMenuItem]
- ld b,a
- ld a,[wListScrollOffset]
- add b
- add a
- ld c,a
- ld b,0
- add hl,bc ; hl = address of currently selected item entry
- ld a,[hl]
- pop hl
- inc a
- jp z,DisplayListMenuIDLoop ; ignore attempts to swap the Cancel menu item
- ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
- and a ; has the first item to swap already been chosen?
- jr nz,.swapItems
-; if not, set the currently selected item as the first item
- ld a,[wCurrentMenuItem]
- inc a
- ld b,a
- ld a,[wListScrollOffset] ; index of top (visible) menu item within the list
- add b
- ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1)
- ld c,20
- call DelayFrames
- jp DisplayListMenuIDLoop
-.swapItems
- ld a,[wCurrentMenuItem]
- inc a
- ld b,a
- ld a,[wListScrollOffset]
- add b
- ld b,a
- ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
- cp b ; is the currently selected item the same as the first item to swap?
- jp z,DisplayListMenuIDLoop ; ignore attempts to swap an item with itself
- dec a
- ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1)
- ld c,20
- call DelayFrames
- push hl
- push de
- ld hl,wList
- ld a,[hli]
- ld h,[hl]
- ld l,a
- inc hl ; hl = beginning of list entries
- ld d,h
- ld e,l ; de = beginning of list entries
- ld a,[wCurrentMenuItem]
- ld b,a
- ld a,[wListScrollOffset]
- add b
- add a
- ld c,a
- ld b,0
- add hl,bc ; hl = address of currently selected item entry
- ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
- add a
- add e
- ld e,a
- jr nc,.noCarry
- inc d
-.noCarry ; de = address of first item to swap
- ld a,[de]
- ld b,a
- ld a,[hli]
- cp b
- jr z,.swapSameItemType
-.swapDifferentItems
- ld [$ff95],a ; [$ff95] = second item ID
- ld a,[hld]
- ld [$ff96],a ; [$ff96] = second item quantity
- ld a,[de]
- ld [hli],a ; put first item ID in second item slot
- inc de
- ld a,[de]
- ld [hl],a ; put first item quantity in second item slot
- ld a,[$ff96]
- ld [de],a ; put second item quantity in first item slot
- dec de
- ld a,[$ff95]
- ld [de],a ; put second item ID in first item slot
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- pop de
- pop hl
- jp DisplayListMenuIDLoop
-.swapSameItemType
- inc de
- ld a,[hl]
- ld b,a
- ld a,[de]
- add b ; a = sum of both item quantities
- cp a,100 ; is the sum too big for one item slot?
- jr c,.combineItemSlots
-; swap enough items from the first slot to max out the second slot if they can't be combined
- sub a,99
- ld [de],a
- ld a,99
- ld [hl],a
- jr .done
-.combineItemSlots
- ld [hl],a ; put the sum in the second item slot
- ld hl,wList
- ld a,[hli]
- ld h,[hl]
- ld l,a
- dec [hl] ; decrease the number of items
- ld a,[hl]
- ld [wd12a],a ; update number of items variable
- cp a,1
- jr nz,.skipSettingMaxMenuItemID
- ld [wMaxMenuItem],a ; if the number of items is only one now, update the max menu item ID
-.skipSettingMaxMenuItemID
- dec de
- ld h,d
- ld l,e
- inc hl
- inc hl ; hl = address of item after first item to swap
-.moveItemsUpLoop ; erase the first item slot and move up all the following item slots to fill the gap
- ld a,[hli]
- ld [de],a
- inc de
- inc a ; reached the $ff terminator?
- jr z,.afterMovingItemsUp
- ld a,[hli]
- ld [de],a
- inc de
- jr .moveItemsUpLoop
-.afterMovingItemsUp
- xor a
- ld [wListScrollOffset],a
- ld [wCurrentMenuItem],a
-.done
- xor a
- ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
- pop de
- pop hl
- jp DisplayListMenuIDLoop
-
-INCLUDE "engine/overworld/pokemart.asm"
-
-INCLUDE "engine/learn_move.asm"
-
-INCLUDE "engine/overworld/pokecenter.asm"
-
-SetLastBlackoutMap:
-; Set the map to return to when
-; blacking out or using Teleport or Dig.
-; Safari rest houses don't count.
-
- push hl
- ld hl, SafariZoneRestHouses
- ld a, [W_CURMAP]
- ld b, a
-.loop
- ld a, [hli]
- cp -1
- jr z, .notresthouse
- cp b
- jr nz, .loop
- jr .done
-
-.notresthouse
- ld a, [wLastMap]
- ld [wLastBlackoutMap], a
-.done
- pop hl
- ret
-
-SafariZoneRestHouses:
- db SAFARI_ZONE_REST_HOUSE_2
- db SAFARI_ZONE_REST_HOUSE_3
- db SAFARI_ZONE_REST_HOUSE_4
- db -1
-
-; function that performs initialization for DisplayTextID
-DisplayTextIDInit: ; 7096 (1:7096)
- xor a
- ld [wListMenuID],a
- ld a,[wAutoTextBoxDrawingControl]
- bit 0,a
- jr nz,.skipDrawingTextBoxBorder
- ld a,[$ff8c] ; text ID (or sprite ID)
- and a
- jr nz,.notStartMenu
-; if text ID is 0 (i.e. the start menu)
-; Note that the start menu text border is also drawn in the function directly
-; below this, so this seems unnecessary.
- ld a,[wd74b]
- bit 5,a ; does the player have the pokedex?
-; start menu with pokedex
- hlCoord 10, 0
- ld b,$0e
- ld c,$08
- jr nz,.drawTextBoxBorder
-; start menu without pokedex
- hlCoord 10, 0
- ld b,$0c
- ld c,$08
- jr .drawTextBoxBorder
-; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box
-.notStartMenu
- hlCoord 0, 12
- ld b,$04
- ld c,$12
-.drawTextBoxBorder
- call TextBoxBorder
-.skipDrawingTextBoxBorder
- ld hl,wFontLoaded
- set 0,[hl]
- ld hl,wFlags_0xcd60
- bit 4,[hl]
- res 4,[hl]
- jr nz,.skipMovingSprites
- call UpdateSprites ; move sprites
-.skipMovingSprites
-; loop to copy C1X9 (direction the sprite is facing) to C2X9 for each sprite
-; this is done because when you talk to an NPC, they turn to look your way
-; the original direction they were facing must be restored after the dialogue is over
- ld hl,wSpriteStateData1 + $19
- ld c,$0f
- ld de,$0010
-.spriteFacingDirectionCopyLoop
- ld a,[hl]
- inc h
- ld [hl],a
- dec h
- add hl,de
- dec c
- jr nz,.spriteFacingDirectionCopyLoop
-; loop to force all the sprites in the middle of animation to stand still
-; (so that they don't like they're frozen mid-step during the dialogue)
- ld hl,wSpriteStateData1 + 2
- ld de,$0010
- ld c,e
-.spriteStandStillLoop
- ld a,[hl]
- cp a,$ff ; is the sprite visible?
- jr z,.nextSprite
-; if it is visible
- and a,$fc
- ld [hl],a
-.nextSprite
- add hl,de
- dec c
- jr nz,.spriteStandStillLoop
- ld b,$9c ; window background address
- call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM
- xor a
- ld [hWY],a ; put the window on the screen
- call LoadFontTilePatterns
- ld a,$01
- ld [H_AUTOBGTRANSFERENABLED],a ; enable continuous WRAM to VRAM transfer each V-blank
- ret
-
-; function that displays the start menu
-DrawStartMenu: ; 710b (1:710b)
- ld a,[wd74b]
- bit 5,a ; does the player have the pokedex?
-; menu with pokedex
- hlCoord 10, 0
- ld b,$0e
- ld c,$08
- jr nz,.drawTextBoxBorder
-; shorter menu if the player doesn't have the pokedex
- hlCoord 10, 0
- ld b,$0c
- ld c,$08
-.drawTextBoxBorder
- call TextBoxBorder
- ld a,%11001011 ; bit mask for down, up, start, B, and A buttons
- ld [wMenuWatchedKeys],a
- ld a,$02
- ld [wTopMenuItemY],a ; Y position of first menu choice
- ld a,$0b
- ld [wTopMenuItemX],a ; X position of first menu choice
- ld a,[wcc2d] ; remembered menu selection from last time
- ld [wCurrentMenuItem],a
- ld [wLastMenuItem],a
- xor a
- ld [wcc37],a
- ld hl,wd730
- set 6,[hl] ; no pauses between printing each letter
- hlCoord 12, 2
- ld a,[wd74b]
- bit 5,a ; does the player have the pokedex?
-; case for not having pokdex
- ld a,$06
- jr z,.storeMenuItemCount
-; case for having pokedex
- ld de,StartMenuPokedexText
- call PrintStartMenuItem
- ld a,$07
-.storeMenuItemCount
- ld [wMaxMenuItem],a ; number of menu items
- ld de,StartMenuPokemonText
- call PrintStartMenuItem
- ld de,StartMenuItemText
- call PrintStartMenuItem
- ld de,wPlayerName ; player's name
- call PrintStartMenuItem
- ld a,[wd72e]
- bit 6,a ; is the player using the link feature?
-; case for not using link feature
- ld de,StartMenuSaveText
- jr z,.printSaveOrResetText
-; case for using link feature
- ld de,StartMenuResetText
-.printSaveOrResetText
- call PrintStartMenuItem
- ld de,StartMenuOptionText
- call PrintStartMenuItem
- ld de,StartMenuExitText
- call PlaceString
- ld hl,wd730
- res 6,[hl] ; turn pauses between printing letters back on
- ret
-
-StartMenuPokedexText: ; 718f (1:718f)
- db "POKéDEX@"
-
-StartMenuPokemonText: ; 7197 (1:7197)
- db "POKéMON@"
-
-StartMenuItemText: ; 719f (1:719f)
- db "ITEM@"
-
-StartMenuSaveText: ; 71a4 (1:71a4)
- db "SAVE@"
-
-StartMenuResetText: ; 71a9 (1:71a9)
- db "RESET@"
-
-StartMenuExitText: ; 71af (1:71af)
- db "EXIT@"
-
-StartMenuOptionText: ; 71b4 (1:71b4)
- db "OPTION@"
-
-PrintStartMenuItem: ; 71bb (1:71bb)
- push hl
- call PlaceString
- pop hl
- ld de,$28
- add hl,de
- ret
-
-INCLUDE "engine/overworld/cable_club_npc.asm"
-
-; function to draw various text boxes
-DisplayTextBoxID_: ; 72ea (1:72ea)
- ld a,[wTextBoxID]
- cp a,TWO_OPTION_MENU
- jp z,DisplayTwoOptionMenu
- ld c,a
- ld hl,TextBoxFunctionTable
- ld de,3
- call SearchTextBoxTable
- jr c,.functionTableMatch
- ld hl,TextBoxCoordTable
- ld de,5
- call SearchTextBoxTable
- jr c,.coordTableMatch
- ld hl,TextBoxTextAndCoordTable
- ld de,9
- call SearchTextBoxTable
- jr c,.textAndCoordTableMatch
-.done
- ret
-.functionTableMatch
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl = address of function
- ld de,.done
- push de
- jp [hl] ; jump to the function
-.coordTableMatch
- call GetTextBoxIDCoords
- call GetAddressOfScreenCoords
- call TextBoxBorder
- ret
-.textAndCoordTableMatch
- call GetTextBoxIDCoords
- push hl
- call GetAddressOfScreenCoords
- call TextBoxBorder
- pop hl
- call GetTextBoxIDText
- ld a,[wd730]
- push af
- ld a,[wd730]
- set 6,a ; no pauses between printing each letter
- ld [wd730],a
- call PlaceString
- pop af
- ld [wd730],a
- call UpdateSprites ; move sprites
- ret
-
-; function to search a table terminated with $ff for a byte matching c in increments of de
-; sets carry flag if a match is found and clears carry flag if not
-SearchTextBoxTable: ; 734c (1:734c)
- dec de
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.notFound
- cp c
- jr z,.found
- add hl,de
- jr .loop
-.found
- scf
-.notFound
- ret
-
-; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable
-; INPUT:
-; hl = address of coordinates
-; OUTPUT:
-; b = height
-; c = width
-; d = row of upper left corner
-; e = column of upper left corner
-GetTextBoxIDCoords: ; 735a (1:735a)
- ld a,[hli] ; column of upper left corner
- ld e,a
- ld a,[hli] ; row of upper left corner
- ld d,a
- ld a,[hli] ; column of lower right corner
- sub e
- dec a
- ld c,a ; c = width
- ld a,[hli] ; row of lower right corner
- sub d
- dec a
- ld b,a ; b = height
- ret
-
-; function to load a text address and text coordinates from the TextBoxTextAndCoordTable
-GetTextBoxIDText: ; 7367 (1:7367)
- ld a,[hli]
- ld e,a
- ld a,[hli]
- ld d,a ; de = address of text
- push de ; save text address
- ld a,[hli]
- ld e,a ; column of upper left corner of text
- ld a,[hl]
- ld d,a ; row of upper left corner of text
- call GetAddressOfScreenCoords
- pop de ; restore text address
- ret
-
-; function to point hl to the screen coordinates
-; INPUT:
-; d = row
-; e = column
-; OUTPUT:
-; hl = address of upper left corner of text box
-GetAddressOfScreenCoords: ; 7375 (1:7375)
- push bc
- ld hl,wTileMap
- ld bc,20
-.loop ; loop to add d rows to the base address
- ld a,d
- and a
- jr z,.addedRows
- add hl,bc
- dec d
- jr .loop
-.addedRows
- pop bc
- add hl,de
- ret
-
-; Format:
-; 00: text box ID
-; 01-02: function address
-TextBoxFunctionTable: ; 7387 (1:7387)
- dbw MONEY_BOX, DisplayMoneyBox
- dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu
- dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu
- db $ff ; terminator
-
-; Format:
-; 00: text box ID
-; 01: column of upper left corner
-; 02: row of upper left corner
-; 03: column of lower right corner
-; 04: row of lower right corner
-TextBoxCoordTable: ; 7391 (1:7391)
- db MESSAGE_BOX, 0, 12, 19, 17
- db $03, 0, 0, 19, 14
- db $07, 0, 0, 11, 6
- db LIST_MENU_BOX, 4, 2, 19, 12
- db $10, 7, 0, 19, 17
- db MON_SPRITE_POPUP, 6, 4, 14, 13
- db $ff ; terminator
-
-; Format:
-; 00: text box ID
-; 01: column of upper left corner
-; 02: row of upper left corner
-; 03: column of lower right corner
-; 04: row of lower right corner
-; 05-06: address of text
-; 07: column of beginning of text
-; 08: row of beginning of text
-; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row]
-TextBoxTextAndCoordTable: ; 73b0 (1:73b0)
- db JP_MOCHIMONO_MENU_TEMPLATE
- db 0,0,14,17 ; text box coordinates
- dw JapaneseMochimonoText
- db 3,0 ; text coordinates
-
- db USE_TOSS_MENU_TEMPLATE
- db 13,10,19,14 ; text box coordinates
- dw UseTossText
- db 15,11 ; text coordinates
-
- db JP_SAVE_MESSAGE_MENU_TEMPLATE
- db 0,0,7,5 ; text box coordinates
- dw JapaneseSaveMessageText
- db 2,2 ; text coordinates
-
- db JP_SPEED_OPTIONS_MENU_TEMPLATE
- db 0,6,5,10 ; text box coordinates
- dw JapaneseSpeedOptionsText
- db 2,7 ; text coordinates
-
- db BATTLE_MENU_TEMPLATE
- db 8,12,19,17 ; text box coordinates
- dw BattleMenuText
- db 10,14 ; text coordinates
-
- db SAFARI_BATTLE_MENU_TEMPLATE
- db 0,12,19,17 ; text box coordinates
- dw SafariZoneBattleMenuText
- db 2,14 ; text coordinates
-
- db SWITCH_STATS_CANCEL_MENU_TEMPLATE
- db 11,11,19,17 ; text box coordinates
- dw SwitchStatsCancelText
- db 13,12 ; text coordinates
-
- db BUY_SELL_QUIT_MENU_TEMPLATE
- db 0,0,10,6 ; text box coordinates
- dw BuySellQuitText
- db 2,1 ; text coordinates
-
- db MONEY_BOX_TEMPLATE
- db 11,0,19,2 ; text box coordinates
- dw MoneyText
- db 13,0 ; text coordinates
-
- db JP_AH_MENU_TEMPLATE
- db 7,6,11,10 ; text box coordinates
- dw JapaneseAhText
- db 8,8 ; text coordinates
-
- db JP_POKEDEX_MENU_TEMPLATE
- db 11,8,19,17 ; text box coordinates
- dw JapanesePokedexMenu
- db 12,10 ; text coordinates
-
-; note that there is no terminator
-
-BuySellQuitText: ; 7413 (1:7413)
- db "BUY"
- next "SELL"
- next "QUIT@@"
-
-UseTossText: ; 7422 (1:7422)
- db "USE"
- next "TOSS@"
-
-JapaneseSaveMessageText: ; 742b (1:742b)
- db "きろく"
- next "メッセージ@"
-
-JapaneseSpeedOptionsText: ; 7435 (1:7435)
- db "はやい"
- next "おそい@"
-
-MoneyText: ; 743d (1:743d)
- db "MONEY@"
-
-JapaneseMochimonoText: ; 7443 (1:7443)
- db "もちもの@"
-
-JapaneseMainMenuText: ; 7448 (1:7448)
- db "つづきから"
- next "さいしょから@"
-
-BattleMenuText: ; 7455 (1:7455)
- db "FIGHT ",$E1,$E2
- next "ITEM RUN@"
-
-SafariZoneBattleMenuText: ; 7468 (1:7468)
- db "BALL× BAIT"
- next "THROW ROCK RUN@"
-
-SwitchStatsCancelText: ; 7489 (1:7489)
- db "SWITCH"
- next "STATS"
- next "CANCEL@"
-
-JapaneseAhText: ; 749d (1:749d)
- db "アッ!@"
-
-JapanesePokedexMenu: ; 74a1 (1:74a1)
- db "データをみる"
- next "なきごえ"
- next "ぶんぷをみる"
- next "キャンセル@"
-
-DisplayMoneyBox: ; 74ba (1:74ba)
- ld hl, wd730
- set 6, [hl]
- ld a, MONEY_BOX_TEMPLATE
- ld [wTextBoxID], a
- call DisplayTextBoxID
- hlCoord 13, 1
- ld b, $1
- ld c, $6
- call ClearScreenArea
- hlCoord 12, 1
- ld de, wPlayerMoney
- ld c, $a3
- call PrintBCDNumber
- ld hl, wd730
- res 6, [hl]
- ret
-
-CurrencyString: ; 74e2 (1:74e2)
- db " ¥@"
-
-DoBuySellQuitMenu: ; 74ea (1:74ea)
- ld a, [wd730]
- set 6, a ; no printing delay
- ld [wd730], a
- xor a
- ld [wd12d], a
- ld a, BUY_SELL_QUIT_MENU_TEMPLATE
- ld [wTextBoxID], a
- call DisplayTextBoxID
- ld a, A_BUTTON | B_BUTTON
- ld [wMenuWatchedKeys], a
- ld a, $2
- ld [wMaxMenuItem], a
- ld a, $1
- ld [wTopMenuItemY], a
- ld a, $1
- ld [wTopMenuItemX], a
- xor a
- ld [wCurrentMenuItem], a
- ld [wLastMenuItem], a
- ld [wcc37], a
- ld a, [wd730]
- res 6, a ; turn on the printing delay
- ld [wd730], a
- call HandleMenuInput
- call PlaceUnfilledArrowMenuCursor
- bit 0, a ; was A pressed?
- jr nz, .pressedA
- bit 1, a ; was B pressed? (always true since only A/B are watched)
- jr z, .pressedA
- ld a, $2
- ld [wd12e], a
- jr .quit
-.pressedA
- ld a, $1
- ld [wd12e], a
- ld a, [wCurrentMenuItem]
- ld [wd12d], a
- ld b, a
- ld a, [wMaxMenuItem]
- cp b
- jr z, .quit
- ret
-.quit
- ld a, $2
- ld [wd12e], a
- ld a, [wCurrentMenuItem]
- ld [wd12d], a
- scf
- ret
-
-; displays a menu with two options to choose from
-; b = Y of upper left corner of text region
-; c = X of upper left corner of text region
-; hl = address where the text box border should be drawn
-DisplayTwoOptionMenu: ; 7559 (1:7559)
- push hl
- ld a, [wd730]
- set 6, a ; no printing delay
- ld [wd730], a
- xor a
- ld [wd12d], a
- ld [wd12e], a
- ld a, A_BUTTON | B_BUTTON
- ld [wMenuWatchedKeys], a
- ld a, $1
- ld [wMaxMenuItem], a
- ld a, b
- ld [wTopMenuItemY], a
- ld a, c
- ld [wTopMenuItemX], a
- xor a
- ld [wLastMenuItem], a
- ld [wcc37], a
- push hl
- ld hl, wTwoOptionMenuID
- bit 7, [hl] ; select second menu item by default?
- res 7, [hl]
- jr z, .storeCurrentMenuItem
- inc a
-.storeCurrentMenuItem
- ld [wCurrentMenuItem], a
- pop hl
- push hl
- push hl
- call TwoOptionMenu_SaveScreenTiles
- ld a, [wTwoOptionMenuID]
- ld hl, TwoOptionMenuStrings
- ld e, a
- ld d, $0
- ld a, $5
-.menuStringLoop
- add hl, de
- dec a
- jr nz, .menuStringLoop
- ld a, [hli]
- ld c, a
- ld a, [hli]
- ld b, a
- ld e, l
- ld d, h
- pop hl
- push de
- ld a, [wTwoOptionMenuID]
- cp TRADE_CANCEL_MENU
- jr nz, .notTradeCancelMenu
- call CableClub_TextBoxBorder
- jr .afterTextBoxBorder
-.notTradeCancelMenu
- call TextBoxBorder
-.afterTextBoxBorder
- call UpdateSprites
- pop hl
- ld a, [hli]
- and a ; put blank line before first menu item?
- ld bc, 20 + 2
- jr z, .noBlankLine
- ld bc, 2 * 20 + 2
-.noBlankLine
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- pop hl
- add hl, bc
- call PlaceString
- ld hl, wd730
- res 6, [hl] ; turn on the printing delay
- ld a, [wTwoOptionMenuID]
- cp NO_YES_MENU
- jr nz, .notNoYesMenu
-; No/Yes menu
-; this menu type ignores the B button
-; it only seems to be used when confirming the deletion of a save file
- xor a
- ld [wTwoOptionMenuID], a
- ld a, [wFlags_0xcd60]
- push af
- push hl
- ld hl, wFlags_0xcd60
- bit 5, [hl]
- set 5, [hl] ; don't play sound when A or B is pressed in menu
- pop hl
-.noYesMenuInputLoop
- call HandleMenuInput
- bit 1, a ; A button pressed?
- jr nz, .noYesMenuInputLoop ; try again if A was not pressed
- pop af
- pop hl
- ld [wFlags_0xcd60], a
- ld a, (SFX_02_40 - SFX_Headers_02) / 3
- call PlaySound
- jr .pressedAButton
-.notNoYesMenu
- xor a
- ld [wTwoOptionMenuID], a
- call HandleMenuInput
- pop hl
- bit 1, a ; A button pressed?
- jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed
-.pressedAButton
- ld a, [wCurrentMenuItem]
- ld [wd12d], a
- and a
- jr nz, .choseSecondMenuItem
-; chose first menu item
- ld a, $1
- ld [wd12e], a
- ld c, 15
- call DelayFrames
- call TwoOptionMenu_RestoreScreenTiles
- and a
- ret
-.choseSecondMenuItem
- ld a, $1
- ld [wCurrentMenuItem], a
- ld [wd12d], a
- ld a, $2
- ld [wd12e], a
- ld c, 15
- call DelayFrames
- call TwoOptionMenu_RestoreScreenTiles
- scf
- ret
-
-; Some of the wider/taller two option menus will not have the screen areas
-; they cover be fully saved/restored by the two functions below.
-; The bottom and right edges of the menu may remain after the function returns.
-
-TwoOptionMenu_SaveScreenTiles: ; 763e (1:763e)
- ld de, wHPBarMaxHP
- ld bc, $506
-.asm_7644
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .asm_7644
- push bc
- ld bc, 14
- add hl, bc
- pop bc
- ld c, $6
- dec b
- jr nz, .asm_7644
- ret
-
-TwoOptionMenu_RestoreScreenTiles: ; 7656 (1:7656)
- ld de, wHPBarMaxHP
- ld bc, $506
-.asm_765c
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .asm_765c
- push bc
- ld bc, $e
- add hl, bc
- pop bc
- ld c, $6
- dec b
- jr nz, .asm_765c
- call UpdateSprites
- ret
-
-; Format:
-; 00: byte width
-; 01: byte height
-; 02: byte put blank line before first menu item
-; 03: word text pointer
-TwoOptionMenuStrings: ; 7671 (1:7671)
- db 4,3,0
- dw .YesNoMenu
- db 6,3,0
- dw .NorthWestMenu
- db 6,3,0
- dw .SouthEastMenu
- db 6,3,0
- dw .YesNoMenu
- db 6,3,0
- dw .NorthEastMenu
- db 7,3,0
- dw .TradeCancelMenu
- db 7,4,1
- dw .HealCancelMenu
- db 4,3,0
- dw .NoYesMenu
-
-.NoYesMenu ; 7699 (1:3699)
- db "NO",$4E,"YES@"
-.YesNoMenu ; 76a0 (1:36a0)
- db "YES",$4E,"NO@"
-.NorthWestMenu ; 76a7 (1:36a7)
- db "NORTH",$4E,"WEST@"
-.SouthEastMenu ; 76b2 (1:36b2)
- db "SOUTH",$4E,"EAST@"
-.NorthEastMenu ; 76bd (1:36bd)
- db "NORTH",$4E,"EAST@"
-.TradeCancelMenu ; 76c8 (1:36c8)
- db "TRADE",$4E,"CANCEL@"
-.HealCancelMenu ; 76d5 (1:36d5)
- db "HEAL",$4E,"CANCEL@"
-
-DisplayFieldMoveMonMenu: ; 76e1 (1:36e1)
- xor a
- ld hl, wWhichTrade
- ld [hli], a
- ld [hli], a
- ld [hli], a
- ld [hli], a
- ld [hli], a
- ld [hl], $c
- call GetMonFieldMoves
- ld a, [wTrainerScreenX]
- and a
- jr nz, .asm_770f
- hlCoord 11, 11
- ld b, $5
- ld c, $7
- call TextBoxBorder
- call UpdateSprites
- ld a, $c
- ld [$fff7], a
- hlCoord 13, 12
- ld de, PokemonMenuEntries
- jp PlaceString
-.asm_770f
- push af
- hlCoord 0, 11
- ld a, [wcd42]
- dec a
- ld e, a
- ld d, $0
- add hl, de
- ld b, $5
- ld a, $12
- sub e
- ld c, a
- pop af
- ld de, $ffd8
-.asm_7725
- add hl, de
- inc b
- inc b
- dec a
- jr nz, .asm_7725
- ld de, $ffec
- add hl, de
- inc b
- call TextBoxBorder
- call UpdateSprites
- hlCoord 0, 12
- ld a, [wcd42]
- inc a
- ld e, a
- ld d, $0
- add hl, de
- ld de, $ffd8
- ld a, [wTrainerScreenX]
-.asm_7747
- add hl, de
- dec a
- jr nz, .asm_7747
- xor a
- ld [wTrainerScreenX], a
- ld de, wWhichTrade
-.asm_7752
- push hl
- ld hl, FieldMoveNames
- ld a, [de]
- and a
- jr z, .asm_7776
- inc de
- ld b, a
-.asm_775c
- dec b
- jr z, .asm_7766
-.asm_775f
- ld a, [hli]
- cp $50
- jr nz, .asm_775f
- jr .asm_775c
-.asm_7766
- ld b, h
- ld c, l
- pop hl
- push de
- ld d, b
- ld e, c
- call PlaceString
- ld bc, $28
- add hl, bc
- pop de
- jr .asm_7752
-.asm_7776
- pop hl
- ld a, [wcd42]
- ld [$fff7], a
- hlCoord 0, 12
- ld a, [wcd42]
- inc a
- ld e, a
- ld d, $0
- add hl, de
- ld de, PokemonMenuEntries
- jp PlaceString
-
-FieldMoveNames: ; 778d (1:778d)
- db "CUT@"
- db "FLY@"
- db "@"
- db "SURF@"
- db "STRENGTH@"
- db "FLASH@"
- db "DIG@"
- db "TELEPORT@"
- db "SOFTBOILED@"
-
-PokemonMenuEntries: ; 77c2 (1:77c2)
- db "STATS"
- next "SWITCH"
- next "CANCEL@"
-
-GetMonFieldMoves: ; 77d6 (1:77d6)
- ld a, [wWhichPokemon]
- ld hl, wPartyMon1Moves
- ld bc, $2c
- call AddNTimes
- ld d, h
- ld e, l
- ld c, $5
- ld hl, wWhichTrade
-.asm_77e9
- push hl
-.asm_77ea
- dec c
- jr z, .asm_7821
- ld a, [de] ; de is RAM address of move
- and a
- jr z, .asm_7821
- ld b, a
- inc de ; go to next move
- ld hl, FieldMoveDisplayData
-.asm_77f6
- ld a, [hli]
- cp $ff
- jr z, .asm_77ea
- cp b
- jr z, .asm_7802
- inc hl
- inc hl
- jr .asm_77f6
-.asm_7802
- ld a, b
- ld [wcd43], a
- ld a, [hli]
- ld b, [hl]
- pop hl
- ld [hli], a
- ld a, [wTrainerScreenX]
- inc a
- ld [wTrainerScreenX], a
- ld a, [wcd42]
- cp b
- jr c, .asm_781b
- ld a, b
- ld [wcd42], a
-.asm_781b
- ld a, [wcd43]
- ld b, a
- jr .asm_77e9
-.asm_7821
- pop hl
- ret
-
-; Format: [Move id], [list priority], [leftmost tile]
-; Move id = id of move
-; List priority = lower number means higher priority when field moves are displayed
-; these priorities must be unique
-; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed
-; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C
-FieldMoveDisplayData: ; 7823 (1:7823)
- db CUT, $01, $0C
- db FLY, $02, $0C
- db $B4, $03, $0C ; unused field move
- db SURF, $04, $0C
- db STRENGTH, $05, $0A
- db FLASH, $06, $0C
- db DIG, $07, $0C
- db TELEPORT, $08, $0A
- db SOFTBOILED, $09, $08
- db $ff ; list terminator
-
-
-INCLUDE "engine/battle/moveEffects/drain_hp_effect.asm"
-
-INCLUDE "engine/menu/players_pc.asm"
-
-_RemovePokemon: ; 7b68 (1:7b68)
- ld hl, wPartyCount ; wPartyCount
- ld a, [wcf95]
- and a
- jr z, .asm_7b74
- ld hl, W_NUMINBOX ; wda80
-.asm_7b74
- ld a, [hl]
- dec a
- ld [hli], a
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld c, a
- ld b, $0
- add hl, bc
- ld e, l
- ld d, h
- inc de
-.asm_7b81
- ld a, [de]
- inc de
- ld [hli], a
- inc a
- jr nz, .asm_7b81
- ld hl, wPartyMonOT ; wd273
- ld d, $5
- ld a, [wcf95]
- and a
- jr z, .asm_7b97
- ld hl, wBoxMonOT
- ld d, $13
-.asm_7b97
- ld a, [wWhichPokemon] ; wWhichPokemon
- call SkipFixedLengthTextEntries
- ld a, [wWhichPokemon] ; wWhichPokemon
- cp d
- jr nz, .asm_7ba6
- ld [hl], $ff
- ret
-.asm_7ba6
- ld d, h
- ld e, l
- ld bc, $b
- add hl, bc
- ld bc, wPartyMonNicks ; wPartyMonNicks
- ld a, [wcf95]
- and a
- jr z, .asm_7bb8
- ld bc, wBoxMonNicks
-.asm_7bb8
- call CopyDataUntil
- ld hl, wPartyMons
- ld bc, wPartyMon2 - wPartyMon1
- ld a, [wcf95]
- and a
- jr z, .asm_7bcd
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1
-.asm_7bcd
- ld a, [wWhichPokemon] ; wWhichPokemon
- call AddNTimes
- ld d, h
- ld e, l
- ld a, [wcf95]
- and a
- jr z, .asm_7be4
- ld bc, wBoxMon2 - wBoxMon1
- add hl, bc
- ld bc, wBoxMonOT
- jr .asm_7beb
-.asm_7be4
- ld bc, wPartyMon2 - wPartyMon1
- add hl, bc
- ld bc, wPartyMonOT ; wd273
-.asm_7beb
- call CopyDataUntil
- ld hl, wPartyMonNicks ; wPartyMonNicks
- ld a, [wcf95]
- and a
- jr z, .asm_7bfa
- ld hl, wBoxMonNicks
-.asm_7bfa
- ld bc, $b
- ld a, [wWhichPokemon] ; wWhichPokemon
- call AddNTimes
- ld d, h
- ld e, l
- ld bc, $b
- add hl, bc
- ld bc, wPokedexOwned ; wPokedexOwned
- ld a, [wcf95]
- and a
- jr z, .asm_7c15
- ld bc, wBoxMonNicksEnd
-.asm_7c15
- jp CopyDataUntil
-
-Func_7c18: ; 7c18 (1:7c18)
- ld hl, wd730
- set 6, [hl]
- predef ShowPokedexData
- ld hl, wd730
- res 6, [hl]
- call ReloadMapData
- ld c, $a
- call DelayFrames
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, $1
- ld hl, wPokedexSeen
- predef FlagActionPredef
- ld a, $1
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a
- ret
-
-
-SECTION "bank3",ROMX,BANK[$3]
-
-INCLUDE "engine/joypad.asm"
-
-INCLUDE "data/map_songs.asm"
-
-INCLUDE "data/map_header_banks.asm"
-
-ClearVariablesAfterLoadingMapData: ; c335 (3:4335)
- ld a, $90
- ld [hWY], a
- ld [rWY], a
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [wStepCounter], a
- ld [W_LONEATTACKNO], a ; W_GYMLEADERNO
- ld [hJoyPressed], a
- ld [hJoyReleased], a
- ld [hJoyHeld], a
- ld [wcd6a], a
- ld [wd5a3], a
- ld hl, wCardKeyDoorY
- ld [hli], a
- ld [hl], a
- ld hl, wWhichTrade
- ld bc, $1e
- call FillMemory
- ret
-
-; only used for setting bit 2 of wd736 upon entering a new map
-IsPlayerStandingOnWarp: ; c35f (3:435f)
- ld a, [wNumberOfWarps]
- and a
- ret z
- ld c, a
- ld hl, wWarpEntries
-.loop
- ld a, [W_YCOORD]
- cp [hl]
- jr nz, .nextWarp1
- inc hl
- ld a, [W_XCOORD]
- cp [hl]
- jr nz, .nextWarp2
- inc hl
- ld a, [hli] ; target warp
- ld [wDestinationWarpID], a
- ld a, [hl] ; target map
- ld [$ff8b], a
- ld hl, wd736
- set 2, [hl] ; standing on warp flag
- ret
-.nextWarp1
- inc hl
-.nextWarp2
- inc hl
- inc hl
- inc hl
- dec c
- jr nz, .loop
- ret
-
-CheckForceBikeOrSurf: ; c38b (3:438b)
- ld hl, wd732
- bit 5, [hl]
- ret nz
- ld hl, ForcedBikeOrSurfMaps
- ld a, [W_YCOORD]
- ld b, a
- ld a, [W_XCOORD]
- ld c, a
- ld a, [W_CURMAP]
- ld d, a
-.loop
- ld a, [hli]
- cp $ff
- ret z ;if we reach FF then it's not part of the list
- cp d ;compare to current map
- jr nz, .incorrectMap
- ld a, [hli]
- cp b ;compare y-coord
- jr nz, .incorrectY
- ld a, [hli]
- cp c ;compare x-coord
- jr nz, .loop ; incorrect x-coord, check next item
- ld a, [W_CURMAP]
- cp SEAFOAM_ISLANDS_4
- ld a, $2
- ld [W_SEAFOAMISLANDS4CURSCRIPT], a
- jr z, .forceSurfing
- ld a, [W_CURMAP]
- cp SEAFOAM_ISLANDS_5
- ld a, $2
- ld [W_SEAFOAMISLANDS5CURSCRIPT], a
- jr z, .forceSurfing
- ;force bike riding
- ld hl, wd732
- set 5, [hl]
- ld a, $1
- ld [wWalkBikeSurfState], a
- ld [wWalkBikeSurfStateCopy], a
- jp ForceBikeOrSurf
-.incorrectMap
- inc hl
-.incorrectY
- inc hl
- jr .loop
-.forceSurfing
- ld a, $2
- ld [wWalkBikeSurfState], a
- ld [wWalkBikeSurfStateCopy], a
- jp ForceBikeOrSurf
-
-INCLUDE "data/force_bike_surf.asm"
-
-IsPlayerFacingEdgeOfMap: ; c3ff (3:43ff)
- push hl
- push de
- push bc
- ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
- srl a
- ld c, a
- ld b, $0
- ld hl, .functionPointerTable
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [W_YCOORD]
- ld b, a
- ld a, [W_XCOORD]
- ld c, a
- ld de, .asm_c41e
- push de
- jp [hl]
-.asm_c41e
- pop bc
- pop de
- pop hl
- ret
-
-.functionPointerTable
- dw .facingDown
- dw .facingUp
- dw .facingLeft
- dw .facingRight
-
-.facingDown
- ld a, [W_CURMAPHEIGHT]
- add a
- dec a
- cp b
- jr z, .setCarry
- jr .resetCarry
-
-.facingUp
- ld a, b
- and a
- jr z, .setCarry
- jr .resetCarry
-
-.facingLeft
- ld a, c
- and a
- jr z, .setCarry
- jr .resetCarry
-
-.facingRight
- ld a, [W_CURMAPWIDTH]
- add a
- dec a
- cp c
- jr z, .setCarry
- jr .resetCarry
-.resetCarry
- and a
- ret
-.setCarry
- scf
- ret
-
-IsWarpTileInFrontOfPlayer: ; c44e (3:444e)
- push hl
- push de
- push bc
- call _GetTileAndCoordsInFrontOfPlayer
- ld a, [W_CURMAP]
- cp SS_ANNE_5
- jr z, .ssAnne5
- ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
- srl a
- ld c, a
- ld b, 0
- ld hl, .warpTileListPointers
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [wTileInFrontOfPlayer]
- ld de, $1
- call IsInArray
-.done
- pop bc
- pop de
- pop hl
- ret
-
-.warpTileListPointers: ; c477 (3:4477)
- dw .facingDownWarpTiles
- dw .facingUpWarpTiles
- dw .facingLeftWarpTiles
- dw .facingRightWarpTiles
-
-.facingDownWarpTiles
- db $01,$12,$17,$3D,$04,$18,$33,$FF
-
-.facingUpWarpTiles
- db $01,$5C,$FF
-
-.facingLeftWarpTiles
- db $1A,$4B,$FF
-
-.facingRightWarpTiles
- db $0F,$4E,$FF
-
-.ssAnne5
- ld a, [wTileInFrontOfPlayer]
- cp $15
- jr nz, .notSSAnne5Warp
- scf
- jr .done
-.notSSAnne5Warp
- and a
- jr .done
-
-IsPlayerStandingOnDoorTileOrWarpTile: ; c49d (3:449d)
- push hl
- push de
- push bc
- callba IsPlayerStandingOnDoorTile
- jr c, .done
- ld a, [W_CURMAPTILESET]
- add a
- ld c, a
- ld b, $0
- ld hl, WarpTileIDPointers
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, $1
- aCoord 8, 9
- call IsInArray
- jr nc, .done
- ld hl, wd736
- res 2, [hl]
-.done
- pop bc
- pop de
- pop hl
- ret
-
-INCLUDE "data/warp_tile_ids.asm"
-
-PrintSafariZoneSteps: ; c52f (3:452f)
- ld a, [W_CURMAP] ; W_CURMAP
- cp SAFARI_ZONE_EAST
- ret c
- cp UNKNOWN_DUNGEON_2
- ret nc
- ld hl, wTileMap
- ld b, $3
- ld c, $7
- call TextBoxBorder
- hlCoord 1, 1
- ld de, wSafariSteps ; wd70d
- ld bc, $203
- call PrintNumber
- hlCoord 4, 1
- ld de, SafariSteps ; $4579
- call PlaceString
- hlCoord 1, 3
- ld de, SafariBallText
- call PlaceString
- ld a, [W_NUMSAFARIBALLS] ; W_NUMSAFARIBALLS
- cp $a
- jr nc, .asm_c56d
- hlCoord 5, 3
- ld a, $7f
- ld [hl], a
-.asm_c56d
- hlCoord 6, 3
- ld de, W_NUMSAFARIBALLS ; W_NUMSAFARIBALLS
- ld bc, $102
- jp PrintNumber
-
-SafariSteps: ; c579 (3:4579)
- db "/500@"
-
-SafariBallText: ; c57e (3:457e)
- db "BALL×× @"
-
-GetTileAndCoordsInFrontOfPlayer: ; c586 (3:4586)
- call GetPredefRegisters
-
-_GetTileAndCoordsInFrontOfPlayer: ; c589 (3:4589)
- ld a, [W_YCOORD]
- ld d, a
- ld a, [W_XCOORD]
- ld e, a
- ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
- and a
- jr nz, .notFacingDown
-; facing down
- aCoord 8, 11
- inc d
- jr .storeTile
-.notFacingDown
- cp SPRITE_FACING_UP
- jr nz, .notFacingUp
-; facing up
- aCoord 8, 7
- dec d
- jr .storeTile
-.notFacingUp
- cp SPRITE_FACING_LEFT
- jr nz, .notFacingLeft
-; facing left
- aCoord 6, 9
- dec e
- jr .storeTile
-.notFacingLeft
- cp SPRITE_FACING_RIGHT
- jr nz, .storeTile
-; facing right
- aCoord 10, 9
- inc e
-.storeTile
- ld c, a
- ld [wTileInFrontOfPlayer], a
- ret
-
-GetTileTwoStepsInFrontOfPlayer: ; c5be (3:45be)
- xor a
- ld [$ffdb], a
- ld hl, W_YCOORD
- ld a, [hli]
- ld d, a
- ld e, [hl]
- ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
- and a
- jr nz, .notFacingDown
-; facing down
- ld hl, $ffdb
- set 0, [hl]
- aCoord 8, 13
- inc d
- jr .storeTile
-.notFacingDown
- cp SPRITE_FACING_UP
- jr nz, .notFacingUp
-; facing up
- ld hl, $ffdb
- set 1, [hl]
- aCoord 8, 5
- dec d
- jr .storeTile
-.notFacingUp
- cp SPRITE_FACING_LEFT
- jr nz, .notFacingLeft
-; facing left
- ld hl, $ffdb
- set 2, [hl]
- aCoord 4, 9
- dec e
- jr .storeTile
-.notFacingLeft
- cp SPRITE_FACING_RIGHT
- jr nz, .storeTile
-; facing right
- ld hl, $ffdb
- set 3, [hl]
- aCoord 12, 9
- inc e
-.storeTile
- ld c, a
- ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a
- ld [wTileInFrontOfPlayer], a
- ret
-
-CheckForCollisionWhenPushingBoulder: ; c60b (3:460b)
- call GetTileTwoStepsInFrontOfPlayer
- ld hl, W_TILESETCOLLISIONPTR
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.loop
- ld a, [hli]
- cp $ff
- jr z, .done ; if the tile two steps ahead is not passable
- cp c
- jr nz, .loop
- ld hl, TilePairCollisionsLand
- call CheckForTilePairCollisions2
- ld a, $ff
- jr c, .done ; if there is an elevation difference between the current tile and the one two steps ahead
- ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult]
- cp $15 ; stairs tile
- ld a, $ff
- jr z, .done ; if the tile two steps ahead is stairs
- call CheckForBoulderCollisionWithSprites
-.done
- ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a
- ret
-
-; sets a to $ff if there is a collision and $00 if there is no collision
-CheckForBoulderCollisionWithSprites: ; c636 (3:4636)
- ld a, [wBoulderSpriteIndex]
- dec a
- swap a
- ld d, 0
- ld e, a
- ld hl, wSpriteStateData2 + $14
- add hl, de
- ld a, [hli] ; map Y position
- ld [$ffdc], a
- ld a, [hl] ; map X position
- ld [$ffdd], a
- ld a, [W_NUMSPRITES]
- ld c, a
- ld de, $f
- ld hl, wSpriteStateData2 + $14
- ld a, [$ffdb]
- and $3 ; facing up or down?
- jr z, .pushingHorizontallyLoop
-.pushingVerticallyLoop
- inc hl
- ld a, [$ffdd]
- cp [hl]
- jr nz, .nextSprite1 ; if X coordinates don't match
- dec hl
- ld a, [hli]
- ld b, a
- ld a, [$ffdb]
- rrca
- jr c, .pushingDown
-; pushing up
- ld a, [$ffdc]
- dec a
- jr .compareYCoords
-.pushingDown
- ld a, [$ffdc]
- inc a
-.compareYCoords
- cp b
- jr z, .failure
-.nextSprite1
- dec c
- jr z, .success
- add hl, de
- jr .pushingVerticallyLoop
-.pushingHorizontallyLoop
- ld a, [hli]
- ld b, a
- ld a, [$ffdc]
- cp b
- jr nz, .nextSprite2
- ld b, [hl]
- ld a, [$ffdb]
- bit 2, a
- jr nz, .pushingLeft
-; pushing right
- ld a, [$ffdd]
- inc a
- jr .compareXCoords
-.pushingLeft
- ld a, [$ffdd]
- dec a
-.compareXCoords
- cp b
- jr z, .failure
-.nextSprite2
- dec c
- jr z, .success
- add hl, de
- jr .pushingHorizontallyLoop
-.failure
- ld a, $ff
- ret
-.success
- xor a
- ret
-
-ApplyOutOfBattlePoisonDamage: ; c69c (3:469c)
- ld a, [wd730]
- add a
- jp c, .noBlackOut ; no black out if joypad states are being simulated
- ld a, [wPartyCount]
- and a
- jp z, .noBlackOut
- call IncrementDayCareMonExp
- ld a, [wStepCounter]
- and $3 ; is the counter a multiple of 4?
- jp nz, .noBlackOut ; only apply poison damage every fourth step
- ld [wWhichPokemon], a
- ld hl, wPartyMon1Status
- ld de, wPartySpecies
-.applyDamageLoop
- ld a, [hl]
- and (1 << PSN)
- jr z, .nextMon2 ; not poisoned
- dec hl
- dec hl
- ld a, [hld]
- ld b, a
- ld a, [hli]
- or b
- jr z, .nextMon ; already fainted
-; subtract 1 from HP
- ld a, [hl]
- dec a
- ld [hld], a
- inc a
- jr nz, .noBorrow
-; borrow 1 from upper byte of HP
- dec [hl]
- inc hl
- jr .nextMon
-.noBorrow
- ld a, [hli]
- or [hl]
- jr nz, .nextMon ; didn't faint from damage
-; the mon fainted from the damage
- push hl
- inc hl
- inc hl
- ld [hl], a
- ld a, [de]
- ld [wd11e], a
- push de
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- xor a
- ld [wJoyIgnore], a
- call EnableAutoTextBoxDrawing
- ld a, $d0
- ld [$ff8c], a
- call DisplayTextID
- pop de
- pop hl
-.nextMon
- inc hl
- inc hl
-.nextMon2
- inc de
- ld a, [de]
- inc a
- jr z, .applyDamageLoopDone
- ld bc, wPartyMon2 - wPartyMon1
- add hl, bc
- push hl
- ld hl, wWhichPokemon
- inc [hl]
- pop hl
- jr .applyDamageLoop
-.applyDamageLoopDone
- ld hl, wPartyMon1Status
- ld a, [wPartyCount]
- ld d, a
- ld e, 0
-.countPoisonedLoop
- ld a, [hl]
- and (1 << PSN)
- or e
- ld e, a
- ld bc, wPartyMon2 - wPartyMon1
- add hl, bc
- dec d
- jr nz, .countPoisonedLoop
- ld a, e
- and a ; are any party members poisoned?
- jr z, .skipPoisonEffectAndSound
- ld b, $2
- predef ChangeBGPalColor0_4Frames ; change BG white to dark grey for 4 frames
- ld a, (SFX_02_43 - SFX_Headers_02) / 3
- call PlaySound
-.skipPoisonEffectAndSound
- predef AnyPartyAlive
- ld a, d
- and a
- jr nz, .noBlackOut
- call EnableAutoTextBoxDrawing
- ld a, $d1
- ld [$ff8c], a
- call DisplayTextID
- ld hl, wd72e
- set 5, [hl]
- ld a, $ff
- jr .done
-.noBlackOut
- xor a
-.done
- ld [wd12d], a
- ret
-
-LoadTilesetHeader: ; c754 (3:4754)
- call GetPredefRegisters
- push hl
- ld d, 0
- ld a, [W_CURMAPTILESET]
- add a
- add a
- ld b, a
- add a
- add b ; a = tileset * 12
- jr nc, .noCarry
- inc d
-.noCarry
- ld e, a
- ld hl, Tilesets
- add hl, de
- ld de, W_TILESETBANK
- ld c, $b
-.copyTilesetHeaderLoop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyTilesetHeaderLoop
- ld a, [hl]
- ld [hTilesetType], a
- xor a
- ld [$ffd8], a
- pop hl
- ld a, [W_CURMAPTILESET]
- push hl
- push de
- ld hl, DungeonTilesets
- ld de, $1
- call IsInArray
- pop de
- pop hl
- jr c, .asm_c797
- ld a, [W_CURMAPTILESET]
- ld b, a
- ld a, [$ff8b]
- cp b
- jr z, .done
-.asm_c797
- ld a, [wDestinationWarpID]
- cp $ff
- jr z, .done
- call LoadDestinationWarpPosition
- ld a, [W_YCOORD]
- and $1
- ld [W_YBLOCKCOORD], a
- ld a, [W_XCOORD]
- and $1
- ld [W_XBLOCKCOORD], a
-.done
- ret
-
-INCLUDE "data/dungeon_tilesets.asm"
-
-INCLUDE "data/tileset_headers.asm"
-
-IncrementDayCareMonExp: ; c8de (3:48de)
- ld a, [W_DAYCARE_IN_USE]
- and a
- ret z
- ld hl, wDayCareMonExp + 2
- inc [hl]
- ret nz
- dec hl
- inc [hl]
- ret nz
- dec hl
- inc [hl]
- ld a, [hl]
- cp $50
- ret c
- ld a, $50
- ld [hl], a
- ret
-
-INCLUDE "data/hide_show_data.asm"
-
-PrintStrengthTxt: ; cd99 (3:4d99)
- ld hl, wd728
- set 0, [hl]
- ld hl, UsedStrengthText
- call PrintText
- ld hl, CanMoveBouldersText
- jp PrintText
-
-UsedStrengthText: ; cdaa (3:4daa)
- TX_FAR _UsedStrengthText
- db $08 ; asm
- ld a, [wcf91]
- call PlayCry
- call Delay3
- jp TextScriptEnd
-
-CanMoveBouldersText: ; cdbb (3:4dbb)
- TX_FAR _CanMoveBouldersText
- db "@"
-
-CheckForForcedBikeSurf: ; cdc0 (3:4dc0)
- ld hl, wd728
- set 1, [hl]
- ld a, [wd732]
- bit 5, a
- jr nz, .asm_cdec
- ld a, [W_CURMAP] ; W_CURMAP
- cp SEAFOAM_ISLANDS_5
- ret nz
- ld a, [wd881]
- and $3
- cp $3
- ret z
- ld hl, CoordsData_cdf7 ; $4df7
- call ArePlayerCoordsInArray
- ret nc
- ld hl, wd728
- res 1, [hl]
- ld hl, CurrentTooFastText
- jp PrintText
-.asm_cdec
- ld hl, wd728
- res 1, [hl]
- ld hl, CyclingIsFunText
- jp PrintText
-
-CoordsData_cdf7: ; cdf7 (3:4df7)
- db $0B,$07,$FF
-
-CurrentTooFastText: ; cdfa (3:4dfa)
- TX_FAR _CurrentTooFastText
- db "@"
-
-CyclingIsFunText: ; cdff (3:4dff)
- TX_FAR _CyclingIsFunText
- db "@"
-
-; function to add an item (in varying quantities) to the player's bag or PC box
-; INPUT:
-; hl = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wcf96] = item quantity
-; sets carry flag if successful, unsets carry flag if unsuccessful
-AddItemToInventory_: ; ce04 (3:4e04)
- ld a,[wcf96] ; a = item quantity
- push af
- push bc
- push de
- push hl
- push hl
- ld d,50 ; PC box can hold 50 items
- ld a,wNumBagItems & $FF
- cp l
- jr nz,.checkIfInventoryFull
- ld a,wNumBagItems >> 8
- cp h
- jr nz,.checkIfInventoryFull
-; if the destination is the bag
- ld d,20 ; bag can hold 20 items
-.checkIfInventoryFull
- ld a,[hl]
- sub d
- ld d,a
- ld a,[hli]
- and a
- jr z,.addNewItem
-.loop
- ld a,[hli]
- ld b,a ; b = ID of current item in table
- ld a,[wcf91] ; a = ID of item being added
- cp b ; does the current item in the table match the item being added?
- jp z,.increaseItemQuantity ; if so, increase the item's quantity
- inc hl
- ld a,[hl]
- cp a,$ff ; is it the end of the table?
- jr nz,.loop
-.addNewItem ; add an item not yet in the inventory
- pop hl
- ld a,d
- and a ; is there room for a new item slot?
- jr z,.done
-; if there is room
- inc [hl] ; increment the number of items in the inventory
- ld a,[hl] ; the number of items will be the index of the new item
- add a
- dec a
- ld c,a
- ld b,0
- add hl,bc ; hl = address to store the item
- ld a,[wcf91]
- ld [hli],a ; store item ID
- ld a,[wcf96]
- ld [hli],a ; store item quantity
- ld [hl],$ff ; store terminator
- jp .success
-.increaseItemQuantity ; increase the quantity of an item already in the inventory
- ld a,[wcf96]
- ld b,a ; b = quantity to add
- ld a,[hl] ; a = existing item quantity
- add b ; a = new item quantity
- cp a,100
- jp c,.storeNewQuantity ; if the new quantity is less than 100, store it
-; if the new quantity is greater than or equal to 100,
-; try to max out the current slot and add the rest in a new slot
- sub a,99
- ld [wcf96],a ; a = amount left over (to put in the new slot)
- ld a,d
- and a ; is there room for a new item slot?
- jr z,.increaseItemQuantityFailed
-; if so, store 99 in the current slot and store the rest in a new slot
- ld a,99
- ld [hli],a
- jp .loop
-.increaseItemQuantityFailed
- pop hl
- and a
- jr .done
-.storeNewQuantity
- ld [hl],a
- pop hl
-.success
- scf
-.done
- pop hl
- pop de
- pop bc
- pop bc
- ld a,b
- ld [wcf96],a ; restore the initial value from when the function was called
- ret
-
-; function to remove an item (in varying quantities) from the player's bag or PC box
-; INPUT:
-; hl = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wWhichPokemon] = index (within the inventory) of the item to remove
-; [wcf96] = quantity to remove
-RemoveItemFromInventory_: ; ce74 (3:4e74)
- push hl
- inc hl
- ld a,[wWhichPokemon] ; index (within the inventory) of the item being removed
- sla a
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- inc hl
- ld a,[wcf96] ; quantity being removed
- ld e,a
- ld a,[hl] ; a = current quantity
- sub e
- ld [hld],a ; store new quantity
- ld [wcf97],a
- and a
- jr nz,.skipMovingUpSlots
-; if the remaining quantity is 0,
-; remove the emptied item slot and move up all the following item slots
-.moveSlotsUp
- ld e,l
- ld d,h
- inc de
- inc de ; de = address of the slot following the emptied one
-.loop ; loop to move up the following slots
- ld a,[de]
- inc de
- ld [hli],a
- cp a,$ff
- jr nz,.loop
-; update menu info
- xor a
- ld [wListScrollOffset],a
- ld [wCurrentMenuItem],a
- ld [wcc2c],a
- ld [wd07e],a
- pop hl
- ld a,[hl] ; a = number of items in inventory
- dec a ; decrement the number of items
- ld [hl],a ; store new number of items
- ld [wd12a],a
- cp a,2
- jr c,.done
- ld [wMaxMenuItem],a
- jr .done
-.skipMovingUpSlots
- pop hl
-.done
- ret
-
-; wild pokemon data: from 4EB8 to 55C7
-
-LoadWildData: ; ceb8 (3:4eb8)
- ld hl,WildDataPointers
- ld a,[W_CURMAP]
-
- ; get wild data for current map
- ld c,a
- ld b,0
- add hl,bc
- add hl,bc
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl now points to wild data for current map
- ld a,[hli]
- ld [W_GRASSRATE],a
- and a
- jr z,.NoGrassData ; if no grass data, skip to surfing data
- push hl
- ld de,W_GRASSMONS ; otherwise, load grass data
- ld bc,$0014
- call CopyData
- pop hl
- ld bc,$0014
- add hl,bc
-.NoGrassData
- ld a,[hli]
- ld [W_WATERRATE],a
- and a
- ret z ; if no water data, we're done
- ld de,W_WATERMONS ; otherwise, load surfing data
- ld bc,$0014
- jp CopyData
-
-INCLUDE "data/wild_mons.asm"
-
-INCLUDE "engine/items/items.asm"
-
-DrawBadges: ; ea03 (3:6a03)
-; Draw 4x2 gym leader faces, with the faces replaced by
-; badges if they are owned. Used in the player status screen.
-
-; In Japanese versions, names are displayed above faces.
-; Instead of removing relevant code, the name graphics were erased.
-
-; Tile ids for face/badge graphics.
- ld de, wTrainerFacingDirection
- ld hl, .FaceBadgeTiles
- ld bc, 8
- call CopyData
-
-; Booleans for each badge.
- ld hl, wcd49
- ld bc, 8
- xor a
- call FillMemory
-
-; Alter these based on owned badges.
- ld de, wcd49
- ld hl, wTrainerFacingDirection
- ld a, [W_OBTAINEDBADGES]
- ld b, a
- ld c, 8
-.CheckBadge
- srl b
- jr nc, .NextBadge
- ld a, [hl]
- add 4 ; Badge graphics are after each face
- ld [hl], a
- ld a, 1
- ld [de], a
-.NextBadge
- inc hl
- inc de
- dec c
- jr nz, .CheckBadge
-
-; Draw two rows of badges.
- ld hl, wWhichTrade
- ld a, $d8 ; [1]
- ld [hli], a
- ld [hl], $60 ; First name
-
- hlCoord 2, 11
- ld de, wcd49
- call .DrawBadgeRow
-
- hlCoord 2, 14
- ld de, wcd49 + 4
-; call .DrawBadgeRow
-; ret
-
-.DrawBadgeRow ; ea4c (3:6a4c)
-; Draw 4 badges.
-
- ld c, 4
-.DrawBadge
- push de
- push hl
-
-; Badge no.
- ld a, [wWhichTrade]
- ld [hli], a
- inc a
- ld [wWhichTrade], a
-
-; Names aren't printed if the badge is owned.
- ld a, [de]
- and a
- ld a, [wTrainerEngageDistance]
- jr nz, .SkipName
- call .PlaceTiles
- jr .PlaceBadge
-
-.SkipName
- inc a
- inc a
- inc hl
-
-.PlaceBadge
- ld [wTrainerEngageDistance], a
- ld de, 20 - 1
- add hl, de
- ld a, [wTrainerFacingDirection]
- call .PlaceTiles
- add hl, de
- call .PlaceTiles
-
-; Shift badge array back one byte.
- push bc
- ld hl, wTrainerFacingDirection + 1
- ld de, wTrainerFacingDirection
- ld bc, 8
- call CopyData
- pop bc
-
- pop hl
- ld de, 4
- add hl, de
-
- pop de
- inc de
- dec c
- jr nz, .DrawBadge
- ret
-
-.PlaceTiles
- ld [hli], a
- inc a
- ld [hl], a
- inc a
- ret
-
-.FaceBadgeTiles
- db $20, $28, $30, $38, $40, $48, $50, $58
-
-GymLeaderFaceAndBadgeTileGraphics: ; ea9e (3:6a9e)
- INCBIN "gfx/badges.2bpp"
-
-; replaces a tile block with the one specified in [wNewTileBlockID]
-; and redraws the map view if necessary
-; b = Y
-; c = X
-ReplaceTileBlock: ; ee9e (3:6e9e)
- call GetPredefRegisters
- ld hl, wOverworldMap
- ld a, [W_CURMAPWIDTH]
- add $6
- ld e, a
- ld d, $0
- add hl, de
- add hl, de
- add hl, de
- ld e, $3
- add hl, de
- ld e, a
- ld a, b
- and a
- jr z, .addX
-; add width * Y
-.addWidthYTimesLoop
- add hl, de
- dec b
- jr nz, .addWidthYTimesLoop
-.addX
- add hl, bc ; add X
- ld a, [wNewTileBlockID]
- ld [hl], a
- ld a, [wCurrentTileBlockMapViewPointer]
- ld c, a
- ld a, [wCurrentTileBlockMapViewPointer + 1]
- ld b, a
- call CompareHLWithBC
- ret c ; return if the replaced tile block is below the map view in memory
- push hl
- ld l, e
- ld h, $0
- ld e, $6
- ld d, h
- add hl, hl
- add hl, hl
- add hl, de
- add hl, bc
- pop bc
- call CompareHLWithBC
- ret c ; return if the replaced tile block is above the map view in memory
-
-RedrawMapView: ; eedc (3:6edc)
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- inc a
- ret z
- ld a, [H_AUTOBGTRANSFERENABLED]
- push af
- ld a, [hTilesetType]
- push af
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [hTilesetType], a ; no flower/water BG tile animations
- call LoadCurrentMapView
- call GoPAL_SET_CF1C
- ld hl, wMapViewVRAMPointer
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, -2 * 32
- add hl, de
- ld a, h
- and $3
- or $98
- ld a, l
- ld [wHPBarMaxHP], a
- ld a, h
- ld [wHPBarMaxHP + 1], a
- ld a, 2
- ld [$ffbe], a
- ld c, 9 ; number of rows of 2x2 tiles (this covers the whole screen)
-.redrawRowLoop
- push bc
- push hl
- push hl
- ld hl, wTileMap - 2 * 20
- ld de, 20
- ld a, [$ffbe]
-.asm_ef1a
- add hl, de
- dec a
- jr nz, .asm_ef1a
- call CopyToScreenEdgeTiles
- pop hl
- ld de, $20
- ld a, [$ffbe]
- ld c, a
-.asm_ef28
- add hl, de
- ld a, h
- and $3
- or $98
- dec c
- jr nz, .asm_ef28
- ld [H_SCREENEDGEREDRAWADDR + 1], a
- ld a, l
- ld [H_SCREENEDGEREDRAWADDR], a
- ld a, REDRAWROW
- ld [H_SCREENEDGEREDRAW], a
- call DelayFrame
- ld hl, $ffbe
- inc [hl]
- inc [hl]
- pop hl
- pop bc
- dec c
- jr nz, .redrawRowLoop
- pop af
- ld [hTilesetType], a
- pop af
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-CompareHLWithBC: ; ef4e (3:6f4e)
- ld a, h
- sub b
- ret nz
- ld a, l
- sub c
- ret
-
-INCLUDE "engine/overworld/cut.asm"
-
-MarkTownVisitedAndLoadMissableObjects: ; f113 (3:7113)
- ld a, [W_CURMAP]
- cp ROUTE_1
- jr nc, .notInTown
- ld c, a
- ld b, $1
- ld hl, W_TOWNVISITEDFLAG ; mark town as visited (for flying)
- predef FlagActionPredef
-.notInTown
- ld hl, MapHSPointers
- ld a, [W_CURMAP]
- ld b, $0
- ld c, a
- add hl, bc
- add hl, bc
- ld a, [hli] ; load missable objects pointer in hl
- ld h, [hl]
- ; fall through
-
-LoadMissableObjects: ; f132 (3:7132)
- ld l, a
- push hl
- ld de, MapHS00 ; calculate difference between out pointer and the base pointer
- ld a, l
- sub e
- jr nc, .asm_f13c
- dec h
-.asm_f13c
- ld l, a
- ld a, h
- sub d
- ld h, a
- ld a, h
- ld [H_DIVIDEND], a
- ld a, l
- ld [H_DIVIDEND+1], a
- xor a
- ld [H_DIVIDEND+2], a
- ld [H_DIVIDEND+3], a
- ld a, $3
- ld [H_DIVISOR], a
- ld b, $2
- call Divide ; divide difference by 3, resulting in the global offset (number of missable items before ours)
- ld a, [W_CURMAP] ; W_CURMAP
- ld b, a
- ld a, [H_DIVIDEND+3]
- ld c, a ; store global offset in c
- ld de, W_MISSABLEOBJECTLIST
- pop hl
-.writeMissableObjectsListLoop
- ld a, [hli]
- cp $ff
- jr z, .done ; end of list
- cp b
- jr nz, .done ; not for current map anymore
- ld a, [hli]
- inc hl
- ld [de], a ; write (map-local) sprite ID
- inc de
- ld a, c
- inc c
- ld [de], a ; write (global) missable object index
- inc de
- jr .writeMissableObjectsListLoop
-.done
- ld a, $ff
- ld [de], a ; write sentinel
- ret
-
-InitializeMissableObjectsFlags: ; f175 (3:7175)
- ld hl, W_MISSABLEOBJECTFLAGS
- ld bc, $20
- xor a
- call FillMemory ; clear missable objects flags
- ld hl, MapHS00
- xor a
- ld [wd048], a
-.missableObjectsLoop
- ld a, [hli]
- cp $ff ; end of list
- ret z
- push hl
- inc hl
- ld a, [hl]
- cp Hide
- jr nz, .asm_f19d
- ld hl, W_MISSABLEOBJECTFLAGS
- ld a, [wd048]
- ld c, a
- ld b, $1
- call MissableObjectFlagAction ; set flag iff Item is hidden
-.asm_f19d
- ld hl, wd048
- inc [hl]
- pop hl
- inc hl
- inc hl
- jr .missableObjectsLoop
-
-; tests if current sprite is a missable object that is hidden/has been removed
-IsObjectHidden: ; f1a6 (3:71a6)
- ld a, [H_CURRENTSPRITEOFFSET]
- swap a
- ld b, a
- ld hl, W_MISSABLEOBJECTLIST
-.loop
- ld a, [hli]
- cp $ff
- jr z, .notHidden ; not missable -> not hidden
- cp b
- ld a, [hli]
- jr nz, .loop
- ld c, a
- ld b, $2
- ld hl, W_MISSABLEOBJECTFLAGS
- call MissableObjectFlagAction
- ld a, c
- and a
- jr nz, .hidden
-.notHidden
- xor a
-.hidden
- ld [$ffe5], a
- ret
-
-; adds missable object (items, leg. pokemon, etc.) to the map
-; [wcc4d]: index of the missable object to be added (global index)
-ShowObject: ; f1c8 (3:71c8)
-ShowObject2:
- ld hl, W_MISSABLEOBJECTFLAGS
- ld a, [wcc4d]
- ld c, a
- ld b, $0
- call MissableObjectFlagAction ; reset "removed" flag
- jp UpdateSprites
-
-; removes missable object (items, leg. pokemon, etc.) from the map
-; [wcc4d]: index of the missable object to be removed (global index)
-HideObject: ; f1d7 (3:71d7)
- ld hl, W_MISSABLEOBJECTFLAGS
- ld a, [wcc4d]
- ld c, a
- ld b, $1
- call MissableObjectFlagAction ; set "removed" flag
- jp UpdateSprites
-
-MissableObjectFlagAction:
-; identical to FlagAction
-
- push hl
- push de
- push bc
-
- ; bit
- ld a, c
- ld d, a
- and 7
- ld e, a
-
- ; byte
- ld a, d
- srl a
- srl a
- srl a
- add l
- ld l, a
- jr nc, .ok
- inc h
-.ok
-
- ; d = 1 << e (bitmask)
- inc e
- ld d, 1
-.shift
- dec e
- jr z, .shifted
- sla d
- jr .shift
-.shifted
-
- ld a, b
- and a
- jr z, .reset
- cp 2
- jr z, .read
-
-.set
- ld a, [hl]
- ld b, a
- ld a, d
- or b
- ld [hl], a
- jr .done
-
-.reset
- ld a, [hl]
- ld b, a
- ld a, d
- xor $ff
- and b
- ld [hl], a
- jr .done
-
-.read
- ld a, [hl]
- ld b, a
- ld a, d
- and b
-
-.done
- pop bc
- pop de
- pop hl
- ld c, a
- ret
-
-TryPushingBoulder: ; f225 (3:7225)
- ld a, [wd728]
- bit 0, a ; using Strength?
- ret z
- ld a, [wFlags_0xcd60]
- bit 1, a ; has boulder dust animation from previous push played yet?
- ret nz
- xor a
- ld [$ff8c], a
- call IsSpriteInFrontOfPlayer
- ld a, [$ff8c]
- ld [wBoulderSpriteIndex], a
- and a
- jp z, ResetBoulderPushFlags
- ld hl, wSpriteStateData1 + 1
- ld d, $0
- ld a, [$ff8c]
- swap a
- ld e, a
- add hl, de
- res 7, [hl]
- call GetSpriteMovementByte2Pointer
- ld a, [hl]
- cp BOULDER_MOVEMENT_BYTE_2
- jp nz, ResetBoulderPushFlags
- ld hl, wFlags_0xcd60
- bit 6, [hl]
- set 6, [hl] ; indicate that the player has tried pushing
- ret z ; the player must try pushing twice before the boulder will move
- ld a, [hJoyHeld]
- and $f0
- ret z
- predef CheckForCollisionWhenPushingBoulder
- ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult]
- and a ; was there a collision?
- jp nz, ResetBoulderPushFlags
- ld a, [hJoyHeld]
- ld b, a
- ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
- cp SPRITE_FACING_UP
- jr z, .pushBoulderUp
- cp SPRITE_FACING_LEFT
- jr z, .pushBoulderLeft
- cp SPRITE_FACING_RIGHT
- jr z, .pushBoulderRight
-.pushBoulderDown
- bit 7, b
- ret z
- ld de, PushBoulderDownMovementData
- jr .done
-.pushBoulderUp
- bit 6, b
- ret z
- ld de, PushBoulderUpMovementData
- jr .done
-.pushBoulderLeft
- bit 5, b
- ret z
- ld de, PushBoulderLeftMovementData
- jr .done
-.pushBoulderRight
- bit 4, b
- ret z
- ld de, PushBoulderRightMovementData
-.done
- call MoveSprite
- ld a, (SFX_02_53 - SFX_Headers_02) / 3
- call PlaySound
- ld hl, wFlags_0xcd60
- set 1, [hl]
- ret
-
-PushBoulderUpMovementData: ; f2ad (3:72ad)
- db NPC_MOVEMENT_UP,$FF
-
-PushBoulderDownMovementData: ; f2af (3:72af)
- db NPC_MOVEMENT_DOWN,$FF
-
-PushBoulderLeftMovementData: ; f2b1 (3:72b1)
- db NPC_MOVEMENT_LEFT,$FF
-
-PushBoulderRightMovementData: ; f2b3 (3:72b3)
- db NPC_MOVEMENT_RIGHT,$FF
-
-DoBoulderDustAnimation: ; f2b5 (3:72b5)
- ld a, [wd730]
- bit 0, a
- ret nz
- callab AnimateBoulderDust
- call DiscardButtonPresses
- ld [wJoyIgnore], a
- call ResetBoulderPushFlags
- set 7, [hl]
- ld a, [wBoulderSpriteIndex]
- ld [H_SPRITEINDEX], a
- call GetSpriteMovementByte2Pointer
- ld [hl], $10
- ld a, (SFX_02_56 - SFX_Headers_02) / 3
- jp PlaySound
-
-ResetBoulderPushFlags: ; f2dd (3:72dd)
- ld hl, wFlags_0xcd60
- res 1, [hl]
- res 6, [hl]
- ret
-
-_AddPartyMon: ; f2e5 (3:72e5)
- ld de, wPartyCount ; wPartyCount
- ld a, [wcc49]
- and $f
- jr z, .asm_f2f2
- ld de, wEnemyPartyCount ; wEnemyPartyCount
-.asm_f2f2
- ld a, [de]
- inc a
- cp PARTY_LENGTH + 1
- ret nc
- ld [de], a
- ld a, [de]
- ld [$ffe4], a
- add e
- ld e, a
- jr nc, .asm_f300
- inc d
-.asm_f300
- ld a, [wcf91]
- ld [de], a
- inc de
- ld a, $ff
- ld [de], a
- ld hl, wPartyMonOT ; wd273
- ld a, [wcc49]
- and $f
- jr z, .asm_f315
- ld hl, wEnemyMonOT
-.asm_f315
- ld a, [$ffe4]
- dec a
- call SkipFixedLengthTextEntries
- ld d, h
- ld e, l
- ld hl, wPlayerName ; wd158
- ld bc, $b
- call CopyData
- ld a, [wcc49]
- and a
- jr nz, .asm_f33f
- ld hl, wPartyMonNicks ; wPartyMonNicks
- ld a, [$ffe4]
- dec a
- call SkipFixedLengthTextEntries
- ld a, $2
- ld [wd07d], a
- predef AskName
-.asm_f33f
- ld hl, wPartyMons
- ld a, [wcc49]
- and $f
- jr z, .asm_f34c
- ld hl, wEnemyMons
-.asm_f34c
- ld a, [$ffe4]
- dec a
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- ld e, l
- ld d, h
- push hl
- ld a, [wcf91]
- ld [wd0b5], a
- call GetMonHeader
- ld hl, W_MONHEADER
- ld a, [hli]
- ld [de], a
- inc de
- pop hl
- push hl
- ld a, [wcc49]
- and $f
- ld a, $98 ; set enemy trainer mon IVs to fixed average values
- ld b, $88
- jr nz, .writeFreshMonData
- ld a, [wcf91]
- ld [wd11e], a
- push de
- predef IndexToPokedex
- pop de
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, $2
- ld hl, wPokedexOwned ; wPokedexOwned
- call FlagAction
- ld a, c
- ld [wd153], a
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, $1
- push bc
- call FlagAction
- pop bc
- ld hl, wPokedexSeen ; wd30a
- call FlagAction
- pop hl
- push hl
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- and a
- jr nz, .copyEnemyMonData
- call Random ; generate random IVs
- ld b, a
- call Random
-.writeFreshMonData ; f3b3
- push bc
- ld bc, $1b
- add hl, bc
- pop bc
- ld [hli], a
- ld [hl], b ; write IVs
- ld bc, $fff4
- add hl, bc
- ld a, $1
- ld c, a
- xor a
- ld b, a
- call CalcStat ; calc HP stat (set cur Hp to max HP)
- ld a, [H_MULTIPLICAND+1]
- ld [de], a
- inc de
- ld a, [H_MULTIPLICAND+2]
- ld [de], a
- inc de
- xor a
- ld [de], a ; level (?)
- inc de
- ld [de], a ; status ailments
- inc de
- jr .copyMonTypesAndMoves
-.copyEnemyMonData
- ld bc, $1b
- add hl, bc
- ld a, [wEnemyMonDVs] ; copy IVs from cur enemy mon
- ld [hli], a
- ld a, [wEnemyMonDVs + 1]
- ld [hl], a
- ld a, [wEnemyMonHP] ; copy HP from cur enemy mon
- ld [de], a
- inc de
- ld a, [wEnemyMonHP+1]
- ld [de], a
- inc de
- xor a
- ld [de], a ; level (?)
- inc de
- ld a, [wEnemyMonStatus] ; copy status ailments from cur enemy mon
- ld [de], a
- inc de
-.copyMonTypesAndMoves
- ld hl, W_MONHTYPES
- ld a, [hli] ; type 1
- ld [de], a
- inc de
- ld a, [hli] ; type 2
- ld [de], a
- inc de
- ld a, [hli] ; unused (?)
- ld [de], a
- ld hl, W_MONHMOVES
- ld a, [hli]
- inc de
- push de
- ld [de], a
- ld a, [hli]
- inc de
- ld [de], a
- ld a, [hli]
- inc de
- ld [de], a
- ld a, [hli]
- inc de
- ld [de], a
- push de
- dec de
- dec de
- dec de
- xor a
- ld [wHPBarMaxHP], a
- predef WriteMonMoves
- pop de
- ld a, [wPlayerID] ; set trainer ID to player ID
- inc de
- ld [de], a
- ld a, [wPlayerID + 1]
- inc de
- ld [de], a
- push de
- ld a, [W_CURENEMYLVL]
- ld d, a
- callab CalcExperience
- pop de
- inc de
- ld a, [H_MULTIPLICAND] ; write experience
- ld [de], a
- inc de
- ld a, [H_MULTIPLICAND+1]
- ld [de], a
- inc de
- ld a, [H_MULTIPLICAND+2]
- ld [de], a
- xor a
- ld b, $a
-.writeEVsLoop ; set all EVs to 0
- inc de
- ld [de], a
- dec b
- jr nz, .writeEVsLoop
- inc de
- inc de
- pop hl
- call AddPartyMon_WriteMovePP
- inc de
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
- ld [de], a
- inc de
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- dec a
- jr nz, .calcFreshStats
- ld hl, wEnemyMonMaxHP ; wEnemyMonMaxHP
- ld bc, $a
- call CopyData ; copy stats of cur enemy mon
- pop hl
- jr .done
-.calcFreshStats
- pop hl
- ld bc, $10
- add hl, bc
- ld b, $0
- call CalcStats ; calculate fresh set of stats
-.done
- scf
- ret
-
-LoadMovePPs: ; f473 (3:7473)
- call GetPredefRegisters
- ; fallthrough
-AddPartyMon_WriteMovePP: ; f476 (3:7476)
- ld b, $4
-.pploop
- ld a, [hli] ; read move ID
- and a
- jr z, .empty
- dec a
- push hl
- push de
- push bc
- ld hl, Moves
- ld bc, $6
- call AddNTimes
- ld de, wcd6d
- ld a, BANK(Moves)
- call FarCopyData
- pop bc
- pop de
- pop hl
- ld a, [wcd72] ; sixth move byte = pp
-.empty
- inc de
- ld [de], a
- dec b
- jr nz, .pploop ; there are still moves to read
- ret
-
-; adds enemy mon [wcf91] (at position [wWhichPokemon] in enemy list) to own party
-; used in the cable club trade center
-_AddEnemyMonToPlayerParty: ; f49d (3:749d)
- ld hl, wPartyCount
- ld a, [hl]
- cp PARTY_LENGTH
- scf
- ret z ; party full, return failure
- inc a
- ld [hl], a ; add 1 to party members
- ld c, a
- ld b, $0
- add hl, bc
- ld a, [wcf91]
- ld [hli], a ; add mon as last list entry
- ld [hl], $ff ; write new sentinel
- ld hl, wPartyMons
- ld a, [wPartyCount]
- dec a
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- ld e, l
- ld d, h
- ld hl, wLoadedMon
- call CopyData ; write new mon's data (from wLoadedMon)
- ld hl, wPartyMonOT
- ld a, [wPartyCount]
- dec a
- call SkipFixedLengthTextEntries
- ld d, h
- ld e, l
- ld hl, wEnemyMonOT
- ld a, [wWhichPokemon]
- call SkipFixedLengthTextEntries
- ld bc, $000b
- call CopyData ; write new mon's OT name (from an enemy mon)
- ld hl, wPartyMonNicks
- ld a, [wPartyCount]
- dec a
- call SkipFixedLengthTextEntries
- ld d, h
- ld e, l
- ld hl, wEnemyMonNicks
- ld a, [wWhichPokemon]
- call SkipFixedLengthTextEntries
- ld bc, $000b
- call CopyData ; write new mon's nickname (from an enemy mon)
- ld a, [wcf91]
- ld [wd11e], a
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, $1
- ld hl, wPokedexOwned
- push bc
- call FlagAction ; add to owned pokemon
- pop bc
- ld hl, wPokedexSeen
- call FlagAction ; add to seen pokemon
- and a
- ret ; return success
-
-Func_f51e: ; f51e (3:751e)
- ld a, [wcf95]
- and a
- jr z, .checkPartyMonSlots
- cp $2
- jr z, .checkPartyMonSlots
- cp $3
- ld hl, wDayCareMon
- jr z, .asm_f575
- ld hl, W_NUMINBOX ; wda80
- ld a, [hl]
- cp MONS_PER_BOX
- jr nz, .partyOrBoxNotFull
- jr .boxFull
-.checkPartyMonSlots
- ld hl, wPartyCount ; wPartyCount
- ld a, [hl]
- cp PARTY_LENGTH
- jr nz, .partyOrBoxNotFull
-.boxFull
- scf
- ret
-.partyOrBoxNotFull
- inc a
- ld [hl], a ; increment number of mons in party/box
- ld c, a
- ld b, $0
- add hl, bc
- ld a, [wcf95]
- cp $2
- ld a, [wDayCareMon]
- jr z, .asm_f556
- ld a, [wcf91]
-.asm_f556
- ld [hli], a ; write new mon ID
- ld [hl], $ff ; write new sentinel
- ld a, [wcf95]
- dec a
- ld hl, wPartyMons
- ld bc, wPartyMon2 - wPartyMon1 ; $2c
- ld a, [wPartyCount] ; wPartyCount
- jr nz, .skipToNewMonEntry
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1 ; $21
- ld a, [W_NUMINBOX] ; wda80
-.skipToNewMonEntry
- dec a
- call AddNTimes
-.asm_f575
- push hl
- ld e, l
- ld d, h
- ld a, [wcf95]
- and a
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1 ; $21
- jr z, .asm_f591
- cp $2
- ld hl, wDayCareMon
- jr z, .asm_f597
- ld hl, wPartyMons
- ld bc, wPartyMon2 - wPartyMon1 ; $2c
-.asm_f591
- ld a, [wWhichPokemon] ; wWhichPokemon
- call AddNTimes
-.asm_f597
- push hl
- push de
- ld bc, wBoxMon2 - wBoxMon1
- call CopyData
- pop de
- pop hl
- ld a, [wcf95]
- and a
- jr z, .asm_f5b4
- cp $2
- jr z, .asm_f5b4
- ld bc, wBoxMon2 - wBoxMon1
- add hl, bc
- ld a, [hl]
- inc de
- inc de
- inc de
- ld [de], a
-.asm_f5b4
- ld a, [wcf95]
- cp $3
- ld de, W_DAYCAREMONOT
- jr z, .asm_f5d3
- dec a
- ld hl, wPartyMonOT ; wd273
- ld a, [wPartyCount] ; wPartyCount
- jr nz, .asm_f5cd
- ld hl, wBoxMonOT
- ld a, [W_NUMINBOX] ; wda80
-.asm_f5cd
- dec a
- call SkipFixedLengthTextEntries
- ld d, h
- ld e, l
-.asm_f5d3
- ld hl, wBoxMonOT
- ld a, [wcf95]
- and a
- jr z, .asm_f5e6
- ld hl, W_DAYCAREMONOT
- cp $2
- jr z, .asm_f5ec
- ld hl, wPartyMonOT ; wd273
-.asm_f5e6
- ld a, [wWhichPokemon] ; wWhichPokemon
- call SkipFixedLengthTextEntries
-.asm_f5ec
- ld bc, $b
- call CopyData
- ld a, [wcf95]
- cp $3
- ld de, W_DAYCAREMONNAME
- jr z, .asm_f611
- dec a
- ld hl, wPartyMonNicks ; wPartyMonNicks
- ld a, [wPartyCount] ; wPartyCount
- jr nz, .asm_f60b
- ld hl, wBoxMonNicks
- ld a, [W_NUMINBOX] ; wda80
-.asm_f60b
- dec a
- call SkipFixedLengthTextEntries
- ld d, h
- ld e, l
-.asm_f611
- ld hl, wBoxMonNicks
- ld a, [wcf95]
- and a
- jr z, .asm_f624
- ld hl, W_DAYCAREMONNAME
- cp $2
- jr z, .asm_f62a
- ld hl, wPartyMonNicks ; wPartyMonNicks
-.asm_f624
- ld a, [wWhichPokemon] ; wWhichPokemon
- call SkipFixedLengthTextEntries
-.asm_f62a
- ld bc, $b
- call CopyData
- pop hl
- ld a, [wcf95]
- cp $1
- jr z, .asm_f664
- cp $3
- jr z, .asm_f664
- push hl
- srl a
- add $2
- ld [wcc49], a
- call LoadMonData
- callba CalcLevelFromExperience
- ld a, d
- ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
- pop hl
- ld bc, wBoxMon2 - wBoxMon1
- add hl, bc
- ld [hli], a
- ld d, h
- ld e, l
- ld bc, $ffee
- add hl, bc
- ld b, $1
- call CalcStats
-.asm_f664
- and a
- ret
-
-
-FlagActionPredef:
- call GetPredefRegisters
-
-FlagAction:
-; Perform action b on bit c
-; in the bitfield at hl.
-; 0: reset
-; 1: set
-; 2: read
-; Return the result in c.
-
- push hl
- push de
- push bc
-
- ; bit
- ld a, c
- ld d, a
- and 7
- ld e, a
-
- ; byte
- ld a, d
- srl a
- srl a
- srl a
- add l
- ld l, a
- jr nc, .ok
- inc h
-.ok
-
- ; d = 1 << e (bitmask)
- inc e
- ld d, 1
-.shift
- dec e
- jr z, .shifted
- sla d
- jr .shift
-.shifted
-
- ld a, b
- and a
- jr z, .reset
- cp 2
- jr z, .read
-
-.set
- ld b, [hl]
- ld a, d
- or b
- ld [hl], a
- jr .done
-
-.reset
- ld b, [hl]
- ld a, d
- xor $ff
- and b
- ld [hl], a
- jr .done
-
-.read
- ld b, [hl]
- ld a, d
- and b
-.done
- pop bc
- pop de
- pop hl
- ld c, a
- ret
-
-
-HealParty:
-; Restore HP and PP.
-
- ld hl, wPartySpecies
- ld de, wPartyMon1HP
-.healmon
- ld a, [hli]
- cp $ff
- jr z, .done
-
- push hl
- push de
-
- ld hl, wPartyMon1Status - wPartyMon1HP
- add hl, de
- xor a
- ld [hl], a
-
- push de
- ld b, NUM_MOVES ; A Pokémon has 4 moves
-.pp
- ld hl, wPartyMon1Moves - wPartyMon1HP
- add hl, de
-
- ld a, [hl]
- and a
- jr z, .nextmove
-
- dec a
- ld hl, wPartyMon1PP - wPartyMon1HP
- add hl, de
-
- push hl
- push de
- push bc
-
- ld hl, Moves
- ld bc, $0006
- call AddNTimes
- ld de, wcd6d
- ld a, BANK(Moves)
- call FarCopyData
- ld a, [wcd72] ; default pp
-
- pop bc
- pop de
- pop hl
-
- inc de
- push bc
- ld b, a
- ld a, [hl]
- and $c0
- add b
- ld [hl], a
- pop bc
-
-.nextmove
- dec b
- jr nz, .pp
- pop de
-
- ld hl, wPartyMon1MaxHP - wPartyMon1HP
- add hl, de
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hl]
- ld [de], a
-
- pop de
- pop hl
-
- push hl
- ld bc, wPartyMon2 - wPartyMon1
- ld h, d
- ld l, e
- add hl, bc
- ld d, h
- ld e, l
- pop hl
- jr .healmon
-
-.done
- xor a
- ld [wWhichPokemon], a
- ld [wd11e], a
-
- ld a, [wPartyCount]
- ld b, a
-.ppup
- push bc
- call RestoreBonusPP
- pop bc
- ld hl, wWhichPokemon
- inc [hl]
- dec b
- jr nz, .ppup
- ret
-
-
-DivideBCDPredef::
-DivideBCDPredef2::
-DivideBCDPredef3::
-DivideBCDPredef4::
- call GetPredefRegisters
-
-DivideBCD::
- xor a
- ld [$ffa5], a
- ld [$ffa6], a
- ld [$ffa7], a
- ld d, $1
-.asm_f72a
- ld a, [$ffa2]
- and $f0
- jr nz, .asm_f75b
- inc d
- ld a, [$ffa2]
- swap a
- and $f0
- ld b, a
- ld a, [$ffa3]
- swap a
- ld [$ffa3], a
- and $f
- or b
- ld [$ffa2], a
- ld a, [$ffa3]
- and $f0
- ld b, a
- ld a, [$ffa4]
- swap a
- ld [$ffa4], a
- and $f
- or b
- ld [$ffa3], a
- ld a, [$ffa4]
- and $f0
- ld [$ffa4], a
- jr .asm_f72a
-.asm_f75b
- push de
- push de
- call Func_f800
- pop de
- ld a, b
- swap a
- and $f0
- ld [$ffa5], a
- dec d
- jr z, .asm_f7bc
- push de
- call Func_f7d7
- call Func_f800
- pop de
- ld a, [$ffa5]
- or b
- ld [$ffa5], a
- dec d
- jr z, .asm_f7bc
- push de
- call Func_f7d7
- call Func_f800
- pop de
- ld a, b
- swap a
- and $f0
- ld [$ffa6], a
- dec d
- jr z, .asm_f7bc
- push de
- call Func_f7d7
- call Func_f800
- pop de
- ld a, [$ffa6]
- or b
- ld [$ffa6], a
- dec d
- jr z, .asm_f7bc
- push de
- call Func_f7d7
- call Func_f800
- pop de
- ld a, b
- swap a
- and $f0
- ld [$ffa7], a
- dec d
- jr z, .asm_f7bc
- push de
- call Func_f7d7
- call Func_f800
- pop de
- ld a, [$ffa7]
- or b
- ld [$ffa7], a
-.asm_f7bc
- ld a, [$ffa5]
- ld [$ffa2], a
- ld a, [$ffa6]
- ld [$ffa3], a
- ld a, [$ffa7]
- ld [$ffa4], a
- pop de
- ld a, $6
- sub d
- and a
- ret z
-.asm_f7ce
- push af
- call Func_f7d7
- pop af
- dec a
- jr nz, .asm_f7ce
- ret
-
-Func_f7d7: ; f7d7 (3:77d7)
- ld a, [$ffa4]
- swap a
- and $f
- ld b, a
- ld a, [$ffa3]
- swap a
- ld [$ffa3], a
- and $f0
- or b
- ld [$ffa4], a
- ld a, [$ffa3]
- and $f
- ld b, a
- ld a, [$ffa2]
- swap a
- ld [$ffa2], a
- and $f0
- or b
- ld [$ffa3], a
- ld a, [$ffa2]
- and $f
- ld [$ffa2], a
- ret
-
-Func_f800: ; f800 (3:7800)
- ld bc, $3
-.asm_f803
- ld de, $ff9f
- ld hl, $ffa2
- push bc
- call StringCmp
- pop bc
- ret c
- inc b
- ld de, $ffa1
- ld hl, $ffa4
- push bc
- call SubBCD
- pop bc
- jr .asm_f803
-
-
-AddBCDPredef::
- call GetPredefRegisters
-
-AddBCD::
- and a
- ld b, c
-.add
- ld a, [de]
- adc [hl]
- daa
- ld [de], a
- dec de
- dec hl
- dec c
- jr nz, .add
- jr nc, .done
- ld a, $99
- inc de
-.fill
- ld [de], a
- inc de
- dec b
- jr nz, .fill
-.done
- ret
-
-
-SubBCDPredef::
- call GetPredefRegisters
-
-SubBCD::
- and a
- ld b, c
-.sub
- ld a, [de]
- sbc [hl]
- daa
- ld [de], a
- dec de
- dec hl
- dec c
- jr nz, .sub
- jr nc, .done
- ld a, $00
- inc de
-.fill
- ld [de], a
- inc de
- dec b
- jr nz, .fill
- scf
-.done
- ret
-
-
-InitPlayerData:
-InitPlayerData2:
-
- call Random
- ld a, [hRandomSub]
- ld [wPlayerID], a
-
- call Random
- ld a, [hRandomAdd]
- ld [wPlayerID + 1], a
-
- ld a, $ff
- ld [wd71b], a ; XXX what's this?
-
- ld hl, wPartyCount
- call InitializeEmptyList
- ld hl, W_NUMINBOX
- call InitializeEmptyList
- ld hl, wNumBagItems
- call InitializeEmptyList
- ld hl, wNumBoxItems
- call InitializeEmptyList
-
-START_MONEY EQU $3000
- ld hl, wPlayerMoney + 1
- ld a, START_MONEY / $100
- ld [hld], a
- xor a
- ld [hli], a
- inc hl
- ld [hl], a
-
- ld [wcc49], a
-
- ld hl, W_OBTAINEDBADGES
- ld [hli], a
-
- ld [hl], a
-
- ld hl, wPlayerCoins
- ld [hli], a
- ld [hl], a
-
- ld hl, W_GAMEPROGRESSFLAGS
- ld bc, $c8
- call FillMemory ; clear all game progress flags
-
- jp InitializeMissableObjectsFlags
-
-InitializeEmptyList:
- xor a ; count
- ld [hli], a
- dec a ; terminator
- ld [hl], a
- ret
-
-
-IsItemInBag_: ; f8a5 (3:78a5)
- call GetPredefRegisters
- ld hl, wNumBagItems ; wNumBagItems
-.asm_f8ab
- inc hl
- ld a, [hli]
- cp $ff
- jr z, .asm_f8b7
- cp b
- jr nz, .asm_f8ab
- ld a, [hl]
- ld b, a
- ret
-.asm_f8b7
- ld b, $0
- ret
-
-FindPathToPlayer: ; f8ba (3:78ba)
- xor a
- ld hl, $ff97
- ld [hli], a
- ld [hli], a
- ld [hli], a
- ld [hl], a
- ld hl, wNPCMovementDirections2
- ld de, $0
-.loop
- ld a, [$ff99]
- ld b, a
- ld a, [$ff95] ; Y distance in steps
- call CalcDifference
- ld d, a
- and a
- jr nz, .asm_f8da
- ld a, [$ff98]
- set 0, a
- ld [$ff98], a
-.asm_f8da
- ld a, [$ff9a]
- ld b, a
- ld a, [$ff96] ; X distance in steps
- call CalcDifference
- ld e, a
- and a
- jr nz, .asm_f8ec
- ld a, [$ff98]
- set 1, a
- ld [$ff98], a
-.asm_f8ec
- ld a, [$ff98]
- cp $3
- jr z, .done
- ld a, e
- cp d
- jr c, .asm_f90a
- ld a, [$ff9d]
- bit 1, a
- jr nz, .asm_f900
- ld d, NPC_MOVEMENT_RIGHT
- jr .asm_f902
-.asm_f900
- ld d, NPC_MOVEMENT_LEFT
-.asm_f902
- ld a, [$ff9a]
- add $1
- ld [$ff9a], a
- jr .asm_f91c
-.asm_f90a
- ld a, [$ff9d]
- bit 0, a
- jr nz, .asm_f914
- ld d, NPC_MOVEMENT_DOWN
- jr .asm_f916
-.asm_f914
- ld d, NPC_MOVEMENT_UP
-.asm_f916
- ld a, [$ff99]
- add $1
- ld [$ff99], a
-.asm_f91c
- ld a, d
- ld [hli], a
- ld a, [$ff97]
- inc a
- ld [$ff97], a
- jp .loop
-.done
- ld [hl], $ff
- ret
-
-CalcPositionOfPlayerRelativeToNPC: ; f929 (3:7929)
- xor a
- ld [$ff9d], a
- ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels
- ld d, a
- ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels
- ld e, a
- ld hl, wSpriteStateData1
- ld a, [$ff95] ; sprite offset
- add l
- add $4
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, d
- ld b, a
- ld a, [hli] ; NPC sprite screen Y position in pixels
- call CalcDifference
- jr nc, .NPCSouthOfOrAlignedWithPlayer
-.NPCNorthOfPlayer
- push hl
- ld hl, $ff9d
- bit 0, [hl]
- set 0, [hl]
- pop hl
- jr .divideYDistance
-.NPCSouthOfOrAlignedWithPlayer
- push hl
- ld hl, $ff9d
- bit 0, [hl]
- res 0, [hl]
- pop hl
-.divideYDistance
- push hl
- ld hl, $ffe5
- ld [hli], a
- ld a, 16
- ld [hli], a
- call DivideBytes ; divide Y absolute distance by 16
- ld a, [hl] ; quotient
- ld [$ff95], a
- pop hl
- inc hl
- ld b, e
- ld a, [hl] ; NPC sprite screen X position in pixels
- call CalcDifference
- jr nc, .NPCEastOfOrAlignedWithPlayer
-.NPCWestOfPlayer
- push hl
- ld hl, $ff9d
- bit 1, [hl]
- set 1, [hl]
- pop hl
- jr .divideXDistance
-.NPCEastOfOrAlignedWithPlayer
- push hl
- ld hl, $ff9d
- bit 1, [hl]
- res 1, [hl]
- pop hl
-.divideXDistance
- ld [$ffe5], a
- ld a, 16
- ld [$ffe6], a
- call DivideBytes ; divide X absolute distance by 16
- ld a, [$ffe7] ; quotient
- ld [$ff96], a
- ld a, [$ff9b]
- and a
- ret z
- ld a, [$ff9d]
- cpl
- and $3
- ld [$ff9d], a
- ret
-
-ConvertNPCMovementDirectionsToJoypadMasks: ; f9a0 (3:79a0)
- ld a, [$ff95]
- ld [wNPCMovementDirections2Index], a
- dec a
- ld de, wSimulatedJoypadStatesEnd
- ld hl, wNPCMovementDirections2
- add l
- ld l, a
- jr nc, .loop
- inc h
-.loop
- ld a, [hld]
- call ConvertNPCMovementDirectionToJoypadMask
- ld [de], a
- inc de
- ld a, [$ff95]
- dec a
- ld [$ff95], a
- jr nz, .loop
- ret
-
-ConvertNPCMovementDirectionToJoypadMask: ; f9bf (3:79bf)
- push hl
- ld b, a
- ld hl, NPCMovementDirectionsToJoypadMasksTable
-.loop
- ld a, [hli]
- cp $ff
- jr z, .done
- cp b
- jr z, .loadJoypadMask
- inc hl
- jr .loop
-.loadJoypadMask
- ld a, [hl]
-.done
- pop hl
- ret
-
-NPCMovementDirectionsToJoypadMasksTable: ; f9d2 (3:79d2)
- db NPC_MOVEMENT_UP, D_UP
- db NPC_MOVEMENT_DOWN, D_DOWN
- db NPC_MOVEMENT_LEFT, D_LEFT
- db NPC_MOVEMENT_RIGHT, D_RIGHT
- db $ff
-
-Func_f9db: ; f9db (3:79db)
- ret
-
-INCLUDE "engine/hp_bar.asm"
-
-INCLUDE "engine/hidden_object_functions3.asm"
-
-
-SECTION "NPC Sprites 1", ROMX, BANK[NPC_SPRITES_1]
-
-OakAideSprite: INCBIN "gfx/sprites/oak_aide.2bpp"
-RockerSprite: INCBIN "gfx/sprites/rocker.2bpp"
-SwimmerSprite: INCBIN "gfx/sprites/swimmer.2bpp"
-WhitePlayerSprite: INCBIN "gfx/sprites/white_player.2bpp"
-GymHelperSprite: INCBIN "gfx/sprites/gym_helper.2bpp"
-OldPersonSprite: INCBIN "gfx/sprites/old_person.2bpp"
-MartGuySprite: INCBIN "gfx/sprites/mart_guy.2bpp"
-FisherSprite: INCBIN "gfx/sprites/fisher.2bpp"
-OldMediumWomanSprite: INCBIN "gfx/sprites/old_medium_woman.2bpp"
-NurseSprite: INCBIN "gfx/sprites/nurse.2bpp"
-CableClubWomanSprite: INCBIN "gfx/sprites/cable_club_woman.2bpp"
-MrMasterballSprite: INCBIN "gfx/sprites/mr_masterball.2bpp"
-LaprasGiverSprite: INCBIN "gfx/sprites/lapras_giver.2bpp"
-WardenSprite: INCBIN "gfx/sprites/warden.2bpp"
-SsCaptainSprite: INCBIN "gfx/sprites/ss_captain.2bpp"
-Fisher2Sprite: INCBIN "gfx/sprites/fisher2.2bpp"
-BlackbeltSprite: INCBIN "gfx/sprites/blackbelt.2bpp"
-GuardSprite: INCBIN "gfx/sprites/guard.2bpp"
-BallSprite: INCBIN "gfx/sprites/ball.2bpp"
-OmanyteSprite: INCBIN "gfx/sprites/omanyte.2bpp"
-BoulderSprite: INCBIN "gfx/sprites/boulder.2bpp"
-PaperSheetSprite: INCBIN "gfx/sprites/paper_sheet.2bpp"
-BookMapDexSprite: INCBIN "gfx/sprites/book_map_dex.2bpp"
-ClipboardSprite: INCBIN "gfx/sprites/clipboard.2bpp"
-SnorlaxSprite: INCBIN "gfx/sprites/snorlax.2bpp"
-OldAmberSprite: INCBIN "gfx/sprites/old_amber.2bpp"
-LyingOldManSprite: INCBIN "gfx/sprites/lying_old_man.2bpp"
-
-
-SECTION "Graphics", ROMX, BANK[GFX]
-
-PokemonLogoGraphics: INCBIN "gfx/pokemon_logo.2bpp"
-FontGraphics: INCBIN "gfx/font.1bpp"
-ABTiles: INCBIN "gfx/AB.2bpp"
-HpBarAndStatusGraphics: INCBIN "gfx/hp_bar_and_status.2bpp"
-BattleHudTiles1: INCBIN "gfx/battle_hud1.1bpp"
-BattleHudTiles2: INCBIN "gfx/battle_hud2.1bpp"
-BattleHudTiles3: INCBIN "gfx/battle_hud3.1bpp"
-NintendoCopyrightLogoGraphics: INCBIN "gfx/copyright.2bpp"
-GamefreakLogoGraphics: INCBIN "gfx/gamefreak.2bpp"
-TextBoxGraphics: INCBIN "gfx/text_box.2bpp"
-PokedexTileGraphics: INCBIN "gfx/pokedex.2bpp"
-WorldMapTileGraphics: INCBIN "gfx/town_map.2bpp"
-PlayerCharacterTitleGraphics: INCBIN "gfx/player_title.2bpp"
-
-
-SECTION "Battle (bank 4)", ROMX, BANK[$4]
-
-INCLUDE "engine/overworld/is_player_just_outside_map.asm"
-INCLUDE "engine/menu/status_screen.asm"
-INCLUDE "engine/menu/party_menu.asm"
-
-RedPicFront:: INCBIN "pic/trainer/red.pic"
-ShrinkPic1:: INCBIN "pic/trainer/shrink1.pic"
-ShrinkPic2:: INCBIN "pic/trainer/shrink2.pic"
-
-INCLUDE "engine/turn_sprite.asm"
-INCLUDE "engine/menu/start_sub_menus.asm"
-INCLUDE "engine/items/tms.asm"
-INCLUDE "engine/battle/end_of_battle.asm"
-INCLUDE "engine/battle/wild_encounters.asm"
-INCLUDE "engine/battle/moveEffects/recoil_effect.asm"
-INCLUDE "engine/battle/moveEffects/conversion_effect.asm"
-INCLUDE "engine/battle/moveEffects/haze_effect.asm"
-INCLUDE "engine/battle/get_trainer_name.asm"
-
-
-SECTION "NPC Sprites 2", ROMX, BANK[NPC_SPRITES_2]
-
-RedCyclingSprite: INCBIN "gfx/sprites/cycling.2bpp"
-RedSprite: INCBIN "gfx/sprites/red.2bpp"
-BlueSprite: INCBIN "gfx/sprites/blue.2bpp"
-OakSprite: INCBIN "gfx/sprites/oak.2bpp"
-BugCatcherSprite: INCBIN "gfx/sprites/bug_catcher.2bpp"
-SlowbroSprite: INCBIN "gfx/sprites/slowbro.2bpp"
-LassSprite: INCBIN "gfx/sprites/lass.2bpp"
-BlackHairBoy1Sprite: INCBIN "gfx/sprites/black_hair_boy_1.2bpp"
-LittleGirlSprite: INCBIN "gfx/sprites/little_girl.2bpp"
-BirdSprite: INCBIN "gfx/sprites/bird.2bpp"
-FatBaldGuySprite: INCBIN "gfx/sprites/fat_bald_guy.2bpp"
-GamblerSprite: INCBIN "gfx/sprites/gambler.2bpp"
-BlackHairBoy2Sprite: INCBIN "gfx/sprites/black_hair_boy_2.2bpp"
-GirlSprite: INCBIN "gfx/sprites/girl.2bpp"
-HikerSprite: INCBIN "gfx/sprites/hiker.2bpp"
-FoulardWomanSprite: INCBIN "gfx/sprites/foulard_woman.2bpp"
-GentlemanSprite: INCBIN "gfx/sprites/gentleman.2bpp"
-DaisySprite: INCBIN "gfx/sprites/daisy.2bpp"
-BikerSprite: INCBIN "gfx/sprites/biker.2bpp"
-SailorSprite: INCBIN "gfx/sprites/sailor.2bpp"
-CookSprite: INCBIN "gfx/sprites/cook.2bpp"
-BikeShopGuySprite: INCBIN "gfx/sprites/bike_shop_guy.2bpp"
-MrFujiSprite: INCBIN "gfx/sprites/mr_fuji.2bpp"
-GiovanniSprite: INCBIN "gfx/sprites/giovanni.2bpp"
-RocketSprite: INCBIN "gfx/sprites/rocket.2bpp"
-MediumSprite: INCBIN "gfx/sprites/medium.2bpp"
-WaiterSprite: INCBIN "gfx/sprites/waiter.2bpp"
-ErikaSprite: INCBIN "gfx/sprites/erika.2bpp"
-MomGeishaSprite: INCBIN "gfx/sprites/mom_geisha.2bpp"
-BrunetteGirlSprite: INCBIN "gfx/sprites/brunette_girl.2bpp"
-LanceSprite: INCBIN "gfx/sprites/lance.2bpp"
-MomSprite: INCBIN "gfx/sprites/mom.2bpp"
-BaldingGuySprite: INCBIN "gfx/sprites/balding_guy.2bpp"
-YoungBoySprite: INCBIN "gfx/sprites/young_boy.2bpp"
-GameboyKidSprite: INCBIN "gfx/sprites/gameboy_kid.2bpp"
-ClefairySprite: INCBIN "gfx/sprites/clefairy.2bpp"
-AgathaSprite: INCBIN "gfx/sprites/agatha.2bpp"
-BrunoSprite: INCBIN "gfx/sprites/bruno.2bpp"
-LoreleiSprite: INCBIN "gfx/sprites/lorelei.2bpp"
-SeelSprite: INCBIN "gfx/sprites/seel.2bpp"
-
-
-SECTION "Battle (bank 5)", ROMX, BANK[$5]
-
-INCLUDE "engine/load_pokedex_tiles.asm"
-INCLUDE "engine/overworld/map_sprites.asm"
-INCLUDE "engine/overworld/emotion_bubbles.asm"
-INCLUDE "engine/evolve_trade.asm"
-INCLUDE "engine/battle/moveEffects/substitute_effect.asm"
-INCLUDE "engine/menu/pc.asm"
-
-
-SECTION "bank6",ROMX,BANK[$6]
-
-INCLUDE "data/mapHeaders/celadoncity.asm"
-INCLUDE "data/mapObjects/celadoncity.asm"
-CeladonCityBlocks: INCBIN "maps/celadoncity.blk"
-
-INCLUDE "data/mapHeaders/pallettown.asm"
-INCLUDE "data/mapObjects/pallettown.asm"
-PalletTownBlocks: INCBIN "maps/pallettown.blk"
-
-INCLUDE "data/mapHeaders/viridiancity.asm"
-INCLUDE "data/mapObjects/viridiancity.asm"
-ViridianCityBlocks: INCBIN "maps/viridiancity.blk"
-
-INCLUDE "data/mapHeaders/pewtercity.asm"
-INCLUDE "data/mapObjects/pewtercity.asm"
-PewterCityBlocks: INCBIN "maps/pewtercity.blk"
-
-INCLUDE "data/mapHeaders/ceruleancity.asm"
-INCLUDE "data/mapObjects/ceruleancity.asm"
-CeruleanCityBlocks: INCBIN "maps/ceruleancity.blk"
-
-INCLUDE "data/mapHeaders/vermilioncity.asm"
-INCLUDE "data/mapObjects/vermilioncity.asm"
-VermilionCityBlocks: INCBIN "maps/vermilioncity.blk"
-
-INCLUDE "data/mapHeaders/fuchsiacity.asm"
-INCLUDE "data/mapObjects/fuchsiacity.asm"
-FuchsiaCityBlocks: INCBIN "maps/fuchsiacity.blk"
-
-INCLUDE "engine/play_time.asm"
-
-INCLUDE "scripts/pallettown.asm"
-INCLUDE "scripts/viridiancity.asm"
-INCLUDE "scripts/pewtercity.asm"
-INCLUDE "scripts/ceruleancity.asm"
-INCLUDE "scripts/vermilioncity.asm"
-INCLUDE "scripts/celadoncity.asm"
-INCLUDE "scripts/fuchsiacity.asm"
-
-INCLUDE "data/mapHeaders/blueshouse.asm"
-INCLUDE "scripts/blueshouse.asm"
-INCLUDE "data/mapObjects/blueshouse.asm"
-BluesHouseBlocks: INCBIN "maps/blueshouse.blk"
-
-INCLUDE "data/mapHeaders/vermilionhouse3.asm"
-INCLUDE "scripts/vermilionhouse3.asm"
-INCLUDE "data/mapObjects/vermilionhouse3.asm"
-VermilionHouse3Blocks: INCBIN "maps/vermilionhouse3.blk"
-
-INCLUDE "data/mapHeaders/indigoplateaulobby.asm"
-INCLUDE "scripts/indigoplateaulobby.asm"
-INCLUDE "data/mapObjects/indigoplateaulobby.asm"
-IndigoPlateauLobbyBlocks: INCBIN "maps/indigoplateaulobby.blk"
-
-INCLUDE "data/mapHeaders/silphco4.asm"
-INCLUDE "scripts/silphco4.asm"
-INCLUDE "data/mapObjects/silphco4.asm"
-SilphCo4Blocks: INCBIN "maps/silphco4.blk"
-
-INCLUDE "data/mapHeaders/silphco5.asm"
-INCLUDE "scripts/silphco5.asm"
-INCLUDE "data/mapObjects/silphco5.asm"
-SilphCo5Blocks: INCBIN "maps/silphco5.blk"
-
-INCLUDE "data/mapHeaders/silphco6.asm"
-INCLUDE "scripts/silphco6.asm"
-INCLUDE "data/mapObjects/silphco6.asm"
-SilphCo6Blocks: INCBIN "maps/silphco6.blk"
-
-INCLUDE "engine/overworld/npc_movement.asm"
-INCLUDE "engine/overworld/doors.asm"
-INCLUDE "engine/overworld/ledges.asm"
-
-
-SECTION "bank7",ROMX,BANK[$7]
-
-INCLUDE "data/mapHeaders/cinnabarisland.asm"
-INCLUDE "data/mapObjects/cinnabarisland.asm"
-CinnabarIslandBlocks: INCBIN "maps/cinnabarisland.blk"
-
-INCLUDE "data/mapHeaders/route1.asm"
-INCLUDE "data/mapObjects/route1.asm"
-Route1Blocks: INCBIN "maps/route1.blk"
-
-UndergroundPathEntranceRoute8Blocks: INCBIN "maps/undergroundpathentranceroute8.blk"
-
-OaksLabBlocks: INCBIN "maps/oakslab.blk"
-
-Route16HouseBlocks:
-Route2HouseBlocks:
-SaffronHouse1Blocks:
-SaffronHouse2Blocks:
-VermilionHouse1Blocks:
-NameRaterBlocks:
-LavenderHouse1Blocks:
-LavenderHouse2Blocks:
-CeruleanHouse1Blocks:
-PewterHouse1Blocks:
-PewterHouse2Blocks:
-ViridianHouseBlocks: INCBIN "maps/viridianhouse.blk"
-
-CeladonMansion5Blocks:
-SchoolBlocks: INCBIN "maps/school.blk"
-
-CeruleanHouseTrashedBlocks: INCBIN "maps/ceruleanhousetrashed.blk"
-
-DiglettsCaveEntranceRoute11Blocks:
-DiglettsCaveRoute2Blocks: INCBIN "maps/diglettscaveroute2.blk"
-
-INCLUDE "text/monster_names.asm"
-
-INCLUDE "engine/clear_save.asm"
-
-INCLUDE "engine/predefs7.asm"
-
-INCLUDE "scripts/cinnabarisland.asm"
-
-INCLUDE "scripts/route1.asm"
-
-INCLUDE "data/mapHeaders/oakslab.asm"
-INCLUDE "scripts/oakslab.asm"
-INCLUDE "data/mapObjects/oakslab.asm"
-
-INCLUDE "data/mapHeaders/viridianmart.asm"
-INCLUDE "scripts/viridianmart.asm"
-INCLUDE "data/mapObjects/viridianmart.asm"
-ViridianMartBlocks: INCBIN "maps/viridianmart.blk"
-
-INCLUDE "data/mapHeaders/school.asm"
-INCLUDE "scripts/school.asm"
-INCLUDE "data/mapObjects/school.asm"
-
-INCLUDE "data/mapHeaders/viridianhouse.asm"
-INCLUDE "scripts/viridianhouse.asm"
-INCLUDE "data/mapObjects/viridianhouse.asm"
-
-INCLUDE "data/mapHeaders/pewterhouse1.asm"
-INCLUDE "scripts/pewterhouse1.asm"
-INCLUDE "data/mapObjects/pewterhouse1.asm"
-
-INCLUDE "data/mapHeaders/pewterhouse2.asm"
-INCLUDE "scripts/pewterhouse2.asm"
-INCLUDE "data/mapObjects/pewterhouse2.asm"
-
-INCLUDE "data/mapHeaders/ceruleanhousetrashed.asm"
-INCLUDE "scripts/ceruleanhousetrashed.asm"
-INCLUDE "data/mapObjects/ceruleanhousetrashed.asm"
-
-INCLUDE "data/mapHeaders/ceruleanhouse1.asm"
-INCLUDE "scripts/ceruleanhouse1.asm"
-INCLUDE "data/mapObjects/ceruleanhouse1.asm"
-
-INCLUDE "data/mapHeaders/bikeshop.asm"
-INCLUDE "scripts/bikeshop.asm"
-INCLUDE "data/mapObjects/bikeshop.asm"
-BikeShopBlocks: INCBIN "maps/bikeshop.blk"
-
-INCLUDE "data/mapHeaders/lavenderhouse1.asm"
-INCLUDE "scripts/lavenderhouse1.asm"
-INCLUDE "data/mapObjects/lavenderhouse1.asm"
-
-INCLUDE "data/mapHeaders/lavenderhouse2.asm"
-INCLUDE "scripts/lavenderhouse2.asm"
-INCLUDE "data/mapObjects/lavenderhouse2.asm"
-
-INCLUDE "data/mapHeaders/namerater.asm"
-INCLUDE "scripts/namerater.asm"
-INCLUDE "data/mapObjects/namerater.asm"
-
-INCLUDE "data/mapHeaders/vermilionhouse1.asm"
-INCLUDE "scripts/vermilionhouse1.asm"
-INCLUDE "data/mapObjects/vermilionhouse1.asm"
-
-INCLUDE "data/mapHeaders/vermiliondock.asm"
-INCLUDE "scripts/vermiliondock.asm"
-INCLUDE "data/mapObjects/vermiliondock.asm"
-VermilionDockBlocks: INCBIN "maps/vermiliondock.blk"
-
-INCLUDE "data/mapHeaders/celadonmansion5.asm"
-INCLUDE "scripts/celadonmansion5.asm"
-INCLUDE "data/mapObjects/celadonmansion5.asm"
-
-INCLUDE "data/mapHeaders/fuchsiamart.asm"
-INCLUDE "scripts/fuchsiamart.asm"
-INCLUDE "data/mapObjects/fuchsiamart.asm"
-FuchsiaMartBlocks: INCBIN "maps/fuchsiamart.blk"
-
-INCLUDE "data/mapHeaders/saffronhouse1.asm"
-INCLUDE "scripts/saffronhouse1.asm"
-INCLUDE "data/mapObjects/saffronhouse1.asm"
-
-INCLUDE "data/mapHeaders/saffronhouse2.asm"
-INCLUDE "scripts/saffronhouse2.asm"
-INCLUDE "data/mapObjects/saffronhouse2.asm"
-
-INCLUDE "data/mapHeaders/diglettscaveroute2.asm"
-INCLUDE "scripts/diglettscaveroute2.asm"
-INCLUDE "data/mapObjects/diglettscaveroute2.asm"
-
-INCLUDE "data/mapHeaders/route2house.asm"
-INCLUDE "scripts/route2house.asm"
-INCLUDE "data/mapObjects/route2house.asm"
-
-INCLUDE "data/mapHeaders/route5gate.asm"
-INCLUDE "scripts/route5gate.asm"
-INCLUDE "data/mapObjects/route5gate.asm"
-Route5GateBlocks: INCBIN "maps/route5gate.blk"
-
-INCLUDE "data/mapHeaders/route6gate.asm"
-INCLUDE "scripts/route6gate.asm"
-INCLUDE "data/mapObjects/route6gate.asm"
-Route6GateBlocks: INCBIN "maps/route6gate.blk"
-
-INCLUDE "data/mapHeaders/route7gate.asm"
-INCLUDE "scripts/route7gate.asm"
-INCLUDE "data/mapObjects/route7gate.asm"
-Route7GateBlocks: INCBIN "maps/route7gate.blk"
-
-INCLUDE "data/mapHeaders/route8gate.asm"
-INCLUDE "scripts/route8gate.asm"
-INCLUDE "data/mapObjects/route8gate.asm"
-Route8GateBlocks: INCBIN "maps/route8gate.blk"
-
-INCLUDE "data/mapHeaders/undergroundpathentranceroute8.asm"
-INCLUDE "scripts/undergroundpathentranceroute8.asm"
-INCLUDE "data/mapObjects/undergroundpathentranceroute8.asm"
-
-INCLUDE "data/mapHeaders/powerplant.asm"
-INCLUDE "scripts/powerplant.asm"
-INCLUDE "data/mapObjects/powerplant.asm"
-PowerPlantBlocks: INCBIN "maps/powerplant.blk"
-
-INCLUDE "data/mapHeaders/diglettscaveroute11.asm"
-INCLUDE "scripts/diglettscaveroute11.asm"
-INCLUDE "data/mapObjects/diglettscaveroute11.asm"
-
-INCLUDE "data/mapHeaders/route16house.asm"
-INCLUDE "scripts/route16house.asm"
-INCLUDE "data/mapObjects/route16house.asm"
-
-INCLUDE "data/mapHeaders/route22gate.asm"
-INCLUDE "scripts/route22gate.asm"
-INCLUDE "data/mapObjects/route22gate.asm"
-Route22GateBlocks: INCBIN "maps/route22gate.blk"
-
-INCLUDE "data/mapHeaders/billshouse.asm"
-INCLUDE "scripts/billshouse.asm"
-INCLUDE "data/mapObjects/billshouse.asm"
-BillsHouseBlocks: INCBIN "maps/billshouse.blk"
-IF DEF(_OPTION_BEACH_HOUSE)
-INCLUDE "data/mapHeaders/beach_house.asm"
-INCLUDE "scripts/beach_house.asm"
-BeachHouseBlockdata: INCBIN "maps/beach_house.blk"
-INCLUDE "data/mapObjects/beach_house.asm"
-ENDC
-
-INCLUDE "engine/menu/oaks_pc.asm"
-
-INCLUDE "engine/hidden_object_functions7.asm"
-
-
-SECTION "Pics 1", ROMX, BANK[PICS_1]
-
-RhydonPicFront:: INCBIN "pic/bmon/rhydon.pic"
-RhydonPicBack:: INCBIN "pic/monback/rhydonb.pic"
-KangaskhanPicFront:: INCBIN "pic/bmon/kangaskhan.pic"
-KangaskhanPicBack:: INCBIN "pic/monback/kangaskhanb.pic"
-NidoranMPicFront:: INCBIN "pic/bmon/nidoranm.pic"
-NidoranMPicBack:: INCBIN "pic/monback/nidoranmb.pic"
-ClefairyPicFront:: INCBIN "pic/bmon/clefairy.pic"
-ClefairyPicBack:: INCBIN "pic/monback/clefairyb.pic"
-SpearowPicFront:: INCBIN "pic/bmon/spearow.pic"
-SpearowPicBack:: INCBIN "pic/monback/spearowb.pic"
-VoltorbPicFront:: INCBIN "pic/bmon/voltorb.pic"
-VoltorbPicBack:: INCBIN "pic/monback/voltorbb.pic"
-NidokingPicFront:: INCBIN "pic/bmon/nidoking.pic"
-NidokingPicBack:: INCBIN "pic/monback/nidokingb.pic"
-SlowbroPicFront:: INCBIN "pic/bmon/slowbro.pic"
-SlowbroPicBack:: INCBIN "pic/monback/slowbrob.pic"
-IvysaurPicFront:: INCBIN "pic/bmon/ivysaur.pic"
-IvysaurPicBack:: INCBIN "pic/monback/ivysaurb.pic"
-ExeggutorPicFront:: INCBIN "pic/bmon/exeggutor.pic"
-ExeggutorPicBack:: INCBIN "pic/monback/exeggutorb.pic"
-LickitungPicFront:: INCBIN "pic/bmon/lickitung.pic"
-LickitungPicBack:: INCBIN "pic/monback/lickitungb.pic"
-ExeggcutePicFront:: INCBIN "pic/bmon/exeggcute.pic"
-ExeggcutePicBack:: INCBIN "pic/monback/exeggcuteb.pic"
-GrimerPicFront:: INCBIN "pic/bmon/grimer.pic"
-GrimerPicBack:: INCBIN "pic/monback/grimerb.pic"
-GengarPicFront:: INCBIN "pic/bmon/gengar.pic"
-GengarPicBack:: INCBIN "pic/monback/gengarb.pic"
-NidoranFPicFront:: INCBIN "pic/bmon/nidoranf.pic"
-NidoranFPicBack:: INCBIN "pic/monback/nidoranfb.pic"
-NidoqueenPicFront:: INCBIN "pic/bmon/nidoqueen.pic"
-NidoqueenPicBack:: INCBIN "pic/monback/nidoqueenb.pic"
-CubonePicFront:: INCBIN "pic/bmon/cubone.pic"
-CubonePicBack:: INCBIN "pic/monback/cuboneb.pic"
-RhyhornPicFront:: INCBIN "pic/bmon/rhyhorn.pic"
-RhyhornPicBack:: INCBIN "pic/monback/rhyhornb.pic"
-LaprasPicFront:: INCBIN "pic/bmon/lapras.pic"
-LaprasPicBack:: INCBIN "pic/monback/laprasb.pic"
-ArcaninePicFront:: INCBIN "pic/bmon/arcanine.pic"
-ArcaninePicBack:: INCBIN "pic/monback/arcanineb.pic"
-GyaradosPicFront:: INCBIN "pic/bmon/gyarados.pic"
-GyaradosPicBack:: INCBIN "pic/monback/gyaradosb.pic"
-ShellderPicFront:: INCBIN "pic/bmon/shellder.pic"
-ShellderPicBack:: INCBIN "pic/monback/shellderb.pic"
-TentacoolPicFront:: INCBIN "pic/bmon/tentacool.pic"
-TentacoolPicBack:: INCBIN "pic/monback/tentacoolb.pic"
-GastlyPicFront:: INCBIN "pic/bmon/gastly.pic"
-GastlyPicBack:: INCBIN "pic/monback/gastlyb.pic"
-ScytherPicFront:: INCBIN "pic/bmon/scyther.pic"
-ScytherPicBack:: INCBIN "pic/monback/scytherb.pic"
-StaryuPicFront:: INCBIN "pic/bmon/staryu.pic"
-StaryuPicBack:: INCBIN "pic/monback/staryub.pic"
-BlastoisePicFront:: INCBIN "pic/bmon/blastoise.pic"
-BlastoisePicBack:: INCBIN "pic/monback/blastoiseb.pic"
-PinsirPicFront:: INCBIN "pic/bmon/pinsir.pic"
-PinsirPicBack:: INCBIN "pic/monback/pinsirb.pic"
-TangelaPicFront:: INCBIN "pic/bmon/tangela.pic"
-TangelaPicBack:: INCBIN "pic/monback/tangelab.pic"
-
-
-SECTION "Battle (bank 9)", ROMX, BANK[$9]
-INCLUDE "engine/battle/print_type.asm"
-INCLUDE "engine/battle/save_trainer_name.asm"
-INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm"
-
-
-SECTION "Pics 2", ROMX, BANK[PICS_2]
-
-GrowlithePicFront:: INCBIN "pic/bmon/growlithe.pic"
-GrowlithePicBack:: INCBIN "pic/monback/growlitheb.pic"
-OnixPicFront:: INCBIN "pic/bmon/onix.pic"
-OnixPicBack:: INCBIN "pic/monback/onixb.pic"
-FearowPicFront:: INCBIN "pic/bmon/fearow.pic"
-FearowPicBack:: INCBIN "pic/monback/fearowb.pic"
-PidgeyPicFront:: INCBIN "pic/bmon/pidgey.pic"
-PidgeyPicBack:: INCBIN "pic/monback/pidgeyb.pic"
-SlowpokePicFront:: INCBIN "pic/bmon/slowpoke.pic"
-SlowpokePicBack:: INCBIN "pic/monback/slowpokeb.pic"
-KadabraPicFront:: INCBIN "pic/bmon/kadabra.pic"
-KadabraPicBack:: INCBIN "pic/monback/kadabrab.pic"
-GravelerPicFront:: INCBIN "pic/bmon/graveler.pic"
-GravelerPicBack:: INCBIN "pic/monback/gravelerb.pic"
-ChanseyPicFront:: INCBIN "pic/bmon/chansey.pic"
-ChanseyPicBack:: INCBIN "pic/monback/chanseyb.pic"
-MachokePicFront:: INCBIN "pic/bmon/machoke.pic"
-MachokePicBack:: INCBIN "pic/monback/machokeb.pic"
-MrMimePicFront:: INCBIN "pic/bmon/mr.mime.pic"
-MrMimePicBack:: INCBIN "pic/monback/mr.mimeb.pic"
-HitmonleePicFront:: INCBIN "pic/bmon/hitmonlee.pic"
-HitmonleePicBack:: INCBIN "pic/monback/hitmonleeb.pic"
-HitmonchanPicFront:: INCBIN "pic/bmon/hitmonchan.pic"
-HitmonchanPicBack:: INCBIN "pic/monback/hitmonchanb.pic"
-ArbokPicFront:: INCBIN "pic/bmon/arbok.pic"
-ArbokPicBack:: INCBIN "pic/monback/arbokb.pic"
-ParasectPicFront:: INCBIN "pic/bmon/parasect.pic"
-ParasectPicBack:: INCBIN "pic/monback/parasectb.pic"
-PsyduckPicFront:: INCBIN "pic/bmon/psyduck.pic"
-PsyduckPicBack:: INCBIN "pic/monback/psyduckb.pic"
-DrowzeePicFront:: INCBIN "pic/bmon/drowzee.pic"
-DrowzeePicBack:: INCBIN "pic/monback/drowzeeb.pic"
-GolemPicFront:: INCBIN "pic/bmon/golem.pic"
-GolemPicBack:: INCBIN "pic/monback/golemb.pic"
-MagmarPicFront:: INCBIN "pic/bmon/magmar.pic"
-MagmarPicBack:: INCBIN "pic/monback/magmarb.pic"
-ElectabuzzPicFront:: INCBIN "pic/bmon/electabuzz.pic"
-ElectabuzzPicBack:: INCBIN "pic/monback/electabuzzb.pic"
-MagnetonPicFront:: INCBIN "pic/bmon/magneton.pic"
-MagnetonPicBack:: INCBIN "pic/monback/magnetonb.pic"
-KoffingPicFront:: INCBIN "pic/bmon/koffing.pic"
-KoffingPicBack:: INCBIN "pic/monback/koffingb.pic"
-MankeyPicFront:: INCBIN "pic/bmon/mankey.pic"
-MankeyPicBack:: INCBIN "pic/monback/mankeyb.pic"
-SeelPicFront:: INCBIN "pic/bmon/seel.pic"
-SeelPicBack:: INCBIN "pic/monback/seelb.pic"
-DiglettPicFront:: INCBIN "pic/bmon/diglett.pic"
-DiglettPicBack:: INCBIN "pic/monback/diglettb.pic"
-TaurosPicFront:: INCBIN "pic/bmon/tauros.pic"
-TaurosPicBack:: INCBIN "pic/monback/taurosb.pic"
-FarfetchdPicFront:: INCBIN "pic/bmon/farfetchd.pic"
-FarfetchdPicBack:: INCBIN "pic/monback/farfetchdb.pic"
-VenonatPicFront:: INCBIN "pic/bmon/venonat.pic"
-VenonatPicBack:: INCBIN "pic/monback/venonatb.pic"
-DragonitePicFront:: INCBIN "pic/bmon/dragonite.pic"
-DragonitePicBack:: INCBIN "pic/monback/dragoniteb.pic"
-DoduoPicFront:: INCBIN "pic/bmon/doduo.pic"
-DoduoPicBack:: INCBIN "pic/monback/doduob.pic"
-PoliwagPicFront:: INCBIN "pic/bmon/poliwag.pic"
-PoliwagPicBack:: INCBIN "pic/monback/poliwagb.pic"
-JynxPicFront:: INCBIN "pic/bmon/jynx.pic"
-JynxPicBack:: INCBIN "pic/monback/jynxb.pic"
-MoltresPicFront:: INCBIN "pic/bmon/moltres.pic"
-MoltresPicBack:: INCBIN "pic/monback/moltresb.pic"
-
-
-SECTION "Battle (bank A)", ROMX, BANK[$A]
-INCLUDE "engine/battle/moveEffects/leech_seed_effect.asm"
-
-
-SECTION "Pics 3", ROMX, BANK[PICS_3]
-
-ArticunoPicFront:: INCBIN "pic/bmon/articuno.pic"
-ArticunoPicBack:: INCBIN "pic/monback/articunob.pic"
-ZapdosPicFront:: INCBIN "pic/bmon/zapdos.pic"
-ZapdosPicBack:: INCBIN "pic/monback/zapdosb.pic"
-DittoPicFront:: INCBIN "pic/bmon/ditto.pic"
-DittoPicBack:: INCBIN "pic/monback/dittob.pic"
-MeowthPicFront:: INCBIN "pic/bmon/meowth.pic"
-MeowthPicBack:: INCBIN "pic/monback/meowthb.pic"
-KrabbyPicFront:: INCBIN "pic/bmon/krabby.pic"
-KrabbyPicBack:: INCBIN "pic/monback/krabbyb.pic"
-VulpixPicFront:: INCBIN "pic/bmon/vulpix.pic"
-VulpixPicBack:: INCBIN "pic/monback/vulpixb.pic"
-NinetalesPicFront:: INCBIN "pic/bmon/ninetales.pic"
-NinetalesPicBack:: INCBIN "pic/monback/ninetalesb.pic"
-PikachuPicFront:: INCBIN "pic/bmon/pikachu.pic"
-PikachuPicBack:: INCBIN "pic/monback/pikachub.pic"
-RaichuPicFront:: INCBIN "pic/bmon/raichu.pic"
-RaichuPicBack:: INCBIN "pic/monback/raichub.pic"
-DratiniPicFront:: INCBIN "pic/bmon/dratini.pic"
-DratiniPicBack:: INCBIN "pic/monback/dratinib.pic"
-DragonairPicFront:: INCBIN "pic/bmon/dragonair.pic"
-DragonairPicBack:: INCBIN "pic/monback/dragonairb.pic"
-KabutoPicFront:: INCBIN "pic/bmon/kabuto.pic"
-KabutoPicBack:: INCBIN "pic/monback/kabutob.pic"
-KabutopsPicFront:: INCBIN "pic/bmon/kabutops.pic"
-KabutopsPicBack:: INCBIN "pic/monback/kabutopsb.pic"
-HorseaPicFront:: INCBIN "pic/bmon/horsea.pic"
-HorseaPicBack:: INCBIN "pic/monback/horseab.pic"
-SeadraPicFront:: INCBIN "pic/bmon/seadra.pic"
-SeadraPicBack:: INCBIN "pic/monback/seadrab.pic"
-SandshrewPicFront:: INCBIN "pic/bmon/sandshrew.pic"
-SandshrewPicBack:: INCBIN "pic/monback/sandshrewb.pic"
-SandslashPicFront:: INCBIN "pic/bmon/sandslash.pic"
-SandslashPicBack:: INCBIN "pic/monback/sandslashb.pic"
-OmanytePicFront:: INCBIN "pic/bmon/omanyte.pic"
-OmanytePicBack:: INCBIN "pic/monback/omanyteb.pic"
-OmastarPicFront:: INCBIN "pic/bmon/omastar.pic"
-OmastarPicBack:: INCBIN "pic/monback/omastarb.pic"
-JigglypuffPicFront:: INCBIN "pic/bmon/jigglypuff.pic"
-JigglypuffPicBack:: INCBIN "pic/monback/jigglypuffb.pic"
-WigglytuffPicFront:: INCBIN "pic/bmon/wigglytuff.pic"
-WigglytuffPicBack:: INCBIN "pic/monback/wigglytuffb.pic"
-EeveePicFront:: INCBIN "pic/bmon/eevee.pic"
-EeveePicBack:: INCBIN "pic/monback/eeveeb.pic"
-FlareonPicFront:: INCBIN "pic/bmon/flareon.pic"
-FlareonPicBack:: INCBIN "pic/monback/flareonb.pic"
-JolteonPicFront:: INCBIN "pic/bmon/jolteon.pic"
-JolteonPicBack:: INCBIN "pic/monback/jolteonb.pic"
-VaporeonPicFront:: INCBIN "pic/bmon/vaporeon.pic"
-VaporeonPicBack:: INCBIN "pic/monback/vaporeonb.pic"
-MachopPicFront:: INCBIN "pic/bmon/machop.pic"
-MachopPicBack:: INCBIN "pic/monback/machopb.pic"
-ZubatPicFront:: INCBIN "pic/bmon/zubat.pic"
-ZubatPicBack:: INCBIN "pic/monback/zubatb.pic"
-EkansPicFront:: INCBIN "pic/bmon/ekans.pic"
-EkansPicBack:: INCBIN "pic/monback/ekansb.pic"
-ParasPicFront:: INCBIN "pic/bmon/paras.pic"
-ParasPicBack:: INCBIN "pic/monback/parasb.pic"
-PoliwhirlPicFront:: INCBIN "pic/bmon/poliwhirl.pic"
-PoliwhirlPicBack:: INCBIN "pic/monback/poliwhirlb.pic"
-PoliwrathPicFront:: INCBIN "pic/bmon/poliwrath.pic"
-PoliwrathPicBack:: INCBIN "pic/monback/poliwrathb.pic"
-WeedlePicFront:: INCBIN "pic/bmon/weedle.pic"
-WeedlePicBack:: INCBIN "pic/monback/weedleb.pic"
-KakunaPicFront:: INCBIN "pic/bmon/kakuna.pic"
-KakunaPicBack:: INCBIN "pic/monback/kakunab.pic"
-BeedrillPicFront:: INCBIN "pic/bmon/beedrill.pic"
-BeedrillPicBack:: INCBIN "pic/monback/beedrillb.pic"
-
-FossilKabutopsPic:: INCBIN "pic/bmon/fossilkabutops.pic"
-
-
-SECTION "Battle (bank B)", ROMX, BANK[$B]
-
-INCLUDE "engine/battle/display_effectiveness.asm"
-
-TrainerInfoTextBoxTileGraphics: INCBIN "gfx/trainer_info.2bpp"
-BlankLeaderNames: INCBIN "gfx/blank_leader_names.2bpp"
-CircleTile: INCBIN "gfx/circle_tile.2bpp"
-BadgeNumbersTileGraphics: INCBIN "gfx/badge_numbers.2bpp"
-
-INCLUDE "engine/items/tmhm.asm"
-INCLUDE "engine/battle/scale_sprites.asm"
-INCLUDE "engine/battle/moveEffects/pay_day_effect.asm"
-INCLUDE "engine/game_corner_slots2.asm"
-
-
-SECTION "Pics 4", ROMX, BANK[PICS_4]
-
-DodrioPicFront:: INCBIN "pic/bmon/dodrio.pic"
-DodrioPicBack:: INCBIN "pic/monback/dodriob.pic"
-PrimeapePicFront:: INCBIN "pic/bmon/primeape.pic"
-PrimeapePicBack:: INCBIN "pic/monback/primeapeb.pic"
-DugtrioPicFront:: INCBIN "pic/bmon/dugtrio.pic"
-DugtrioPicBack:: INCBIN "pic/monback/dugtriob.pic"
-VenomothPicFront:: INCBIN "pic/bmon/venomoth.pic"
-VenomothPicBack:: INCBIN "pic/monback/venomothb.pic"
-DewgongPicFront:: INCBIN "pic/bmon/dewgong.pic"
-DewgongPicBack:: INCBIN "pic/monback/dewgongb.pic"
-CaterpiePicFront:: INCBIN "pic/bmon/caterpie.pic"
-CaterpiePicBack:: INCBIN "pic/monback/caterpieb.pic"
-MetapodPicFront:: INCBIN "pic/bmon/metapod.pic"
-MetapodPicBack:: INCBIN "pic/monback/metapodb.pic"
-ButterfreePicFront:: INCBIN "pic/bmon/butterfree.pic"
-ButterfreePicBack:: INCBIN "pic/monback/butterfreeb.pic"
-MachampPicFront:: INCBIN "pic/bmon/machamp.pic"
-MachampPicBack:: INCBIN "pic/monback/machampb.pic"
-GolduckPicFront:: INCBIN "pic/bmon/golduck.pic"
-GolduckPicBack:: INCBIN "pic/monback/golduckb.pic"
-HypnoPicFront:: INCBIN "pic/bmon/hypno.pic"
-HypnoPicBack:: INCBIN "pic/monback/hypnob.pic"
-GolbatPicFront:: INCBIN "pic/bmon/golbat.pic"
-GolbatPicBack:: INCBIN "pic/monback/golbatb.pic"
-MewtwoPicFront:: INCBIN "pic/bmon/mewtwo.pic"
-MewtwoPicBack:: INCBIN "pic/monback/mewtwob.pic"
-SnorlaxPicFront:: INCBIN "pic/bmon/snorlax.pic"
-SnorlaxPicBack:: INCBIN "pic/monback/snorlaxb.pic"
-MagikarpPicFront:: INCBIN "pic/bmon/magikarp.pic"
-MagikarpPicBack:: INCBIN "pic/monback/magikarpb.pic"
-MukPicFront:: INCBIN "pic/bmon/muk.pic"
-MukPicBack:: INCBIN "pic/monback/mukb.pic"
-KinglerPicFront:: INCBIN "pic/bmon/kingler.pic"
-KinglerPicBack:: INCBIN "pic/monback/kinglerb.pic"
-CloysterPicFront:: INCBIN "pic/bmon/cloyster.pic"
-CloysterPicBack:: INCBIN "pic/monback/cloysterb.pic"
-ElectrodePicFront:: INCBIN "pic/bmon/electrode.pic"
-ElectrodePicBack:: INCBIN "pic/monback/electrodeb.pic"
-ClefablePicFront:: INCBIN "pic/bmon/clefable.pic"
-ClefablePicBack:: INCBIN "pic/monback/clefableb.pic"
-WeezingPicFront:: INCBIN "pic/bmon/weezing.pic"
-WeezingPicBack:: INCBIN "pic/monback/weezingb.pic"
-PersianPicFront:: INCBIN "pic/bmon/persian.pic"
-PersianPicBack:: INCBIN "pic/monback/persianb.pic"
-MarowakPicFront:: INCBIN "pic/bmon/marowak.pic"
-MarowakPicBack:: INCBIN "pic/monback/marowakb.pic"
-HaunterPicFront:: INCBIN "pic/bmon/haunter.pic"
-HaunterPicBack:: INCBIN "pic/monback/haunterb.pic"
-AbraPicFront:: INCBIN "pic/bmon/abra.pic"
-AbraPicBack:: INCBIN "pic/monback/abrab.pic"
-AlakazamPicFront:: INCBIN "pic/bmon/alakazam.pic"
-AlakazamPicBack:: INCBIN "pic/monback/alakazamb.pic"
-PidgeottoPicFront:: INCBIN "pic/bmon/pidgeotto.pic"
-PidgeottoPicBack:: INCBIN "pic/monback/pidgeottob.pic"
-PidgeotPicFront:: INCBIN "pic/bmon/pidgeot.pic"
-PidgeotPicBack:: INCBIN "pic/monback/pidgeotb.pic"
-StarmiePicFront:: INCBIN "pic/bmon/starmie.pic"
-StarmiePicBack:: INCBIN "pic/monback/starmieb.pic"
-
-RedPicBack:: INCBIN "pic/trainer/redb.pic"
-OldManPic:: INCBIN "pic/trainer/oldman.pic"
-
-
-SECTION "Battle (bank C)", ROMX, BANK[$C]
-INCLUDE "engine/battle/moveEffects/mist_effect.asm"
-INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm"
-
-
-SECTION "Pics 5", ROMX, BANK[PICS_5]
-
-BulbasaurPicFront:: INCBIN "pic/bmon/bulbasaur.pic"
-BulbasaurPicBack:: INCBIN "pic/monback/bulbasaurb.pic"
-VenusaurPicFront:: INCBIN "pic/bmon/venusaur.pic"
-VenusaurPicBack:: INCBIN "pic/monback/venusaurb.pic"
-TentacruelPicFront:: INCBIN "pic/bmon/tentacruel.pic"
-TentacruelPicBack:: INCBIN "pic/monback/tentacruelb.pic"
-GoldeenPicFront:: INCBIN "pic/bmon/goldeen.pic"
-GoldeenPicBack:: INCBIN "pic/monback/goldeenb.pic"
-SeakingPicFront:: INCBIN "pic/bmon/seaking.pic"
-SeakingPicBack:: INCBIN "pic/monback/seakingb.pic"
-PonytaPicFront:: INCBIN "pic/bmon/ponyta.pic"
-RapidashPicFront:: INCBIN "pic/bmon/rapidash.pic"
-PonytaPicBack:: INCBIN "pic/monback/ponytab.pic"
-RapidashPicBack:: INCBIN "pic/monback/rapidashb.pic"
-RattataPicFront:: INCBIN "pic/bmon/rattata.pic"
-RattataPicBack:: INCBIN "pic/monback/rattatab.pic"
-RaticatePicFront:: INCBIN "pic/bmon/raticate.pic"
-RaticatePicBack:: INCBIN "pic/monback/raticateb.pic"
-NidorinoPicFront:: INCBIN "pic/bmon/nidorino.pic"
-NidorinoPicBack:: INCBIN "pic/monback/nidorinob.pic"
-NidorinaPicFront:: INCBIN "pic/bmon/nidorina.pic"
-NidorinaPicBack:: INCBIN "pic/monback/nidorinab.pic"
-GeodudePicFront:: INCBIN "pic/bmon/geodude.pic"
-GeodudePicBack:: INCBIN "pic/monback/geodudeb.pic"
-PorygonPicFront:: INCBIN "pic/bmon/porygon.pic"
-PorygonPicBack:: INCBIN "pic/monback/porygonb.pic"
-AerodactylPicFront:: INCBIN "pic/bmon/aerodactyl.pic"
-AerodactylPicBack:: INCBIN "pic/monback/aerodactylb.pic"
-MagnemitePicFront:: INCBIN "pic/bmon/magnemite.pic"
-MagnemitePicBack:: INCBIN "pic/monback/magnemiteb.pic"
-CharmanderPicFront:: INCBIN "pic/bmon/charmander.pic"
-CharmanderPicBack:: INCBIN "pic/monback/charmanderb.pic"
-SquirtlePicFront:: INCBIN "pic/bmon/squirtle.pic"
-SquirtlePicBack:: INCBIN "pic/monback/squirtleb.pic"
-CharmeleonPicFront:: INCBIN "pic/bmon/charmeleon.pic"
-CharmeleonPicBack:: INCBIN "pic/monback/charmeleonb.pic"
-WartortlePicFront:: INCBIN "pic/bmon/wartortle.pic"
-WartortlePicBack:: INCBIN "pic/monback/wartortleb.pic"
-CharizardPicFront:: INCBIN "pic/bmon/charizard.pic"
-CharizardPicBack:: INCBIN "pic/monback/charizardb.pic"
-FossilAerodactylPic:: INCBIN "pic/bmon/fossilaerodactyl.pic"
-GhostPic:: INCBIN "pic/other/ghost.pic"
-OddishPicFront:: INCBIN "pic/bmon/oddish.pic"
-OddishPicBack:: INCBIN "pic/monback/oddishb.pic"
-GloomPicFront:: INCBIN "pic/bmon/gloom.pic"
-GloomPicBack:: INCBIN "pic/monback/gloomb.pic"
-VileplumePicFront:: INCBIN "pic/bmon/vileplume.pic"
-VileplumePicBack:: INCBIN "pic/monback/vileplumeb.pic"
-BellsproutPicFront:: INCBIN "pic/bmon/bellsprout.pic"
-BellsproutPicBack:: INCBIN "pic/monback/bellsproutb.pic"
-WeepinbellPicFront:: INCBIN "pic/bmon/weepinbell.pic"
-WeepinbellPicBack:: INCBIN "pic/monback/weepinbellb.pic"
-VictreebelPicFront:: INCBIN "pic/bmon/victreebel.pic"
-VictreebelPicBack:: INCBIN "pic/monback/victreebelb.pic"
-
-
-SECTION "Battle (bank D)", ROMX, BANK[$D]
-
-INCLUDE "engine/titlescreen2.asm"
-INCLUDE "engine/battle/link_battle_versus_text.asm"
-INCLUDE "engine/slot_machine.asm"
-INCLUDE "engine/overworld/pewter_guys.asm"
-INCLUDE "engine/multiply_divide.asm"
-INCLUDE "engine/game_corner_slots.asm"
-
-
-SECTION "bankE",ROMX,BANK[$E]
-
-INCLUDE "data/moves.asm"
-BaseStats: INCLUDE "data/base_stats.asm"
-INCLUDE "data/cries.asm"
-INCLUDE "engine/battle/unused_stats_functions.asm"
-INCLUDE "engine/battle/scroll_draw_trainer_pic.asm"
-INCLUDE "engine/battle/trainer_ai.asm"
-INCLUDE "engine/battle/draw_hud_pokeball_gfx.asm"
-
-TradingAnimationGraphics:
- INCBIN "gfx/game_boy.norepeat.2bpp"
- INCBIN "gfx/link_cable.2bpp"
-
-TradingAnimationGraphics2:
-; Pokeball traveling through the link cable.
- INCBIN "gfx/trade2.2bpp"
-
-INCLUDE "engine/evos_moves.asm"
-INCLUDE "engine/battle/moveEffects/heal_effect.asm"
-INCLUDE "engine/battle/moveEffects/transform_effect.asm"
-INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm"
-
-
-SECTION "bankF",ROMX,BANK[$F]
-
-INCLUDE "engine/battle/core.asm"
-
-
-SECTION "bank10",ROMX,BANK[$10]
-
-INCLUDE "engine/menu/pokedex.asm"
-INCLUDE "engine/trade.asm"
-INCLUDE "engine/intro.asm"
-INCLUDE "engine/trade2.asm"
-
-
-SECTION "bank11",ROMX,BANK[$11]
-
-INCLUDE "data/mapHeaders/lavendertown.asm"
-INCLUDE "data/mapObjects/lavendertown.asm"
-LavenderTownBlocks: INCBIN "maps/lavendertown.blk"
-
-ViridianPokecenterBlocks: INCBIN "maps/viridianpokecenter.blk"
-
-SafariZoneRestHouse1Blocks:
-SafariZoneRestHouse2Blocks:
-SafariZoneRestHouse3Blocks:
-SafariZoneRestHouse4Blocks: INCBIN "maps/safarizoneresthouse1.blk"
-
-INCLUDE "scripts/lavendertown.asm"
-
-INCLUDE "engine/pokedex_rating.asm"
-
-INCLUDE "data/mapHeaders/viridianpokecenter.asm"
-INCLUDE "scripts/viridianpokecenter.asm"
-INCLUDE "data/mapObjects/viridianpokecenter.asm"
-
-INCLUDE "data/mapHeaders/mansion1.asm"
-INCLUDE "scripts/mansion1.asm"
-INCLUDE "data/mapObjects/mansion1.asm"
-Mansion1Blocks: INCBIN "maps/mansion1.blk"
-
-INCLUDE "data/mapHeaders/rocktunnel1.asm"
-INCLUDE "scripts/rocktunnel1.asm"
-INCLUDE "data/mapObjects/rocktunnel1.asm"
-RockTunnel1Blocks: INCBIN "maps/rocktunnel1.blk"
-
-INCLUDE "data/mapHeaders/seafoamislands1.asm"
-INCLUDE "scripts/seafoamislands1.asm"
-INCLUDE "data/mapObjects/seafoamislands1.asm"
-SeafoamIslands1Blocks: INCBIN "maps/seafoamislands1.blk"
-
-INCLUDE "data/mapHeaders/ssanne3.asm"
-INCLUDE "scripts/ssanne3.asm"
-INCLUDE "data/mapObjects/ssanne3.asm"
-SSAnne3Blocks: INCBIN "maps/ssanne3.blk"
-
-INCLUDE "data/mapHeaders/victoryroad3.asm"
-INCLUDE "scripts/victoryroad3.asm"
-INCLUDE "data/mapObjects/victoryroad3.asm"
-VictoryRoad3Blocks: INCBIN "maps/victoryroad3.blk"
-
-INCLUDE "data/mapHeaders/rockethideout1.asm"
-INCLUDE "scripts/rockethideout1.asm"
-INCLUDE "data/mapObjects/rockethideout1.asm"
-RocketHideout1Blocks: INCBIN "maps/rockethideout1.blk"
-
-INCLUDE "data/mapHeaders/rockethideout2.asm"
-INCLUDE "scripts/rockethideout2.asm"
-INCLUDE "data/mapObjects/rockethideout2.asm"
-RocketHideout2Blocks: INCBIN "maps/rockethideout2.blk"
-
-INCLUDE "data/mapHeaders/rockethideout3.asm"
-INCLUDE "scripts/rockethideout3.asm"
-INCLUDE "data/mapObjects/rockethideout3.asm"
-RocketHideout3Blocks: INCBIN "maps/rockethideout3.blk"
-
-INCLUDE "data/mapHeaders/rockethideout4.asm"
-INCLUDE "scripts/rockethideout4.asm"
-INCLUDE "data/mapObjects/rockethideout4.asm"
-RocketHideout4Blocks: INCBIN "maps/rockethideout4.blk"
-
-INCLUDE "data/mapHeaders/rockethideoutelevator.asm"
-INCLUDE "scripts/rockethideoutelevator.asm"
-INCLUDE "data/mapObjects/rockethideoutelevator.asm"
-RocketHideoutElevatorBlocks: INCBIN "maps/rockethideoutelevator.blk"
-
-INCLUDE "data/mapHeaders/silphcoelevator.asm"
-INCLUDE "scripts/silphcoelevator.asm"
-INCLUDE "data/mapObjects/silphcoelevator.asm"
-SilphCoElevatorBlocks: INCBIN "maps/silphcoelevator.blk"
-
-INCLUDE "data/mapHeaders/safarizoneeast.asm"
-INCLUDE "scripts/safarizoneeast.asm"
-INCLUDE "data/mapObjects/safarizoneeast.asm"
-SafariZoneEastBlocks: INCBIN "maps/safarizoneeast.blk"
-
-INCLUDE "data/mapHeaders/safarizonenorth.asm"
-INCLUDE "scripts/safarizonenorth.asm"
-INCLUDE "data/mapObjects/safarizonenorth.asm"
-SafariZoneNorthBlocks: INCBIN "maps/safarizonenorth.blk"
-
-INCLUDE "data/mapHeaders/safarizonecenter.asm"
-INCLUDE "scripts/safarizonecenter.asm"
-INCLUDE "data/mapObjects/safarizonecenter.asm"
-SafariZoneCenterBlocks: INCBIN "maps/safarizonecenter.blk"
-
-INCLUDE "data/mapHeaders/safarizoneresthouse1.asm"
-INCLUDE "scripts/safarizoneresthouse1.asm"
-INCLUDE "data/mapObjects/safarizoneresthouse1.asm"
-
-INCLUDE "data/mapHeaders/safarizoneresthouse2.asm"
-INCLUDE "scripts/safarizoneresthouse2.asm"
-INCLUDE "data/mapObjects/safarizoneresthouse2.asm"
-
-INCLUDE "data/mapHeaders/safarizoneresthouse3.asm"
-INCLUDE "scripts/safarizoneresthouse3.asm"
-INCLUDE "data/mapObjects/safarizoneresthouse3.asm"
-
-INCLUDE "data/mapHeaders/safarizoneresthouse4.asm"
-INCLUDE "scripts/safarizoneresthouse4.asm"
-INCLUDE "data/mapObjects/safarizoneresthouse4.asm"
-
-INCLUDE "data/mapHeaders/unknowndungeon2.asm"
-INCLUDE "scripts/unknowndungeon2.asm"
-INCLUDE "data/mapObjects/unknowndungeon2.asm"
-UnknownDungeon2Blocks: INCBIN "maps/unknowndungeon2.blk"
-
-INCLUDE "data/mapHeaders/unknowndungeon3.asm"
-INCLUDE "scripts/unknowndungeon3.asm"
-INCLUDE "data/mapObjects/unknowndungeon3.asm"
-UnknownDungeon3Blocks: INCBIN "maps/unknowndungeon3.blk"
-
-INCLUDE "data/mapHeaders/rocktunnel2.asm"
-INCLUDE "scripts/rocktunnel2.asm"
-INCLUDE "data/mapObjects/rocktunnel2.asm"
-RockTunnel2Blocks: INCBIN "maps/rocktunnel2.blk"
-
-INCLUDE "data/mapHeaders/seafoamislands2.asm"
-INCLUDE "scripts/seafoamislands2.asm"
-INCLUDE "data/mapObjects/seafoamislands2.asm"
-SeafoamIslands2Blocks: INCBIN "maps/seafoamislands2.blk"
-
-INCLUDE "data/mapHeaders/seafoamislands3.asm"
-INCLUDE "scripts/seafoamislands3.asm"
-INCLUDE "data/mapObjects/seafoamislands3.asm"
-SeafoamIslands3Blocks: INCBIN "maps/seafoamislands3.blk"
-
-INCLUDE "data/mapHeaders/seafoamislands4.asm"
-INCLUDE "scripts/seafoamislands4.asm"
-INCLUDE "data/mapObjects/seafoamislands4.asm"
-SeafoamIslands4Blocks: INCBIN "maps/seafoamislands4.blk"
-
-INCLUDE "data/mapHeaders/seafoamislands5.asm"
-INCLUDE "scripts/seafoamislands5.asm"
-INCLUDE "data/mapObjects/seafoamislands5.asm"
-SeafoamIslands5Blocks: INCBIN "maps/seafoamislands5.blk"
-
-INCLUDE "engine/overworld/hidden_objects.asm"
-
-
-SECTION "bank12",ROMX,BANK[$12]
-
-INCLUDE "data/mapHeaders/route7.asm"
-INCLUDE "data/mapObjects/route7.asm"
-Route7Blocks: INCBIN "maps/route7.blk"
-
-CeladonPokecenterBlocks:
-RockTunnelPokecenterBlocks:
-MtMoonPokecenterBlocks: INCBIN "maps/mtmoonpokecenter.blk"
-
-Route18GateBlocks:
-Route15GateBlocks:
-Route11GateBlocks: INCBIN "maps/route11gate.blk"
-
-Route18GateUpstairsBlocks:
-Route16GateUpstairsBlocks:
-Route12GateUpstairsBlocks:
-Route15GateUpstairsBlocks:
-Route11GateUpstairsBlocks: INCBIN "maps/route11gateupstairs.blk"
-
-INCLUDE "engine/predefs12.asm"
-
-INCLUDE "scripts/route7.asm"
-
-INCLUDE "data/mapHeaders/redshouse1f.asm"
-INCLUDE "scripts/redshouse1f.asm"
-INCLUDE "data/mapObjects/redshouse1f.asm"
-RedsHouse1FBlocks: INCBIN "maps/redshouse1f.blk"
-
-INCLUDE "data/mapHeaders/celadonmart3.asm"
-INCLUDE "scripts/celadonmart3.asm"
-INCLUDE "data/mapObjects/celadonmart3.asm"
-CeladonMart3Blocks: INCBIN "maps/celadonmart3.blk"
-
-INCLUDE "data/mapHeaders/celadonmart4.asm"
-INCLUDE "scripts/celadonmart4.asm"
-INCLUDE "data/mapObjects/celadonmart4.asm"
-CeladonMart4Blocks: INCBIN "maps/celadonmart4.blk"
-
-INCLUDE "data/mapHeaders/celadonmartroof.asm"
-INCLUDE "scripts/celadonmartroof.asm"
-INCLUDE "data/mapObjects/celadonmartroof.asm"
-CeladonMartRoofBlocks: INCBIN "maps/celadonmartroof.blk"
-
-INCLUDE "data/mapHeaders/celadonmartelevator.asm"
-INCLUDE "scripts/celadonmartelevator.asm"
-INCLUDE "data/mapObjects/celadonmartelevator.asm"
-CeladonMartElevatorBlocks: INCBIN "maps/celadonmartelevator.blk"
-
-INCLUDE "data/mapHeaders/celadonmansion1.asm"
-INCLUDE "scripts/celadonmansion1.asm"
-INCLUDE "data/mapObjects/celadonmansion1.asm"
-CeladonMansion1Blocks: INCBIN "maps/celadonmansion1.blk"
-
-INCLUDE "data/mapHeaders/celadonmansion2.asm"
-INCLUDE "scripts/celadonmansion2.asm"
-INCLUDE "data/mapObjects/celadonmansion2.asm"
-CeladonMansion2Blocks: INCBIN "maps/celadonmansion2.blk"
-
-INCLUDE "data/mapHeaders/celadonmansion3.asm"
-INCLUDE "scripts/celadonmansion3.asm"
-INCLUDE "data/mapObjects/celadonmansion3.asm"
-CeladonMansion3Blocks: INCBIN "maps/celadonmansion3.blk"
-
-INCLUDE "data/mapHeaders/celadonmansion4.asm"
-INCLUDE "scripts/celadonmansion4.asm"
-INCLUDE "data/mapObjects/celadonmansion4.asm"
-CeladonMansion4Blocks: INCBIN "maps/celadonmansion4.blk"
-
-INCLUDE "data/mapHeaders/celadonpokecenter.asm"
-INCLUDE "scripts/celadonpokecenter.asm"
-INCLUDE "data/mapObjects/celadonpokecenter.asm"
-
-INCLUDE "data/mapHeaders/celadongym.asm"
-INCLUDE "scripts/celadongym.asm"
-INCLUDE "data/mapObjects/celadongym.asm"
-CeladonGymBlocks: INCBIN "maps/celadongym.blk"
-
-INCLUDE "data/mapHeaders/celadongamecorner.asm"
-INCLUDE "scripts/celadongamecorner.asm"
-INCLUDE "data/mapObjects/celadongamecorner.asm"
-CeladonGameCornerBlocks: INCBIN "maps/celadongamecorner.blk"
-
-INCLUDE "data/mapHeaders/celadonmart5.asm"
-INCLUDE "scripts/celadonmart5.asm"
-INCLUDE "data/mapObjects/celadonmart5.asm"
-CeladonMart5Blocks: INCBIN "maps/celadonmart5.blk"
-
-INCLUDE "data/mapHeaders/celadonprizeroom.asm"
-INCLUDE "scripts/celadonprizeroom.asm"
-INCLUDE "data/mapObjects/celadonprizeroom.asm"
-CeladonPrizeRoomBlocks: INCBIN "maps/celadonprizeroom.blk"
-
-INCLUDE "data/mapHeaders/celadondiner.asm"
-INCLUDE "scripts/celadondiner.asm"
-INCLUDE "data/mapObjects/celadondiner.asm"
-CeladonDinerBlocks: INCBIN "maps/celadondiner.blk"
-
-INCLUDE "data/mapHeaders/celadonhouse.asm"
-INCLUDE "scripts/celadonhouse.asm"
-INCLUDE "data/mapObjects/celadonhouse.asm"
-CeladonHouseBlocks: INCBIN "maps/celadonhouse.blk"
-
-INCLUDE "data/mapHeaders/celadonhotel.asm"
-INCLUDE "scripts/celadonhotel.asm"
-INCLUDE "data/mapObjects/celadonhotel.asm"
-CeladonHotelBlocks: INCBIN "maps/celadonhotel.blk"
-
-INCLUDE "data/mapHeaders/mtmoonpokecenter.asm"
-INCLUDE "scripts/mtmoonpokecenter.asm"
-INCLUDE "data/mapObjects/mtmoonpokecenter.asm"
-
-INCLUDE "data/mapHeaders/rocktunnelpokecenter.asm"
-INCLUDE "scripts/rocktunnelpokecenter.asm"
-INCLUDE "data/mapObjects/rocktunnelpokecenter.asm"
-
-INCLUDE "data/mapHeaders/route11gate.asm"
-INCLUDE "scripts/route11gate.asm"
-INCLUDE "data/mapObjects/route11gate.asm"
-
-INCLUDE "data/mapHeaders/route11gateupstairs.asm"
-INCLUDE "scripts/route11gateupstairs.asm"
-INCLUDE "data/mapObjects/route11gateupstairs.asm"
-
-INCLUDE "data/mapHeaders/route12gate.asm"
-INCLUDE "scripts/route12gate.asm"
-INCLUDE "data/mapObjects/route12gate.asm"
-Route12GateBlocks: INCBIN "maps/route12gate.blk"
-
-INCLUDE "data/mapHeaders/route12gateupstairs.asm"
-INCLUDE "scripts/route12gateupstairs.asm"
-INCLUDE "data/mapObjects/route12gateupstairs.asm"
-
-INCLUDE "data/mapHeaders/route15gate.asm"
-INCLUDE "scripts/route15gate.asm"
-INCLUDE "data/mapObjects/route15gate.asm"
-
-INCLUDE "data/mapHeaders/route15gateupstairs.asm"
-INCLUDE "scripts/route15gateupstairs.asm"
-INCLUDE "data/mapObjects/route15gateupstairs.asm"
-
-INCLUDE "data/mapHeaders/route16gate.asm"
-INCLUDE "scripts/route16gate.asm"
-INCLUDE "data/mapObjects/route16gate.asm"
-Route16GateBlocks: INCBIN "maps/route16gate.blk"
-
-INCLUDE "data/mapHeaders/route16gateupstairs.asm"
-INCLUDE "scripts/route16gateupstairs.asm"
-INCLUDE "data/mapObjects/route16gateupstairs.asm"
-
-INCLUDE "data/mapHeaders/route18gate.asm"
-INCLUDE "scripts/route18gate.asm"
-INCLUDE "data/mapObjects/route18gate.asm"
-
-INCLUDE "data/mapHeaders/route18gateupstairs.asm"
-INCLUDE "scripts/route18gateupstairs.asm"
-INCLUDE "data/mapObjects/route18gateupstairs.asm"
-
-INCLUDE "data/mapHeaders/mtmoon1.asm"
-INCLUDE "scripts/mtmoon1.asm"
-INCLUDE "data/mapObjects/mtmoon1.asm"
-MtMoon1Blocks: INCBIN "maps/mtmoon1.blk"
-
-INCLUDE "data/mapHeaders/mtmoon3.asm"
-INCLUDE "scripts/mtmoon3.asm"
-INCLUDE "data/mapObjects/mtmoon3.asm"
-MtMoon3Blocks: INCBIN "maps/mtmoon3.blk"
-
-INCLUDE "data/mapHeaders/safarizonewest.asm"
-INCLUDE "scripts/safarizonewest.asm"
-INCLUDE "data/mapObjects/safarizonewest.asm"
-SafariZoneWestBlocks: INCBIN "maps/safarizonewest.blk"
-
-INCLUDE "data/mapHeaders/safarizonesecrethouse.asm"
-INCLUDE "scripts/safarizonesecrethouse.asm"
-INCLUDE "data/mapObjects/safarizonesecrethouse.asm"
-SafariZoneSecretHouseBlocks: INCBIN "maps/safarizonesecrethouse.blk"
-
-
-SECTION "bank13",ROMX,BANK[$13]
-
-TrainerPics::
-YoungsterPic:: INCBIN "pic/trainer/youngster.pic"
-BugCatcherPic:: INCBIN "pic/trainer/bugcatcher.pic"
-LassPic:: INCBIN "pic/trainer/lass.pic"
-SailorPic:: INCBIN "pic/trainer/sailor.pic"
-JrTrainerMPic:: INCBIN "pic/trainer/jr.trainerm.pic"
-JrTrainerFPic:: INCBIN "pic/trainer/jr.trainerf.pic"
-PokemaniacPic:: INCBIN "pic/trainer/pokemaniac.pic"
-SuperNerdPic:: INCBIN "pic/trainer/supernerd.pic"
-HikerPic:: INCBIN "pic/trainer/hiker.pic"
-BikerPic:: INCBIN "pic/trainer/biker.pic"
-BurglarPic:: INCBIN "pic/trainer/burglar.pic"
-EngineerPic:: INCBIN "pic/trainer/engineer.pic"
-FisherPic:: INCBIN "pic/trainer/fisher.pic"
-SwimmerPic:: INCBIN "pic/trainer/swimmer.pic"
-CueBallPic:: INCBIN "pic/trainer/cueball.pic"
-GamblerPic:: INCBIN "pic/trainer/gambler.pic"
-BeautyPic:: INCBIN "pic/trainer/beauty.pic"
-PsychicPic:: INCBIN "pic/trainer/psychic.pic"
-RockerPic:: INCBIN "pic/trainer/rocker.pic"
-JugglerPic:: INCBIN "pic/trainer/juggler.pic"
-TamerPic:: INCBIN "pic/trainer/tamer.pic"
-BirdKeeperPic:: INCBIN "pic/trainer/birdkeeper.pic"
-BlackbeltPic:: INCBIN "pic/trainer/blackbelt.pic"
-Rival1Pic:: INCBIN "pic/trainer/rival1.pic"
-ProfOakPic:: INCBIN "pic/trainer/prof.oak.pic"
-ChiefPic::
-ScientistPic:: INCBIN "pic/trainer/scientist.pic"
-GiovanniPic:: INCBIN "pic/trainer/giovanni.pic"
-RocketPic:: INCBIN "pic/trainer/rocket.pic"
-CooltrainerMPic:: INCBIN "pic/trainer/cooltrainerm.pic"
-CooltrainerFPic:: INCBIN "pic/trainer/cooltrainerf.pic"
-BrunoPic:: INCBIN "pic/trainer/bruno.pic"
-BrockPic:: INCBIN "pic/trainer/brock.pic"
-MistyPic:: INCBIN "pic/trainer/misty.pic"
-LtSurgePic:: INCBIN "pic/trainer/lt.surge.pic"
-ErikaPic:: INCBIN "pic/trainer/erika.pic"
-KogaPic:: INCBIN "pic/trainer/koga.pic"
-BlainePic:: INCBIN "pic/trainer/blaine.pic"
-SabrinaPic:: INCBIN "pic/trainer/sabrina.pic"
-GentlemanPic:: INCBIN "pic/trainer/gentleman.pic"
-Rival2Pic:: INCBIN "pic/trainer/rival2.pic"
-Rival3Pic:: INCBIN "pic/trainer/rival3.pic"
-LoreleiPic:: INCBIN "pic/trainer/lorelei.pic"
-ChannelerPic:: INCBIN "pic/trainer/channeler.pic"
-AgathaPic:: INCBIN "pic/trainer/agatha.pic"
-LancePic:: INCBIN "pic/trainer/lance.pic"
-
-INCLUDE "data/mapHeaders/battlecenterm.asm"
-INCLUDE "scripts/battlecenterm.asm"
-INCLUDE "data/mapObjects/battlecenterm.asm"
-BattleCenterMBlocks: INCBIN "maps/battlecenterm.blk"
-
-INCLUDE "data/mapHeaders/tradecenterm.asm"
-INCLUDE "scripts/tradecenterm.asm"
-INCLUDE "data/mapObjects/tradecenterm.asm"
-TradeCenterMBlocks: INCBIN "maps/tradecenterm.blk"
-
-INCLUDE "engine/give_pokemon.asm"
-
-INCLUDE "engine/predefs.asm"
-
-
-SECTION "bank14",ROMX,BANK[$14]
-
-INCLUDE "data/mapHeaders/route22.asm"
-INCLUDE "data/mapObjects/route22.asm"
-Route22Blocks: INCBIN "maps/route22.blk"
-
-INCLUDE "data/mapHeaders/route20.asm"
-INCLUDE "data/mapObjects/route20.asm"
-Route20Blocks: INCBIN "maps/route20.blk"
-
-INCLUDE "data/mapHeaders/route23.asm"
-INCLUDE "data/mapObjects/route23.asm"
-Route23Blocks: INCBIN "maps/route23.blk"
-
-INCLUDE "data/mapHeaders/route24.asm"
-INCLUDE "data/mapObjects/route24.asm"
-Route24Blocks: INCBIN "maps/route24.blk"
-
-INCLUDE "data/mapHeaders/route25.asm"
-INCLUDE "data/mapObjects/route25.asm"
-Route25Blocks: INCBIN "maps/route25.blk"
-
-INCLUDE "data/mapHeaders/indigoplateau.asm"
-INCLUDE "scripts/indigoplateau.asm"
-INCLUDE "data/mapObjects/indigoplateau.asm"
-IndigoPlateauBlocks: INCBIN "maps/indigoplateau.blk"
-
-INCLUDE "data/mapHeaders/saffroncity.asm"
-INCLUDE "data/mapObjects/saffroncity.asm"
-SaffronCityBlocks: INCBIN "maps/saffroncity.blk"
-INCLUDE "scripts/saffroncity.asm"
-
-INCLUDE "scripts/route20.asm"
-INCLUDE "scripts/route22.asm"
-INCLUDE "scripts/route23.asm"
-INCLUDE "scripts/route24.asm"
-INCLUDE "scripts/route25.asm"
-
-INCLUDE "data/mapHeaders/victoryroad2.asm"
-INCLUDE "scripts/victoryroad2.asm"
-INCLUDE "data/mapObjects/victoryroad2.asm"
-VictoryRoad2Blocks: INCBIN "maps/victoryroad2.blk"
-
-INCLUDE "data/mapHeaders/mtmoon2.asm"
-INCLUDE "scripts/mtmoon2.asm"
-INCLUDE "data/mapObjects/mtmoon2.asm"
-MtMoon2Blocks: INCBIN "maps/mtmoon2.blk"
-
-INCLUDE "data/mapHeaders/silphco7.asm"
-INCLUDE "scripts/silphco7.asm"
-INCLUDE "data/mapObjects/silphco7.asm"
-SilphCo7Blocks: INCBIN "maps/silphco7.blk"
-
-INCLUDE "data/mapHeaders/mansion2.asm"
-INCLUDE "scripts/mansion2.asm"
-INCLUDE "data/mapObjects/mansion2.asm"
-Mansion2Blocks: INCBIN "maps/mansion2.blk"
-
-INCLUDE "data/mapHeaders/mansion3.asm"
-INCLUDE "scripts/mansion3.asm"
-INCLUDE "data/mapObjects/mansion3.asm"
-Mansion3Blocks: INCBIN "maps/mansion3.blk"
-
-INCLUDE "data/mapHeaders/mansion4.asm"
-INCLUDE "scripts/mansion4.asm"
-INCLUDE "data/mapObjects/mansion4.asm"
-Mansion4Blocks: INCBIN "maps/mansion4.blk"
-
-INCLUDE "engine/battle/init_battle_variables.asm"
-INCLUDE "engine/battle/moveEffects/paralyze_effect.asm"
-
-INCLUDE "engine/overworld/card_key.asm"
-
-INCLUDE "engine/menu/prize_menu.asm"
-
-INCLUDE "engine/hidden_object_functions14.asm"
-
-
-SECTION "bank15",ROMX,BANK[$15]
-
-INCLUDE "data/mapHeaders/route2.asm"
-INCLUDE "data/mapObjects/route2.asm"
-Route2Blocks: INCBIN "maps/route2.blk"
-
-INCLUDE "data/mapHeaders/route3.asm"
-INCLUDE "data/mapObjects/route3.asm"
-Route3Blocks: INCBIN "maps/route3.blk"
-
-INCLUDE "data/mapHeaders/route4.asm"
-INCLUDE "data/mapObjects/route4.asm"
-Route4Blocks: INCBIN "maps/route4.blk"
-
-INCLUDE "data/mapHeaders/route5.asm"
-INCLUDE "data/mapObjects/route5.asm"
-Route5Blocks: INCBIN "maps/route5.blk"
-
-INCLUDE "data/mapHeaders/route9.asm"
-INCLUDE "data/mapObjects/route9.asm"
-Route9Blocks: INCBIN "maps/route9.blk"
-
-INCLUDE "data/mapHeaders/route13.asm"
-INCLUDE "data/mapObjects/route13.asm"
-Route13Blocks: INCBIN "maps/route13.blk"
-
-INCLUDE "data/mapHeaders/route14.asm"
-INCLUDE "data/mapObjects/route14.asm"
-Route14Blocks: INCBIN "maps/route14.blk"
-
-INCLUDE "data/mapHeaders/route17.asm"
-INCLUDE "data/mapObjects/route17.asm"
-Route17Blocks: INCBIN "maps/route17.blk"
-
-INCLUDE "data/mapHeaders/route19.asm"
-INCLUDE "data/mapObjects/route19.asm"
-IF DEF(_OPTION_BEACH_HOUSE)
-Route19Blocks: INCBIN "maps/route19-yellow.blk"
-ELSE
-Route19Blocks: INCBIN "maps/route19.blk"
-ENDC
-
-INCLUDE "data/mapHeaders/route21.asm"
-INCLUDE "data/mapObjects/route21.asm"
-Route21Blocks: INCBIN "maps/route21.blk"
-
-VermilionHouse2Blocks:
-Route12HouseBlocks:
-DayCareMBlocks: INCBIN "maps/daycarem.blk"
-
-FuchsiaHouse3Blocks: INCBIN "maps/fuchsiahouse3.blk"
-
-INCLUDE "engine/battle/experience.asm"
-
-INCLUDE "scripts/route2.asm"
-INCLUDE "scripts/route3.asm"
-INCLUDE "scripts/route4.asm"
-INCLUDE "scripts/route5.asm"
-INCLUDE "scripts/route9.asm"
-INCLUDE "scripts/route13.asm"
-INCLUDE "scripts/route14.asm"
-INCLUDE "scripts/route17.asm"
-INCLUDE "scripts/route19.asm"
-INCLUDE "scripts/route21.asm"
-
-INCLUDE "data/mapHeaders/vermilionhouse2.asm"
-INCLUDE "scripts/vermilionhouse2.asm"
-INCLUDE "data/mapObjects/vermilionhouse2.asm"
-
-INCLUDE "data/mapHeaders/celadonmart2.asm"
-INCLUDE "scripts/celadonmart2.asm"
-INCLUDE "data/mapObjects/celadonmart2.asm"
-CeladonMart2Blocks: INCBIN "maps/celadonmart2.blk"
-
-INCLUDE "data/mapHeaders/fuchsiahouse3.asm"
-INCLUDE "scripts/fuchsiahouse3.asm"
-INCLUDE "data/mapObjects/fuchsiahouse3.asm"
-
-INCLUDE "data/mapHeaders/daycarem.asm"
-INCLUDE "scripts/daycarem.asm"
-INCLUDE "data/mapObjects/daycarem.asm"
-
-INCLUDE "data/mapHeaders/route12house.asm"
-INCLUDE "scripts/route12house.asm"
-INCLUDE "data/mapObjects/route12house.asm"
-
-INCLUDE "data/mapHeaders/silphco8.asm"
-INCLUDE "scripts/silphco8.asm"
-INCLUDE "data/mapObjects/silphco8.asm"
-SilphCo8Blocks: INCBIN "maps/silphco8.blk"
-
-INCLUDE "engine/menu/diploma.asm"
-
-INCLUDE "engine/overworld/trainers.asm"
-
-
-SECTION "bank16",ROMX,BANK[$16]
-
-INCLUDE "data/mapHeaders/route6.asm"
-INCLUDE "data/mapObjects/route6.asm"
-Route6Blocks: INCBIN "maps/route6.blk"
-
-INCLUDE "data/mapHeaders/route8.asm"
-INCLUDE "data/mapObjects/route8.asm"
-Route8Blocks: INCBIN "maps/route8.blk"
-
-INCLUDE "data/mapHeaders/route10.asm"
-INCLUDE "data/mapObjects/route10.asm"
-Route10Blocks: INCBIN "maps/route10.blk"
-
-INCLUDE "data/mapHeaders/route11.asm"
-INCLUDE "data/mapObjects/route11.asm"
-Route11Blocks: INCBIN "maps/route11.blk"
-
-INCLUDE "data/mapHeaders/route12.asm"
-INCLUDE "data/mapObjects/route12.asm"
-Route12Blocks: INCBIN "maps/route12.blk"
-
-INCLUDE "data/mapHeaders/route15.asm"
-INCLUDE "data/mapObjects/route15.asm"
-Route15Blocks: INCBIN "maps/route15.blk"
-
-INCLUDE "data/mapHeaders/route16.asm"
-INCLUDE "data/mapObjects/route16.asm"
-Route16Blocks: INCBIN "maps/route16.blk"
-
-INCLUDE "data/mapHeaders/route18.asm"
-INCLUDE "data/mapObjects/route18.asm"
-Route18Blocks: INCBIN "maps/route18.blk"
-
- INCBIN "maps/unusedblocks58d7d.blk"
-
-INCLUDE "engine/battle/common_text.asm"
-
-INCLUDE "engine/experience.asm"
-
-INCLUDE "engine/overworld/oaks_aide.asm"
-
-INCLUDE "scripts/route6.asm"
-INCLUDE "scripts/route8.asm"
-INCLUDE "scripts/route10.asm"
-INCLUDE "scripts/route11.asm"
-INCLUDE "scripts/route12.asm"
-INCLUDE "scripts/route15.asm"
-INCLUDE "scripts/route16.asm"
-INCLUDE "scripts/route18.asm"
-
-INCLUDE "data/mapHeaders/fanclub.asm"
-INCLUDE "scripts/fanclub.asm"
-INCLUDE "data/mapObjects/fanclub.asm"
-FanClubBlocks:
- INCBIN "maps/fanclub.blk"
-
-INCLUDE "data/mapHeaders/silphco2.asm"
-INCLUDE "scripts/silphco2.asm"
-INCLUDE "data/mapObjects/silphco2.asm"
-SilphCo2Blocks:
- INCBIN "maps/silphco2.blk"
-
-INCLUDE "data/mapHeaders/silphco3.asm"
-INCLUDE "scripts/silphco3.asm"
-INCLUDE "data/mapObjects/silphco3.asm"
-SilphCo3Blocks:
- INCBIN "maps/silphco3.blk"
-
-INCLUDE "data/mapHeaders/silphco10.asm"
-INCLUDE "scripts/silphco10.asm"
-INCLUDE "data/mapObjects/silphco10.asm"
-SilphCo10Blocks:
- INCBIN "maps/silphco10.blk"
-
-INCLUDE "data/mapHeaders/lance.asm"
-INCLUDE "scripts/lance.asm"
-INCLUDE "data/mapObjects/lance.asm"
-LanceBlocks:
- INCBIN "maps/lance.blk"
-
-INCLUDE "data/mapHeaders/halloffameroom.asm"
-INCLUDE "scripts/halloffameroom.asm"
-INCLUDE "data/mapObjects/halloffameroom.asm"
-HallofFameRoomBlocks:
- INCBIN "maps/halloffameroom.blk"
-
-INCLUDE "engine/overworld/saffron_guards.asm"
-
-
-SECTION "bank17",ROMX,BANK[$17]
-
-SaffronMartBlocks:
-LavenderMartBlocks:
-CeruleanMartBlocks:
-VermilionMartBlocks: INCBIN "maps/vermilionmart.blk"
-
-CopycatsHouse2FBlocks:
-RedsHouse2FBlocks: INCBIN "maps/redshouse2f.blk"
-
-Museum1FBlocks: INCBIN "maps/museum1f.blk"
-
-Museum2FBlocks: INCBIN "maps/museum2f.blk"
-
-SaffronPokecenterBlocks:
-VermilionPokecenterBlocks:
-LavenderPokecenterBlocks:
-PewterPokecenterBlocks: INCBIN "maps/pewterpokecenter.blk"
-
-UndergroundPathEntranceRoute7Blocks:
-UndergroundPathEntranceRoute7CopyBlocks:
-UndergroundPathEntranceRoute6Blocks:
-UndergroundPathEntranceRoute5Blocks: INCBIN "maps/undergroundpathentranceroute5.blk"
-
-Route2GateBlocks:
-ViridianForestEntranceBlocks:
-ViridianForestExitBlocks: INCBIN "maps/viridianforestexit.blk"
-
-INCLUDE "data/mapHeaders/redshouse2f.asm"
-INCLUDE "scripts/redshouse2f.asm"
-INCLUDE "data/mapObjects/redshouse2f.asm"
-
-INCLUDE "engine/predefs17.asm"
-
-INCLUDE "data/mapHeaders/museum1f.asm"
-INCLUDE "scripts/museum1f.asm"
-INCLUDE "data/mapObjects/museum1f.asm"
-
-INCLUDE "data/mapHeaders/museum2f.asm"
-INCLUDE "scripts/museum2f.asm"
-INCLUDE "data/mapObjects/museum2f.asm"
-
-INCLUDE "data/mapHeaders/pewtergym.asm"
-INCLUDE "scripts/pewtergym.asm"
-INCLUDE "data/mapObjects/pewtergym.asm"
-PewterGymBlocks: INCBIN "maps/pewtergym.blk"
-
-INCLUDE "data/mapHeaders/pewterpokecenter.asm"
-INCLUDE "scripts/pewterpokecenter.asm"
-INCLUDE "data/mapObjects/pewterpokecenter.asm"
-
-INCLUDE "data/mapHeaders/ceruleanpokecenter.asm"
-INCLUDE "scripts/ceruleanpokecenter.asm"
-INCLUDE "data/mapObjects/ceruleanpokecenter.asm"
-CeruleanPokecenterBlocks: INCBIN "maps/ceruleanpokecenter.blk"
-
-INCLUDE "data/mapHeaders/ceruleangym.asm"
-INCLUDE "scripts/ceruleangym.asm"
-INCLUDE "data/mapObjects/ceruleangym.asm"
-CeruleanGymBlocks: INCBIN "maps/ceruleangym.blk"
-
-INCLUDE "data/mapHeaders/ceruleanmart.asm"
-INCLUDE "scripts/ceruleanmart.asm"
-INCLUDE "data/mapObjects/ceruleanmart.asm"
-
-INCLUDE "data/mapHeaders/lavenderpokecenter.asm"
-INCLUDE "scripts/lavenderpokecenter.asm"
-INCLUDE "data/mapObjects/lavenderpokecenter.asm"
-
-INCLUDE "data/mapHeaders/lavendermart.asm"
-INCLUDE "scripts/lavendermart.asm"
-INCLUDE "data/mapObjects/lavendermart.asm"
-
-INCLUDE "data/mapHeaders/vermilionpokecenter.asm"
-INCLUDE "scripts/vermilionpokecenter.asm"
-INCLUDE "data/mapObjects/vermilionpokecenter.asm"
-
-INCLUDE "data/mapHeaders/vermilionmart.asm"
-INCLUDE "scripts/vermilionmart.asm"
-INCLUDE "data/mapObjects/vermilionmart.asm"
-
-INCLUDE "data/mapHeaders/vermiliongym.asm"
-INCLUDE "scripts/vermiliongym.asm"
-INCLUDE "data/mapObjects/vermiliongym.asm"
-VermilionGymBlocks: INCBIN "maps/vermiliongym.blk"
-
-INCLUDE "data/mapHeaders/copycatshouse2f.asm"
-INCLUDE "scripts/copycatshouse2f.asm"
-INCLUDE "data/mapObjects/copycatshouse2f.asm"
-
-INCLUDE "data/mapHeaders/fightingdojo.asm"
-INCLUDE "scripts/fightingdojo.asm"
-INCLUDE "data/mapObjects/fightingdojo.asm"
-FightingDojoBlocks: INCBIN "maps/fightingdojo.blk"
-
-INCLUDE "data/mapHeaders/saffrongym.asm"
-INCLUDE "scripts/saffrongym.asm"
-INCLUDE "data/mapObjects/saffrongym.asm"
-SaffronGymBlocks: INCBIN "maps/saffrongym.blk"
-
-INCLUDE "data/mapHeaders/saffronmart.asm"
-INCLUDE "scripts/saffronmart.asm"
-INCLUDE "data/mapObjects/saffronmart.asm"
-
-INCLUDE "data/mapHeaders/silphco1.asm"
-INCLUDE "scripts/silphco1.asm"
-INCLUDE "data/mapObjects/silphco1.asm"
-SilphCo1Blocks: INCBIN "maps/silphco1.blk"
-
-INCLUDE "data/mapHeaders/saffronpokecenter.asm"
-INCLUDE "scripts/saffronpokecenter.asm"
-INCLUDE "data/mapObjects/saffronpokecenter.asm"
-
-INCLUDE "data/mapHeaders/viridianforestexit.asm"
-INCLUDE "scripts/viridianforestexit.asm"
-INCLUDE "data/mapObjects/viridianforestexit.asm"
-
-INCLUDE "data/mapHeaders/route2gate.asm"
-INCLUDE "scripts/route2gate.asm"
-INCLUDE "data/mapObjects/route2gate.asm"
-
-INCLUDE "data/mapHeaders/viridianforestentrance.asm"
-INCLUDE "scripts/viridianforestentrance.asm"
-INCLUDE "data/mapObjects/viridianforestentrance.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathentranceroute5.asm"
-INCLUDE "scripts/undergroundpathentranceroute5.asm"
-INCLUDE "data/mapObjects/undergroundpathentranceroute5.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathentranceroute6.asm"
-INCLUDE "scripts/undergroundpathentranceroute6.asm"
-INCLUDE "data/mapObjects/undergroundpathentranceroute6.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathentranceroute7.asm"
-INCLUDE "scripts/undergroundpathentranceroute7.asm"
-INCLUDE "data/mapObjects/undergroundpathentranceroute7.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathentranceroute7copy.asm"
-INCLUDE "scripts/undergroundpathentranceroute7copy.asm"
-INCLUDE "data/mapObjects/undergroundpathentranceroute7copy.asm"
-
-INCLUDE "data/mapHeaders/silphco9.asm"
-INCLUDE "scripts/silphco9.asm"
-INCLUDE "data/mapObjects/silphco9.asm"
-SilphCo9Blocks: INCBIN "maps/silphco9.blk"
-
-INCLUDE "data/mapHeaders/victoryroad1.asm"
-INCLUDE "scripts/victoryroad1.asm"
-INCLUDE "data/mapObjects/victoryroad1.asm"
-VictoryRoad1Blocks: INCBIN "maps/victoryroad1.blk"
-
-INCLUDE "engine/predefs17_2.asm"
-
-INCLUDE "engine/hidden_object_functions17.asm"
-
-
-SECTION "bank18",ROMX,BANK[$18]
-
-ViridianForestBlocks: INCBIN "maps/viridianforest.blk"
-UndergroundPathNSBlocks: INCBIN "maps/undergroundpathns.blk"
-UndergroundPathWEBlocks: INCBIN "maps/undergroundpathwe.blk"
-
- INCBIN "maps/unusedblocks60258.blk"
-
-SSAnne10Blocks:
-SSAnne9Blocks: INCBIN "maps/ssanne9.blk"
-
-INCLUDE "data/mapHeaders/pokemontower1.asm"
-INCLUDE "scripts/pokemontower1.asm"
-INCLUDE "data/mapObjects/pokemontower1.asm"
-PokemonTower1Blocks: INCBIN "maps/pokemontower1.blk"
-
-INCLUDE "data/mapHeaders/pokemontower2.asm"
-INCLUDE "scripts/pokemontower2.asm"
-INCLUDE "data/mapObjects/pokemontower2.asm"
-PokemonTower2Blocks: INCBIN "maps/pokemontower2.blk"
-
-INCLUDE "data/mapHeaders/pokemontower3.asm"
-INCLUDE "scripts/pokemontower3.asm"
-INCLUDE "data/mapObjects/pokemontower3.asm"
-PokemonTower3Blocks: INCBIN "maps/pokemontower3.blk"
-
-INCLUDE "data/mapHeaders/pokemontower4.asm"
-INCLUDE "scripts/pokemontower4.asm"
-INCLUDE "data/mapObjects/pokemontower4.asm"
-PokemonTower4Blocks: INCBIN "maps/pokemontower4.blk"
-
-INCLUDE "data/mapHeaders/pokemontower5.asm"
-INCLUDE "scripts/pokemontower5.asm"
-INCLUDE "data/mapObjects/pokemontower5.asm"
-PokemonTower5Blocks: INCBIN "maps/pokemontower5.blk"
-
-INCLUDE "data/mapHeaders/pokemontower6.asm"
-INCLUDE "scripts/pokemontower6.asm"
-INCLUDE "data/mapObjects/pokemontower6.asm"
-PokemonTower6Blocks: INCBIN "maps/pokemontower6.blk"
-
- INCBIN "maps/unusedblocks60cef.blk"
-
-INCLUDE "data/mapHeaders/pokemontower7.asm"
-INCLUDE "scripts/pokemontower7.asm"
-INCLUDE "data/mapObjects/pokemontower7.asm"
-PokemonTower7Blocks: INCBIN "maps/pokemontower7.blk"
-
-INCLUDE "data/mapHeaders/celadonmart1.asm"
-INCLUDE "scripts/celadonmart1.asm"
-INCLUDE "data/mapObjects/celadonmart1.asm"
-CeladonMart1Blocks: INCBIN "maps/celadonmart1.blk"
-
-INCLUDE "engine/overworld/cinnabar_lab.asm"
-
-INCLUDE "data/mapHeaders/viridianforest.asm"
-INCLUDE "scripts/viridianforest.asm"
-INCLUDE "data/mapObjects/viridianforest.asm"
-
-INCLUDE "data/mapHeaders/ssanne1.asm"
-INCLUDE "scripts/ssanne1.asm"
-INCLUDE "data/mapObjects/ssanne1.asm"
-SSAnne1Blocks: INCBIN "maps/ssanne1.blk"
-
-INCLUDE "data/mapHeaders/ssanne2.asm"
-INCLUDE "scripts/ssanne2.asm"
-INCLUDE "data/mapObjects/ssanne2.asm"
-SSAnne2Blocks: INCBIN "maps/ssanne2.blk"
-
-INCLUDE "data/mapHeaders/ssanne4.asm"
-INCLUDE "scripts/ssanne4.asm"
-INCLUDE "data/mapObjects/ssanne4.asm"
-SSAnne4Blocks: INCBIN "maps/ssanne4.blk"
-
-INCLUDE "data/mapHeaders/ssanne5.asm"
-INCLUDE "scripts/ssanne5.asm"
-INCLUDE "data/mapObjects/ssanne5.asm"
-SSAnne5Blocks: INCBIN "maps/ssanne5.blk"
-
-INCLUDE "data/mapHeaders/ssanne6.asm"
-INCLUDE "scripts/ssanne6.asm"
-INCLUDE "data/mapObjects/ssanne6.asm"
-SSAnne6Blocks: INCBIN "maps/ssanne6.blk"
-
-INCLUDE "data/mapHeaders/ssanne7.asm"
-INCLUDE "scripts/ssanne7.asm"
-INCLUDE "data/mapObjects/ssanne7.asm"
-SSAnne7Blocks: INCBIN "maps/ssanne7.blk"
-
-INCLUDE "data/mapHeaders/ssanne8.asm"
-INCLUDE "scripts/ssanne8.asm"
-INCLUDE "data/mapObjects/ssanne8.asm"
-SSAnne8Blocks: INCBIN "maps/ssanne8.blk"
-
-INCLUDE "data/mapHeaders/ssanne9.asm"
-INCLUDE "scripts/ssanne9.asm"
-INCLUDE "data/mapObjects/ssanne9.asm"
-
-INCLUDE "data/mapHeaders/ssanne10.asm"
-INCLUDE "scripts/ssanne10.asm"
-INCLUDE "data/mapObjects/ssanne10.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathns.asm"
-INCLUDE "scripts/undergroundpathns.asm"
-INCLUDE "data/mapObjects/undergroundpathns.asm"
-
-INCLUDE "data/mapHeaders/undergroundpathwe.asm"
-INCLUDE "scripts/undergroundpathwe.asm"
-INCLUDE "data/mapObjects/undergroundpathwe.asm"
-
-INCLUDE "data/mapHeaders/diglettscave.asm"
-INCLUDE "scripts/diglettscave.asm"
-INCLUDE "data/mapObjects/diglettscave.asm"
-DiglettsCaveBlocks: INCBIN "maps/diglettscave.blk"
-
-INCLUDE "data/mapHeaders/silphco11.asm"
-INCLUDE "scripts/silphco11.asm"
-INCLUDE "data/mapObjects/silphco11.asm"
-SilphCo11Blocks: INCBIN "maps/silphco11.blk"
-
-INCLUDE "engine/hidden_object_functions18.asm"
-
-
-SECTION "bank19",ROMX,BANK[$19]
-
-Overworld_GFX: INCBIN "gfx/tilesets/overworld.t2.2bpp"
-Overworld_Block: INCBIN "gfx/blocksets/overworld.bst"
-
-RedsHouse1_GFX:
-RedsHouse2_GFX: INCBIN "gfx/tilesets/reds_house.t7.2bpp"
-RedsHouse1_Block:
-RedsHouse2_Block: INCBIN "gfx/blocksets/reds_house.bst"
-
-House_GFX: INCBIN "gfx/tilesets/house.t2.2bpp"
-House_Block: INCBIN "gfx/blocksets/house.bst"
-Mansion_GFX: INCBIN "gfx/tilesets/mansion.t2.2bpp"
-Mansion_Block: INCBIN "gfx/blocksets/mansion.bst"
-ShipPort_GFX: INCBIN "gfx/tilesets/ship_port.t2.2bpp"
-ShipPort_Block: INCBIN "gfx/blocksets/ship_port.bst"
-Interior_GFX: INCBIN "gfx/tilesets/interior.t1.2bpp"
-Interior_Block: INCBIN "gfx/blocksets/interior.bst"
-Plateau_GFX: INCBIN "gfx/tilesets/plateau.t10.2bpp"
-Plateau_Block: INCBIN "gfx/blocksets/plateau.bst"
-
-
-SECTION "bank1A",ROMX,BANK[$1A]
-
-INCLUDE "engine/battle/decrement_pp.asm"
-
-Version_GFX:
-IF DEF(_RED)
- INCBIN "gfx/red/redgreenversion.1bpp" ; 10 tiles
-ENDC
-IF DEF(_BLUE)
- INCBIN "gfx/blue/blueversion.1bpp" ; 8 tiles
-ENDC
-
-Dojo_GFX:
-Gym_GFX: INCBIN "gfx/tilesets/gym.2bpp"
-Dojo_Block:
-Gym_Block: INCBIN "gfx/blocksets/gym.bst"
-
-Mart_GFX:
-Pokecenter_GFX: INCBIN "gfx/tilesets/pokecenter.2bpp"
-Mart_Block:
-Pokecenter_Block: INCBIN "gfx/blocksets/pokecenter.bst"
-
-ForestGate_GFX:
-Museum_GFX:
-Gate_GFX: INCBIN "gfx/tilesets/gate.t1.2bpp"
-ForestGate_Block:
-Museum_Block:
-Gate_Block: INCBIN "gfx/blocksets/gate.bst"
-
-Forest_GFX: INCBIN "gfx/tilesets/forest.2bpp"
-Forest_Block: INCBIN "gfx/blocksets/forest.bst"
-Facility_GFX: INCBIN "gfx/tilesets/facility.2bpp"
-Facility_Block: INCBIN "gfx/blocksets/facility.bst"
-
-
-SECTION "bank1B",ROMX,BANK[$1B]
-
-Cemetery_GFX: INCBIN "gfx/tilesets/cemetery.t4.2bpp"
-Cemetery_Block: INCBIN "gfx/blocksets/cemetery.bst"
-Cavern_GFX: INCBIN "gfx/tilesets/cavern.t14.2bpp"
-Cavern_Block: INCBIN "gfx/blocksets/cavern.bst"
-Lobby_GFX: INCBIN "gfx/tilesets/lobby.t2.2bpp"
-Lobby_Block: INCBIN "gfx/blocksets/lobby.bst"
-Ship_GFX: INCBIN "gfx/tilesets/ship.t6.2bpp"
-Ship_Block: INCBIN "gfx/blocksets/ship.bst"
-Lab_GFX: INCBIN "gfx/tilesets/lab.t4.2bpp"
-Lab_Block: INCBIN "gfx/blocksets/lab.bst"
-Club_GFX: INCBIN "gfx/tilesets/club.t5.2bpp"
-Club_Block: INCBIN "gfx/blocksets/club.bst"
-Underground_GFX: INCBIN "gfx/tilesets/underground.t7.2bpp"
-Underground_Block: INCBIN "gfx/blocksets/underground.bst"
-
-
-SECTION "bank1C",ROMX,BANK[$1C]
-
-INCLUDE "engine/gamefreak.asm"
-INCLUDE "engine/hall_of_fame.asm"
-INCLUDE "engine/overworld/healing_machine.asm"
-INCLUDE "engine/overworld/player_animations.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"
-INCLUDE "engine/palettes.asm"
-INCLUDE "engine/save.asm"
-
-
-SECTION "bank1D",ROMX,BANK[$1D]
-
-CopycatsHouse1FBlocks: INCBIN "maps/copycatshouse1f.blk"
-
-CinnabarMartBlocks:
-PewterMartBlocks: INCBIN "maps/pewtermart.blk"
-
-FuchsiaHouse1Blocks: INCBIN "maps/fuchsiahouse1.blk"
-
-CinnabarPokecenterBlocks:
-FuchsiaPokecenterBlocks: INCBIN "maps/fuchsiapokecenter.blk"
-
-CeruleanHouse2Blocks: INCBIN "maps/ceruleanhouse2.blk"
-
-INCLUDE "engine/HoF_room_pc.asm"
-
-INCLUDE "engine/status_ailments.asm"
-
-INCLUDE "engine/items/itemfinder.asm"
-
-INCLUDE "scripts/ceruleancity2.asm"
-
-INCLUDE "data/mapHeaders/viridiangym.asm"
-INCLUDE "scripts/viridiangym.asm"
-INCLUDE "data/mapObjects/viridiangym.asm"
-ViridianGymBlocks: INCBIN "maps/viridiangym.blk"
-
-INCLUDE "data/mapHeaders/pewtermart.asm"
-INCLUDE "scripts/pewtermart.asm"
-INCLUDE "data/mapObjects/pewtermart.asm"
-
-INCLUDE "data/mapHeaders/unknowndungeon1.asm"
-INCLUDE "scripts/unknowndungeon1.asm"
-INCLUDE "data/mapObjects/unknowndungeon1.asm"
-UnknownDungeon1Blocks: INCBIN "maps/unknowndungeon1.blk"
-
-INCLUDE "data/mapHeaders/ceruleanhouse2.asm"
-INCLUDE "scripts/ceruleanhouse2.asm"
-INCLUDE "data/mapObjects/ceruleanhouse2.asm"
-
-INCLUDE "engine/menu/vending_machine.asm"
-
-INCLUDE "data/mapHeaders/fuchsiahouse1.asm"
-INCLUDE "scripts/fuchsiahouse1.asm"
-INCLUDE "data/mapObjects/fuchsiahouse1.asm"
-
-INCLUDE "data/mapHeaders/fuchsiapokecenter.asm"
-INCLUDE "scripts/fuchsiapokecenter.asm"
-INCLUDE "data/mapObjects/fuchsiapokecenter.asm"
-
-INCLUDE "data/mapHeaders/fuchsiahouse2.asm"
-INCLUDE "scripts/fuchsiahouse2.asm"
-INCLUDE "data/mapObjects/fuchsiahouse2.asm"
-FuchsiaHouse2Blocks: INCBIN "maps/fuchsiahouse2.blk"
-
-INCLUDE "data/mapHeaders/safarizoneentrance.asm"
-INCLUDE "scripts/safarizoneentrance.asm"
-INCLUDE "data/mapObjects/safarizoneentrance.asm"
-SafariZoneEntranceBlocks: INCBIN "maps/safarizoneentrance.blk"
-
-INCLUDE "data/mapHeaders/fuchsiagym.asm"
-INCLUDE "scripts/fuchsiagym.asm"
-INCLUDE "data/mapObjects/fuchsiagym.asm"
-FuchsiaGymBlocks: INCBIN "maps/fuchsiagym.blk"
-
-INCLUDE "data/mapHeaders/fuchsiameetingroom.asm"
-INCLUDE "scripts/fuchsiameetingroom.asm"
-INCLUDE "data/mapObjects/fuchsiameetingroom.asm"
-FuchsiaMeetingRoomBlocks: INCBIN "maps/fuchsiameetingroom.blk"
-
-INCLUDE "data/mapHeaders/cinnabargym.asm"
-INCLUDE "scripts/cinnabargym.asm"
-INCLUDE "data/mapObjects/cinnabargym.asm"
-CinnabarGymBlocks: INCBIN "maps/cinnabargym.blk"
-
-INCLUDE "data/mapHeaders/lab1.asm"
-INCLUDE "scripts/lab1.asm"
-INCLUDE "data/mapObjects/lab1.asm"
-Lab1Blocks: INCBIN "maps/lab1.blk"
-
-INCLUDE "data/mapHeaders/lab2.asm"
-INCLUDE "scripts/lab2.asm"
-INCLUDE "data/mapObjects/lab2.asm"
-Lab2Blocks: INCBIN "maps/lab2.blk"
-
-INCLUDE "data/mapHeaders/lab3.asm"
-INCLUDE "scripts/lab3.asm"
-INCLUDE "data/mapObjects/lab3.asm"
-Lab3Blocks: INCBIN "maps/lab3.blk"
-
-INCLUDE "data/mapHeaders/lab4.asm"
-INCLUDE "scripts/lab4.asm"
-INCLUDE "data/mapObjects/lab4.asm"
-Lab4Blocks: INCBIN "maps/lab4.blk"
-
-INCLUDE "data/mapHeaders/cinnabarpokecenter.asm"
-INCLUDE "scripts/cinnabarpokecenter.asm"
-INCLUDE "data/mapObjects/cinnabarpokecenter.asm"
-
-INCLUDE "data/mapHeaders/cinnabarmart.asm"
-INCLUDE "scripts/cinnabarmart.asm"
-INCLUDE "data/mapObjects/cinnabarmart.asm"
-
-INCLUDE "data/mapHeaders/copycatshouse1f.asm"
-INCLUDE "scripts/copycatshouse1f.asm"
-INCLUDE "data/mapObjects/copycatshouse1f.asm"
-
-INCLUDE "data/mapHeaders/gary.asm"
-INCLUDE "scripts/gary.asm"
-INCLUDE "data/mapObjects/gary.asm"
-GaryBlocks: INCBIN "maps/gary.blk"
-
-INCLUDE "data/mapHeaders/lorelei.asm"
-INCLUDE "scripts/lorelei.asm"
-INCLUDE "data/mapObjects/lorelei.asm"
-LoreleiBlocks: INCBIN "maps/lorelei.blk"
-
-INCLUDE "data/mapHeaders/bruno.asm"
-INCLUDE "scripts/bruno.asm"
-INCLUDE "data/mapObjects/bruno.asm"
-BrunoBlocks: INCBIN "maps/bruno.blk"
-
-INCLUDE "data/mapHeaders/agatha.asm"
-INCLUDE "scripts/agatha.asm"
-INCLUDE "data/mapObjects/agatha.asm"
-AgathaBlocks: INCBIN "maps/agatha.blk"
-
-INCLUDE "engine/menu/league_pc.asm"
-
-INCLUDE "engine/overworld/hidden_items.asm"
-
-
-SECTION "bank1E",ROMX,BANK[$1E]
-
-INCLUDE "engine/battle/animations.asm"
-
-INCLUDE "engine/overworld/cut2.asm"
-
-INCLUDE "engine/overworld/ssanne.asm"
-
-RedFishingTilesFront: INCBIN "gfx/red_fishing_tile_front.2bpp"
-RedFishingTilesBack: INCBIN "gfx/red_fishing_tile_back.2bpp"
-RedFishingTilesSide: INCBIN "gfx/red_fishing_tile_side.2bpp"
-RedFishingRodTiles: INCBIN "gfx/red_fishingrod_tiles.2bpp"
-
-INCLUDE "data/animations.asm"
-
-INCLUDE "engine/evolution.asm"
-
-INCLUDE "engine/overworld/elevator.asm"
-
-INCLUDE "engine/items/tm_prices.asm"
-
-IF DEF(_OPTION_BEACH_HOUSE)
-SECTION "bank3C",ROMX[$4314],BANK[$3C]
-
-BeachHouse_GFX:
- INCBIN "gfx/tilesets/beachhouse.2bpp"
-
-BeachHouse_Block:
- INCBIN "gfx/blocksets/beachhouse.bst"
-ENDC
-
-SECTION "bank3d",ROMX,BANK[$3D]
-
-INCLUDE "engine/random.asm"
+INCLUDE "constants.asm"
+
+NPC_SPRITES_1 EQU $4
+NPC_SPRITES_2 EQU $5
+
+GFX EQU $4
+
+PICS_1 EQU $9
+PICS_2 EQU $A
+PICS_3 EQU $B
+PICS_4 EQU $C
+PICS_5 EQU $D
+
+
+INCLUDE "home.asm"
+
+
+SECTION "bank1",ROMX,BANK[$1]
+
+INCLUDE "data/facing.asm"
+
+ResetStatusAndHalveMoneyOnBlackout::
+; Reset player status on blackout.
+ xor a
+ ld [wBattleResult], a
+ ld [wWalkBikeSurfState], a
+ ld [W_ISINBATTLE], a
+ ld [wMapPalOffset], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ld [hJoyHeld], a
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld [wFlags_0xcd60], a
+
+ ld [$ff9f], a
+ ld [$ff9f + 1], a
+ ld [$ff9f + 2], a
+ call HasEnoughMoney
+ jr c, .lostmoney ; never happens
+
+ ; Halve the player's money.
+ ld a, [wPlayerMoney]
+ ld [$ff9f], a
+ ld a, [wPlayerMoney + 1]
+ ld [$ff9f + 1], a
+ ld a, [wPlayerMoney + 2]
+ ld [$ff9f + 2], a
+ xor a
+ ld [$ffa2], a
+ ld [$ffa3], a
+ ld a, 2
+ ld [$ffa4], a
+ predef DivideBCDPredef3
+ ld a, [$ffa2]
+ ld [wPlayerMoney], a
+ ld a, [$ffa2 + 1]
+ ld [wPlayerMoney + 1], a
+ ld a, [$ffa2 + 2]
+ ld [wPlayerMoney + 2], a
+
+.lostmoney
+ ld hl, wd732
+ set 2, [hl]
+ res 3, [hl]
+ set 6, [hl]
+ ld a, %11111111
+ ld [wJoyIgnore], a
+ predef_jump HealParty
+
+
+MewPicFront:: INCBIN "pic/bmon/mew.pic"
+MewPicBack:: INCBIN "pic/monback/mewb.pic"
+INCLUDE "data/baseStats/mew.asm"
+
+INCLUDE "engine/battle/safari_zone.asm"
+
+INCLUDE "engine/titlescreen.asm"
+
+NintenText: db "NINTEN@"
+SonyText: db "SONY@"
+
+
+LoadMonData_:
+; Load monster [wWhichPokemon] from list [wcc49]:
+; 0: partymon
+; 1: enemymon
+; 2: boxmon
+; 3: daycaremon
+; Return monster id at wcf91 and its data at wLoadedMon.
+; Also load base stats at W_MONHDEXNUM for convenience.
+
+ ld a, [wDayCareMonSpecies]
+ ld [wcf91], a
+ ld a, [wcc49]
+ cp 3
+ jr z, .GetMonHeader
+
+ ld a, [wWhichPokemon]
+ ld e, a
+ callab GetMonSpecies
+
+.GetMonHeader
+ ld a, [wcf91]
+ ld [wd0b5], a ; input for GetMonHeader
+ call GetMonHeader
+
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wcc49]
+ cp 1
+ jr c, .getMonEntry
+
+ ld hl, wEnemyMons
+ jr z, .getMonEntry
+
+ cp 2
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1
+ jr z, .getMonEntry
+
+ ld hl, wDayCareMon
+ jr .copyMonData
+
+.getMonEntry
+ ld a, [wWhichPokemon]
+ call AddNTimes
+
+.copyMonData
+ ld de, wLoadedMon
+ ld bc, wPartyMon2 - wPartyMon1
+ jp CopyData
+
+
+INCLUDE "data/item_prices.asm"
+INCLUDE "text/item_names.asm"
+
+UnusedNames:
+ db "かみなりバッヂ@"
+ db "かいがらバッヂ@"
+ db "おじぞうバッヂ@"
+ db "はやぶさバッヂ@"
+ db "ひんやりバッヂ@"
+ db "なかよしバッヂ@"
+ db "バラバッヂ@"
+ db "ひのたまバッヂ@"
+ db "ゴールドバッヂ@"
+ db "たまご@"
+ db "ひよこ@"
+ db "ブロンズ@"
+ db "シルバー@"
+ db "ゴールド@"
+ db "プチキャプテン@"
+ db "キャプテン@"
+ db "プチマスター@"
+ db "マスター@"
+ db "エクセレント"
+
+INCLUDE "engine/overworld/oam.asm"
+INCLUDE "engine/oam_dma.asm"
+
+PrintWaitingText:
+ hlCoord 3, 10
+ ld b, $1
+ ld c, $b
+ ld a, [W_ISINBATTLE]
+ and a
+ jr z, .asm_4c17
+ call TextBoxBorder
+ jr .asm_4c1a
+.asm_4c17
+ call CableClub_TextBoxBorder
+.asm_4c1a
+ hlCoord 4, 11
+ ld de, WaitingText
+ call PlaceString
+ ld c, 50
+ jp DelayFrames
+
+WaitingText:
+ db "Waiting...!@"
+
+
+_UpdateSprites: ; 4c34 (1:4c34)
+ ld h, $c1
+ inc h
+ ld a, $e ; wSpriteStateData2 + $0e
+.spriteLoop
+ ld l, a
+ sub $e
+ ld c, a
+ ld [H_CURRENTSPRITEOFFSET], a
+ ld a, [hl]
+ and a
+ jr z, .skipSprite ; tests $c2Xe
+ push hl
+ push de
+ push bc
+ call .updateCurrentSprite
+ pop bc
+ pop de
+ pop hl
+.skipSprite
+ ld a, l
+ add $10 ; move to next sprite
+ cp $e ; test for overflow (back at $0e)
+ jr nz, .spriteLoop
+ ret
+.updateCurrentSprite ; 4c54 (1:4c54)
+ cp $1
+ jp nz, UpdateNonPlayerSprite
+ jp UpdatePlayerSprite
+
+UpdateNonPlayerSprite:
+ dec a
+ swap a
+ ld [$ff93], a ; $10 * sprite#
+ ld a, [wNPCMovementScriptSpriteOffset] ; some sprite offset?
+ ld b, a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ cp b
+ jr nz, .unequal
+ jp Func_5236
+.unequal
+ jp Func_4ed1
+
+; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET)
+; is going to collide with another sprite by looping over the other sprites.
+; The current sprite's offset will be labelled with i (e.g. $c1i0).
+; The loop sprite's offset will labelled with j (e.g. $c1j0).
+;
+; Note that the Y coordinate of the sprite (in [$c1k4]) is one of the following
+; 9 values when the sprite is aligned with the grid: $fc, $0c, $1c, $2c, ..., $7c.
+; The reason that 4 is added below to the coordinate is to make it align with a
+; multiple of $10 to make comparisons easier.
+DetectCollisionBetweenSprites:
+ nop
+
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add wSpriteStateData1 % $100
+ ld l, a
+
+ ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused)
+ and a ; is this sprite slot slot used?
+ ret z ; return if not used
+
+ ld a, l
+ add 3
+ ld l, a
+
+ ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1)
+ call SetSpriteCollisionValues
+
+ ld a, [hli] ; a = [$C1i4] (Y screen coordinate)
+ add 4 ; align with multiple of $10
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving south or
+; subtract 7 from a if moving north.
+ add b
+ and $f0
+ or c
+
+ ld [$ff90], a ; store Y coordinate adjusted for direction of movement
+
+ ld a, [hli] ; a = [$c1i5] (delta X) (-1, 0, or 1)
+ call SetSpriteCollisionValues
+ ld a, [hl] ; a = [$C1i6] (X screen coordinate)
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving east or
+; subtract 7 from a if moving west.
+ add b
+ and $f0
+ or c
+
+ ld [$ff91], a ; store X coordinate adjusted for direction of movement
+
+ ld a, l
+ add 7
+ ld l, a
+
+ xor a
+ ld [hld], a ; zero [$c1id] XXX what's [$c1id] for?
+ ld [hld], a ; zero [$c1ic] (directions in which collisions occurred)
+
+ ld a, [$ff91]
+ ld [hld], a ; [$c1ib] = adjusted X coordiate
+ ld a, [$ff90]
+ ld [hl], a ; [$c1ia] = adjusted Y coordinate
+
+ xor a ; zero the loop counter
+
+.loop
+ ld [$ff8f], a ; store loop counter
+ swap a
+ ld e, a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ cp e ; does the loop sprite match the current sprite?
+ jp z, .next ; go to the next sprite if they match
+
+ ld d, h
+ ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused)
+ and a ; is this sprite slot slot used?
+ jp z, .next ; go the next sprite if not used
+
+ inc e
+ inc e
+ ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen)
+ inc a
+ jp z, .next ; go the next sprite if offscreen
+
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add 10
+ ld l, a
+
+ inc e
+ ld a, [de] ; a = [$c1j3] (delta Y)
+ call SetSpriteCollisionValues
+
+ inc e
+ ld a, [de] ; a = [$C1j4] (Y screen coordinate)
+ add 4 ; align with multiple of $10
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving south or
+; subtract 7 from a if moving north.
+ add b
+ and $f0
+ or c
+
+ sub [hl] ; subtract the adjusted Y coordinate of sprite i ([$c1ia]) from that of sprite j
+
+; calculate the absolute value of the difference to get the distance
+ jr nc, .noCarry1
+ cpl
+ inc a
+.noCarry1
+ ld [$ff90], a ; store the distance between the two sprites' adjusted Y values
+
+; Use the carry flag set by the above subtraction to determine which sprite's
+; Y coordinate is larger. This information is used later to set [$c1ic],
+; which stores which direction the collision occurred in.
+; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2.
+; If sprite i's Y is larger, set lowest 2 bits of c to 10.
+; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01.
+ push af
+ rl c
+ pop af
+ ccf
+ rl c
+
+; If sprite i's delta Y is 0, then b = 7, else b = 9.
+ ld b, 7
+ ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate)
+ and $f
+ jr z, .next1
+ ld b, 9
+
+.next1
+ ld a, [$ff90] ; a = distance between adjusted Y coordinates
+ sub b
+ ld [$ff92], a ; store distance adjusted using sprite i's direction
+ ld a, b
+ ld [$ff90], a ; store 7 or 9 depending on sprite i's delta Y
+ jr c, .checkXDistance
+
+; If sprite j's delta Y is 0, then b = 7, else b = 9.
+ ld b, 7
+ dec e
+ ld a, [de] ; a = [$c1j3] (delta Y)
+ inc e
+ and a
+ jr z, .next2
+ ld b, 9
+
+.next2
+ ld a, [$ff92] ; a = distance adjusted using sprite i's direction
+ sub b ; adjust distance using sprite j's direction
+ jr z, .checkXDistance
+ jr nc, .next ; go to next sprite if distance is still positive after both adjustments
+
+.checkXDistance
+ inc e
+ inc l
+ ld a, [de] ; a = [$c1j5] (delta X)
+
+ push bc
+
+ call SetSpriteCollisionValues
+ inc e
+ ld a, [de] ; a = [$c1j6] (X screen coordinate)
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving east or
+; subtract 7 from a if moving west.
+ add b
+ and $f0
+ or c
+
+ pop bc
+
+ sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j
+
+; calculate the absolute value of the difference to get the distance
+ jr nc, .noCarry2
+ cpl
+ inc a
+.noCarry2
+ ld [$ff91], a ; store the distance between the two sprites' adjusted X values
+
+; Use the carry flag set by the above subtraction to determine which sprite's
+; X coordinate is larger. This information is used later to set [$c1ic],
+; which stores which direction the collision occurred in.
+; The following 5 lines set the lowest 2 bits of c.
+; If sprite i's X is larger, set lowest 2 bits of c to 10.
+; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01.
+ push af
+ rl c
+ pop af
+ ccf
+ rl c
+
+; If sprite i's delta X is 0, then b = 7, else b = 9.
+ ld b, 7
+ ld a, [hl] ; a = [$c1ib] (adjusted X coordinate)
+ and $f
+ jr z, .next3
+ ld b, 9
+
+.next3
+ ld a, [$ff91] ; a = distance between adjusted X coordinates
+ sub b
+ ld [$ff92], a ; store distance adjusted using sprite i's direction
+ ld a, b
+ ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X
+ jr c, .collision
+
+; If sprite j's delta X is 0, then b = 7, else b = 9.
+ ld b, 7
+ dec e
+ ld a, [de] ; a = [$c1j5] (delta X)
+ inc e
+ and a
+ jr z, .next4
+ ld b, 9
+
+.next4
+ ld a, [$ff92] ; a = distance adjusted using sprite i's direction
+ sub b ; adjust distance using sprite j's direction
+ jr z, .collision
+ jr nc, .next ; go to next sprite if distance is still positive after both adjustments
+
+.collision
+ ld a, [$ff91] ; a = 7 or 9 depending on sprite i's delta X
+ ld b, a
+ ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y
+ inc l
+
+; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100.
+; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa)
+ cp b
+ jr c, .next5
+ ld b, %1100
+ jr .next6
+.next5
+ ld b, %0011
+
+.next6
+ ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis)
+ and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above
+ or [hl] ; or with existing collision direction bits in [$c1ic]
+ ld [hl], a ; store new value
+ ld a, c ; useless code because a is overwritten before being used again
+
+; set bit in [$c1ie] or [$c1if] to indicate which sprite the collision occurred with
+ inc l
+ inc l
+ ld a, [$ff8f] ; a = loop counter
+ ld de, SpriteCollisionBitTable
+ add a
+ add e
+ ld e, a
+ jr nc, .noCarry3
+ inc d
+.noCarry3
+ ld a, [de]
+ or [hl]
+ ld [hli], a
+ inc de
+ ld a, [de]
+ or [hl]
+ ld [hl], a
+
+.next
+ ld a, [$ff8f] ; a = loop counter
+ inc a
+ cp $10
+ jp nz, .loop
+ ret
+
+; takes delta X or delta Y in a
+; b = delta X/Y
+; c = 0 if delta X/Y is 0
+; c = 7 if delta X/Y is 1
+; c = 9 if delta X/Y is -1
+SetSpriteCollisionValues:
+ and a
+ ld b, 0
+ ld c, 0
+ jr z, .done
+ ld c, 9
+ cp -1
+ jr z, .ok
+ ld c, 7
+ ld a, 0
+.ok
+ ld b, a
+.done
+ ret
+
+SpriteCollisionBitTable:
+ db %00000000,%00000001
+ db %00000000,%00000010
+ db %00000000,%00000100
+ db %00000000,%00001000
+ db %00000000,%00010000
+ db %00000000,%00100000
+ db %00000000,%01000000
+ db %00000000,%10000000
+ db %00000001,%00000000
+ db %00000010,%00000000
+ db %00000100,%00000000
+ db %00001000,%00000000
+ db %00010000,%00000000
+ db %00100000,%00000000
+ db %01000000,%00000000
+ db %10000000,%00000000
+
+TestBattle:
+ ret
+
+.loop
+ call GBPalNormal
+
+ ; Don't mess around
+ ; with obedience.
+ ld a, %10000000 ; EARTHBADGE
+ ld [W_OBTAINEDBADGES], a
+
+ ld hl, W_FLAGS_D733
+ set 0, [hl]
+
+ ; Reset the party.
+ ld hl, wPartyCount
+ xor a
+ ld [hli], a
+ dec a
+ ld [hl], a
+
+ ; Give the player a
+ ; level 20 Rhydon.
+ ld a, RHYDON
+ ld [wcf91], a
+ ld a, 20
+ ld [W_CURENEMYLVL], a
+ xor a
+ ld [wcc49], a
+ ld [W_CURMAP], a
+ call AddPartyMon
+
+ ; Fight against a
+ ; level 20 Rhydon.
+ ld a, RHYDON
+ ld [W_CUROPPONENT], a
+
+ predef InitOpponent
+
+ ; When the battle ends,
+ ; do it all again.
+ ld a, 1
+ ld [wUpdateSpritesEnabled], a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ jr .loop
+
+INCLUDE "engine/overworld/item.asm"
+INCLUDE "engine/overworld/movement.asm"
+
+INCLUDE "engine/cable_club.asm"
+
+LoadTrainerInfoTextBoxTiles: ; 5ae6 (1:5ae6)
+ ld de, TrainerInfoTextBoxTileGraphics ; $7b98
+ ld hl, vChars2 + $760
+ ld bc, (BANK(TrainerInfoTextBoxTileGraphics) << 8) +$09
+ jp CopyVideoData
+
+INCLUDE "engine/menu/main_menu.asm"
+
+INCLUDE "engine/oak_speech.asm"
+
+SpecialWarpIn: ; 62ce (1:62ce)
+ call LoadSpecialWarpData
+ predef LoadTilesetHeader
+ ld hl,wd732
+ bit 2,[hl] ; dungeon warp or fly warp?
+ res 2,[hl]
+ jr z,.next
+; if dungeon warp or fly warp
+ ld a,[wDestinationMap]
+ jr .next2
+.next
+ bit 1,[hl]
+ jr z,.next3
+ call EmptyFunc
+.next3
+ ld a,0
+.next2
+ ld b,a
+ ld a,[wd72d]
+ and a
+ jr nz,.next4
+ ld a,b
+.next4
+ ld hl,wd732
+ bit 4,[hl] ; dungeon warp?
+ ret nz
+; if not dungeon warp
+ ld [wLastMap],a
+ ret
+
+; gets the map ID, tile block map view pointer, tileset, and coordinates
+LoadSpecialWarpData: ; 62ff (1:62ff)
+ ld a, [wd72d]
+ cp BATTLE_CENTER
+ jr nz, .notBattleCenter
+ ld hl, BattleCenterSpec1
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right
+ jr z, .copyWarpData
+ ld hl, BattleCenterSpec2
+ jr .copyWarpData
+.notBattleCenter
+ cp TRADE_CENTER
+ jr nz, .notTradeCenter
+ ld hl, TradeCenterSpec1
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .copyWarpData
+ ld hl, TradeCenterSpec2
+ jr .copyWarpData
+.notTradeCenter
+ ld a, [wd732]
+ bit 1, a
+ jr nz, .notFirstMap
+ bit 2, a
+ jr nz, .notFirstMap
+ ld hl, FirstMapSpec
+.copyWarpData
+ ld de, W_CURMAP
+ ld c, $7
+.copyWarpDataLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyWarpDataLoop
+ ld a, [hli]
+ ld [W_CURMAPTILESET], a
+ xor a
+ jr .done
+.notFirstMap
+ ld a, [wLastMap]
+ ld hl, wd732
+ bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
+ jr nz, .usedDunegonWarp
+ bit 6, [hl] ; return to last pokemon center (or player's house)?
+ res 6, [hl]
+ jr z, .otherDestination
+; return to last pokemon center or player's house
+ ld a, [wLastBlackoutMap]
+ jr .usedFlyWarp
+.usedDunegonWarp
+ ld hl, wd72d
+ res 4, [hl]
+ ld a, [wDungeonWarpDestinationMap]
+ ld b, a
+ ld [W_CURMAP], a
+ ld a, [wWhichDungeonWarp]
+ ld c, a
+ ld hl, DungeonWarpList
+ ld de, $0
+ ld a, $6
+ ld [wd12f], a
+.dungeonWarpListLoop
+ ld a, [hli]
+ cp b
+ jr z, .matchedDungeonWarpDestinationMap
+ inc hl
+ jr .nextDungeonWarp
+.matchedDungeonWarpDestinationMap
+ ld a, [hli]
+ cp c
+ jr z, .matchedDungeonWarpID
+.nextDungeonWarp
+ ld a, [wd12f]
+ add e
+ ld e, a
+ jr .dungeonWarpListLoop
+.matchedDungeonWarpID
+ ld hl, DungeonWarpData
+ add hl, de
+ jr .copyWarpData2
+.otherDestination
+ ld a, [wDestinationMap]
+.usedFlyWarp
+ ld b, a
+ ld [W_CURMAP], a
+ ld hl, FlyWarpDataPtr
+.flyWarpDataPtrLoop
+ ld a, [hli]
+ inc hl
+ cp b
+ jr z, .foundFlyWarpMatch
+ inc hl
+ inc hl
+ jr .flyWarpDataPtrLoop
+.foundFlyWarpMatch
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.copyWarpData2
+ ld de, wCurrentTileBlockMapViewPointer
+ ld c, $6
+.copyWarpDataLoop2
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyWarpDataLoop2
+ xor a ; OVERWORLD
+ ld [W_CURMAPTILESET], a
+.done
+ ld [wYOffsetSinceLastSpecialWarp], a
+ ld [wXOffsetSinceLastSpecialWarp], a
+ ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps
+ ld [wDestinationWarpID], a
+ ret
+
+INCLUDE "data/special_warps.asm"
+
+; This function appears to never be used.
+; It is likely a debugging feature to give the player Tsunekazu Ishihara's
+; favorite Pokemon. This is indicated by the overpowered Exeggutor, which
+; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC
+; interview on February 8, 2000.
+; "Exeggutor is my favorite. That's because I was always using this character
+; while I was debugging the program."
+; http://www.ign.com/articles/2000/02/09/abc-news-pokamon-chat-transcript
+
+SetIshiharaTeam: ; 64ca (1:64ca)
+ ld de, IshiharaTeam
+.loop
+ ld a, [de]
+ cp $ff
+ ret z
+ ld [wcf91], a
+ inc de
+ ld a, [de]
+ ld [W_CURENEMYLVL], a
+ inc de
+ call AddPartyMon
+ jr .loop
+
+IshiharaTeam: ; 64df (1:64df)
+ db EXEGGUTOR,90
+ db MEW,20
+ db JOLTEON,56
+ db DUGTRIO,56
+ db ARTICUNO,57
+ db $FF
+
+EmptyFunc: ; 64ea (1:64ea)
+ ret
+
+INCLUDE "engine/menu/naming_screen.asm"
+
+INCLUDE "engine/oak_speech2.asm"
+
+; subtracts the amount the player paid from their money
+; sets carry flag if there is enough money and unsets carry flag if not
+SubtractAmountPaidFromMoney_: ; 6b21 (1:6b21)
+ ld de,wPlayerMoney
+ ld hl,$ff9f ; total price of items
+ ld c,3 ; length of money in bytes
+ call StringCmp
+ ret c
+ ld de,wPlayerMoney + 2
+ ld hl,$ffa1 ; total price of items
+ ld c,3 ; length of money in bytes
+ predef SubBCDPredef ; subtract total price from money
+ ld a,MONEY_BOX
+ ld [wTextBoxID],a
+ call DisplayTextBoxID ; redraw money text box
+ and a
+ ret
+
+HandleItemListSwapping: ; 6b44 (1:6b44)
+ ld a,[wListMenuID]
+ cp a,ITEMLISTMENU
+ jp nz,DisplayListMenuIDLoop ; only rearrange item list menus
+ push hl
+ ld hl,wList
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ inc hl ; hl = beginning of list entries
+ ld a,[wCurrentMenuItem]
+ ld b,a
+ ld a,[wListScrollOffset]
+ add b
+ add a
+ ld c,a
+ ld b,0
+ add hl,bc ; hl = address of currently selected item entry
+ ld a,[hl]
+ pop hl
+ inc a
+ jp z,DisplayListMenuIDLoop ; ignore attempts to swap the Cancel menu item
+ ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
+ and a ; has the first item to swap already been chosen?
+ jr nz,.swapItems
+; if not, set the currently selected item as the first item
+ ld a,[wCurrentMenuItem]
+ inc a
+ ld b,a
+ ld a,[wListScrollOffset] ; index of top (visible) menu item within the list
+ add b
+ ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1)
+ ld c,20
+ call DelayFrames
+ jp DisplayListMenuIDLoop
+.swapItems
+ ld a,[wCurrentMenuItem]
+ inc a
+ ld b,a
+ ld a,[wListScrollOffset]
+ add b
+ ld b,a
+ ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
+ cp b ; is the currently selected item the same as the first item to swap?
+ jp z,DisplayListMenuIDLoop ; ignore attempts to swap an item with itself
+ dec a
+ ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1)
+ ld c,20
+ call DelayFrames
+ push hl
+ push de
+ ld hl,wList
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ inc hl ; hl = beginning of list entries
+ ld d,h
+ ld e,l ; de = beginning of list entries
+ ld a,[wCurrentMenuItem]
+ ld b,a
+ ld a,[wListScrollOffset]
+ add b
+ add a
+ ld c,a
+ ld b,0
+ add hl,bc ; hl = address of currently selected item entry
+ ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
+ add a
+ add e
+ ld e,a
+ jr nc,.noCarry
+ inc d
+.noCarry ; de = address of first item to swap
+ ld a,[de]
+ ld b,a
+ ld a,[hli]
+ cp b
+ jr z,.swapSameItemType
+.swapDifferentItems
+ ld [$ff95],a ; [$ff95] = second item ID
+ ld a,[hld]
+ ld [$ff96],a ; [$ff96] = second item quantity
+ ld a,[de]
+ ld [hli],a ; put first item ID in second item slot
+ inc de
+ ld a,[de]
+ ld [hl],a ; put first item quantity in second item slot
+ ld a,[$ff96]
+ ld [de],a ; put second item quantity in first item slot
+ dec de
+ ld a,[$ff95]
+ ld [de],a ; put second item ID in first item slot
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ pop de
+ pop hl
+ jp DisplayListMenuIDLoop
+.swapSameItemType
+ inc de
+ ld a,[hl]
+ ld b,a
+ ld a,[de]
+ add b ; a = sum of both item quantities
+ cp a,100 ; is the sum too big for one item slot?
+ jr c,.combineItemSlots
+; swap enough items from the first slot to max out the second slot if they can't be combined
+ sub a,99
+ ld [de],a
+ ld a,99
+ ld [hl],a
+ jr .done
+.combineItemSlots
+ ld [hl],a ; put the sum in the second item slot
+ ld hl,wList
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ dec [hl] ; decrease the number of items
+ ld a,[hl]
+ ld [wd12a],a ; update number of items variable
+ cp a,1
+ jr nz,.skipSettingMaxMenuItemID
+ ld [wMaxMenuItem],a ; if the number of items is only one now, update the max menu item ID
+.skipSettingMaxMenuItemID
+ dec de
+ ld h,d
+ ld l,e
+ inc hl
+ inc hl ; hl = address of item after first item to swap
+.moveItemsUpLoop ; erase the first item slot and move up all the following item slots to fill the gap
+ ld a,[hli]
+ ld [de],a
+ inc de
+ inc a ; reached the $ff terminator?
+ jr z,.afterMovingItemsUp
+ ld a,[hli]
+ ld [de],a
+ inc de
+ jr .moveItemsUpLoop
+.afterMovingItemsUp
+ xor a
+ ld [wListScrollOffset],a
+ ld [wCurrentMenuItem],a
+.done
+ xor a
+ ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
+ pop de
+ pop hl
+ jp DisplayListMenuIDLoop
+
+INCLUDE "engine/overworld/pokemart.asm"
+
+INCLUDE "engine/learn_move.asm"
+
+INCLUDE "engine/overworld/pokecenter.asm"
+
+SetLastBlackoutMap:
+; Set the map to return to when
+; blacking out or using Teleport or Dig.
+; Safari rest houses don't count.
+
+ push hl
+ ld hl, SafariZoneRestHouses
+ ld a, [W_CURMAP]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .notresthouse
+ cp b
+ jr nz, .loop
+ jr .done
+
+.notresthouse
+ ld a, [wLastMap]
+ ld [wLastBlackoutMap], a
+.done
+ pop hl
+ ret
+
+SafariZoneRestHouses:
+ db SAFARI_ZONE_REST_HOUSE_2
+ db SAFARI_ZONE_REST_HOUSE_3
+ db SAFARI_ZONE_REST_HOUSE_4
+ db -1
+
+; function that performs initialization for DisplayTextID
+DisplayTextIDInit: ; 7096 (1:7096)
+ xor a
+ ld [wListMenuID],a
+ ld a,[wAutoTextBoxDrawingControl]
+ bit 0,a
+ jr nz,.skipDrawingTextBoxBorder
+ ld a,[$ff8c] ; text ID (or sprite ID)
+ and a
+ jr nz,.notStartMenu
+; if text ID is 0 (i.e. the start menu)
+; Note that the start menu text border is also drawn in the function directly
+; below this, so this seems unnecessary.
+ ld a,[wd74b]
+ bit 5,a ; does the player have the pokedex?
+; start menu with pokedex
+ hlCoord 10, 0
+ ld b,$0e
+ ld c,$08
+ jr nz,.drawTextBoxBorder
+; start menu without pokedex
+ hlCoord 10, 0
+ ld b,$0c
+ ld c,$08
+ jr .drawTextBoxBorder
+; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box
+.notStartMenu
+ hlCoord 0, 12
+ ld b,$04
+ ld c,$12
+.drawTextBoxBorder
+ call TextBoxBorder
+.skipDrawingTextBoxBorder
+ ld hl,wFontLoaded
+ set 0,[hl]
+ ld hl,wFlags_0xcd60
+ bit 4,[hl]
+ res 4,[hl]
+ jr nz,.skipMovingSprites
+ call UpdateSprites ; move sprites
+.skipMovingSprites
+; loop to copy C1X9 (direction the sprite is facing) to C2X9 for each sprite
+; this is done because when you talk to an NPC, they turn to look your way
+; the original direction they were facing must be restored after the dialogue is over
+ ld hl,wSpriteStateData1 + $19
+ ld c,$0f
+ ld de,$0010
+.spriteFacingDirectionCopyLoop
+ ld a,[hl]
+ inc h
+ ld [hl],a
+ dec h
+ add hl,de
+ dec c
+ jr nz,.spriteFacingDirectionCopyLoop
+; loop to force all the sprites in the middle of animation to stand still
+; (so that they don't like they're frozen mid-step during the dialogue)
+ ld hl,wSpriteStateData1 + 2
+ ld de,$0010
+ ld c,e
+.spriteStandStillLoop
+ ld a,[hl]
+ cp a,$ff ; is the sprite visible?
+ jr z,.nextSprite
+; if it is visible
+ and a,$fc
+ ld [hl],a
+.nextSprite
+ add hl,de
+ dec c
+ jr nz,.spriteStandStillLoop
+ ld b,$9c ; window background address
+ call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM
+ xor a
+ ld [hWY],a ; put the window on the screen
+ call LoadFontTilePatterns
+ ld a,$01
+ ld [H_AUTOBGTRANSFERENABLED],a ; enable continuous WRAM to VRAM transfer each V-blank
+ ret
+
+; function that displays the start menu
+DrawStartMenu: ; 710b (1:710b)
+ ld a,[wd74b]
+ bit 5,a ; does the player have the pokedex?
+; menu with pokedex
+ hlCoord 10, 0
+ ld b,$0e
+ ld c,$08
+ jr nz,.drawTextBoxBorder
+; shorter menu if the player doesn't have the pokedex
+ hlCoord 10, 0
+ ld b,$0c
+ ld c,$08
+.drawTextBoxBorder
+ call TextBoxBorder
+ ld a,%11001011 ; bit mask for down, up, start, B, and A buttons
+ ld [wMenuWatchedKeys],a
+ ld a,$02
+ ld [wTopMenuItemY],a ; Y position of first menu choice
+ ld a,$0b
+ ld [wTopMenuItemX],a ; X position of first menu choice
+ ld a,[wcc2d] ; remembered menu selection from last time
+ ld [wCurrentMenuItem],a
+ ld [wLastMenuItem],a
+ xor a
+ ld [wcc37],a
+ ld hl,wd730
+ set 6,[hl] ; no pauses between printing each letter
+ hlCoord 12, 2
+ ld a,[wd74b]
+ bit 5,a ; does the player have the pokedex?
+; case for not having pokdex
+ ld a,$06
+ jr z,.storeMenuItemCount
+; case for having pokedex
+ ld de,StartMenuPokedexText
+ call PrintStartMenuItem
+ ld a,$07
+.storeMenuItemCount
+ ld [wMaxMenuItem],a ; number of menu items
+ ld de,StartMenuPokemonText
+ call PrintStartMenuItem
+ ld de,StartMenuItemText
+ call PrintStartMenuItem
+ ld de,wPlayerName ; player's name
+ call PrintStartMenuItem
+ ld a,[wd72e]
+ bit 6,a ; is the player using the link feature?
+; case for not using link feature
+ ld de,StartMenuSaveText
+ jr z,.printSaveOrResetText
+; case for using link feature
+ ld de,StartMenuResetText
+.printSaveOrResetText
+ call PrintStartMenuItem
+ ld de,StartMenuOptionText
+ call PrintStartMenuItem
+ ld de,StartMenuExitText
+ call PlaceString
+ ld hl,wd730
+ res 6,[hl] ; turn pauses between printing letters back on
+ ret
+
+StartMenuPokedexText: ; 718f (1:718f)
+ db "POKéDEX@"
+
+StartMenuPokemonText: ; 7197 (1:7197)
+ db "POKéMON@"
+
+StartMenuItemText: ; 719f (1:719f)
+ db "ITEM@"
+
+StartMenuSaveText: ; 71a4 (1:71a4)
+ db "SAVE@"
+
+StartMenuResetText: ; 71a9 (1:71a9)
+ db "RESET@"
+
+StartMenuExitText: ; 71af (1:71af)
+ db "EXIT@"
+
+StartMenuOptionText: ; 71b4 (1:71b4)
+ db "OPTION@"
+
+PrintStartMenuItem: ; 71bb (1:71bb)
+ push hl
+ call PlaceString
+ pop hl
+ ld de,$28
+ add hl,de
+ ret
+
+INCLUDE "engine/overworld/cable_club_npc.asm"
+
+; function to draw various text boxes
+DisplayTextBoxID_: ; 72ea (1:72ea)
+ ld a,[wTextBoxID]
+ cp a,TWO_OPTION_MENU
+ jp z,DisplayTwoOptionMenu
+ ld c,a
+ ld hl,TextBoxFunctionTable
+ ld de,3
+ call SearchTextBoxTable
+ jr c,.functionTableMatch
+ ld hl,TextBoxCoordTable
+ ld de,5
+ call SearchTextBoxTable
+ jr c,.coordTableMatch
+ ld hl,TextBoxTextAndCoordTable
+ ld de,9
+ call SearchTextBoxTable
+ jr c,.textAndCoordTableMatch
+.done
+ ret
+.functionTableMatch
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a ; hl = address of function
+ ld de,.done
+ push de
+ jp [hl] ; jump to the function
+.coordTableMatch
+ call GetTextBoxIDCoords
+ call GetAddressOfScreenCoords
+ call TextBoxBorder
+ ret
+.textAndCoordTableMatch
+ call GetTextBoxIDCoords
+ push hl
+ call GetAddressOfScreenCoords
+ call TextBoxBorder
+ pop hl
+ call GetTextBoxIDText
+ ld a,[wd730]
+ push af
+ ld a,[wd730]
+ set 6,a ; no pauses between printing each letter
+ ld [wd730],a
+ call PlaceString
+ pop af
+ ld [wd730],a
+ call UpdateSprites ; move sprites
+ ret
+
+; function to search a table terminated with $ff for a byte matching c in increments of de
+; sets carry flag if a match is found and clears carry flag if not
+SearchTextBoxTable: ; 734c (1:734c)
+ dec de
+.loop
+ ld a,[hli]
+ cp a,$ff
+ jr z,.notFound
+ cp c
+ jr z,.found
+ add hl,de
+ jr .loop
+.found
+ scf
+.notFound
+ ret
+
+; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable
+; INPUT:
+; hl = address of coordinates
+; OUTPUT:
+; b = height
+; c = width
+; d = row of upper left corner
+; e = column of upper left corner
+GetTextBoxIDCoords: ; 735a (1:735a)
+ ld a,[hli] ; column of upper left corner
+ ld e,a
+ ld a,[hli] ; row of upper left corner
+ ld d,a
+ ld a,[hli] ; column of lower right corner
+ sub e
+ dec a
+ ld c,a ; c = width
+ ld a,[hli] ; row of lower right corner
+ sub d
+ dec a
+ ld b,a ; b = height
+ ret
+
+; function to load a text address and text coordinates from the TextBoxTextAndCoordTable
+GetTextBoxIDText: ; 7367 (1:7367)
+ ld a,[hli]
+ ld e,a
+ ld a,[hli]
+ ld d,a ; de = address of text
+ push de ; save text address
+ ld a,[hli]
+ ld e,a ; column of upper left corner of text
+ ld a,[hl]
+ ld d,a ; row of upper left corner of text
+ call GetAddressOfScreenCoords
+ pop de ; restore text address
+ ret
+
+; function to point hl to the screen coordinates
+; INPUT:
+; d = row
+; e = column
+; OUTPUT:
+; hl = address of upper left corner of text box
+GetAddressOfScreenCoords: ; 7375 (1:7375)
+ push bc
+ ld hl,wTileMap
+ ld bc,20
+.loop ; loop to add d rows to the base address
+ ld a,d
+ and a
+ jr z,.addedRows
+ add hl,bc
+ dec d
+ jr .loop
+.addedRows
+ pop bc
+ add hl,de
+ ret
+
+; Format:
+; 00: text box ID
+; 01-02: function address
+TextBoxFunctionTable: ; 7387 (1:7387)
+ dbw MONEY_BOX, DisplayMoneyBox
+ dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu
+ dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu
+ db $ff ; terminator
+
+; Format:
+; 00: text box ID
+; 01: column of upper left corner
+; 02: row of upper left corner
+; 03: column of lower right corner
+; 04: row of lower right corner
+TextBoxCoordTable: ; 7391 (1:7391)
+ db MESSAGE_BOX, 0, 12, 19, 17
+ db $03, 0, 0, 19, 14
+ db $07, 0, 0, 11, 6
+ db LIST_MENU_BOX, 4, 2, 19, 12
+ db $10, 7, 0, 19, 17
+ db MON_SPRITE_POPUP, 6, 4, 14, 13
+ db $ff ; terminator
+
+; Format:
+; 00: text box ID
+; 01: column of upper left corner
+; 02: row of upper left corner
+; 03: column of lower right corner
+; 04: row of lower right corner
+; 05-06: address of text
+; 07: column of beginning of text
+; 08: row of beginning of text
+; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row]
+TextBoxTextAndCoordTable: ; 73b0 (1:73b0)
+ db JP_MOCHIMONO_MENU_TEMPLATE
+ db 0,0,14,17 ; text box coordinates
+ dw JapaneseMochimonoText
+ db 3,0 ; text coordinates
+
+ db USE_TOSS_MENU_TEMPLATE
+ db 13,10,19,14 ; text box coordinates
+ dw UseTossText
+ db 15,11 ; text coordinates
+
+ db JP_SAVE_MESSAGE_MENU_TEMPLATE
+ db 0,0,7,5 ; text box coordinates
+ dw JapaneseSaveMessageText
+ db 2,2 ; text coordinates
+
+ db JP_SPEED_OPTIONS_MENU_TEMPLATE
+ db 0,6,5,10 ; text box coordinates
+ dw JapaneseSpeedOptionsText
+ db 2,7 ; text coordinates
+
+ db BATTLE_MENU_TEMPLATE
+ db 8,12,19,17 ; text box coordinates
+ dw BattleMenuText
+ db 10,14 ; text coordinates
+
+ db SAFARI_BATTLE_MENU_TEMPLATE
+ db 0,12,19,17 ; text box coordinates
+ dw SafariZoneBattleMenuText
+ db 2,14 ; text coordinates
+
+ db SWITCH_STATS_CANCEL_MENU_TEMPLATE
+ db 11,11,19,17 ; text box coordinates
+ dw SwitchStatsCancelText
+ db 13,12 ; text coordinates
+
+ db BUY_SELL_QUIT_MENU_TEMPLATE
+ db 0,0,10,6 ; text box coordinates
+ dw BuySellQuitText
+ db 2,1 ; text coordinates
+
+ db MONEY_BOX_TEMPLATE
+ db 11,0,19,2 ; text box coordinates
+ dw MoneyText
+ db 13,0 ; text coordinates
+
+ db JP_AH_MENU_TEMPLATE
+ db 7,6,11,10 ; text box coordinates
+ dw JapaneseAhText
+ db 8,8 ; text coordinates
+
+ db JP_POKEDEX_MENU_TEMPLATE
+ db 11,8,19,17 ; text box coordinates
+ dw JapanesePokedexMenu
+ db 12,10 ; text coordinates
+
+; note that there is no terminator
+
+BuySellQuitText: ; 7413 (1:7413)
+ db "BUY"
+ next "SELL"
+ next "QUIT@@"
+
+UseTossText: ; 7422 (1:7422)
+ db "USE"
+ next "TOSS@"
+
+JapaneseSaveMessageText: ; 742b (1:742b)
+ db "きろく"
+ next "メッセージ@"
+
+JapaneseSpeedOptionsText: ; 7435 (1:7435)
+ db "はやい"
+ next "おそい@"
+
+MoneyText: ; 743d (1:743d)
+ db "MONEY@"
+
+JapaneseMochimonoText: ; 7443 (1:7443)
+ db "もちもの@"
+
+JapaneseMainMenuText: ; 7448 (1:7448)
+ db "つづきから"
+ next "さいしょから@"
+
+BattleMenuText: ; 7455 (1:7455)
+ db "FIGHT ",$E1,$E2
+ next "ITEM RUN@"
+
+SafariZoneBattleMenuText: ; 7468 (1:7468)
+ db "BALL× BAIT"
+ next "THROW ROCK RUN@"
+
+SwitchStatsCancelText: ; 7489 (1:7489)
+ db "SWITCH"
+ next "STATS"
+ next "CANCEL@"
+
+JapaneseAhText: ; 749d (1:749d)
+ db "アッ!@"
+
+JapanesePokedexMenu: ; 74a1 (1:74a1)
+ db "データをみる"
+ next "なきごえ"
+ next "ぶんぷをみる"
+ next "キャンセル@"
+
+DisplayMoneyBox: ; 74ba (1:74ba)
+ ld hl, wd730
+ set 6, [hl]
+ ld a, MONEY_BOX_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ hlCoord 13, 1
+ ld b, $1
+ ld c, $6
+ call ClearScreenArea
+ hlCoord 12, 1
+ ld de, wPlayerMoney
+ ld c, $a3
+ call PrintBCDNumber
+ ld hl, wd730
+ res 6, [hl]
+ ret
+
+CurrencyString: ; 74e2 (1:74e2)
+ db " ¥@"
+
+DoBuySellQuitMenu: ; 74ea (1:74ea)
+ ld a, [wd730]
+ set 6, a ; no printing delay
+ ld [wd730], a
+ xor a
+ ld [wd12d], a
+ ld a, BUY_SELL_QUIT_MENU_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $2
+ ld [wMaxMenuItem], a
+ ld a, $1
+ ld [wTopMenuItemY], a
+ ld a, $1
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wcc37], a
+ ld a, [wd730]
+ res 6, a ; turn on the printing delay
+ ld [wd730], a
+ call HandleMenuInput
+ call PlaceUnfilledArrowMenuCursor
+ bit 0, a ; was A pressed?
+ jr nz, .pressedA
+ bit 1, a ; was B pressed? (always true since only A/B are watched)
+ jr z, .pressedA
+ ld a, $2
+ ld [wd12e], a
+ jr .quit
+.pressedA
+ ld a, $1
+ ld [wd12e], a
+ ld a, [wCurrentMenuItem]
+ ld [wd12d], a
+ ld b, a
+ ld a, [wMaxMenuItem]
+ cp b
+ jr z, .quit
+ ret
+.quit
+ ld a, $2
+ ld [wd12e], a
+ ld a, [wCurrentMenuItem]
+ ld [wd12d], a
+ scf
+ ret
+
+; displays a menu with two options to choose from
+; b = Y of upper left corner of text region
+; c = X of upper left corner of text region
+; hl = address where the text box border should be drawn
+DisplayTwoOptionMenu: ; 7559 (1:7559)
+ push hl
+ ld a, [wd730]
+ set 6, a ; no printing delay
+ ld [wd730], a
+ xor a
+ ld [wd12d], a
+ ld [wd12e], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $1
+ ld [wMaxMenuItem], a
+ ld a, b
+ ld [wTopMenuItemY], a
+ ld a, c
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wLastMenuItem], a
+ ld [wcc37], a
+ push hl
+ ld hl, wTwoOptionMenuID
+ bit 7, [hl] ; select second menu item by default?
+ res 7, [hl]
+ jr z, .storeCurrentMenuItem
+ inc a
+.storeCurrentMenuItem
+ ld [wCurrentMenuItem], a
+ pop hl
+ push hl
+ push hl
+ call TwoOptionMenu_SaveScreenTiles
+ ld a, [wTwoOptionMenuID]
+ ld hl, TwoOptionMenuStrings
+ ld e, a
+ ld d, $0
+ ld a, $5
+.menuStringLoop
+ add hl, de
+ dec a
+ jr nz, .menuStringLoop
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ ld e, l
+ ld d, h
+ pop hl
+ push de
+ ld a, [wTwoOptionMenuID]
+ cp TRADE_CANCEL_MENU
+ jr nz, .notTradeCancelMenu
+ call CableClub_TextBoxBorder
+ jr .afterTextBoxBorder
+.notTradeCancelMenu
+ call TextBoxBorder
+.afterTextBoxBorder
+ call UpdateSprites
+ pop hl
+ ld a, [hli]
+ and a ; put blank line before first menu item?
+ ld bc, 20 + 2
+ jr z, .noBlankLine
+ ld bc, 2 * 20 + 2
+.noBlankLine
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ pop hl
+ add hl, bc
+ call PlaceString
+ ld hl, wd730
+ res 6, [hl] ; turn on the printing delay
+ ld a, [wTwoOptionMenuID]
+ cp NO_YES_MENU
+ jr nz, .notNoYesMenu
+; No/Yes menu
+; this menu type ignores the B button
+; it only seems to be used when confirming the deletion of a save file
+ xor a
+ ld [wTwoOptionMenuID], a
+ ld a, [wFlags_0xcd60]
+ push af
+ push hl
+ ld hl, wFlags_0xcd60
+ bit 5, [hl]
+ set 5, [hl] ; don't play sound when A or B is pressed in menu
+ pop hl
+.noYesMenuInputLoop
+ call HandleMenuInput
+ bit 1, a ; A button pressed?
+ jr nz, .noYesMenuInputLoop ; try again if A was not pressed
+ pop af
+ pop hl
+ ld [wFlags_0xcd60], a
+ ld a, (SFX_02_40 - SFX_Headers_02) / 3
+ call PlaySound
+ jr .pressedAButton
+.notNoYesMenu
+ xor a
+ ld [wTwoOptionMenuID], a
+ call HandleMenuInput
+ pop hl
+ bit 1, a ; A button pressed?
+ jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed
+.pressedAButton
+ ld a, [wCurrentMenuItem]
+ ld [wd12d], a
+ and a
+ jr nz, .choseSecondMenuItem
+; chose first menu item
+ ld a, $1
+ ld [wd12e], a
+ ld c, 15
+ call DelayFrames
+ call TwoOptionMenu_RestoreScreenTiles
+ and a
+ ret
+.choseSecondMenuItem
+ ld a, $1
+ ld [wCurrentMenuItem], a
+ ld [wd12d], a
+ ld a, $2
+ ld [wd12e], a
+ ld c, 15
+ call DelayFrames
+ call TwoOptionMenu_RestoreScreenTiles
+ scf
+ ret
+
+; Some of the wider/taller two option menus will not have the screen areas
+; they cover be fully saved/restored by the two functions below.
+; The bottom and right edges of the menu may remain after the function returns.
+
+TwoOptionMenu_SaveScreenTiles: ; 763e (1:763e)
+ ld de, wHPBarMaxHP
+ ld bc, $506
+.asm_7644
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .asm_7644
+ push bc
+ ld bc, 14
+ add hl, bc
+ pop bc
+ ld c, $6
+ dec b
+ jr nz, .asm_7644
+ ret
+
+TwoOptionMenu_RestoreScreenTiles: ; 7656 (1:7656)
+ ld de, wHPBarMaxHP
+ ld bc, $506
+.asm_765c
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .asm_765c
+ push bc
+ ld bc, $e
+ add hl, bc
+ pop bc
+ ld c, $6
+ dec b
+ jr nz, .asm_765c
+ call UpdateSprites
+ ret
+
+; Format:
+; 00: byte width
+; 01: byte height
+; 02: byte put blank line before first menu item
+; 03: word text pointer
+TwoOptionMenuStrings: ; 7671 (1:7671)
+ db 4,3,0
+ dw .YesNoMenu
+ db 6,3,0
+ dw .NorthWestMenu
+ db 6,3,0
+ dw .SouthEastMenu
+ db 6,3,0
+ dw .YesNoMenu
+ db 6,3,0
+ dw .NorthEastMenu
+ db 7,3,0
+ dw .TradeCancelMenu
+ db 7,4,1
+ dw .HealCancelMenu
+ db 4,3,0
+ dw .NoYesMenu
+
+.NoYesMenu ; 7699 (1:3699)
+ db "NO",$4E,"YES@"
+.YesNoMenu ; 76a0 (1:36a0)
+ db "YES",$4E,"NO@"
+.NorthWestMenu ; 76a7 (1:36a7)
+ db "NORTH",$4E,"WEST@"
+.SouthEastMenu ; 76b2 (1:36b2)
+ db "SOUTH",$4E,"EAST@"
+.NorthEastMenu ; 76bd (1:36bd)
+ db "NORTH",$4E,"EAST@"
+.TradeCancelMenu ; 76c8 (1:36c8)
+ db "TRADE",$4E,"CANCEL@"
+.HealCancelMenu ; 76d5 (1:36d5)
+ db "HEAL",$4E,"CANCEL@"
+
+DisplayFieldMoveMonMenu: ; 76e1 (1:36e1)
+ xor a
+ ld hl, wWhichTrade
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], $c
+ call GetMonFieldMoves
+ ld a, [wTrainerScreenX]
+ and a
+ jr nz, .asm_770f
+ hlCoord 11, 11
+ ld b, $5
+ ld c, $7
+ call TextBoxBorder
+ call UpdateSprites
+ ld a, $c
+ ld [$fff7], a
+ hlCoord 13, 12
+ ld de, PokemonMenuEntries
+ jp PlaceString
+.asm_770f
+ push af
+ hlCoord 0, 11
+ ld a, [wcd42]
+ dec a
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld b, $5
+ ld a, $12
+ sub e
+ ld c, a
+ pop af
+ ld de, $ffd8
+.asm_7725
+ add hl, de
+ inc b
+ inc b
+ dec a
+ jr nz, .asm_7725
+ ld de, $ffec
+ add hl, de
+ inc b
+ call TextBoxBorder
+ call UpdateSprites
+ hlCoord 0, 12
+ ld a, [wcd42]
+ inc a
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld de, $ffd8
+ ld a, [wTrainerScreenX]
+.asm_7747
+ add hl, de
+ dec a
+ jr nz, .asm_7747
+ xor a
+ ld [wTrainerScreenX], a
+ ld de, wWhichTrade
+.asm_7752
+ push hl
+ ld hl, FieldMoveNames
+ ld a, [de]
+ and a
+ jr z, .asm_7776
+ inc de
+ ld b, a
+.asm_775c
+ dec b
+ jr z, .asm_7766
+.asm_775f
+ ld a, [hli]
+ cp $50
+ jr nz, .asm_775f
+ jr .asm_775c
+.asm_7766
+ ld b, h
+ ld c, l
+ pop hl
+ push de
+ ld d, b
+ ld e, c
+ call PlaceString
+ ld bc, $28
+ add hl, bc
+ pop de
+ jr .asm_7752
+.asm_7776
+ pop hl
+ ld a, [wcd42]
+ ld [$fff7], a
+ hlCoord 0, 12
+ ld a, [wcd42]
+ inc a
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld de, PokemonMenuEntries
+ jp PlaceString
+
+FieldMoveNames: ; 778d (1:778d)
+ db "CUT@"
+ db "FLY@"
+ db "@"
+ db "SURF@"
+ db "STRENGTH@"
+ db "FLASH@"
+ db "DIG@"
+ db "TELEPORT@"
+ db "SOFTBOILED@"
+
+PokemonMenuEntries: ; 77c2 (1:77c2)
+ db "STATS"
+ next "SWITCH"
+ next "CANCEL@"
+
+GetMonFieldMoves: ; 77d6 (1:77d6)
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1Moves
+ ld bc, $2c
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld c, $5
+ ld hl, wWhichTrade
+.asm_77e9
+ push hl
+.asm_77ea
+ dec c
+ jr z, .asm_7821
+ ld a, [de] ; de is RAM address of move
+ and a
+ jr z, .asm_7821
+ ld b, a
+ inc de ; go to next move
+ ld hl, FieldMoveDisplayData
+.asm_77f6
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_77ea
+ cp b
+ jr z, .asm_7802
+ inc hl
+ inc hl
+ jr .asm_77f6
+.asm_7802
+ ld a, b
+ ld [wcd43], a
+ ld a, [hli]
+ ld b, [hl]
+ pop hl
+ ld [hli], a
+ ld a, [wTrainerScreenX]
+ inc a
+ ld [wTrainerScreenX], a
+ ld a, [wcd42]
+ cp b
+ jr c, .asm_781b
+ ld a, b
+ ld [wcd42], a
+.asm_781b
+ ld a, [wcd43]
+ ld b, a
+ jr .asm_77e9
+.asm_7821
+ pop hl
+ ret
+
+; Format: [Move id], [list priority], [leftmost tile]
+; Move id = id of move
+; List priority = lower number means higher priority when field moves are displayed
+; these priorities must be unique
+; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed
+; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C
+FieldMoveDisplayData: ; 7823 (1:7823)
+ db CUT, $01, $0C
+ db FLY, $02, $0C
+ db $B4, $03, $0C ; unused field move
+ db SURF, $04, $0C
+ db STRENGTH, $05, $0A
+ db FLASH, $06, $0C
+ db DIG, $07, $0C
+ db TELEPORT, $08, $0A
+ db SOFTBOILED, $09, $08
+ db $ff ; list terminator
+
+
+INCLUDE "engine/battle/moveEffects/drain_hp_effect.asm"
+
+INCLUDE "engine/menu/players_pc.asm"
+
+_RemovePokemon: ; 7b68 (1:7b68)
+ ld hl, wPartyCount ; wPartyCount
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7b74
+ ld hl, W_NUMINBOX ; wda80
+.asm_7b74
+ ld a, [hl]
+ dec a
+ ld [hli], a
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld e, l
+ ld d, h
+ inc de
+.asm_7b81
+ ld a, [de]
+ inc de
+ ld [hli], a
+ inc a
+ jr nz, .asm_7b81
+ ld hl, wPartyMonOT ; wd273
+ ld d, $5
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7b97
+ ld hl, wBoxMonOT
+ ld d, $13
+.asm_7b97
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call SkipFixedLengthTextEntries
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ cp d
+ jr nz, .asm_7ba6
+ ld [hl], $ff
+ ret
+.asm_7ba6
+ ld d, h
+ ld e, l
+ ld bc, $b
+ add hl, bc
+ ld bc, wPartyMonNicks ; wPartyMonNicks
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7bb8
+ ld bc, wBoxMonNicks
+.asm_7bb8
+ call CopyDataUntil
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7bcd
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1
+.asm_7bcd
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7be4
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc
+ ld bc, wBoxMonOT
+ jr .asm_7beb
+.asm_7be4
+ ld bc, wPartyMon2 - wPartyMon1
+ add hl, bc
+ ld bc, wPartyMonOT ; wd273
+.asm_7beb
+ call CopyDataUntil
+ ld hl, wPartyMonNicks ; wPartyMonNicks
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7bfa
+ ld hl, wBoxMonNicks
+.asm_7bfa
+ ld bc, $b
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld bc, $b
+ add hl, bc
+ ld bc, wPokedexOwned ; wPokedexOwned
+ ld a, [wcf95]
+ and a
+ jr z, .asm_7c15
+ ld bc, wBoxMonNicksEnd
+.asm_7c15
+ jp CopyDataUntil
+
+Func_7c18: ; 7c18 (1:7c18)
+ ld hl, wd730
+ set 6, [hl]
+ predef ShowPokedexData
+ ld hl, wd730
+ res 6, [hl]
+ call ReloadMapData
+ ld c, $a
+ call DelayFrames
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, $1
+ ld hl, wPokedexSeen
+ predef FlagActionPredef
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ret
+
+
+SECTION "bank3",ROMX,BANK[$3]
+
+INCLUDE "engine/joypad.asm"
+
+INCLUDE "data/map_songs.asm"
+
+INCLUDE "data/map_header_banks.asm"
+
+ClearVariablesAfterLoadingMapData: ; c335 (3:4335)
+ ld a, $90
+ ld [hWY], a
+ ld [rWY], a
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld [wStepCounter], a
+ ld [W_LONEATTACKNO], a ; W_GYMLEADERNO
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
+ ld [hJoyHeld], a
+ ld [wcd6a], a
+ ld [wd5a3], a
+ ld hl, wCardKeyDoorY
+ ld [hli], a
+ ld [hl], a
+ ld hl, wWhichTrade
+ ld bc, $1e
+ call FillMemory
+ ret
+
+; only used for setting bit 2 of wd736 upon entering a new map
+IsPlayerStandingOnWarp: ; c35f (3:435f)
+ ld a, [wNumberOfWarps]
+ and a
+ ret z
+ ld c, a
+ ld hl, wWarpEntries
+.loop
+ ld a, [W_YCOORD]
+ cp [hl]
+ jr nz, .nextWarp1
+ inc hl
+ ld a, [W_XCOORD]
+ cp [hl]
+ jr nz, .nextWarp2
+ inc hl
+ ld a, [hli] ; target warp
+ ld [wDestinationWarpID], a
+ ld a, [hl] ; target map
+ ld [$ff8b], a
+ ld hl, wd736
+ set 2, [hl] ; standing on warp flag
+ ret
+.nextWarp1
+ inc hl
+.nextWarp2
+ inc hl
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+
+CheckForceBikeOrSurf: ; c38b (3:438b)
+ ld hl, wd732
+ bit 5, [hl]
+ ret nz
+ ld hl, ForcedBikeOrSurfMaps
+ ld a, [W_YCOORD]
+ ld b, a
+ ld a, [W_XCOORD]
+ ld c, a
+ ld a, [W_CURMAP]
+ ld d, a
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z ;if we reach FF then it's not part of the list
+ cp d ;compare to current map
+ jr nz, .incorrectMap
+ ld a, [hli]
+ cp b ;compare y-coord
+ jr nz, .incorrectY
+ ld a, [hli]
+ cp c ;compare x-coord
+ jr nz, .loop ; incorrect x-coord, check next item
+ ld a, [W_CURMAP]
+ cp SEAFOAM_ISLANDS_4
+ ld a, $2
+ ld [W_SEAFOAMISLANDS4CURSCRIPT], a
+ jr z, .forceSurfing
+ ld a, [W_CURMAP]
+ cp SEAFOAM_ISLANDS_5
+ ld a, $2
+ ld [W_SEAFOAMISLANDS5CURSCRIPT], a
+ jr z, .forceSurfing
+ ;force bike riding
+ ld hl, wd732
+ set 5, [hl]
+ ld a, $1
+ ld [wWalkBikeSurfState], a
+ ld [wWalkBikeSurfStateCopy], a
+ jp ForceBikeOrSurf
+.incorrectMap
+ inc hl
+.incorrectY
+ inc hl
+ jr .loop
+.forceSurfing
+ ld a, $2
+ ld [wWalkBikeSurfState], a
+ ld [wWalkBikeSurfStateCopy], a
+ jp ForceBikeOrSurf
+
+INCLUDE "data/force_bike_surf.asm"
+
+IsPlayerFacingEdgeOfMap: ; c3ff (3:43ff)
+ push hl
+ push de
+ push bc
+ ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
+ srl a
+ ld c, a
+ ld b, $0
+ ld hl, .functionPointerTable
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [W_YCOORD]
+ ld b, a
+ ld a, [W_XCOORD]
+ ld c, a
+ ld de, .asm_c41e
+ push de
+ jp [hl]
+.asm_c41e
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.functionPointerTable
+ dw .facingDown
+ dw .facingUp
+ dw .facingLeft
+ dw .facingRight
+
+.facingDown
+ ld a, [W_CURMAPHEIGHT]
+ add a
+ dec a
+ cp b
+ jr z, .setCarry
+ jr .resetCarry
+
+.facingUp
+ ld a, b
+ and a
+ jr z, .setCarry
+ jr .resetCarry
+
+.facingLeft
+ ld a, c
+ and a
+ jr z, .setCarry
+ jr .resetCarry
+
+.facingRight
+ ld a, [W_CURMAPWIDTH]
+ add a
+ dec a
+ cp c
+ jr z, .setCarry
+ jr .resetCarry
+.resetCarry
+ and a
+ ret
+.setCarry
+ scf
+ ret
+
+IsWarpTileInFrontOfPlayer: ; c44e (3:444e)
+ push hl
+ push de
+ push bc
+ call _GetTileAndCoordsInFrontOfPlayer
+ ld a, [W_CURMAP]
+ cp SS_ANNE_5
+ jr z, .ssAnne5
+ ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
+ srl a
+ ld c, a
+ ld b, 0
+ ld hl, .warpTileListPointers
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wTileInFrontOfPlayer]
+ ld de, $1
+ call IsInArray
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.warpTileListPointers: ; c477 (3:4477)
+ dw .facingDownWarpTiles
+ dw .facingUpWarpTiles
+ dw .facingLeftWarpTiles
+ dw .facingRightWarpTiles
+
+.facingDownWarpTiles
+ db $01,$12,$17,$3D,$04,$18,$33,$FF
+
+.facingUpWarpTiles
+ db $01,$5C,$FF
+
+.facingLeftWarpTiles
+ db $1A,$4B,$FF
+
+.facingRightWarpTiles
+ db $0F,$4E,$FF
+
+.ssAnne5
+ ld a, [wTileInFrontOfPlayer]
+ cp $15
+ jr nz, .notSSAnne5Warp
+ scf
+ jr .done
+.notSSAnne5Warp
+ and a
+ jr .done
+
+IsPlayerStandingOnDoorTileOrWarpTile: ; c49d (3:449d)
+ push hl
+ push de
+ push bc
+ callba IsPlayerStandingOnDoorTile
+ jr c, .done
+ ld a, [W_CURMAPTILESET]
+ add a
+ ld c, a
+ ld b, $0
+ ld hl, WarpTileIDPointers
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, $1
+ aCoord 8, 9
+ call IsInArray
+ jr nc, .done
+ ld hl, wd736
+ res 2, [hl]
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+INCLUDE "data/warp_tile_ids.asm"
+
+PrintSafariZoneSteps: ; c52f (3:452f)
+ ld a, [W_CURMAP] ; W_CURMAP
+ cp SAFARI_ZONE_EAST
+ ret c
+ cp UNKNOWN_DUNGEON_2
+ ret nc
+ ld hl, wTileMap
+ ld b, $3
+ ld c, $7
+ call TextBoxBorder
+ hlCoord 1, 1
+ ld de, wSafariSteps ; wd70d
+ ld bc, $203
+ call PrintNumber
+ hlCoord 4, 1
+ ld de, SafariSteps ; $4579
+ call PlaceString
+ hlCoord 1, 3
+ ld de, SafariBallText
+ call PlaceString
+ ld a, [W_NUMSAFARIBALLS] ; W_NUMSAFARIBALLS
+ cp $a
+ jr nc, .asm_c56d
+ hlCoord 5, 3
+ ld a, $7f
+ ld [hl], a
+.asm_c56d
+ hlCoord 6, 3
+ ld de, W_NUMSAFARIBALLS ; W_NUMSAFARIBALLS
+ ld bc, $102
+ jp PrintNumber
+
+SafariSteps: ; c579 (3:4579)
+ db "/500@"
+
+SafariBallText: ; c57e (3:457e)
+ db "BALL×× @"
+
+GetTileAndCoordsInFrontOfPlayer: ; c586 (3:4586)
+ call GetPredefRegisters
+
+_GetTileAndCoordsInFrontOfPlayer: ; c589 (3:4589)
+ ld a, [W_YCOORD]
+ ld d, a
+ ld a, [W_XCOORD]
+ ld e, a
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ and a
+ jr nz, .notFacingDown
+; facing down
+ aCoord 8, 11
+ inc d
+ jr .storeTile
+.notFacingDown
+ cp SPRITE_FACING_UP
+ jr nz, .notFacingUp
+; facing up
+ aCoord 8, 7
+ dec d
+ jr .storeTile
+.notFacingUp
+ cp SPRITE_FACING_LEFT
+ jr nz, .notFacingLeft
+; facing left
+ aCoord 6, 9
+ dec e
+ jr .storeTile
+.notFacingLeft
+ cp SPRITE_FACING_RIGHT
+ jr nz, .storeTile
+; facing right
+ aCoord 10, 9
+ inc e
+.storeTile
+ ld c, a
+ ld [wTileInFrontOfPlayer], a
+ ret
+
+GetTileTwoStepsInFrontOfPlayer: ; c5be (3:45be)
+ xor a
+ ld [$ffdb], a
+ ld hl, W_YCOORD
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ and a
+ jr nz, .notFacingDown
+; facing down
+ ld hl, $ffdb
+ set 0, [hl]
+ aCoord 8, 13
+ inc d
+ jr .storeTile
+.notFacingDown
+ cp SPRITE_FACING_UP
+ jr nz, .notFacingUp
+; facing up
+ ld hl, $ffdb
+ set 1, [hl]
+ aCoord 8, 5
+ dec d
+ jr .storeTile
+.notFacingUp
+ cp SPRITE_FACING_LEFT
+ jr nz, .notFacingLeft
+; facing left
+ ld hl, $ffdb
+ set 2, [hl]
+ aCoord 4, 9
+ dec e
+ jr .storeTile
+.notFacingLeft
+ cp SPRITE_FACING_RIGHT
+ jr nz, .storeTile
+; facing right
+ ld hl, $ffdb
+ set 3, [hl]
+ aCoord 12, 9
+ inc e
+.storeTile
+ ld c, a
+ ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a
+ ld [wTileInFrontOfPlayer], a
+ ret
+
+CheckForCollisionWhenPushingBoulder: ; c60b (3:460b)
+ call GetTileTwoStepsInFrontOfPlayer
+ ld hl, W_TILESETCOLLISIONPTR
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done ; if the tile two steps ahead is not passable
+ cp c
+ jr nz, .loop
+ ld hl, TilePairCollisionsLand
+ call CheckForTilePairCollisions2
+ ld a, $ff
+ jr c, .done ; if there is an elevation difference between the current tile and the one two steps ahead
+ ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult]
+ cp $15 ; stairs tile
+ ld a, $ff
+ jr z, .done ; if the tile two steps ahead is stairs
+ call CheckForBoulderCollisionWithSprites
+.done
+ ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a
+ ret
+
+; sets a to $ff if there is a collision and $00 if there is no collision
+CheckForBoulderCollisionWithSprites: ; c636 (3:4636)
+ ld a, [wBoulderSpriteIndex]
+ dec a
+ swap a
+ ld d, 0
+ ld e, a
+ ld hl, wSpriteStateData2 + $14
+ add hl, de
+ ld a, [hli] ; map Y position
+ ld [$ffdc], a
+ ld a, [hl] ; map X position
+ ld [$ffdd], a
+ ld a, [W_NUMSPRITES]
+ ld c, a
+ ld de, $f
+ ld hl, wSpriteStateData2 + $14
+ ld a, [$ffdb]
+ and $3 ; facing up or down?
+ jr z, .pushingHorizontallyLoop
+.pushingVerticallyLoop
+ inc hl
+ ld a, [$ffdd]
+ cp [hl]
+ jr nz, .nextSprite1 ; if X coordinates don't match
+ dec hl
+ ld a, [hli]
+ ld b, a
+ ld a, [$ffdb]
+ rrca
+ jr c, .pushingDown
+; pushing up
+ ld a, [$ffdc]
+ dec a
+ jr .compareYCoords
+.pushingDown
+ ld a, [$ffdc]
+ inc a
+.compareYCoords
+ cp b
+ jr z, .failure
+.nextSprite1
+ dec c
+ jr z, .success
+ add hl, de
+ jr .pushingVerticallyLoop
+.pushingHorizontallyLoop
+ ld a, [hli]
+ ld b, a
+ ld a, [$ffdc]
+ cp b
+ jr nz, .nextSprite2
+ ld b, [hl]
+ ld a, [$ffdb]
+ bit 2, a
+ jr nz, .pushingLeft
+; pushing right
+ ld a, [$ffdd]
+ inc a
+ jr .compareXCoords
+.pushingLeft
+ ld a, [$ffdd]
+ dec a
+.compareXCoords
+ cp b
+ jr z, .failure
+.nextSprite2
+ dec c
+ jr z, .success
+ add hl, de
+ jr .pushingHorizontallyLoop
+.failure
+ ld a, $ff
+ ret
+.success
+ xor a
+ ret
+
+ApplyOutOfBattlePoisonDamage: ; c69c (3:469c)
+ ld a, [wd730]
+ add a
+ jp c, .noBlackOut ; no black out if joypad states are being simulated
+ ld a, [wPartyCount]
+ and a
+ jp z, .noBlackOut
+ call IncrementDayCareMonExp
+ ld a, [wStepCounter]
+ and $3 ; is the counter a multiple of 4?
+ jp nz, .noBlackOut ; only apply poison damage every fourth step
+ ld [wWhichPokemon], a
+ ld hl, wPartyMon1Status
+ ld de, wPartySpecies
+.applyDamageLoop
+ ld a, [hl]
+ and (1 << PSN)
+ jr z, .nextMon2 ; not poisoned
+ dec hl
+ dec hl
+ ld a, [hld]
+ ld b, a
+ ld a, [hli]
+ or b
+ jr z, .nextMon ; already fainted
+; subtract 1 from HP
+ ld a, [hl]
+ dec a
+ ld [hld], a
+ inc a
+ jr nz, .noBorrow
+; borrow 1 from upper byte of HP
+ dec [hl]
+ inc hl
+ jr .nextMon
+.noBorrow
+ ld a, [hli]
+ or [hl]
+ jr nz, .nextMon ; didn't faint from damage
+; the mon fainted from the damage
+ push hl
+ inc hl
+ inc hl
+ ld [hl], a
+ ld a, [de]
+ ld [wd11e], a
+ push de
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ xor a
+ ld [wJoyIgnore], a
+ call EnableAutoTextBoxDrawing
+ ld a, $d0
+ ld [$ff8c], a
+ call DisplayTextID
+ pop de
+ pop hl
+.nextMon
+ inc hl
+ inc hl
+.nextMon2
+ inc de
+ ld a, [de]
+ inc a
+ jr z, .applyDamageLoopDone
+ ld bc, wPartyMon2 - wPartyMon1
+ add hl, bc
+ push hl
+ ld hl, wWhichPokemon
+ inc [hl]
+ pop hl
+ jr .applyDamageLoop
+.applyDamageLoopDone
+ ld hl, wPartyMon1Status
+ ld a, [wPartyCount]
+ ld d, a
+ ld e, 0
+.countPoisonedLoop
+ ld a, [hl]
+ and (1 << PSN)
+ or e
+ ld e, a
+ ld bc, wPartyMon2 - wPartyMon1
+ add hl, bc
+ dec d
+ jr nz, .countPoisonedLoop
+ ld a, e
+ and a ; are any party members poisoned?
+ jr z, .skipPoisonEffectAndSound
+ ld b, $2
+ predef ChangeBGPalColor0_4Frames ; change BG white to dark grey for 4 frames
+ ld a, (SFX_02_43 - SFX_Headers_02) / 3
+ call PlaySound
+.skipPoisonEffectAndSound
+ predef AnyPartyAlive
+ ld a, d
+ and a
+ jr nz, .noBlackOut
+ call EnableAutoTextBoxDrawing
+ ld a, $d1
+ ld [$ff8c], a
+ call DisplayTextID
+ ld hl, wd72e
+ set 5, [hl]
+ ld a, $ff
+ jr .done
+.noBlackOut
+ xor a
+.done
+ ld [wd12d], a
+ ret
+
+LoadTilesetHeader: ; c754 (3:4754)
+ call GetPredefRegisters
+ push hl
+ ld d, 0
+ ld a, [W_CURMAPTILESET]
+ add a
+ add a
+ ld b, a
+ add a
+ add b ; a = tileset * 12
+ jr nc, .noCarry
+ inc d
+.noCarry
+ ld e, a
+ ld hl, Tilesets
+ add hl, de
+ ld de, W_TILESETBANK
+ ld c, $b
+.copyTilesetHeaderLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyTilesetHeaderLoop
+ ld a, [hl]
+ ld [hTilesetType], a
+ xor a
+ ld [$ffd8], a
+ pop hl
+ ld a, [W_CURMAPTILESET]
+ push hl
+ push de
+ ld hl, DungeonTilesets
+ ld de, $1
+ call IsInArray
+ pop de
+ pop hl
+ jr c, .asm_c797
+ ld a, [W_CURMAPTILESET]
+ ld b, a
+ ld a, [$ff8b]
+ cp b
+ jr z, .done
+.asm_c797
+ ld a, [wDestinationWarpID]
+ cp $ff
+ jr z, .done
+ call LoadDestinationWarpPosition
+ ld a, [W_YCOORD]
+ and $1
+ ld [W_YBLOCKCOORD], a
+ ld a, [W_XCOORD]
+ and $1
+ ld [W_XBLOCKCOORD], a
+.done
+ ret
+
+INCLUDE "data/dungeon_tilesets.asm"
+
+INCLUDE "data/tileset_headers.asm"
+
+IncrementDayCareMonExp: ; c8de (3:48de)
+ ld a, [W_DAYCARE_IN_USE]
+ and a
+ ret z
+ ld hl, wDayCareMonExp + 2
+ inc [hl]
+ ret nz
+ dec hl
+ inc [hl]
+ ret nz
+ dec hl
+ inc [hl]
+ ld a, [hl]
+ cp $50
+ ret c
+ ld a, $50
+ ld [hl], a
+ ret
+
+INCLUDE "data/hide_show_data.asm"
+
+PrintStrengthTxt: ; cd99 (3:4d99)
+ ld hl, wd728
+ set 0, [hl]
+ ld hl, UsedStrengthText
+ call PrintText
+ ld hl, CanMoveBouldersText
+ jp PrintText
+
+UsedStrengthText: ; cdaa (3:4daa)
+ TX_FAR _UsedStrengthText
+ db $08 ; asm
+ ld a, [wcf91]
+ call PlayCry
+ call Delay3
+ jp TextScriptEnd
+
+CanMoveBouldersText: ; cdbb (3:4dbb)
+ TX_FAR _CanMoveBouldersText
+ db "@"
+
+CheckForForcedBikeSurf: ; cdc0 (3:4dc0)
+ ld hl, wd728
+ set 1, [hl]
+ ld a, [wd732]
+ bit 5, a
+ jr nz, .asm_cdec
+ ld a, [W_CURMAP] ; W_CURMAP
+ cp SEAFOAM_ISLANDS_5
+ ret nz
+ ld a, [wd881]
+ and $3
+ cp $3
+ ret z
+ ld hl, CoordsData_cdf7 ; $4df7
+ call ArePlayerCoordsInArray
+ ret nc
+ ld hl, wd728
+ res 1, [hl]
+ ld hl, CurrentTooFastText
+ jp PrintText
+.asm_cdec
+ ld hl, wd728
+ res 1, [hl]
+ ld hl, CyclingIsFunText
+ jp PrintText
+
+CoordsData_cdf7: ; cdf7 (3:4df7)
+ db $0B,$07,$FF
+
+CurrentTooFastText: ; cdfa (3:4dfa)
+ TX_FAR _CurrentTooFastText
+ db "@"
+
+CyclingIsFunText: ; cdff (3:4dff)
+ TX_FAR _CyclingIsFunText
+ db "@"
+
+; function to add an item (in varying quantities) to the player's bag or PC box
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wcf96] = item quantity
+; sets carry flag if successful, unsets carry flag if unsuccessful
+AddItemToInventory_: ; ce04 (3:4e04)
+ ld a,[wcf96] ; a = item quantity
+ push af
+ push bc
+ push de
+ push hl
+ push hl
+ ld d,50 ; PC box can hold 50 items
+ ld a,wNumBagItems & $FF
+ cp l
+ jr nz,.checkIfInventoryFull
+ ld a,wNumBagItems >> 8
+ cp h
+ jr nz,.checkIfInventoryFull
+; if the destination is the bag
+ ld d,20 ; bag can hold 20 items
+.checkIfInventoryFull
+ ld a,[hl]
+ sub d
+ ld d,a
+ ld a,[hli]
+ and a
+ jr z,.addNewItem
+.loop
+ ld a,[hli]
+ ld b,a ; b = ID of current item in table
+ ld a,[wcf91] ; a = ID of item being added
+ cp b ; does the current item in the table match the item being added?
+ jp z,.increaseItemQuantity ; if so, increase the item's quantity
+ inc hl
+ ld a,[hl]
+ cp a,$ff ; is it the end of the table?
+ jr nz,.loop
+.addNewItem ; add an item not yet in the inventory
+ pop hl
+ ld a,d
+ and a ; is there room for a new item slot?
+ jr z,.done
+; if there is room
+ inc [hl] ; increment the number of items in the inventory
+ ld a,[hl] ; the number of items will be the index of the new item
+ add a
+ dec a
+ ld c,a
+ ld b,0
+ add hl,bc ; hl = address to store the item
+ ld a,[wcf91]
+ ld [hli],a ; store item ID
+ ld a,[wcf96]
+ ld [hli],a ; store item quantity
+ ld [hl],$ff ; store terminator
+ jp .success
+.increaseItemQuantity ; increase the quantity of an item already in the inventory
+ ld a,[wcf96]
+ ld b,a ; b = quantity to add
+ ld a,[hl] ; a = existing item quantity
+ add b ; a = new item quantity
+ cp a,100
+ jp c,.storeNewQuantity ; if the new quantity is less than 100, store it
+; if the new quantity is greater than or equal to 100,
+; try to max out the current slot and add the rest in a new slot
+ sub a,99
+ ld [wcf96],a ; a = amount left over (to put in the new slot)
+ ld a,d
+ and a ; is there room for a new item slot?
+ jr z,.increaseItemQuantityFailed
+; if so, store 99 in the current slot and store the rest in a new slot
+ ld a,99
+ ld [hli],a
+ jp .loop
+.increaseItemQuantityFailed
+ pop hl
+ and a
+ jr .done
+.storeNewQuantity
+ ld [hl],a
+ pop hl
+.success
+ scf
+.done
+ pop hl
+ pop de
+ pop bc
+ pop bc
+ ld a,b
+ ld [wcf96],a ; restore the initial value from when the function was called
+ ret
+
+; function to remove an item (in varying quantities) from the player's bag or PC box
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wWhichPokemon] = index (within the inventory) of the item to remove
+; [wcf96] = quantity to remove
+RemoveItemFromInventory_: ; ce74 (3:4e74)
+ push hl
+ inc hl
+ ld a,[wWhichPokemon] ; index (within the inventory) of the item being removed
+ sla a
+ add l
+ ld l,a
+ jr nc,.noCarry
+ inc h
+.noCarry
+ inc hl
+ ld a,[wcf96] ; quantity being removed
+ ld e,a
+ ld a,[hl] ; a = current quantity
+ sub e
+ ld [hld],a ; store new quantity
+ ld [wcf97],a
+ and a
+ jr nz,.skipMovingUpSlots
+; if the remaining quantity is 0,
+; remove the emptied item slot and move up all the following item slots
+.moveSlotsUp
+ ld e,l
+ ld d,h
+ inc de
+ inc de ; de = address of the slot following the emptied one
+.loop ; loop to move up the following slots
+ ld a,[de]
+ inc de
+ ld [hli],a
+ cp a,$ff
+ jr nz,.loop
+; update menu info
+ xor a
+ ld [wListScrollOffset],a
+ ld [wCurrentMenuItem],a
+ ld [wcc2c],a
+ ld [wd07e],a
+ pop hl
+ ld a,[hl] ; a = number of items in inventory
+ dec a ; decrement the number of items
+ ld [hl],a ; store new number of items
+ ld [wd12a],a
+ cp a,2
+ jr c,.done
+ ld [wMaxMenuItem],a
+ jr .done
+.skipMovingUpSlots
+ pop hl
+.done
+ ret
+
+; wild pokemon data: from 4EB8 to 55C7
+
+LoadWildData: ; ceb8 (3:4eb8)
+ ld hl,WildDataPointers
+ ld a,[W_CURMAP]
+
+ ; get wild data for current map
+ ld c,a
+ ld b,0
+ add hl,bc
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a ; hl now points to wild data for current map
+ ld a,[hli]
+ ld [W_GRASSRATE],a
+ and a
+ jr z,.NoGrassData ; if no grass data, skip to surfing data
+ push hl
+ ld de,W_GRASSMONS ; otherwise, load grass data
+ ld bc,$0014
+ call CopyData
+ pop hl
+ ld bc,$0014
+ add hl,bc
+.NoGrassData
+ ld a,[hli]
+ ld [W_WATERRATE],a
+ and a
+ ret z ; if no water data, we're done
+ ld de,W_WATERMONS ; otherwise, load surfing data
+ ld bc,$0014
+ jp CopyData
+
+INCLUDE "data/wild_mons.asm"
+
+INCLUDE "engine/items/items.asm"
+
+DrawBadges: ; ea03 (3:6a03)
+; Draw 4x2 gym leader faces, with the faces replaced by
+; badges if they are owned. Used in the player status screen.
+
+; In Japanese versions, names are displayed above faces.
+; Instead of removing relevant code, the name graphics were erased.
+
+; Tile ids for face/badge graphics.
+ ld de, wTrainerFacingDirection
+ ld hl, .FaceBadgeTiles
+ ld bc, 8
+ call CopyData
+
+; Booleans for each badge.
+ ld hl, wcd49
+ ld bc, 8
+ xor a
+ call FillMemory
+
+; Alter these based on owned badges.
+ ld de, wcd49
+ ld hl, wTrainerFacingDirection
+ ld a, [W_OBTAINEDBADGES]
+ ld b, a
+ ld c, 8
+.CheckBadge
+ srl b
+ jr nc, .NextBadge
+ ld a, [hl]
+ add 4 ; Badge graphics are after each face
+ ld [hl], a
+ ld a, 1
+ ld [de], a
+.NextBadge
+ inc hl
+ inc de
+ dec c
+ jr nz, .CheckBadge
+
+; Draw two rows of badges.
+ ld hl, wWhichTrade
+ ld a, $d8 ; [1]
+ ld [hli], a
+ ld [hl], $60 ; First name
+
+ hlCoord 2, 11
+ ld de, wcd49
+ call .DrawBadgeRow
+
+ hlCoord 2, 14
+ ld de, wcd49 + 4
+; call .DrawBadgeRow
+; ret
+
+.DrawBadgeRow ; ea4c (3:6a4c)
+; Draw 4 badges.
+
+ ld c, 4
+.DrawBadge
+ push de
+ push hl
+
+; Badge no.
+ ld a, [wWhichTrade]
+ ld [hli], a
+ inc a
+ ld [wWhichTrade], a
+
+; Names aren't printed if the badge is owned.
+ ld a, [de]
+ and a
+ ld a, [wTrainerEngageDistance]
+ jr nz, .SkipName
+ call .PlaceTiles
+ jr .PlaceBadge
+
+.SkipName
+ inc a
+ inc a
+ inc hl
+
+.PlaceBadge
+ ld [wTrainerEngageDistance], a
+ ld de, 20 - 1
+ add hl, de
+ ld a, [wTrainerFacingDirection]
+ call .PlaceTiles
+ add hl, de
+ call .PlaceTiles
+
+; Shift badge array back one byte.
+ push bc
+ ld hl, wTrainerFacingDirection + 1
+ ld de, wTrainerFacingDirection
+ ld bc, 8
+ call CopyData
+ pop bc
+
+ pop hl
+ ld de, 4
+ add hl, de
+
+ pop de
+ inc de
+ dec c
+ jr nz, .DrawBadge
+ ret
+
+.PlaceTiles
+ ld [hli], a
+ inc a
+ ld [hl], a
+ inc a
+ ret
+
+.FaceBadgeTiles
+ db $20, $28, $30, $38, $40, $48, $50, $58
+
+GymLeaderFaceAndBadgeTileGraphics: ; ea9e (3:6a9e)
+ INCBIN "gfx/badges.2bpp"
+
+; replaces a tile block with the one specified in [wNewTileBlockID]
+; and redraws the map view if necessary
+; b = Y
+; c = X
+ReplaceTileBlock: ; ee9e (3:6e9e)
+ call GetPredefRegisters
+ ld hl, wOverworldMap
+ ld a, [W_CURMAPWIDTH]
+ add $6
+ ld e, a
+ ld d, $0
+ add hl, de
+ add hl, de
+ add hl, de
+ ld e, $3
+ add hl, de
+ ld e, a
+ ld a, b
+ and a
+ jr z, .addX
+; add width * Y
+.addWidthYTimesLoop
+ add hl, de
+ dec b
+ jr nz, .addWidthYTimesLoop
+.addX
+ add hl, bc ; add X
+ ld a, [wNewTileBlockID]
+ ld [hl], a
+ ld a, [wCurrentTileBlockMapViewPointer]
+ ld c, a
+ ld a, [wCurrentTileBlockMapViewPointer + 1]
+ ld b, a
+ call CompareHLWithBC
+ ret c ; return if the replaced tile block is below the map view in memory
+ push hl
+ ld l, e
+ ld h, $0
+ ld e, $6
+ ld d, h
+ add hl, hl
+ add hl, hl
+ add hl, de
+ add hl, bc
+ pop bc
+ call CompareHLWithBC
+ ret c ; return if the replaced tile block is above the map view in memory
+
+RedrawMapView: ; eedc (3:6edc)
+ ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ inc a
+ ret z
+ ld a, [H_AUTOBGTRANSFERENABLED]
+ push af
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld [hTilesetType], a ; no flower/water BG tile animations
+ call LoadCurrentMapView
+ call GoPAL_SET_CF1C
+ ld hl, wMapViewVRAMPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, -2 * 32
+ add hl, de
+ ld a, h
+ and $3
+ or $98
+ ld a, l
+ ld [wHPBarMaxHP], a
+ ld a, h
+ ld [wHPBarMaxHP + 1], a
+ ld a, 2
+ ld [$ffbe], a
+ ld c, 9 ; number of rows of 2x2 tiles (this covers the whole screen)
+.redrawRowLoop
+ push bc
+ push hl
+ push hl
+ ld hl, wTileMap - 2 * 20
+ ld de, 20
+ ld a, [$ffbe]
+.asm_ef1a
+ add hl, de
+ dec a
+ jr nz, .asm_ef1a
+ call CopyToScreenEdgeTiles
+ pop hl
+ ld de, $20
+ ld a, [$ffbe]
+ ld c, a
+.asm_ef28
+ add hl, de
+ ld a, h
+ and $3
+ or $98
+ dec c
+ jr nz, .asm_ef28
+ ld [H_SCREENEDGEREDRAWADDR + 1], a
+ ld a, l
+ ld [H_SCREENEDGEREDRAWADDR], a
+ ld a, REDRAWROW
+ ld [H_SCREENEDGEREDRAW], a
+ call DelayFrame
+ ld hl, $ffbe
+ inc [hl]
+ inc [hl]
+ pop hl
+ pop bc
+ dec c
+ jr nz, .redrawRowLoop
+ pop af
+ ld [hTilesetType], a
+ pop af
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+CompareHLWithBC: ; ef4e (3:6f4e)
+ ld a, h
+ sub b
+ ret nz
+ ld a, l
+ sub c
+ ret
+
+INCLUDE "engine/overworld/cut.asm"
+
+MarkTownVisitedAndLoadMissableObjects: ; f113 (3:7113)
+ ld a, [W_CURMAP]
+ cp ROUTE_1
+ jr nc, .notInTown
+ ld c, a
+ ld b, $1
+ ld hl, W_TOWNVISITEDFLAG ; mark town as visited (for flying)
+ predef FlagActionPredef
+.notInTown
+ ld hl, MapHSPointers
+ ld a, [W_CURMAP]
+ ld b, $0
+ ld c, a
+ add hl, bc
+ add hl, bc
+ ld a, [hli] ; load missable objects pointer in hl
+ ld h, [hl]
+ ; fall through
+
+LoadMissableObjects: ; f132 (3:7132)
+ ld l, a
+ push hl
+ ld de, MapHS00 ; calculate difference between out pointer and the base pointer
+ ld a, l
+ sub e
+ jr nc, .asm_f13c
+ dec h
+.asm_f13c
+ ld l, a
+ ld a, h
+ sub d
+ ld h, a
+ ld a, h
+ ld [H_DIVIDEND], a
+ ld a, l
+ ld [H_DIVIDEND+1], a
+ xor a
+ ld [H_DIVIDEND+2], a
+ ld [H_DIVIDEND+3], a
+ ld a, $3
+ ld [H_DIVISOR], a
+ ld b, $2
+ call Divide ; divide difference by 3, resulting in the global offset (number of missable items before ours)
+ ld a, [W_CURMAP] ; W_CURMAP
+ ld b, a
+ ld a, [H_DIVIDEND+3]
+ ld c, a ; store global offset in c
+ ld de, W_MISSABLEOBJECTLIST
+ pop hl
+.writeMissableObjectsListLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .done ; end of list
+ cp b
+ jr nz, .done ; not for current map anymore
+ ld a, [hli]
+ inc hl
+ ld [de], a ; write (map-local) sprite ID
+ inc de
+ ld a, c
+ inc c
+ ld [de], a ; write (global) missable object index
+ inc de
+ jr .writeMissableObjectsListLoop
+.done
+ ld a, $ff
+ ld [de], a ; write sentinel
+ ret
+
+InitializeMissableObjectsFlags: ; f175 (3:7175)
+ ld hl, W_MISSABLEOBJECTFLAGS
+ ld bc, $20
+ xor a
+ call FillMemory ; clear missable objects flags
+ ld hl, MapHS00
+ xor a
+ ld [wd048], a
+.missableObjectsLoop
+ ld a, [hli]
+ cp $ff ; end of list
+ ret z
+ push hl
+ inc hl
+ ld a, [hl]
+ cp Hide
+ jr nz, .asm_f19d
+ ld hl, W_MISSABLEOBJECTFLAGS
+ ld a, [wd048]
+ ld c, a
+ ld b, $1
+ call MissableObjectFlagAction ; set flag iff Item is hidden
+.asm_f19d
+ ld hl, wd048
+ inc [hl]
+ pop hl
+ inc hl
+ inc hl
+ jr .missableObjectsLoop
+
+; tests if current sprite is a missable object that is hidden/has been removed
+IsObjectHidden: ; f1a6 (3:71a6)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ swap a
+ ld b, a
+ ld hl, W_MISSABLEOBJECTLIST
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .notHidden ; not missable -> not hidden
+ cp b
+ ld a, [hli]
+ jr nz, .loop
+ ld c, a
+ ld b, $2
+ ld hl, W_MISSABLEOBJECTFLAGS
+ call MissableObjectFlagAction
+ ld a, c
+ and a
+ jr nz, .hidden
+.notHidden
+ xor a
+.hidden
+ ld [$ffe5], a
+ ret
+
+; adds missable object (items, leg. pokemon, etc.) to the map
+; [wcc4d]: index of the missable object to be added (global index)
+ShowObject: ; f1c8 (3:71c8)
+ShowObject2:
+ ld hl, W_MISSABLEOBJECTFLAGS
+ ld a, [wcc4d]
+ ld c, a
+ ld b, $0
+ call MissableObjectFlagAction ; reset "removed" flag
+ jp UpdateSprites
+
+; removes missable object (items, leg. pokemon, etc.) from the map
+; [wcc4d]: index of the missable object to be removed (global index)
+HideObject: ; f1d7 (3:71d7)
+ ld hl, W_MISSABLEOBJECTFLAGS
+ ld a, [wcc4d]
+ ld c, a
+ ld b, $1
+ call MissableObjectFlagAction ; set "removed" flag
+ jp UpdateSprites
+
+MissableObjectFlagAction:
+; identical to FlagAction
+
+ push hl
+ push de
+ push bc
+
+ ; bit
+ ld a, c
+ ld d, a
+ and 7
+ ld e, a
+
+ ; byte
+ ld a, d
+ srl a
+ srl a
+ srl a
+ add l
+ ld l, a
+ jr nc, .ok
+ inc h
+.ok
+
+ ; d = 1 << e (bitmask)
+ inc e
+ ld d, 1
+.shift
+ dec e
+ jr z, .shifted
+ sla d
+ jr .shift
+.shifted
+
+ ld a, b
+ and a
+ jr z, .reset
+ cp 2
+ jr z, .read
+
+.set
+ ld a, [hl]
+ ld b, a
+ ld a, d
+ or b
+ ld [hl], a
+ jr .done
+
+.reset
+ ld a, [hl]
+ ld b, a
+ ld a, d
+ xor $ff
+ and b
+ ld [hl], a
+ jr .done
+
+.read
+ ld a, [hl]
+ ld b, a
+ ld a, d
+ and b
+
+.done
+ pop bc
+ pop de
+ pop hl
+ ld c, a
+ ret
+
+TryPushingBoulder: ; f225 (3:7225)
+ ld a, [wd728]
+ bit 0, a ; using Strength?
+ ret z
+ ld a, [wFlags_0xcd60]
+ bit 1, a ; has boulder dust animation from previous push played yet?
+ ret nz
+ xor a
+ ld [$ff8c], a
+ call IsSpriteInFrontOfPlayer
+ ld a, [$ff8c]
+ ld [wBoulderSpriteIndex], a
+ and a
+ jp z, ResetBoulderPushFlags
+ ld hl, wSpriteStateData1 + 1
+ ld d, $0
+ ld a, [$ff8c]
+ swap a
+ ld e, a
+ add hl, de
+ res 7, [hl]
+ call GetSpriteMovementByte2Pointer
+ ld a, [hl]
+ cp BOULDER_MOVEMENT_BYTE_2
+ jp nz, ResetBoulderPushFlags
+ ld hl, wFlags_0xcd60
+ bit 6, [hl]
+ set 6, [hl] ; indicate that the player has tried pushing
+ ret z ; the player must try pushing twice before the boulder will move
+ ld a, [hJoyHeld]
+ and $f0
+ ret z
+ predef CheckForCollisionWhenPushingBoulder
+ ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult]
+ and a ; was there a collision?
+ jp nz, ResetBoulderPushFlags
+ ld a, [hJoyHeld]
+ ld b, a
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_UP
+ jr z, .pushBoulderUp
+ cp SPRITE_FACING_LEFT
+ jr z, .pushBoulderLeft
+ cp SPRITE_FACING_RIGHT
+ jr z, .pushBoulderRight
+.pushBoulderDown
+ bit 7, b
+ ret z
+ ld de, PushBoulderDownMovementData
+ jr .done
+.pushBoulderUp
+ bit 6, b
+ ret z
+ ld de, PushBoulderUpMovementData
+ jr .done
+.pushBoulderLeft
+ bit 5, b
+ ret z
+ ld de, PushBoulderLeftMovementData
+ jr .done
+.pushBoulderRight
+ bit 4, b
+ ret z
+ ld de, PushBoulderRightMovementData
+.done
+ call MoveSprite
+ ld a, (SFX_02_53 - SFX_Headers_02) / 3
+ call PlaySound
+ ld hl, wFlags_0xcd60
+ set 1, [hl]
+ ret
+
+PushBoulderUpMovementData: ; f2ad (3:72ad)
+ db NPC_MOVEMENT_UP,$FF
+
+PushBoulderDownMovementData: ; f2af (3:72af)
+ db NPC_MOVEMENT_DOWN,$FF
+
+PushBoulderLeftMovementData: ; f2b1 (3:72b1)
+ db NPC_MOVEMENT_LEFT,$FF
+
+PushBoulderRightMovementData: ; f2b3 (3:72b3)
+ db NPC_MOVEMENT_RIGHT,$FF
+
+DoBoulderDustAnimation: ; f2b5 (3:72b5)
+ ld a, [wd730]
+ bit 0, a
+ ret nz
+ callab AnimateBoulderDust
+ call DiscardButtonPresses
+ ld [wJoyIgnore], a
+ call ResetBoulderPushFlags
+ set 7, [hl]
+ ld a, [wBoulderSpriteIndex]
+ ld [H_SPRITEINDEX], a
+ call GetSpriteMovementByte2Pointer
+ ld [hl], $10
+ ld a, (SFX_02_56 - SFX_Headers_02) / 3
+ jp PlaySound
+
+ResetBoulderPushFlags: ; f2dd (3:72dd)
+ ld hl, wFlags_0xcd60
+ res 1, [hl]
+ res 6, [hl]
+ ret
+
+_AddPartyMon: ; f2e5 (3:72e5)
+ ld de, wPartyCount ; wPartyCount
+ ld a, [wcc49]
+ and $f
+ jr z, .asm_f2f2
+ ld de, wEnemyPartyCount ; wEnemyPartyCount
+.asm_f2f2
+ ld a, [de]
+ inc a
+ cp PARTY_LENGTH + 1
+ ret nc
+ ld [de], a
+ ld a, [de]
+ ld [$ffe4], a
+ add e
+ ld e, a
+ jr nc, .asm_f300
+ inc d
+.asm_f300
+ ld a, [wcf91]
+ ld [de], a
+ inc de
+ ld a, $ff
+ ld [de], a
+ ld hl, wPartyMonOT ; wd273
+ ld a, [wcc49]
+ and $f
+ jr z, .asm_f315
+ ld hl, wEnemyMonOT
+.asm_f315
+ ld a, [$ffe4]
+ dec a
+ call SkipFixedLengthTextEntries
+ ld d, h
+ ld e, l
+ ld hl, wPlayerName ; wd158
+ ld bc, $b
+ call CopyData
+ ld a, [wcc49]
+ and a
+ jr nz, .asm_f33f
+ ld hl, wPartyMonNicks ; wPartyMonNicks
+ ld a, [$ffe4]
+ dec a
+ call SkipFixedLengthTextEntries
+ ld a, $2
+ ld [wd07d], a
+ predef AskName
+.asm_f33f
+ ld hl, wPartyMons
+ ld a, [wcc49]
+ and $f
+ jr z, .asm_f34c
+ ld hl, wEnemyMons
+.asm_f34c
+ ld a, [$ffe4]
+ dec a
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld e, l
+ ld d, h
+ push hl
+ ld a, [wcf91]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, W_MONHEADER
+ ld a, [hli]
+ ld [de], a
+ inc de
+ pop hl
+ push hl
+ ld a, [wcc49]
+ and $f
+ ld a, $98 ; set enemy trainer mon IVs to fixed average values
+ ld b, $88
+ jr nz, .writeFreshMonData
+ ld a, [wcf91]
+ ld [wd11e], a
+ push de
+ predef IndexToPokedex
+ pop de
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, $2
+ ld hl, wPokedexOwned ; wPokedexOwned
+ call FlagAction
+ ld a, c
+ ld [wd153], a
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, $1
+ push bc
+ call FlagAction
+ pop bc
+ ld hl, wPokedexSeen ; wd30a
+ call FlagAction
+ pop hl
+ push hl
+ ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ and a
+ jr nz, .copyEnemyMonData
+ call Random ; generate random IVs
+ ld b, a
+ call Random
+.writeFreshMonData ; f3b3
+ push bc
+ ld bc, $1b
+ add hl, bc
+ pop bc
+ ld [hli], a
+ ld [hl], b ; write IVs
+ ld bc, $fff4
+ add hl, bc
+ ld a, $1
+ ld c, a
+ xor a
+ ld b, a
+ call CalcStat ; calc HP stat (set cur Hp to max HP)
+ ld a, [H_MULTIPLICAND+1]
+ ld [de], a
+ inc de
+ ld a, [H_MULTIPLICAND+2]
+ ld [de], a
+ inc de
+ xor a
+ ld [de], a ; level (?)
+ inc de
+ ld [de], a ; status ailments
+ inc de
+ jr .copyMonTypesAndMoves
+.copyEnemyMonData
+ ld bc, $1b
+ add hl, bc
+ ld a, [wEnemyMonDVs] ; copy IVs from cur enemy mon
+ ld [hli], a
+ ld a, [wEnemyMonDVs + 1]
+ ld [hl], a
+ ld a, [wEnemyMonHP] ; copy HP from cur enemy mon
+ ld [de], a
+ inc de
+ ld a, [wEnemyMonHP+1]
+ ld [de], a
+ inc de
+ xor a
+ ld [de], a ; level (?)
+ inc de
+ ld a, [wEnemyMonStatus] ; copy status ailments from cur enemy mon
+ ld [de], a
+ inc de
+.copyMonTypesAndMoves
+ ld hl, W_MONHTYPES
+ ld a, [hli] ; type 1
+ ld [de], a
+ inc de
+ ld a, [hli] ; type 2
+ ld [de], a
+ inc de
+ ld a, [hli] ; unused (?)
+ ld [de], a
+ ld hl, W_MONHMOVES
+ ld a, [hli]
+ inc de
+ push de
+ ld [de], a
+ ld a, [hli]
+ inc de
+ ld [de], a
+ ld a, [hli]
+ inc de
+ ld [de], a
+ ld a, [hli]
+ inc de
+ ld [de], a
+ push de
+ dec de
+ dec de
+ dec de
+ xor a
+ ld [wHPBarMaxHP], a
+ predef WriteMonMoves
+ pop de
+ ld a, [wPlayerID] ; set trainer ID to player ID
+ inc de
+ ld [de], a
+ ld a, [wPlayerID + 1]
+ inc de
+ ld [de], a
+ push de
+ ld a, [W_CURENEMYLVL]
+ ld d, a
+ callab CalcExperience
+ pop de
+ inc de
+ ld a, [H_MULTIPLICAND] ; write experience
+ ld [de], a
+ inc de
+ ld a, [H_MULTIPLICAND+1]
+ ld [de], a
+ inc de
+ ld a, [H_MULTIPLICAND+2]
+ ld [de], a
+ xor a
+ ld b, $a
+.writeEVsLoop ; set all EVs to 0
+ inc de
+ ld [de], a
+ dec b
+ jr nz, .writeEVsLoop
+ inc de
+ inc de
+ pop hl
+ call AddPartyMon_WriteMovePP
+ inc de
+ ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld [de], a
+ inc de
+ ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ dec a
+ jr nz, .calcFreshStats
+ ld hl, wEnemyMonMaxHP ; wEnemyMonMaxHP
+ ld bc, $a
+ call CopyData ; copy stats of cur enemy mon
+ pop hl
+ jr .done
+.calcFreshStats
+ pop hl
+ ld bc, $10
+ add hl, bc
+ ld b, $0
+ call CalcStats ; calculate fresh set of stats
+.done
+ scf
+ ret
+
+LoadMovePPs: ; f473 (3:7473)
+ call GetPredefRegisters
+ ; fallthrough
+AddPartyMon_WriteMovePP: ; f476 (3:7476)
+ ld b, $4
+.pploop
+ ld a, [hli] ; read move ID
+ and a
+ jr z, .empty
+ dec a
+ push hl
+ push de
+ push bc
+ ld hl, Moves
+ ld bc, $6
+ call AddNTimes
+ ld de, wcd6d
+ ld a, BANK(Moves)
+ call FarCopyData
+ pop bc
+ pop de
+ pop hl
+ ld a, [wcd72] ; sixth move byte = pp
+.empty
+ inc de
+ ld [de], a
+ dec b
+ jr nz, .pploop ; there are still moves to read
+ ret
+
+; adds enemy mon [wcf91] (at position [wWhichPokemon] in enemy list) to own party
+; used in the cable club trade center
+_AddEnemyMonToPlayerParty: ; f49d (3:749d)
+ ld hl, wPartyCount
+ ld a, [hl]
+ cp PARTY_LENGTH
+ scf
+ ret z ; party full, return failure
+ inc a
+ ld [hl], a ; add 1 to party members
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [wcf91]
+ ld [hli], a ; add mon as last list entry
+ ld [hl], $ff ; write new sentinel
+ ld hl, wPartyMons
+ ld a, [wPartyCount]
+ dec a
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ld hl, wLoadedMon
+ call CopyData ; write new mon's data (from wLoadedMon)
+ ld hl, wPartyMonOT
+ ld a, [wPartyCount]
+ dec a
+ call SkipFixedLengthTextEntries
+ ld d, h
+ ld e, l
+ ld hl, wEnemyMonOT
+ ld a, [wWhichPokemon]
+ call SkipFixedLengthTextEntries
+ ld bc, $000b
+ call CopyData ; write new mon's OT name (from an enemy mon)
+ ld hl, wPartyMonNicks
+ ld a, [wPartyCount]
+ dec a
+ call SkipFixedLengthTextEntries
+ ld d, h
+ ld e, l
+ ld hl, wEnemyMonNicks
+ ld a, [wWhichPokemon]
+ call SkipFixedLengthTextEntries
+ ld bc, $000b
+ call CopyData ; write new mon's nickname (from an enemy mon)
+ ld a, [wcf91]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, $1
+ ld hl, wPokedexOwned
+ push bc
+ call FlagAction ; add to owned pokemon
+ pop bc
+ ld hl, wPokedexSeen
+ call FlagAction ; add to seen pokemon
+ and a
+ ret ; return success
+
+Func_f51e: ; f51e (3:751e)
+ ld a, [wcf95]
+ and a
+ jr z, .checkPartyMonSlots
+ cp $2
+ jr z, .checkPartyMonSlots
+ cp $3
+ ld hl, wDayCareMon
+ jr z, .asm_f575
+ ld hl, W_NUMINBOX ; wda80
+ ld a, [hl]
+ cp MONS_PER_BOX
+ jr nz, .partyOrBoxNotFull
+ jr .boxFull
+.checkPartyMonSlots
+ ld hl, wPartyCount ; wPartyCount
+ ld a, [hl]
+ cp PARTY_LENGTH
+ jr nz, .partyOrBoxNotFull
+.boxFull
+ scf
+ ret
+.partyOrBoxNotFull
+ inc a
+ ld [hl], a ; increment number of mons in party/box
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [wcf95]
+ cp $2
+ ld a, [wDayCareMon]
+ jr z, .asm_f556
+ ld a, [wcf91]
+.asm_f556
+ ld [hli], a ; write new mon ID
+ ld [hl], $ff ; write new sentinel
+ ld a, [wcf95]
+ dec a
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1 ; $2c
+ ld a, [wPartyCount] ; wPartyCount
+ jr nz, .skipToNewMonEntry
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1 ; $21
+ ld a, [W_NUMINBOX] ; wda80
+.skipToNewMonEntry
+ dec a
+ call AddNTimes
+.asm_f575
+ push hl
+ ld e, l
+ ld d, h
+ ld a, [wcf95]
+ and a
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1 ; $21
+ jr z, .asm_f591
+ cp $2
+ ld hl, wDayCareMon
+ jr z, .asm_f597
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1 ; $2c
+.asm_f591
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call AddNTimes
+.asm_f597
+ push hl
+ push de
+ ld bc, wBoxMon2 - wBoxMon1
+ call CopyData
+ pop de
+ pop hl
+ ld a, [wcf95]
+ and a
+ jr z, .asm_f5b4
+ cp $2
+ jr z, .asm_f5b4
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc
+ ld a, [hl]
+ inc de
+ inc de
+ inc de
+ ld [de], a
+.asm_f5b4
+ ld a, [wcf95]
+ cp $3
+ ld de, W_DAYCAREMONOT
+ jr z, .asm_f5d3
+ dec a
+ ld hl, wPartyMonOT ; wd273
+ ld a, [wPartyCount] ; wPartyCount
+ jr nz, .asm_f5cd
+ ld hl, wBoxMonOT
+ ld a, [W_NUMINBOX] ; wda80
+.asm_f5cd
+ dec a
+ call SkipFixedLengthTextEntries
+ ld d, h
+ ld e, l
+.asm_f5d3
+ ld hl, wBoxMonOT
+ ld a, [wcf95]
+ and a
+ jr z, .asm_f5e6
+ ld hl, W_DAYCAREMONOT
+ cp $2
+ jr z, .asm_f5ec
+ ld hl, wPartyMonOT ; wd273
+.asm_f5e6
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call SkipFixedLengthTextEntries
+.asm_f5ec
+ ld bc, $b
+ call CopyData
+ ld a, [wcf95]
+ cp $3
+ ld de, W_DAYCAREMONNAME
+ jr z, .asm_f611
+ dec a
+ ld hl, wPartyMonNicks ; wPartyMonNicks
+ ld a, [wPartyCount] ; wPartyCount
+ jr nz, .asm_f60b
+ ld hl, wBoxMonNicks
+ ld a, [W_NUMINBOX] ; wda80
+.asm_f60b
+ dec a
+ call SkipFixedLengthTextEntries
+ ld d, h
+ ld e, l
+.asm_f611
+ ld hl, wBoxMonNicks
+ ld a, [wcf95]
+ and a
+ jr z, .asm_f624
+ ld hl, W_DAYCAREMONNAME
+ cp $2
+ jr z, .asm_f62a
+ ld hl, wPartyMonNicks ; wPartyMonNicks
+.asm_f624
+ ld a, [wWhichPokemon] ; wWhichPokemon
+ call SkipFixedLengthTextEntries
+.asm_f62a
+ ld bc, $b
+ call CopyData
+ pop hl
+ ld a, [wcf95]
+ cp $1
+ jr z, .asm_f664
+ cp $3
+ jr z, .asm_f664
+ push hl
+ srl a
+ add $2
+ ld [wcc49], a
+ call LoadMonData
+ callba CalcLevelFromExperience
+ ld a, d
+ ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
+ pop hl
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc
+ ld [hli], a
+ ld d, h
+ ld e, l
+ ld bc, $ffee
+ add hl, bc
+ ld b, $1
+ call CalcStats
+.asm_f664
+ and a
+ ret
+
+
+FlagActionPredef:
+ call GetPredefRegisters
+
+FlagAction:
+; Perform action b on bit c
+; in the bitfield at hl.
+; 0: reset
+; 1: set
+; 2: read
+; Return the result in c.
+
+ push hl
+ push de
+ push bc
+
+ ; bit
+ ld a, c
+ ld d, a
+ and 7
+ ld e, a
+
+ ; byte
+ ld a, d
+ srl a
+ srl a
+ srl a
+ add l
+ ld l, a
+ jr nc, .ok
+ inc h
+.ok
+
+ ; d = 1 << e (bitmask)
+ inc e
+ ld d, 1
+.shift
+ dec e
+ jr z, .shifted
+ sla d
+ jr .shift
+.shifted
+
+ ld a, b
+ and a
+ jr z, .reset
+ cp 2
+ jr z, .read
+
+.set
+ ld b, [hl]
+ ld a, d
+ or b
+ ld [hl], a
+ jr .done
+
+.reset
+ ld b, [hl]
+ ld a, d
+ xor $ff
+ and b
+ ld [hl], a
+ jr .done
+
+.read
+ ld b, [hl]
+ ld a, d
+ and b
+.done
+ pop bc
+ pop de
+ pop hl
+ ld c, a
+ ret
+
+
+HealParty:
+; Restore HP and PP.
+
+ ld hl, wPartySpecies
+ ld de, wPartyMon1HP
+.healmon
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+
+ push hl
+ push de
+
+ ld hl, wPartyMon1Status - wPartyMon1HP
+ add hl, de
+ xor a
+ ld [hl], a
+
+ push de
+ ld b, NUM_MOVES ; A Pokémon has 4 moves
+.pp
+ ld hl, wPartyMon1Moves - wPartyMon1HP
+ add hl, de
+
+ ld a, [hl]
+ and a
+ jr z, .nextmove
+
+ dec a
+ ld hl, wPartyMon1PP - wPartyMon1HP
+ add hl, de
+
+ push hl
+ push de
+ push bc
+
+ ld hl, Moves
+ ld bc, $0006
+ call AddNTimes
+ ld de, wcd6d
+ ld a, BANK(Moves)
+ call FarCopyData
+ ld a, [wcd72] ; default pp
+
+ pop bc
+ pop de
+ pop hl
+
+ inc de
+ push bc
+ ld b, a
+ ld a, [hl]
+ and $c0
+ add b
+ ld [hl], a
+ pop bc
+
+.nextmove
+ dec b
+ jr nz, .pp
+ pop de
+
+ ld hl, wPartyMon1MaxHP - wPartyMon1HP
+ add hl, de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+
+ pop de
+ pop hl
+
+ push hl
+ ld bc, wPartyMon2 - wPartyMon1
+ ld h, d
+ ld l, e
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ jr .healmon
+
+.done
+ xor a
+ ld [wWhichPokemon], a
+ ld [wd11e], a
+
+ ld a, [wPartyCount]
+ ld b, a
+.ppup
+ push bc
+ call RestoreBonusPP
+ pop bc
+ ld hl, wWhichPokemon
+ inc [hl]
+ dec b
+ jr nz, .ppup
+ ret
+
+
+DivideBCDPredef::
+DivideBCDPredef2::
+DivideBCDPredef3::
+DivideBCDPredef4::
+ call GetPredefRegisters
+
+DivideBCD::
+ xor a
+ ld [$ffa5], a
+ ld [$ffa6], a
+ ld [$ffa7], a
+ ld d, $1
+.asm_f72a
+ ld a, [$ffa2]
+ and $f0
+ jr nz, .asm_f75b
+ inc d
+ ld a, [$ffa2]
+ swap a
+ and $f0
+ ld b, a
+ ld a, [$ffa3]
+ swap a
+ ld [$ffa3], a
+ and $f
+ or b
+ ld [$ffa2], a
+ ld a, [$ffa3]
+ and $f0
+ ld b, a
+ ld a, [$ffa4]
+ swap a
+ ld [$ffa4], a
+ and $f
+ or b
+ ld [$ffa3], a
+ ld a, [$ffa4]
+ and $f0
+ ld [$ffa4], a
+ jr .asm_f72a
+.asm_f75b
+ push de
+ push de
+ call Func_f800
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ld [$ffa5], a
+ dec d
+ jr z, .asm_f7bc
+ push de
+ call Func_f7d7
+ call Func_f800
+ pop de
+ ld a, [$ffa5]
+ or b
+ ld [$ffa5], a
+ dec d
+ jr z, .asm_f7bc
+ push de
+ call Func_f7d7
+ call Func_f800
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ld [$ffa6], a
+ dec d
+ jr z, .asm_f7bc
+ push de
+ call Func_f7d7
+ call Func_f800
+ pop de
+ ld a, [$ffa6]
+ or b
+ ld [$ffa6], a
+ dec d
+ jr z, .asm_f7bc
+ push de
+ call Func_f7d7
+ call Func_f800
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ld [$ffa7], a
+ dec d
+ jr z, .asm_f7bc
+ push de
+ call Func_f7d7
+ call Func_f800
+ pop de
+ ld a, [$ffa7]
+ or b
+ ld [$ffa7], a
+.asm_f7bc
+ ld a, [$ffa5]
+ ld [$ffa2], a
+ ld a, [$ffa6]
+ ld [$ffa3], a
+ ld a, [$ffa7]
+ ld [$ffa4], a
+ pop de
+ ld a, $6
+ sub d
+ and a
+ ret z
+.asm_f7ce
+ push af
+ call Func_f7d7
+ pop af
+ dec a
+ jr nz, .asm_f7ce
+ ret
+
+Func_f7d7: ; f7d7 (3:77d7)
+ ld a, [$ffa4]
+ swap a
+ and $f
+ ld b, a
+ ld a, [$ffa3]
+ swap a
+ ld [$ffa3], a
+ and $f0
+ or b
+ ld [$ffa4], a
+ ld a, [$ffa3]
+ and $f
+ ld b, a
+ ld a, [$ffa2]
+ swap a
+ ld [$ffa2], a
+ and $f0
+ or b
+ ld [$ffa3], a
+ ld a, [$ffa2]
+ and $f
+ ld [$ffa2], a
+ ret
+
+Func_f800: ; f800 (3:7800)
+ ld bc, $3
+.asm_f803
+ ld de, $ff9f
+ ld hl, $ffa2
+ push bc
+ call StringCmp
+ pop bc
+ ret c
+ inc b
+ ld de, $ffa1
+ ld hl, $ffa4
+ push bc
+ call SubBCD
+ pop bc
+ jr .asm_f803
+
+
+AddBCDPredef::
+ call GetPredefRegisters
+
+AddBCD::
+ and a
+ ld b, c
+.add
+ ld a, [de]
+ adc [hl]
+ daa
+ ld [de], a
+ dec de
+ dec hl
+ dec c
+ jr nz, .add
+ jr nc, .done
+ ld a, $99
+ inc de
+.fill
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .fill
+.done
+ ret
+
+
+SubBCDPredef::
+ call GetPredefRegisters
+
+SubBCD::
+ and a
+ ld b, c
+.sub
+ ld a, [de]
+ sbc [hl]
+ daa
+ ld [de], a
+ dec de
+ dec hl
+ dec c
+ jr nz, .sub
+ jr nc, .done
+ ld a, $00
+ inc de
+.fill
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .fill
+ scf
+.done
+ ret
+
+
+InitPlayerData:
+InitPlayerData2:
+
+ call Random
+ ld a, [hRandomSub]
+ ld [wPlayerID], a
+
+ call Random
+ ld a, [hRandomAdd]
+ ld [wPlayerID + 1], a
+
+ ld a, $ff
+ ld [wd71b], a ; XXX what's this?
+
+ ld hl, wPartyCount
+ call InitializeEmptyList
+ ld hl, W_NUMINBOX
+ call InitializeEmptyList
+ ld hl, wNumBagItems
+ call InitializeEmptyList
+ ld hl, wNumBoxItems
+ call InitializeEmptyList
+
+START_MONEY EQU $3000
+ ld hl, wPlayerMoney + 1
+ ld a, START_MONEY / $100
+ ld [hld], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld [hl], a
+
+ ld [wcc49], a
+
+ ld hl, W_OBTAINEDBADGES
+ ld [hli], a
+
+ ld [hl], a
+
+ ld hl, wPlayerCoins
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, W_GAMEPROGRESSFLAGS
+ ld bc, $c8
+ call FillMemory ; clear all game progress flags
+
+ jp InitializeMissableObjectsFlags
+
+InitializeEmptyList:
+ xor a ; count
+ ld [hli], a
+ dec a ; terminator
+ ld [hl], a
+ ret
+
+
+IsItemInBag_: ; f8a5 (3:78a5)
+ call GetPredefRegisters
+ ld hl, wNumBagItems ; wNumBagItems
+.asm_f8ab
+ inc hl
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_f8b7
+ cp b
+ jr nz, .asm_f8ab
+ ld a, [hl]
+ ld b, a
+ ret
+.asm_f8b7
+ ld b, $0
+ ret
+
+FindPathToPlayer: ; f8ba (3:78ba)
+ xor a
+ ld hl, $ff97
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wNPCMovementDirections2
+ ld de, $0
+.loop
+ ld a, [$ff99]
+ ld b, a
+ ld a, [$ff95] ; Y distance in steps
+ call CalcDifference
+ ld d, a
+ and a
+ jr nz, .asm_f8da
+ ld a, [$ff98]
+ set 0, a
+ ld [$ff98], a
+.asm_f8da
+ ld a, [$ff9a]
+ ld b, a
+ ld a, [$ff96] ; X distance in steps
+ call CalcDifference
+ ld e, a
+ and a
+ jr nz, .asm_f8ec
+ ld a, [$ff98]
+ set 1, a
+ ld [$ff98], a
+.asm_f8ec
+ ld a, [$ff98]
+ cp $3
+ jr z, .done
+ ld a, e
+ cp d
+ jr c, .asm_f90a
+ ld a, [$ff9d]
+ bit 1, a
+ jr nz, .asm_f900
+ ld d, NPC_MOVEMENT_RIGHT
+ jr .asm_f902
+.asm_f900
+ ld d, NPC_MOVEMENT_LEFT
+.asm_f902
+ ld a, [$ff9a]
+ add $1
+ ld [$ff9a], a
+ jr .asm_f91c
+.asm_f90a
+ ld a, [$ff9d]
+ bit 0, a
+ jr nz, .asm_f914
+ ld d, NPC_MOVEMENT_DOWN
+ jr .asm_f916
+.asm_f914
+ ld d, NPC_MOVEMENT_UP
+.asm_f916
+ ld a, [$ff99]
+ add $1
+ ld [$ff99], a
+.asm_f91c
+ ld a, d
+ ld [hli], a
+ ld a, [$ff97]
+ inc a
+ ld [$ff97], a
+ jp .loop
+.done
+ ld [hl], $ff
+ ret
+
+CalcPositionOfPlayerRelativeToNPC: ; f929 (3:7929)
+ xor a
+ ld [$ff9d], a
+ ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels
+ ld d, a
+ ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels
+ ld e, a
+ ld hl, wSpriteStateData1
+ ld a, [$ff95] ; sprite offset
+ add l
+ add $4
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld a, d
+ ld b, a
+ ld a, [hli] ; NPC sprite screen Y position in pixels
+ call CalcDifference
+ jr nc, .NPCSouthOfOrAlignedWithPlayer
+.NPCNorthOfPlayer
+ push hl
+ ld hl, $ff9d
+ bit 0, [hl]
+ set 0, [hl]
+ pop hl
+ jr .divideYDistance
+.NPCSouthOfOrAlignedWithPlayer
+ push hl
+ ld hl, $ff9d
+ bit 0, [hl]
+ res 0, [hl]
+ pop hl
+.divideYDistance
+ push hl
+ ld hl, $ffe5
+ ld [hli], a
+ ld a, 16
+ ld [hli], a
+ call DivideBytes ; divide Y absolute distance by 16
+ ld a, [hl] ; quotient
+ ld [$ff95], a
+ pop hl
+ inc hl
+ ld b, e
+ ld a, [hl] ; NPC sprite screen X position in pixels
+ call CalcDifference
+ jr nc, .NPCEastOfOrAlignedWithPlayer
+.NPCWestOfPlayer
+ push hl
+ ld hl, $ff9d
+ bit 1, [hl]
+ set 1, [hl]
+ pop hl
+ jr .divideXDistance
+.NPCEastOfOrAlignedWithPlayer
+ push hl
+ ld hl, $ff9d
+ bit 1, [hl]
+ res 1, [hl]
+ pop hl
+.divideXDistance
+ ld [$ffe5], a
+ ld a, 16
+ ld [$ffe6], a
+ call DivideBytes ; divide X absolute distance by 16
+ ld a, [$ffe7] ; quotient
+ ld [$ff96], a
+ ld a, [$ff9b]
+ and a
+ ret z
+ ld a, [$ff9d]
+ cpl
+ and $3
+ ld [$ff9d], a
+ ret
+
+ConvertNPCMovementDirectionsToJoypadMasks: ; f9a0 (3:79a0)
+ ld a, [$ff95]
+ ld [wNPCMovementDirections2Index], a
+ dec a
+ ld de, wSimulatedJoypadStatesEnd
+ ld hl, wNPCMovementDirections2
+ add l
+ ld l, a
+ jr nc, .loop
+ inc h
+.loop
+ ld a, [hld]
+ call ConvertNPCMovementDirectionToJoypadMask
+ ld [de], a
+ inc de
+ ld a, [$ff95]
+ dec a
+ ld [$ff95], a
+ jr nz, .loop
+ ret
+
+ConvertNPCMovementDirectionToJoypadMask: ; f9bf (3:79bf)
+ push hl
+ ld b, a
+ ld hl, NPCMovementDirectionsToJoypadMasksTable
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ cp b
+ jr z, .loadJoypadMask
+ inc hl
+ jr .loop
+.loadJoypadMask
+ ld a, [hl]
+.done
+ pop hl
+ ret
+
+NPCMovementDirectionsToJoypadMasksTable: ; f9d2 (3:79d2)
+ db NPC_MOVEMENT_UP, D_UP
+ db NPC_MOVEMENT_DOWN, D_DOWN
+ db NPC_MOVEMENT_LEFT, D_LEFT
+ db NPC_MOVEMENT_RIGHT, D_RIGHT
+ db $ff
+
+Func_f9db: ; f9db (3:79db)
+ ret
+
+INCLUDE "engine/hp_bar.asm"
+
+INCLUDE "engine/hidden_object_functions3.asm"
+
+
+SECTION "NPC Sprites 1", ROMX, BANK[NPC_SPRITES_1]
+
+OakAideSprite: INCBIN "gfx/sprites/oak_aide.2bpp"
+RockerSprite: INCBIN "gfx/sprites/rocker.2bpp"
+SwimmerSprite: INCBIN "gfx/sprites/swimmer.2bpp"
+WhitePlayerSprite: INCBIN "gfx/sprites/white_player.2bpp"
+GymHelperSprite: INCBIN "gfx/sprites/gym_helper.2bpp"
+OldPersonSprite: INCBIN "gfx/sprites/old_person.2bpp"
+MartGuySprite: INCBIN "gfx/sprites/mart_guy.2bpp"
+FisherSprite: INCBIN "gfx/sprites/fisher.2bpp"
+OldMediumWomanSprite: INCBIN "gfx/sprites/old_medium_woman.2bpp"
+NurseSprite: INCBIN "gfx/sprites/nurse.2bpp"
+CableClubWomanSprite: INCBIN "gfx/sprites/cable_club_woman.2bpp"
+MrMasterballSprite: INCBIN "gfx/sprites/mr_masterball.2bpp"
+LaprasGiverSprite: INCBIN "gfx/sprites/lapras_giver.2bpp"
+WardenSprite: INCBIN "gfx/sprites/warden.2bpp"
+SsCaptainSprite: INCBIN "gfx/sprites/ss_captain.2bpp"
+Fisher2Sprite: INCBIN "gfx/sprites/fisher2.2bpp"
+BlackbeltSprite: INCBIN "gfx/sprites/blackbelt.2bpp"
+GuardSprite: INCBIN "gfx/sprites/guard.2bpp"
+BallSprite: INCBIN "gfx/sprites/ball.2bpp"
+OmanyteSprite: INCBIN "gfx/sprites/omanyte.2bpp"
+BoulderSprite: INCBIN "gfx/sprites/boulder.2bpp"
+PaperSheetSprite: INCBIN "gfx/sprites/paper_sheet.2bpp"
+BookMapDexSprite: INCBIN "gfx/sprites/book_map_dex.2bpp"
+ClipboardSprite: INCBIN "gfx/sprites/clipboard.2bpp"
+SnorlaxSprite: INCBIN "gfx/sprites/snorlax.2bpp"
+OldAmberSprite: INCBIN "gfx/sprites/old_amber.2bpp"
+LyingOldManSprite: INCBIN "gfx/sprites/lying_old_man.2bpp"
+
+
+SECTION "Graphics", ROMX, BANK[GFX]
+
+PokemonLogoGraphics: INCBIN "gfx/pokemon_logo.2bpp"
+FontGraphics: INCBIN "gfx/font.1bpp"
+ABTiles: INCBIN "gfx/AB.2bpp"
+HpBarAndStatusGraphics: INCBIN "gfx/hp_bar_and_status.2bpp"
+BattleHudTiles1: INCBIN "gfx/battle_hud1.1bpp"
+BattleHudTiles2: INCBIN "gfx/battle_hud2.1bpp"
+BattleHudTiles3: INCBIN "gfx/battle_hud3.1bpp"
+NintendoCopyrightLogoGraphics: INCBIN "gfx/copyright.2bpp"
+GamefreakLogoGraphics: INCBIN "gfx/gamefreak.2bpp"
+TextBoxGraphics: INCBIN "gfx/text_box.2bpp"
+PokedexTileGraphics: INCBIN "gfx/pokedex.2bpp"
+WorldMapTileGraphics: INCBIN "gfx/town_map.2bpp"
+PlayerCharacterTitleGraphics: INCBIN "gfx/player_title.2bpp"
+
+
+SECTION "Battle (bank 4)", ROMX, BANK[$4]
+
+INCLUDE "engine/overworld/is_player_just_outside_map.asm"
+INCLUDE "engine/menu/status_screen.asm"
+INCLUDE "engine/menu/party_menu.asm"
+
+RedPicFront:: INCBIN "pic/trainer/red.pic"
+ShrinkPic1:: INCBIN "pic/trainer/shrink1.pic"
+ShrinkPic2:: INCBIN "pic/trainer/shrink2.pic"
+
+INCLUDE "engine/turn_sprite.asm"
+INCLUDE "engine/menu/start_sub_menus.asm"
+INCLUDE "engine/items/tms.asm"
+INCLUDE "engine/battle/end_of_battle.asm"
+INCLUDE "engine/battle/wild_encounters.asm"
+INCLUDE "engine/battle/moveEffects/recoil_effect.asm"
+INCLUDE "engine/battle/moveEffects/conversion_effect.asm"
+INCLUDE "engine/battle/moveEffects/haze_effect.asm"
+INCLUDE "engine/battle/get_trainer_name.asm"
+
+
+SECTION "NPC Sprites 2", ROMX, BANK[NPC_SPRITES_2]
+
+RedCyclingSprite: INCBIN "gfx/sprites/cycling.2bpp"
+RedSprite: INCBIN "gfx/sprites/red.2bpp"
+BlueSprite: INCBIN "gfx/sprites/blue.2bpp"
+OakSprite: INCBIN "gfx/sprites/oak.2bpp"
+BugCatcherSprite: INCBIN "gfx/sprites/bug_catcher.2bpp"
+SlowbroSprite: INCBIN "gfx/sprites/slowbro.2bpp"
+LassSprite: INCBIN "gfx/sprites/lass.2bpp"
+BlackHairBoy1Sprite: INCBIN "gfx/sprites/black_hair_boy_1.2bpp"
+LittleGirlSprite: INCBIN "gfx/sprites/little_girl.2bpp"
+BirdSprite: INCBIN "gfx/sprites/bird.2bpp"
+FatBaldGuySprite: INCBIN "gfx/sprites/fat_bald_guy.2bpp"
+GamblerSprite: INCBIN "gfx/sprites/gambler.2bpp"
+BlackHairBoy2Sprite: INCBIN "gfx/sprites/black_hair_boy_2.2bpp"
+GirlSprite: INCBIN "gfx/sprites/girl.2bpp"
+HikerSprite: INCBIN "gfx/sprites/hiker.2bpp"
+FoulardWomanSprite: INCBIN "gfx/sprites/foulard_woman.2bpp"
+GentlemanSprite: INCBIN "gfx/sprites/gentleman.2bpp"
+DaisySprite: INCBIN "gfx/sprites/daisy.2bpp"
+BikerSprite: INCBIN "gfx/sprites/biker.2bpp"
+SailorSprite: INCBIN "gfx/sprites/sailor.2bpp"
+CookSprite: INCBIN "gfx/sprites/cook.2bpp"
+BikeShopGuySprite: INCBIN "gfx/sprites/bike_shop_guy.2bpp"
+MrFujiSprite: INCBIN "gfx/sprites/mr_fuji.2bpp"
+GiovanniSprite: INCBIN "gfx/sprites/giovanni.2bpp"
+RocketSprite: INCBIN "gfx/sprites/rocket.2bpp"
+MediumSprite: INCBIN "gfx/sprites/medium.2bpp"
+WaiterSprite: INCBIN "gfx/sprites/waiter.2bpp"
+ErikaSprite: INCBIN "gfx/sprites/erika.2bpp"
+MomGeishaSprite: INCBIN "gfx/sprites/mom_geisha.2bpp"
+BrunetteGirlSprite: INCBIN "gfx/sprites/brunette_girl.2bpp"
+LanceSprite: INCBIN "gfx/sprites/lance.2bpp"
+MomSprite: INCBIN "gfx/sprites/mom.2bpp"
+BaldingGuySprite: INCBIN "gfx/sprites/balding_guy.2bpp"
+YoungBoySprite: INCBIN "gfx/sprites/young_boy.2bpp"
+GameboyKidSprite: INCBIN "gfx/sprites/gameboy_kid.2bpp"
+ClefairySprite: INCBIN "gfx/sprites/clefairy.2bpp"
+AgathaSprite: INCBIN "gfx/sprites/agatha.2bpp"
+BrunoSprite: INCBIN "gfx/sprites/bruno.2bpp"
+LoreleiSprite: INCBIN "gfx/sprites/lorelei.2bpp"
+SeelSprite: INCBIN "gfx/sprites/seel.2bpp"
+
+
+SECTION "Battle (bank 5)", ROMX, BANK[$5]
+
+INCLUDE "engine/load_pokedex_tiles.asm"
+INCLUDE "engine/overworld/map_sprites.asm"
+INCLUDE "engine/overworld/emotion_bubbles.asm"
+INCLUDE "engine/evolve_trade.asm"
+INCLUDE "engine/battle/moveEffects/substitute_effect.asm"
+INCLUDE "engine/menu/pc.asm"
+
+
+SECTION "bank6",ROMX,BANK[$6]
+
+INCLUDE "data/mapHeaders/celadoncity.asm"
+INCLUDE "data/mapObjects/celadoncity.asm"
+CeladonCityBlocks: INCBIN "maps/celadoncity.blk"
+
+INCLUDE "data/mapHeaders/pallettown.asm"
+INCLUDE "data/mapObjects/pallettown.asm"
+PalletTownBlocks: INCBIN "maps/pallettown.blk"
+
+INCLUDE "data/mapHeaders/viridiancity.asm"
+INCLUDE "data/mapObjects/viridiancity.asm"
+ViridianCityBlocks: INCBIN "maps/viridiancity.blk"
+
+INCLUDE "data/mapHeaders/pewtercity.asm"
+INCLUDE "data/mapObjects/pewtercity.asm"
+PewterCityBlocks: INCBIN "maps/pewtercity.blk"
+
+INCLUDE "data/mapHeaders/ceruleancity.asm"
+INCLUDE "data/mapObjects/ceruleancity.asm"
+CeruleanCityBlocks: INCBIN "maps/ceruleancity.blk"
+
+INCLUDE "data/mapHeaders/vermilioncity.asm"
+INCLUDE "data/mapObjects/vermilioncity.asm"
+VermilionCityBlocks: INCBIN "maps/vermilioncity.blk"
+
+INCLUDE "data/mapHeaders/fuchsiacity.asm"
+INCLUDE "data/mapObjects/fuchsiacity.asm"
+FuchsiaCityBlocks: INCBIN "maps/fuchsiacity.blk"
+
+INCLUDE "engine/play_time.asm"
+
+INCLUDE "scripts/pallettown.asm"
+INCLUDE "scripts/viridiancity.asm"
+INCLUDE "scripts/pewtercity.asm"
+INCLUDE "scripts/ceruleancity.asm"
+INCLUDE "scripts/vermilioncity.asm"
+INCLUDE "scripts/celadoncity.asm"
+INCLUDE "scripts/fuchsiacity.asm"
+
+INCLUDE "data/mapHeaders/blueshouse.asm"
+INCLUDE "scripts/blueshouse.asm"
+INCLUDE "data/mapObjects/blueshouse.asm"
+BluesHouseBlocks: INCBIN "maps/blueshouse.blk"
+
+INCLUDE "data/mapHeaders/vermilionhouse3.asm"
+INCLUDE "scripts/vermilionhouse3.asm"
+INCLUDE "data/mapObjects/vermilionhouse3.asm"
+VermilionHouse3Blocks: INCBIN "maps/vermilionhouse3.blk"
+
+INCLUDE "data/mapHeaders/indigoplateaulobby.asm"
+INCLUDE "scripts/indigoplateaulobby.asm"
+INCLUDE "data/mapObjects/indigoplateaulobby.asm"
+IndigoPlateauLobbyBlocks: INCBIN "maps/indigoplateaulobby.blk"
+
+INCLUDE "data/mapHeaders/silphco4.asm"
+INCLUDE "scripts/silphco4.asm"
+INCLUDE "data/mapObjects/silphco4.asm"
+SilphCo4Blocks: INCBIN "maps/silphco4.blk"
+
+INCLUDE "data/mapHeaders/silphco5.asm"
+INCLUDE "scripts/silphco5.asm"
+INCLUDE "data/mapObjects/silphco5.asm"
+SilphCo5Blocks: INCBIN "maps/silphco5.blk"
+
+INCLUDE "data/mapHeaders/silphco6.asm"
+INCLUDE "scripts/silphco6.asm"
+INCLUDE "data/mapObjects/silphco6.asm"
+SilphCo6Blocks: INCBIN "maps/silphco6.blk"
+
+INCLUDE "engine/overworld/npc_movement.asm"
+INCLUDE "engine/overworld/doors.asm"
+INCLUDE "engine/overworld/ledges.asm"
+
+
+SECTION "bank7",ROMX,BANK[$7]
+
+INCLUDE "data/mapHeaders/cinnabarisland.asm"
+INCLUDE "data/mapObjects/cinnabarisland.asm"
+CinnabarIslandBlocks: INCBIN "maps/cinnabarisland.blk"
+
+INCLUDE "data/mapHeaders/route1.asm"
+INCLUDE "data/mapObjects/route1.asm"
+Route1Blocks: INCBIN "maps/route1.blk"
+
+UndergroundPathEntranceRoute8Blocks: INCBIN "maps/undergroundpathentranceroute8.blk"
+
+OaksLabBlocks: INCBIN "maps/oakslab.blk"
+
+Route16HouseBlocks:
+Route2HouseBlocks:
+SaffronHouse1Blocks:
+SaffronHouse2Blocks:
+VermilionHouse1Blocks:
+NameRaterBlocks:
+LavenderHouse1Blocks:
+LavenderHouse2Blocks:
+CeruleanHouse1Blocks:
+PewterHouse1Blocks:
+PewterHouse2Blocks:
+ViridianHouseBlocks: INCBIN "maps/viridianhouse.blk"
+
+CeladonMansion5Blocks:
+SchoolBlocks: INCBIN "maps/school.blk"
+
+CeruleanHouseTrashedBlocks: INCBIN "maps/ceruleanhousetrashed.blk"
+
+DiglettsCaveEntranceRoute11Blocks:
+DiglettsCaveRoute2Blocks: INCBIN "maps/diglettscaveroute2.blk"
+
+INCLUDE "text/monster_names.asm"
+
+INCLUDE "engine/clear_save.asm"
+
+INCLUDE "engine/predefs7.asm"
+
+INCLUDE "scripts/cinnabarisland.asm"
+
+INCLUDE "scripts/route1.asm"
+
+INCLUDE "data/mapHeaders/oakslab.asm"
+INCLUDE "scripts/oakslab.asm"
+INCLUDE "data/mapObjects/oakslab.asm"
+
+INCLUDE "data/mapHeaders/viridianmart.asm"
+INCLUDE "scripts/viridianmart.asm"
+INCLUDE "data/mapObjects/viridianmart.asm"
+ViridianMartBlocks: INCBIN "maps/viridianmart.blk"
+
+INCLUDE "data/mapHeaders/school.asm"
+INCLUDE "scripts/school.asm"
+INCLUDE "data/mapObjects/school.asm"
+
+INCLUDE "data/mapHeaders/viridianhouse.asm"
+INCLUDE "scripts/viridianhouse.asm"
+INCLUDE "data/mapObjects/viridianhouse.asm"
+
+INCLUDE "data/mapHeaders/pewterhouse1.asm"
+INCLUDE "scripts/pewterhouse1.asm"
+INCLUDE "data/mapObjects/pewterhouse1.asm"
+
+INCLUDE "data/mapHeaders/pewterhouse2.asm"
+INCLUDE "scripts/pewterhouse2.asm"
+INCLUDE "data/mapObjects/pewterhouse2.asm"
+
+INCLUDE "data/mapHeaders/ceruleanhousetrashed.asm"
+INCLUDE "scripts/ceruleanhousetrashed.asm"
+INCLUDE "data/mapObjects/ceruleanhousetrashed.asm"
+
+INCLUDE "data/mapHeaders/ceruleanhouse1.asm"
+INCLUDE "scripts/ceruleanhouse1.asm"
+INCLUDE "data/mapObjects/ceruleanhouse1.asm"
+
+INCLUDE "data/mapHeaders/bikeshop.asm"
+INCLUDE "scripts/bikeshop.asm"
+INCLUDE "data/mapObjects/bikeshop.asm"
+BikeShopBlocks: INCBIN "maps/bikeshop.blk"
+
+INCLUDE "data/mapHeaders/lavenderhouse1.asm"
+INCLUDE "scripts/lavenderhouse1.asm"
+INCLUDE "data/mapObjects/lavenderhouse1.asm"
+
+INCLUDE "data/mapHeaders/lavenderhouse2.asm"
+INCLUDE "scripts/lavenderhouse2.asm"
+INCLUDE "data/mapObjects/lavenderhouse2.asm"
+
+INCLUDE "data/mapHeaders/namerater.asm"
+INCLUDE "scripts/namerater.asm"
+INCLUDE "data/mapObjects/namerater.asm"
+
+INCLUDE "data/mapHeaders/vermilionhouse1.asm"
+INCLUDE "scripts/vermilionhouse1.asm"
+INCLUDE "data/mapObjects/vermilionhouse1.asm"
+
+INCLUDE "data/mapHeaders/vermiliondock.asm"
+INCLUDE "scripts/vermiliondock.asm"
+INCLUDE "data/mapObjects/vermiliondock.asm"
+VermilionDockBlocks: INCBIN "maps/vermiliondock.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion5.asm"
+INCLUDE "scripts/celadonmansion5.asm"
+INCLUDE "data/mapObjects/celadonmansion5.asm"
+
+INCLUDE "data/mapHeaders/fuchsiamart.asm"
+INCLUDE "scripts/fuchsiamart.asm"
+INCLUDE "data/mapObjects/fuchsiamart.asm"
+FuchsiaMartBlocks: INCBIN "maps/fuchsiamart.blk"
+
+INCLUDE "data/mapHeaders/saffronhouse1.asm"
+INCLUDE "scripts/saffronhouse1.asm"
+INCLUDE "data/mapObjects/saffronhouse1.asm"
+
+INCLUDE "data/mapHeaders/saffronhouse2.asm"
+INCLUDE "scripts/saffronhouse2.asm"
+INCLUDE "data/mapObjects/saffronhouse2.asm"
+
+INCLUDE "data/mapHeaders/diglettscaveroute2.asm"
+INCLUDE "scripts/diglettscaveroute2.asm"
+INCLUDE "data/mapObjects/diglettscaveroute2.asm"
+
+INCLUDE "data/mapHeaders/route2house.asm"
+INCLUDE "scripts/route2house.asm"
+INCLUDE "data/mapObjects/route2house.asm"
+
+INCLUDE "data/mapHeaders/route5gate.asm"
+INCLUDE "scripts/route5gate.asm"
+INCLUDE "data/mapObjects/route5gate.asm"
+Route5GateBlocks: INCBIN "maps/route5gate.blk"
+
+INCLUDE "data/mapHeaders/route6gate.asm"
+INCLUDE "scripts/route6gate.asm"
+INCLUDE "data/mapObjects/route6gate.asm"
+Route6GateBlocks: INCBIN "maps/route6gate.blk"
+
+INCLUDE "data/mapHeaders/route7gate.asm"
+INCLUDE "scripts/route7gate.asm"
+INCLUDE "data/mapObjects/route7gate.asm"
+Route7GateBlocks: INCBIN "maps/route7gate.blk"
+
+INCLUDE "data/mapHeaders/route8gate.asm"
+INCLUDE "scripts/route8gate.asm"
+INCLUDE "data/mapObjects/route8gate.asm"
+Route8GateBlocks: INCBIN "maps/route8gate.blk"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute8.asm"
+INCLUDE "scripts/undergroundpathentranceroute8.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute8.asm"
+
+INCLUDE "data/mapHeaders/powerplant.asm"
+INCLUDE "scripts/powerplant.asm"
+INCLUDE "data/mapObjects/powerplant.asm"
+PowerPlantBlocks: INCBIN "maps/powerplant.blk"
+
+INCLUDE "data/mapHeaders/diglettscaveroute11.asm"
+INCLUDE "scripts/diglettscaveroute11.asm"
+INCLUDE "data/mapObjects/diglettscaveroute11.asm"
+
+INCLUDE "data/mapHeaders/route16house.asm"
+INCLUDE "scripts/route16house.asm"
+INCLUDE "data/mapObjects/route16house.asm"
+
+INCLUDE "data/mapHeaders/route22gate.asm"
+INCLUDE "scripts/route22gate.asm"
+INCLUDE "data/mapObjects/route22gate.asm"
+Route22GateBlocks: INCBIN "maps/route22gate.blk"
+
+INCLUDE "data/mapHeaders/billshouse.asm"
+INCLUDE "scripts/billshouse.asm"
+INCLUDE "data/mapObjects/billshouse.asm"
+BillsHouseBlocks: INCBIN "maps/billshouse.blk"
+IF DEF(_OPTION_BEACH_HOUSE)
+INCLUDE "data/mapHeaders/beach_house.asm"
+INCLUDE "scripts/beach_house.asm"
+BeachHouseBlockdata: INCBIN "maps/beach_house.blk"
+INCLUDE "data/mapObjects/beach_house.asm"
+ENDC
+
+INCLUDE "engine/menu/oaks_pc.asm"
+
+INCLUDE "engine/hidden_object_functions7.asm"
+
+
+SECTION "Pics 1", ROMX, BANK[PICS_1]
+
+RhydonPicFront:: INCBIN "pic/bmon/rhydon.pic"
+RhydonPicBack:: INCBIN "pic/monback/rhydonb.pic"
+KangaskhanPicFront:: INCBIN "pic/bmon/kangaskhan.pic"
+KangaskhanPicBack:: INCBIN "pic/monback/kangaskhanb.pic"
+NidoranMPicFront:: INCBIN "pic/bmon/nidoranm.pic"
+NidoranMPicBack:: INCBIN "pic/monback/nidoranmb.pic"
+ClefairyPicFront:: INCBIN "pic/bmon/clefairy.pic"
+ClefairyPicBack:: INCBIN "pic/monback/clefairyb.pic"
+SpearowPicFront:: INCBIN "pic/bmon/spearow.pic"
+SpearowPicBack:: INCBIN "pic/monback/spearowb.pic"
+VoltorbPicFront:: INCBIN "pic/bmon/voltorb.pic"
+VoltorbPicBack:: INCBIN "pic/monback/voltorbb.pic"
+NidokingPicFront:: INCBIN "pic/bmon/nidoking.pic"
+NidokingPicBack:: INCBIN "pic/monback/nidokingb.pic"
+SlowbroPicFront:: INCBIN "pic/bmon/slowbro.pic"
+SlowbroPicBack:: INCBIN "pic/monback/slowbrob.pic"
+IvysaurPicFront:: INCBIN "pic/bmon/ivysaur.pic"
+IvysaurPicBack:: INCBIN "pic/monback/ivysaurb.pic"
+ExeggutorPicFront:: INCBIN "pic/bmon/exeggutor.pic"
+ExeggutorPicBack:: INCBIN "pic/monback/exeggutorb.pic"
+LickitungPicFront:: INCBIN "pic/bmon/lickitung.pic"
+LickitungPicBack:: INCBIN "pic/monback/lickitungb.pic"
+ExeggcutePicFront:: INCBIN "pic/bmon/exeggcute.pic"
+ExeggcutePicBack:: INCBIN "pic/monback/exeggcuteb.pic"
+GrimerPicFront:: INCBIN "pic/bmon/grimer.pic"
+GrimerPicBack:: INCBIN "pic/monback/grimerb.pic"
+GengarPicFront:: INCBIN "pic/bmon/gengar.pic"
+GengarPicBack:: INCBIN "pic/monback/gengarb.pic"
+NidoranFPicFront:: INCBIN "pic/bmon/nidoranf.pic"
+NidoranFPicBack:: INCBIN "pic/monback/nidoranfb.pic"
+NidoqueenPicFront:: INCBIN "pic/bmon/nidoqueen.pic"
+NidoqueenPicBack:: INCBIN "pic/monback/nidoqueenb.pic"
+CubonePicFront:: INCBIN "pic/bmon/cubone.pic"
+CubonePicBack:: INCBIN "pic/monback/cuboneb.pic"
+RhyhornPicFront:: INCBIN "pic/bmon/rhyhorn.pic"
+RhyhornPicBack:: INCBIN "pic/monback/rhyhornb.pic"
+LaprasPicFront:: INCBIN "pic/bmon/lapras.pic"
+LaprasPicBack:: INCBIN "pic/monback/laprasb.pic"
+ArcaninePicFront:: INCBIN "pic/bmon/arcanine.pic"
+ArcaninePicBack:: INCBIN "pic/monback/arcanineb.pic"
+GyaradosPicFront:: INCBIN "pic/bmon/gyarados.pic"
+GyaradosPicBack:: INCBIN "pic/monback/gyaradosb.pic"
+ShellderPicFront:: INCBIN "pic/bmon/shellder.pic"
+ShellderPicBack:: INCBIN "pic/monback/shellderb.pic"
+TentacoolPicFront:: INCBIN "pic/bmon/tentacool.pic"
+TentacoolPicBack:: INCBIN "pic/monback/tentacoolb.pic"
+GastlyPicFront:: INCBIN "pic/bmon/gastly.pic"
+GastlyPicBack:: INCBIN "pic/monback/gastlyb.pic"
+ScytherPicFront:: INCBIN "pic/bmon/scyther.pic"
+ScytherPicBack:: INCBIN "pic/monback/scytherb.pic"
+StaryuPicFront:: INCBIN "pic/bmon/staryu.pic"
+StaryuPicBack:: INCBIN "pic/monback/staryub.pic"
+BlastoisePicFront:: INCBIN "pic/bmon/blastoise.pic"
+BlastoisePicBack:: INCBIN "pic/monback/blastoiseb.pic"
+PinsirPicFront:: INCBIN "pic/bmon/pinsir.pic"
+PinsirPicBack:: INCBIN "pic/monback/pinsirb.pic"
+TangelaPicFront:: INCBIN "pic/bmon/tangela.pic"
+TangelaPicBack:: INCBIN "pic/monback/tangelab.pic"
+
+
+SECTION "Battle (bank 9)", ROMX, BANK[$9]
+INCLUDE "engine/battle/print_type.asm"
+INCLUDE "engine/battle/save_trainer_name.asm"
+INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm"
+
+
+SECTION "Pics 2", ROMX, BANK[PICS_2]
+
+GrowlithePicFront:: INCBIN "pic/bmon/growlithe.pic"
+GrowlithePicBack:: INCBIN "pic/monback/growlitheb.pic"
+OnixPicFront:: INCBIN "pic/bmon/onix.pic"
+OnixPicBack:: INCBIN "pic/monback/onixb.pic"
+FearowPicFront:: INCBIN "pic/bmon/fearow.pic"
+FearowPicBack:: INCBIN "pic/monback/fearowb.pic"
+PidgeyPicFront:: INCBIN "pic/bmon/pidgey.pic"
+PidgeyPicBack:: INCBIN "pic/monback/pidgeyb.pic"
+SlowpokePicFront:: INCBIN "pic/bmon/slowpoke.pic"
+SlowpokePicBack:: INCBIN "pic/monback/slowpokeb.pic"
+KadabraPicFront:: INCBIN "pic/bmon/kadabra.pic"
+KadabraPicBack:: INCBIN "pic/monback/kadabrab.pic"
+GravelerPicFront:: INCBIN "pic/bmon/graveler.pic"
+GravelerPicBack:: INCBIN "pic/monback/gravelerb.pic"
+ChanseyPicFront:: INCBIN "pic/bmon/chansey.pic"
+ChanseyPicBack:: INCBIN "pic/monback/chanseyb.pic"
+MachokePicFront:: INCBIN "pic/bmon/machoke.pic"
+MachokePicBack:: INCBIN "pic/monback/machokeb.pic"
+MrMimePicFront:: INCBIN "pic/bmon/mr.mime.pic"
+MrMimePicBack:: INCBIN "pic/monback/mr.mimeb.pic"
+HitmonleePicFront:: INCBIN "pic/bmon/hitmonlee.pic"
+HitmonleePicBack:: INCBIN "pic/monback/hitmonleeb.pic"
+HitmonchanPicFront:: INCBIN "pic/bmon/hitmonchan.pic"
+HitmonchanPicBack:: INCBIN "pic/monback/hitmonchanb.pic"
+ArbokPicFront:: INCBIN "pic/bmon/arbok.pic"
+ArbokPicBack:: INCBIN "pic/monback/arbokb.pic"
+ParasectPicFront:: INCBIN "pic/bmon/parasect.pic"
+ParasectPicBack:: INCBIN "pic/monback/parasectb.pic"
+PsyduckPicFront:: INCBIN "pic/bmon/psyduck.pic"
+PsyduckPicBack:: INCBIN "pic/monback/psyduckb.pic"
+DrowzeePicFront:: INCBIN "pic/bmon/drowzee.pic"
+DrowzeePicBack:: INCBIN "pic/monback/drowzeeb.pic"
+GolemPicFront:: INCBIN "pic/bmon/golem.pic"
+GolemPicBack:: INCBIN "pic/monback/golemb.pic"
+MagmarPicFront:: INCBIN "pic/bmon/magmar.pic"
+MagmarPicBack:: INCBIN "pic/monback/magmarb.pic"
+ElectabuzzPicFront:: INCBIN "pic/bmon/electabuzz.pic"
+ElectabuzzPicBack:: INCBIN "pic/monback/electabuzzb.pic"
+MagnetonPicFront:: INCBIN "pic/bmon/magneton.pic"
+MagnetonPicBack:: INCBIN "pic/monback/magnetonb.pic"
+KoffingPicFront:: INCBIN "pic/bmon/koffing.pic"
+KoffingPicBack:: INCBIN "pic/monback/koffingb.pic"
+MankeyPicFront:: INCBIN "pic/bmon/mankey.pic"
+MankeyPicBack:: INCBIN "pic/monback/mankeyb.pic"
+SeelPicFront:: INCBIN "pic/bmon/seel.pic"
+SeelPicBack:: INCBIN "pic/monback/seelb.pic"
+DiglettPicFront:: INCBIN "pic/bmon/diglett.pic"
+DiglettPicBack:: INCBIN "pic/monback/diglettb.pic"
+TaurosPicFront:: INCBIN "pic/bmon/tauros.pic"
+TaurosPicBack:: INCBIN "pic/monback/taurosb.pic"
+FarfetchdPicFront:: INCBIN "pic/bmon/farfetchd.pic"
+FarfetchdPicBack:: INCBIN "pic/monback/farfetchdb.pic"
+VenonatPicFront:: INCBIN "pic/bmon/venonat.pic"
+VenonatPicBack:: INCBIN "pic/monback/venonatb.pic"
+DragonitePicFront:: INCBIN "pic/bmon/dragonite.pic"
+DragonitePicBack:: INCBIN "pic/monback/dragoniteb.pic"
+DoduoPicFront:: INCBIN "pic/bmon/doduo.pic"
+DoduoPicBack:: INCBIN "pic/monback/doduob.pic"
+PoliwagPicFront:: INCBIN "pic/bmon/poliwag.pic"
+PoliwagPicBack:: INCBIN "pic/monback/poliwagb.pic"
+JynxPicFront:: INCBIN "pic/bmon/jynx.pic"
+JynxPicBack:: INCBIN "pic/monback/jynxb.pic"
+MoltresPicFront:: INCBIN "pic/bmon/moltres.pic"
+MoltresPicBack:: INCBIN "pic/monback/moltresb.pic"
+
+
+SECTION "Battle (bank A)", ROMX, BANK[$A]
+INCLUDE "engine/battle/moveEffects/leech_seed_effect.asm"
+
+
+SECTION "Pics 3", ROMX, BANK[PICS_3]
+
+ArticunoPicFront:: INCBIN "pic/bmon/articuno.pic"
+ArticunoPicBack:: INCBIN "pic/monback/articunob.pic"
+ZapdosPicFront:: INCBIN "pic/bmon/zapdos.pic"
+ZapdosPicBack:: INCBIN "pic/monback/zapdosb.pic"
+DittoPicFront:: INCBIN "pic/bmon/ditto.pic"
+DittoPicBack:: INCBIN "pic/monback/dittob.pic"
+MeowthPicFront:: INCBIN "pic/bmon/meowth.pic"
+MeowthPicBack:: INCBIN "pic/monback/meowthb.pic"
+KrabbyPicFront:: INCBIN "pic/bmon/krabby.pic"
+KrabbyPicBack:: INCBIN "pic/monback/krabbyb.pic"
+VulpixPicFront:: INCBIN "pic/bmon/vulpix.pic"
+VulpixPicBack:: INCBIN "pic/monback/vulpixb.pic"
+NinetalesPicFront:: INCBIN "pic/bmon/ninetales.pic"
+NinetalesPicBack:: INCBIN "pic/monback/ninetalesb.pic"
+PikachuPicFront:: INCBIN "pic/bmon/pikachu.pic"
+PikachuPicBack:: INCBIN "pic/monback/pikachub.pic"
+RaichuPicFront:: INCBIN "pic/bmon/raichu.pic"
+RaichuPicBack:: INCBIN "pic/monback/raichub.pic"
+DratiniPicFront:: INCBIN "pic/bmon/dratini.pic"
+DratiniPicBack:: INCBIN "pic/monback/dratinib.pic"
+DragonairPicFront:: INCBIN "pic/bmon/dragonair.pic"
+DragonairPicBack:: INCBIN "pic/monback/dragonairb.pic"
+KabutoPicFront:: INCBIN "pic/bmon/kabuto.pic"
+KabutoPicBack:: INCBIN "pic/monback/kabutob.pic"
+KabutopsPicFront:: INCBIN "pic/bmon/kabutops.pic"
+KabutopsPicBack:: INCBIN "pic/monback/kabutopsb.pic"
+HorseaPicFront:: INCBIN "pic/bmon/horsea.pic"
+HorseaPicBack:: INCBIN "pic/monback/horseab.pic"
+SeadraPicFront:: INCBIN "pic/bmon/seadra.pic"
+SeadraPicBack:: INCBIN "pic/monback/seadrab.pic"
+SandshrewPicFront:: INCBIN "pic/bmon/sandshrew.pic"
+SandshrewPicBack:: INCBIN "pic/monback/sandshrewb.pic"
+SandslashPicFront:: INCBIN "pic/bmon/sandslash.pic"
+SandslashPicBack:: INCBIN "pic/monback/sandslashb.pic"
+OmanytePicFront:: INCBIN "pic/bmon/omanyte.pic"
+OmanytePicBack:: INCBIN "pic/monback/omanyteb.pic"
+OmastarPicFront:: INCBIN "pic/bmon/omastar.pic"
+OmastarPicBack:: INCBIN "pic/monback/omastarb.pic"
+JigglypuffPicFront:: INCBIN "pic/bmon/jigglypuff.pic"
+JigglypuffPicBack:: INCBIN "pic/monback/jigglypuffb.pic"
+WigglytuffPicFront:: INCBIN "pic/bmon/wigglytuff.pic"
+WigglytuffPicBack:: INCBIN "pic/monback/wigglytuffb.pic"
+EeveePicFront:: INCBIN "pic/bmon/eevee.pic"
+EeveePicBack:: INCBIN "pic/monback/eeveeb.pic"
+FlareonPicFront:: INCBIN "pic/bmon/flareon.pic"
+FlareonPicBack:: INCBIN "pic/monback/flareonb.pic"
+JolteonPicFront:: INCBIN "pic/bmon/jolteon.pic"
+JolteonPicBack:: INCBIN "pic/monback/jolteonb.pic"
+VaporeonPicFront:: INCBIN "pic/bmon/vaporeon.pic"
+VaporeonPicBack:: INCBIN "pic/monback/vaporeonb.pic"
+MachopPicFront:: INCBIN "pic/bmon/machop.pic"
+MachopPicBack:: INCBIN "pic/monback/machopb.pic"
+ZubatPicFront:: INCBIN "pic/bmon/zubat.pic"
+ZubatPicBack:: INCBIN "pic/monback/zubatb.pic"
+EkansPicFront:: INCBIN "pic/bmon/ekans.pic"
+EkansPicBack:: INCBIN "pic/monback/ekansb.pic"
+ParasPicFront:: INCBIN "pic/bmon/paras.pic"
+ParasPicBack:: INCBIN "pic/monback/parasb.pic"
+PoliwhirlPicFront:: INCBIN "pic/bmon/poliwhirl.pic"
+PoliwhirlPicBack:: INCBIN "pic/monback/poliwhirlb.pic"
+PoliwrathPicFront:: INCBIN "pic/bmon/poliwrath.pic"
+PoliwrathPicBack:: INCBIN "pic/monback/poliwrathb.pic"
+WeedlePicFront:: INCBIN "pic/bmon/weedle.pic"
+WeedlePicBack:: INCBIN "pic/monback/weedleb.pic"
+KakunaPicFront:: INCBIN "pic/bmon/kakuna.pic"
+KakunaPicBack:: INCBIN "pic/monback/kakunab.pic"
+BeedrillPicFront:: INCBIN "pic/bmon/beedrill.pic"
+BeedrillPicBack:: INCBIN "pic/monback/beedrillb.pic"
+
+FossilKabutopsPic:: INCBIN "pic/bmon/fossilkabutops.pic"
+
+
+SECTION "Battle (bank B)", ROMX, BANK[$B]
+
+INCLUDE "engine/battle/display_effectiveness.asm"
+
+TrainerInfoTextBoxTileGraphics: INCBIN "gfx/trainer_info.2bpp"
+BlankLeaderNames: INCBIN "gfx/blank_leader_names.2bpp"
+CircleTile: INCBIN "gfx/circle_tile.2bpp"
+BadgeNumbersTileGraphics: INCBIN "gfx/badge_numbers.2bpp"
+
+INCLUDE "engine/items/tmhm.asm"
+INCLUDE "engine/battle/scale_sprites.asm"
+INCLUDE "engine/battle/moveEffects/pay_day_effect.asm"
+INCLUDE "engine/game_corner_slots2.asm"
+
+
+SECTION "Pics 4", ROMX, BANK[PICS_4]
+
+DodrioPicFront:: INCBIN "pic/bmon/dodrio.pic"
+DodrioPicBack:: INCBIN "pic/monback/dodriob.pic"
+PrimeapePicFront:: INCBIN "pic/bmon/primeape.pic"
+PrimeapePicBack:: INCBIN "pic/monback/primeapeb.pic"
+DugtrioPicFront:: INCBIN "pic/bmon/dugtrio.pic"
+DugtrioPicBack:: INCBIN "pic/monback/dugtriob.pic"
+VenomothPicFront:: INCBIN "pic/bmon/venomoth.pic"
+VenomothPicBack:: INCBIN "pic/monback/venomothb.pic"
+DewgongPicFront:: INCBIN "pic/bmon/dewgong.pic"
+DewgongPicBack:: INCBIN "pic/monback/dewgongb.pic"
+CaterpiePicFront:: INCBIN "pic/bmon/caterpie.pic"
+CaterpiePicBack:: INCBIN "pic/monback/caterpieb.pic"
+MetapodPicFront:: INCBIN "pic/bmon/metapod.pic"
+MetapodPicBack:: INCBIN "pic/monback/metapodb.pic"
+ButterfreePicFront:: INCBIN "pic/bmon/butterfree.pic"
+ButterfreePicBack:: INCBIN "pic/monback/butterfreeb.pic"
+MachampPicFront:: INCBIN "pic/bmon/machamp.pic"
+MachampPicBack:: INCBIN "pic/monback/machampb.pic"
+GolduckPicFront:: INCBIN "pic/bmon/golduck.pic"
+GolduckPicBack:: INCBIN "pic/monback/golduckb.pic"
+HypnoPicFront:: INCBIN "pic/bmon/hypno.pic"
+HypnoPicBack:: INCBIN "pic/monback/hypnob.pic"
+GolbatPicFront:: INCBIN "pic/bmon/golbat.pic"
+GolbatPicBack:: INCBIN "pic/monback/golbatb.pic"
+MewtwoPicFront:: INCBIN "pic/bmon/mewtwo.pic"
+MewtwoPicBack:: INCBIN "pic/monback/mewtwob.pic"
+SnorlaxPicFront:: INCBIN "pic/bmon/snorlax.pic"
+SnorlaxPicBack:: INCBIN "pic/monback/snorlaxb.pic"
+MagikarpPicFront:: INCBIN "pic/bmon/magikarp.pic"
+MagikarpPicBack:: INCBIN "pic/monback/magikarpb.pic"
+MukPicFront:: INCBIN "pic/bmon/muk.pic"
+MukPicBack:: INCBIN "pic/monback/mukb.pic"
+KinglerPicFront:: INCBIN "pic/bmon/kingler.pic"
+KinglerPicBack:: INCBIN "pic/monback/kinglerb.pic"
+CloysterPicFront:: INCBIN "pic/bmon/cloyster.pic"
+CloysterPicBack:: INCBIN "pic/monback/cloysterb.pic"
+ElectrodePicFront:: INCBIN "pic/bmon/electrode.pic"
+ElectrodePicBack:: INCBIN "pic/monback/electrodeb.pic"
+ClefablePicFront:: INCBIN "pic/bmon/clefable.pic"
+ClefablePicBack:: INCBIN "pic/monback/clefableb.pic"
+WeezingPicFront:: INCBIN "pic/bmon/weezing.pic"
+WeezingPicBack:: INCBIN "pic/monback/weezingb.pic"
+PersianPicFront:: INCBIN "pic/bmon/persian.pic"
+PersianPicBack:: INCBIN "pic/monback/persianb.pic"
+MarowakPicFront:: INCBIN "pic/bmon/marowak.pic"
+MarowakPicBack:: INCBIN "pic/monback/marowakb.pic"
+HaunterPicFront:: INCBIN "pic/bmon/haunter.pic"
+HaunterPicBack:: INCBIN "pic/monback/haunterb.pic"
+AbraPicFront:: INCBIN "pic/bmon/abra.pic"
+AbraPicBack:: INCBIN "pic/monback/abrab.pic"
+AlakazamPicFront:: INCBIN "pic/bmon/alakazam.pic"
+AlakazamPicBack:: INCBIN "pic/monback/alakazamb.pic"
+PidgeottoPicFront:: INCBIN "pic/bmon/pidgeotto.pic"
+PidgeottoPicBack:: INCBIN "pic/monback/pidgeottob.pic"
+PidgeotPicFront:: INCBIN "pic/bmon/pidgeot.pic"
+PidgeotPicBack:: INCBIN "pic/monback/pidgeotb.pic"
+StarmiePicFront:: INCBIN "pic/bmon/starmie.pic"
+StarmiePicBack:: INCBIN "pic/monback/starmieb.pic"
+
+RedPicBack:: INCBIN "pic/trainer/redb.pic"
+OldManPic:: INCBIN "pic/trainer/oldman.pic"
+
+
+SECTION "Battle (bank C)", ROMX, BANK[$C]
+INCLUDE "engine/battle/moveEffects/mist_effect.asm"
+INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm"
+
+
+SECTION "Pics 5", ROMX, BANK[PICS_5]
+
+BulbasaurPicFront:: INCBIN "pic/bmon/bulbasaur.pic"
+BulbasaurPicBack:: INCBIN "pic/monback/bulbasaurb.pic"
+VenusaurPicFront:: INCBIN "pic/bmon/venusaur.pic"
+VenusaurPicBack:: INCBIN "pic/monback/venusaurb.pic"
+TentacruelPicFront:: INCBIN "pic/bmon/tentacruel.pic"
+TentacruelPicBack:: INCBIN "pic/monback/tentacruelb.pic"
+GoldeenPicFront:: INCBIN "pic/bmon/goldeen.pic"
+GoldeenPicBack:: INCBIN "pic/monback/goldeenb.pic"
+SeakingPicFront:: INCBIN "pic/bmon/seaking.pic"
+SeakingPicBack:: INCBIN "pic/monback/seakingb.pic"
+PonytaPicFront:: INCBIN "pic/bmon/ponyta.pic"
+RapidashPicFront:: INCBIN "pic/bmon/rapidash.pic"
+PonytaPicBack:: INCBIN "pic/monback/ponytab.pic"
+RapidashPicBack:: INCBIN "pic/monback/rapidashb.pic"
+RattataPicFront:: INCBIN "pic/bmon/rattata.pic"
+RattataPicBack:: INCBIN "pic/monback/rattatab.pic"
+RaticatePicFront:: INCBIN "pic/bmon/raticate.pic"
+RaticatePicBack:: INCBIN "pic/monback/raticateb.pic"
+NidorinoPicFront:: INCBIN "pic/bmon/nidorino.pic"
+NidorinoPicBack:: INCBIN "pic/monback/nidorinob.pic"
+NidorinaPicFront:: INCBIN "pic/bmon/nidorina.pic"
+NidorinaPicBack:: INCBIN "pic/monback/nidorinab.pic"
+GeodudePicFront:: INCBIN "pic/bmon/geodude.pic"
+GeodudePicBack:: INCBIN "pic/monback/geodudeb.pic"
+PorygonPicFront:: INCBIN "pic/bmon/porygon.pic"
+PorygonPicBack:: INCBIN "pic/monback/porygonb.pic"
+AerodactylPicFront:: INCBIN "pic/bmon/aerodactyl.pic"
+AerodactylPicBack:: INCBIN "pic/monback/aerodactylb.pic"
+MagnemitePicFront:: INCBIN "pic/bmon/magnemite.pic"
+MagnemitePicBack:: INCBIN "pic/monback/magnemiteb.pic"
+CharmanderPicFront:: INCBIN "pic/bmon/charmander.pic"
+CharmanderPicBack:: INCBIN "pic/monback/charmanderb.pic"
+SquirtlePicFront:: INCBIN "pic/bmon/squirtle.pic"
+SquirtlePicBack:: INCBIN "pic/monback/squirtleb.pic"
+CharmeleonPicFront:: INCBIN "pic/bmon/charmeleon.pic"
+CharmeleonPicBack:: INCBIN "pic/monback/charmeleonb.pic"
+WartortlePicFront:: INCBIN "pic/bmon/wartortle.pic"
+WartortlePicBack:: INCBIN "pic/monback/wartortleb.pic"
+CharizardPicFront:: INCBIN "pic/bmon/charizard.pic"
+CharizardPicBack:: INCBIN "pic/monback/charizardb.pic"
+FossilAerodactylPic:: INCBIN "pic/bmon/fossilaerodactyl.pic"
+GhostPic:: INCBIN "pic/other/ghost.pic"
+OddishPicFront:: INCBIN "pic/bmon/oddish.pic"
+OddishPicBack:: INCBIN "pic/monback/oddishb.pic"
+GloomPicFront:: INCBIN "pic/bmon/gloom.pic"
+GloomPicBack:: INCBIN "pic/monback/gloomb.pic"
+VileplumePicFront:: INCBIN "pic/bmon/vileplume.pic"
+VileplumePicBack:: INCBIN "pic/monback/vileplumeb.pic"
+BellsproutPicFront:: INCBIN "pic/bmon/bellsprout.pic"
+BellsproutPicBack:: INCBIN "pic/monback/bellsproutb.pic"
+WeepinbellPicFront:: INCBIN "pic/bmon/weepinbell.pic"
+WeepinbellPicBack:: INCBIN "pic/monback/weepinbellb.pic"
+VictreebelPicFront:: INCBIN "pic/bmon/victreebel.pic"
+VictreebelPicBack:: INCBIN "pic/monback/victreebelb.pic"
+
+
+SECTION "Battle (bank D)", ROMX, BANK[$D]
+
+INCLUDE "engine/titlescreen2.asm"
+INCLUDE "engine/battle/link_battle_versus_text.asm"
+INCLUDE "engine/slot_machine.asm"
+INCLUDE "engine/overworld/pewter_guys.asm"
+INCLUDE "engine/multiply_divide.asm"
+INCLUDE "engine/game_corner_slots.asm"
+
+
+SECTION "bankE",ROMX,BANK[$E]
+
+INCLUDE "data/moves.asm"
+BaseStats: INCLUDE "data/base_stats.asm"
+INCLUDE "data/cries.asm"
+INCLUDE "engine/battle/unused_stats_functions.asm"
+INCLUDE "engine/battle/scroll_draw_trainer_pic.asm"
+INCLUDE "engine/battle/trainer_ai.asm"
+INCLUDE "engine/battle/draw_hud_pokeball_gfx.asm"
+
+TradingAnimationGraphics:
+ INCBIN "gfx/game_boy.norepeat.2bpp"
+ INCBIN "gfx/link_cable.2bpp"
+
+TradingAnimationGraphics2:
+; Pokeball traveling through the link cable.
+ INCBIN "gfx/trade2.2bpp"
+
+INCLUDE "engine/evos_moves.asm"
+INCLUDE "engine/battle/moveEffects/heal_effect.asm"
+INCLUDE "engine/battle/moveEffects/transform_effect.asm"
+INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm"
+
+
+SECTION "bankF",ROMX,BANK[$F]
+
+INCLUDE "engine/battle/core.asm"
+
+
+SECTION "bank10",ROMX,BANK[$10]
+
+INCLUDE "engine/menu/pokedex.asm"
+INCLUDE "engine/trade.asm"
+INCLUDE "engine/intro.asm"
+INCLUDE "engine/trade2.asm"
+
+
+SECTION "bank11",ROMX,BANK[$11]
+
+INCLUDE "data/mapHeaders/lavendertown.asm"
+INCLUDE "data/mapObjects/lavendertown.asm"
+LavenderTownBlocks: INCBIN "maps/lavendertown.blk"
+
+ViridianPokecenterBlocks: INCBIN "maps/viridianpokecenter.blk"
+
+SafariZoneRestHouse1Blocks:
+SafariZoneRestHouse2Blocks:
+SafariZoneRestHouse3Blocks:
+SafariZoneRestHouse4Blocks: INCBIN "maps/safarizoneresthouse1.blk"
+
+INCLUDE "scripts/lavendertown.asm"
+
+INCLUDE "engine/pokedex_rating.asm"
+
+INCLUDE "data/mapHeaders/viridianpokecenter.asm"
+INCLUDE "scripts/viridianpokecenter.asm"
+INCLUDE "data/mapObjects/viridianpokecenter.asm"
+
+INCLUDE "data/mapHeaders/mansion1.asm"
+INCLUDE "scripts/mansion1.asm"
+INCLUDE "data/mapObjects/mansion1.asm"
+Mansion1Blocks: INCBIN "maps/mansion1.blk"
+
+INCLUDE "data/mapHeaders/rocktunnel1.asm"
+INCLUDE "scripts/rocktunnel1.asm"
+INCLUDE "data/mapObjects/rocktunnel1.asm"
+RockTunnel1Blocks: INCBIN "maps/rocktunnel1.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands1.asm"
+INCLUDE "scripts/seafoamislands1.asm"
+INCLUDE "data/mapObjects/seafoamislands1.asm"
+SeafoamIslands1Blocks: INCBIN "maps/seafoamislands1.blk"
+
+INCLUDE "data/mapHeaders/ssanne3.asm"
+INCLUDE "scripts/ssanne3.asm"
+INCLUDE "data/mapObjects/ssanne3.asm"
+SSAnne3Blocks: INCBIN "maps/ssanne3.blk"
+
+INCLUDE "data/mapHeaders/victoryroad3.asm"
+INCLUDE "scripts/victoryroad3.asm"
+INCLUDE "data/mapObjects/victoryroad3.asm"
+VictoryRoad3Blocks: INCBIN "maps/victoryroad3.blk"
+
+INCLUDE "data/mapHeaders/rockethideout1.asm"
+INCLUDE "scripts/rockethideout1.asm"
+INCLUDE "data/mapObjects/rockethideout1.asm"
+RocketHideout1Blocks: INCBIN "maps/rockethideout1.blk"
+
+INCLUDE "data/mapHeaders/rockethideout2.asm"
+INCLUDE "scripts/rockethideout2.asm"
+INCLUDE "data/mapObjects/rockethideout2.asm"
+RocketHideout2Blocks: INCBIN "maps/rockethideout2.blk"
+
+INCLUDE "data/mapHeaders/rockethideout3.asm"
+INCLUDE "scripts/rockethideout3.asm"
+INCLUDE "data/mapObjects/rockethideout3.asm"
+RocketHideout3Blocks: INCBIN "maps/rockethideout3.blk"
+
+INCLUDE "data/mapHeaders/rockethideout4.asm"
+INCLUDE "scripts/rockethideout4.asm"
+INCLUDE "data/mapObjects/rockethideout4.asm"
+RocketHideout4Blocks: INCBIN "maps/rockethideout4.blk"
+
+INCLUDE "data/mapHeaders/rockethideoutelevator.asm"
+INCLUDE "scripts/rockethideoutelevator.asm"
+INCLUDE "data/mapObjects/rockethideoutelevator.asm"
+RocketHideoutElevatorBlocks: INCBIN "maps/rockethideoutelevator.blk"
+
+INCLUDE "data/mapHeaders/silphcoelevator.asm"
+INCLUDE "scripts/silphcoelevator.asm"
+INCLUDE "data/mapObjects/silphcoelevator.asm"
+SilphCoElevatorBlocks: INCBIN "maps/silphcoelevator.blk"
+
+INCLUDE "data/mapHeaders/safarizoneeast.asm"
+INCLUDE "scripts/safarizoneeast.asm"
+INCLUDE "data/mapObjects/safarizoneeast.asm"
+SafariZoneEastBlocks: INCBIN "maps/safarizoneeast.blk"
+
+INCLUDE "data/mapHeaders/safarizonenorth.asm"
+INCLUDE "scripts/safarizonenorth.asm"
+INCLUDE "data/mapObjects/safarizonenorth.asm"
+SafariZoneNorthBlocks: INCBIN "maps/safarizonenorth.blk"
+
+INCLUDE "data/mapHeaders/safarizonecenter.asm"
+INCLUDE "scripts/safarizonecenter.asm"
+INCLUDE "data/mapObjects/safarizonecenter.asm"
+SafariZoneCenterBlocks: INCBIN "maps/safarizonecenter.blk"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse1.asm"
+INCLUDE "scripts/safarizoneresthouse1.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse1.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse2.asm"
+INCLUDE "scripts/safarizoneresthouse2.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse2.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse3.asm"
+INCLUDE "scripts/safarizoneresthouse3.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse3.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse4.asm"
+INCLUDE "scripts/safarizoneresthouse4.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse4.asm"
+
+INCLUDE "data/mapHeaders/unknowndungeon2.asm"
+INCLUDE "scripts/unknowndungeon2.asm"
+INCLUDE "data/mapObjects/unknowndungeon2.asm"
+UnknownDungeon2Blocks: INCBIN "maps/unknowndungeon2.blk"
+
+INCLUDE "data/mapHeaders/unknowndungeon3.asm"
+INCLUDE "scripts/unknowndungeon3.asm"
+INCLUDE "data/mapObjects/unknowndungeon3.asm"
+UnknownDungeon3Blocks: INCBIN "maps/unknowndungeon3.blk"
+
+INCLUDE "data/mapHeaders/rocktunnel2.asm"
+INCLUDE "scripts/rocktunnel2.asm"
+INCLUDE "data/mapObjects/rocktunnel2.asm"
+RockTunnel2Blocks: INCBIN "maps/rocktunnel2.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands2.asm"
+INCLUDE "scripts/seafoamislands2.asm"
+INCLUDE "data/mapObjects/seafoamislands2.asm"
+SeafoamIslands2Blocks: INCBIN "maps/seafoamislands2.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands3.asm"
+INCLUDE "scripts/seafoamislands3.asm"
+INCLUDE "data/mapObjects/seafoamislands3.asm"
+SeafoamIslands3Blocks: INCBIN "maps/seafoamislands3.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands4.asm"
+INCLUDE "scripts/seafoamislands4.asm"
+INCLUDE "data/mapObjects/seafoamislands4.asm"
+SeafoamIslands4Blocks: INCBIN "maps/seafoamislands4.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands5.asm"
+INCLUDE "scripts/seafoamislands5.asm"
+INCLUDE "data/mapObjects/seafoamislands5.asm"
+SeafoamIslands5Blocks: INCBIN "maps/seafoamislands5.blk"
+
+INCLUDE "engine/overworld/hidden_objects.asm"
+
+
+SECTION "bank12",ROMX,BANK[$12]
+
+INCLUDE "data/mapHeaders/route7.asm"
+INCLUDE "data/mapObjects/route7.asm"
+Route7Blocks: INCBIN "maps/route7.blk"
+
+CeladonPokecenterBlocks:
+RockTunnelPokecenterBlocks:
+MtMoonPokecenterBlocks: INCBIN "maps/mtmoonpokecenter.blk"
+
+Route18GateBlocks:
+Route15GateBlocks:
+Route11GateBlocks: INCBIN "maps/route11gate.blk"
+
+Route18GateUpstairsBlocks:
+Route16GateUpstairsBlocks:
+Route12GateUpstairsBlocks:
+Route15GateUpstairsBlocks:
+Route11GateUpstairsBlocks: INCBIN "maps/route11gateupstairs.blk"
+
+INCLUDE "engine/predefs12.asm"
+
+INCLUDE "scripts/route7.asm"
+
+INCLUDE "data/mapHeaders/redshouse1f.asm"
+INCLUDE "scripts/redshouse1f.asm"
+INCLUDE "data/mapObjects/redshouse1f.asm"
+RedsHouse1FBlocks: INCBIN "maps/redshouse1f.blk"
+
+INCLUDE "data/mapHeaders/celadonmart3.asm"
+INCLUDE "scripts/celadonmart3.asm"
+INCLUDE "data/mapObjects/celadonmart3.asm"
+CeladonMart3Blocks: INCBIN "maps/celadonmart3.blk"
+
+INCLUDE "data/mapHeaders/celadonmart4.asm"
+INCLUDE "scripts/celadonmart4.asm"
+INCLUDE "data/mapObjects/celadonmart4.asm"
+CeladonMart4Blocks: INCBIN "maps/celadonmart4.blk"
+
+INCLUDE "data/mapHeaders/celadonmartroof.asm"
+INCLUDE "scripts/celadonmartroof.asm"
+INCLUDE "data/mapObjects/celadonmartroof.asm"
+CeladonMartRoofBlocks: INCBIN "maps/celadonmartroof.blk"
+
+INCLUDE "data/mapHeaders/celadonmartelevator.asm"
+INCLUDE "scripts/celadonmartelevator.asm"
+INCLUDE "data/mapObjects/celadonmartelevator.asm"
+CeladonMartElevatorBlocks: INCBIN "maps/celadonmartelevator.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion1.asm"
+INCLUDE "scripts/celadonmansion1.asm"
+INCLUDE "data/mapObjects/celadonmansion1.asm"
+CeladonMansion1Blocks: INCBIN "maps/celadonmansion1.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion2.asm"
+INCLUDE "scripts/celadonmansion2.asm"
+INCLUDE "data/mapObjects/celadonmansion2.asm"
+CeladonMansion2Blocks: INCBIN "maps/celadonmansion2.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion3.asm"
+INCLUDE "scripts/celadonmansion3.asm"
+INCLUDE "data/mapObjects/celadonmansion3.asm"
+CeladonMansion3Blocks: INCBIN "maps/celadonmansion3.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion4.asm"
+INCLUDE "scripts/celadonmansion4.asm"
+INCLUDE "data/mapObjects/celadonmansion4.asm"
+CeladonMansion4Blocks: INCBIN "maps/celadonmansion4.blk"
+
+INCLUDE "data/mapHeaders/celadonpokecenter.asm"
+INCLUDE "scripts/celadonpokecenter.asm"
+INCLUDE "data/mapObjects/celadonpokecenter.asm"
+
+INCLUDE "data/mapHeaders/celadongym.asm"
+INCLUDE "scripts/celadongym.asm"
+INCLUDE "data/mapObjects/celadongym.asm"
+CeladonGymBlocks: INCBIN "maps/celadongym.blk"
+
+INCLUDE "data/mapHeaders/celadongamecorner.asm"
+INCLUDE "scripts/celadongamecorner.asm"
+INCLUDE "data/mapObjects/celadongamecorner.asm"
+CeladonGameCornerBlocks: INCBIN "maps/celadongamecorner.blk"
+
+INCLUDE "data/mapHeaders/celadonmart5.asm"
+INCLUDE "scripts/celadonmart5.asm"
+INCLUDE "data/mapObjects/celadonmart5.asm"
+CeladonMart5Blocks: INCBIN "maps/celadonmart5.blk"
+
+INCLUDE "data/mapHeaders/celadonprizeroom.asm"
+INCLUDE "scripts/celadonprizeroom.asm"
+INCLUDE "data/mapObjects/celadonprizeroom.asm"
+CeladonPrizeRoomBlocks: INCBIN "maps/celadonprizeroom.blk"
+
+INCLUDE "data/mapHeaders/celadondiner.asm"
+INCLUDE "scripts/celadondiner.asm"
+INCLUDE "data/mapObjects/celadondiner.asm"
+CeladonDinerBlocks: INCBIN "maps/celadondiner.blk"
+
+INCLUDE "data/mapHeaders/celadonhouse.asm"
+INCLUDE "scripts/celadonhouse.asm"
+INCLUDE "data/mapObjects/celadonhouse.asm"
+CeladonHouseBlocks: INCBIN "maps/celadonhouse.blk"
+
+INCLUDE "data/mapHeaders/celadonhotel.asm"
+INCLUDE "scripts/celadonhotel.asm"
+INCLUDE "data/mapObjects/celadonhotel.asm"
+CeladonHotelBlocks: INCBIN "maps/celadonhotel.blk"
+
+INCLUDE "data/mapHeaders/mtmoonpokecenter.asm"
+INCLUDE "scripts/mtmoonpokecenter.asm"
+INCLUDE "data/mapObjects/mtmoonpokecenter.asm"
+
+INCLUDE "data/mapHeaders/rocktunnelpokecenter.asm"
+INCLUDE "scripts/rocktunnelpokecenter.asm"
+INCLUDE "data/mapObjects/rocktunnelpokecenter.asm"
+
+INCLUDE "data/mapHeaders/route11gate.asm"
+INCLUDE "scripts/route11gate.asm"
+INCLUDE "data/mapObjects/route11gate.asm"
+
+INCLUDE "data/mapHeaders/route11gateupstairs.asm"
+INCLUDE "scripts/route11gateupstairs.asm"
+INCLUDE "data/mapObjects/route11gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route12gate.asm"
+INCLUDE "scripts/route12gate.asm"
+INCLUDE "data/mapObjects/route12gate.asm"
+Route12GateBlocks: INCBIN "maps/route12gate.blk"
+
+INCLUDE "data/mapHeaders/route12gateupstairs.asm"
+INCLUDE "scripts/route12gateupstairs.asm"
+INCLUDE "data/mapObjects/route12gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route15gate.asm"
+INCLUDE "scripts/route15gate.asm"
+INCLUDE "data/mapObjects/route15gate.asm"
+
+INCLUDE "data/mapHeaders/route15gateupstairs.asm"
+INCLUDE "scripts/route15gateupstairs.asm"
+INCLUDE "data/mapObjects/route15gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route16gate.asm"
+INCLUDE "scripts/route16gate.asm"
+INCLUDE "data/mapObjects/route16gate.asm"
+Route16GateBlocks: INCBIN "maps/route16gate.blk"
+
+INCLUDE "data/mapHeaders/route16gateupstairs.asm"
+INCLUDE "scripts/route16gateupstairs.asm"
+INCLUDE "data/mapObjects/route16gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route18gate.asm"
+INCLUDE "scripts/route18gate.asm"
+INCLUDE "data/mapObjects/route18gate.asm"
+
+INCLUDE "data/mapHeaders/route18gateupstairs.asm"
+INCLUDE "scripts/route18gateupstairs.asm"
+INCLUDE "data/mapObjects/route18gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/mtmoon1.asm"
+INCLUDE "scripts/mtmoon1.asm"
+INCLUDE "data/mapObjects/mtmoon1.asm"
+MtMoon1Blocks: INCBIN "maps/mtmoon1.blk"
+
+INCLUDE "data/mapHeaders/mtmoon3.asm"
+INCLUDE "scripts/mtmoon3.asm"
+INCLUDE "data/mapObjects/mtmoon3.asm"
+MtMoon3Blocks: INCBIN "maps/mtmoon3.blk"
+
+INCLUDE "data/mapHeaders/safarizonewest.asm"
+INCLUDE "scripts/safarizonewest.asm"
+INCLUDE "data/mapObjects/safarizonewest.asm"
+SafariZoneWestBlocks: INCBIN "maps/safarizonewest.blk"
+
+INCLUDE "data/mapHeaders/safarizonesecrethouse.asm"
+INCLUDE "scripts/safarizonesecrethouse.asm"
+INCLUDE "data/mapObjects/safarizonesecrethouse.asm"
+SafariZoneSecretHouseBlocks: INCBIN "maps/safarizonesecrethouse.blk"
+
+
+SECTION "bank13",ROMX,BANK[$13]
+
+TrainerPics::
+YoungsterPic:: INCBIN "pic/trainer/youngster.pic"
+BugCatcherPic:: INCBIN "pic/trainer/bugcatcher.pic"
+LassPic:: INCBIN "pic/trainer/lass.pic"
+SailorPic:: INCBIN "pic/trainer/sailor.pic"
+JrTrainerMPic:: INCBIN "pic/trainer/jr.trainerm.pic"
+JrTrainerFPic:: INCBIN "pic/trainer/jr.trainerf.pic"
+PokemaniacPic:: INCBIN "pic/trainer/pokemaniac.pic"
+SuperNerdPic:: INCBIN "pic/trainer/supernerd.pic"
+HikerPic:: INCBIN "pic/trainer/hiker.pic"
+BikerPic:: INCBIN "pic/trainer/biker.pic"
+BurglarPic:: INCBIN "pic/trainer/burglar.pic"
+EngineerPic:: INCBIN "pic/trainer/engineer.pic"
+FisherPic:: INCBIN "pic/trainer/fisher.pic"
+SwimmerPic:: INCBIN "pic/trainer/swimmer.pic"
+CueBallPic:: INCBIN "pic/trainer/cueball.pic"
+GamblerPic:: INCBIN "pic/trainer/gambler.pic"
+BeautyPic:: INCBIN "pic/trainer/beauty.pic"
+PsychicPic:: INCBIN "pic/trainer/psychic.pic"
+RockerPic:: INCBIN "pic/trainer/rocker.pic"
+JugglerPic:: INCBIN "pic/trainer/juggler.pic"
+TamerPic:: INCBIN "pic/trainer/tamer.pic"
+BirdKeeperPic:: INCBIN "pic/trainer/birdkeeper.pic"
+BlackbeltPic:: INCBIN "pic/trainer/blackbelt.pic"
+Rival1Pic:: INCBIN "pic/trainer/rival1.pic"
+ProfOakPic:: INCBIN "pic/trainer/prof.oak.pic"
+ChiefPic::
+ScientistPic:: INCBIN "pic/trainer/scientist.pic"
+GiovanniPic:: INCBIN "pic/trainer/giovanni.pic"
+RocketPic:: INCBIN "pic/trainer/rocket.pic"
+CooltrainerMPic:: INCBIN "pic/trainer/cooltrainerm.pic"
+CooltrainerFPic:: INCBIN "pic/trainer/cooltrainerf.pic"
+BrunoPic:: INCBIN "pic/trainer/bruno.pic"
+BrockPic:: INCBIN "pic/trainer/brock.pic"
+MistyPic:: INCBIN "pic/trainer/misty.pic"
+LtSurgePic:: INCBIN "pic/trainer/lt.surge.pic"
+ErikaPic:: INCBIN "pic/trainer/erika.pic"
+KogaPic:: INCBIN "pic/trainer/koga.pic"
+BlainePic:: INCBIN "pic/trainer/blaine.pic"
+SabrinaPic:: INCBIN "pic/trainer/sabrina.pic"
+GentlemanPic:: INCBIN "pic/trainer/gentleman.pic"
+Rival2Pic:: INCBIN "pic/trainer/rival2.pic"
+Rival3Pic:: INCBIN "pic/trainer/rival3.pic"
+LoreleiPic:: INCBIN "pic/trainer/lorelei.pic"
+ChannelerPic:: INCBIN "pic/trainer/channeler.pic"
+AgathaPic:: INCBIN "pic/trainer/agatha.pic"
+LancePic:: INCBIN "pic/trainer/lance.pic"
+
+INCLUDE "data/mapHeaders/battlecenterm.asm"
+INCLUDE "scripts/battlecenterm.asm"
+INCLUDE "data/mapObjects/battlecenterm.asm"
+BattleCenterMBlocks: INCBIN "maps/battlecenterm.blk"
+
+INCLUDE "data/mapHeaders/tradecenterm.asm"
+INCLUDE "scripts/tradecenterm.asm"
+INCLUDE "data/mapObjects/tradecenterm.asm"
+TradeCenterMBlocks: INCBIN "maps/tradecenterm.blk"
+
+INCLUDE "engine/give_pokemon.asm"
+
+INCLUDE "engine/predefs.asm"
+
+
+SECTION "bank14",ROMX,BANK[$14]
+
+INCLUDE "data/mapHeaders/route22.asm"
+INCLUDE "data/mapObjects/route22.asm"
+Route22Blocks: INCBIN "maps/route22.blk"
+
+INCLUDE "data/mapHeaders/route20.asm"
+INCLUDE "data/mapObjects/route20.asm"
+Route20Blocks: INCBIN "maps/route20.blk"
+
+INCLUDE "data/mapHeaders/route23.asm"
+INCLUDE "data/mapObjects/route23.asm"
+Route23Blocks: INCBIN "maps/route23.blk"
+
+INCLUDE "data/mapHeaders/route24.asm"
+INCLUDE "data/mapObjects/route24.asm"
+Route24Blocks: INCBIN "maps/route24.blk"
+
+INCLUDE "data/mapHeaders/route25.asm"
+INCLUDE "data/mapObjects/route25.asm"
+Route25Blocks: INCBIN "maps/route25.blk"
+
+INCLUDE "data/mapHeaders/indigoplateau.asm"
+INCLUDE "scripts/indigoplateau.asm"
+INCLUDE "data/mapObjects/indigoplateau.asm"
+IndigoPlateauBlocks: INCBIN "maps/indigoplateau.blk"
+
+INCLUDE "data/mapHeaders/saffroncity.asm"
+INCLUDE "data/mapObjects/saffroncity.asm"
+SaffronCityBlocks: INCBIN "maps/saffroncity.blk"
+INCLUDE "scripts/saffroncity.asm"
+
+INCLUDE "scripts/route20.asm"
+INCLUDE "scripts/route22.asm"
+INCLUDE "scripts/route23.asm"
+INCLUDE "scripts/route24.asm"
+INCLUDE "scripts/route25.asm"
+
+INCLUDE "data/mapHeaders/victoryroad2.asm"
+INCLUDE "scripts/victoryroad2.asm"
+INCLUDE "data/mapObjects/victoryroad2.asm"
+VictoryRoad2Blocks: INCBIN "maps/victoryroad2.blk"
+
+INCLUDE "data/mapHeaders/mtmoon2.asm"
+INCLUDE "scripts/mtmoon2.asm"
+INCLUDE "data/mapObjects/mtmoon2.asm"
+MtMoon2Blocks: INCBIN "maps/mtmoon2.blk"
+
+INCLUDE "data/mapHeaders/silphco7.asm"
+INCLUDE "scripts/silphco7.asm"
+INCLUDE "data/mapObjects/silphco7.asm"
+SilphCo7Blocks: INCBIN "maps/silphco7.blk"
+
+INCLUDE "data/mapHeaders/mansion2.asm"
+INCLUDE "scripts/mansion2.asm"
+INCLUDE "data/mapObjects/mansion2.asm"
+Mansion2Blocks: INCBIN "maps/mansion2.blk"
+
+INCLUDE "data/mapHeaders/mansion3.asm"
+INCLUDE "scripts/mansion3.asm"
+INCLUDE "data/mapObjects/mansion3.asm"
+Mansion3Blocks: INCBIN "maps/mansion3.blk"
+
+INCLUDE "data/mapHeaders/mansion4.asm"
+INCLUDE "scripts/mansion4.asm"
+INCLUDE "data/mapObjects/mansion4.asm"
+Mansion4Blocks: INCBIN "maps/mansion4.blk"
+
+INCLUDE "engine/battle/init_battle_variables.asm"
+INCLUDE "engine/battle/moveEffects/paralyze_effect.asm"
+
+INCLUDE "engine/overworld/card_key.asm"
+
+INCLUDE "engine/menu/prize_menu.asm"
+
+INCLUDE "engine/hidden_object_functions14.asm"
+
+
+SECTION "bank15",ROMX,BANK[$15]
+
+INCLUDE "data/mapHeaders/route2.asm"
+INCLUDE "data/mapObjects/route2.asm"
+Route2Blocks: INCBIN "maps/route2.blk"
+
+INCLUDE "data/mapHeaders/route3.asm"
+INCLUDE "data/mapObjects/route3.asm"
+Route3Blocks: INCBIN "maps/route3.blk"
+
+INCLUDE "data/mapHeaders/route4.asm"
+INCLUDE "data/mapObjects/route4.asm"
+Route4Blocks: INCBIN "maps/route4.blk"
+
+INCLUDE "data/mapHeaders/route5.asm"
+INCLUDE "data/mapObjects/route5.asm"
+Route5Blocks: INCBIN "maps/route5.blk"
+
+INCLUDE "data/mapHeaders/route9.asm"
+INCLUDE "data/mapObjects/route9.asm"
+Route9Blocks: INCBIN "maps/route9.blk"
+
+INCLUDE "data/mapHeaders/route13.asm"
+INCLUDE "data/mapObjects/route13.asm"
+Route13Blocks: INCBIN "maps/route13.blk"
+
+INCLUDE "data/mapHeaders/route14.asm"
+INCLUDE "data/mapObjects/route14.asm"
+Route14Blocks: INCBIN "maps/route14.blk"
+
+INCLUDE "data/mapHeaders/route17.asm"
+INCLUDE "data/mapObjects/route17.asm"
+Route17Blocks: INCBIN "maps/route17.blk"
+
+INCLUDE "data/mapHeaders/route19.asm"
+INCLUDE "data/mapObjects/route19.asm"
+IF DEF(_OPTION_BEACH_HOUSE)
+Route19Blocks: INCBIN "maps/route19-yellow.blk"
+ELSE
+Route19Blocks: INCBIN "maps/route19.blk"
+ENDC
+
+INCLUDE "data/mapHeaders/route21.asm"
+INCLUDE "data/mapObjects/route21.asm"
+Route21Blocks: INCBIN "maps/route21.blk"
+
+VermilionHouse2Blocks:
+Route12HouseBlocks:
+DayCareMBlocks: INCBIN "maps/daycarem.blk"
+
+FuchsiaHouse3Blocks: INCBIN "maps/fuchsiahouse3.blk"
+
+INCLUDE "engine/battle/experience.asm"
+
+INCLUDE "scripts/route2.asm"
+INCLUDE "scripts/route3.asm"
+INCLUDE "scripts/route4.asm"
+INCLUDE "scripts/route5.asm"
+INCLUDE "scripts/route9.asm"
+INCLUDE "scripts/route13.asm"
+INCLUDE "scripts/route14.asm"
+INCLUDE "scripts/route17.asm"
+INCLUDE "scripts/route19.asm"
+INCLUDE "scripts/route21.asm"
+
+INCLUDE "data/mapHeaders/vermilionhouse2.asm"
+INCLUDE "scripts/vermilionhouse2.asm"
+INCLUDE "data/mapObjects/vermilionhouse2.asm"
+
+INCLUDE "data/mapHeaders/celadonmart2.asm"
+INCLUDE "scripts/celadonmart2.asm"
+INCLUDE "data/mapObjects/celadonmart2.asm"
+CeladonMart2Blocks: INCBIN "maps/celadonmart2.blk"
+
+INCLUDE "data/mapHeaders/fuchsiahouse3.asm"
+INCLUDE "scripts/fuchsiahouse3.asm"
+INCLUDE "data/mapObjects/fuchsiahouse3.asm"
+
+INCLUDE "data/mapHeaders/daycarem.asm"
+INCLUDE "scripts/daycarem.asm"
+INCLUDE "data/mapObjects/daycarem.asm"
+
+INCLUDE "data/mapHeaders/route12house.asm"
+INCLUDE "scripts/route12house.asm"
+INCLUDE "data/mapObjects/route12house.asm"
+
+INCLUDE "data/mapHeaders/silphco8.asm"
+INCLUDE "scripts/silphco8.asm"
+INCLUDE "data/mapObjects/silphco8.asm"
+SilphCo8Blocks: INCBIN "maps/silphco8.blk"
+
+INCLUDE "engine/menu/diploma.asm"
+
+INCLUDE "engine/overworld/trainers.asm"
+
+
+SECTION "bank16",ROMX,BANK[$16]
+
+INCLUDE "data/mapHeaders/route6.asm"
+INCLUDE "data/mapObjects/route6.asm"
+Route6Blocks: INCBIN "maps/route6.blk"
+
+INCLUDE "data/mapHeaders/route8.asm"
+INCLUDE "data/mapObjects/route8.asm"
+Route8Blocks: INCBIN "maps/route8.blk"
+
+INCLUDE "data/mapHeaders/route10.asm"
+INCLUDE "data/mapObjects/route10.asm"
+Route10Blocks: INCBIN "maps/route10.blk"
+
+INCLUDE "data/mapHeaders/route11.asm"
+INCLUDE "data/mapObjects/route11.asm"
+Route11Blocks: INCBIN "maps/route11.blk"
+
+INCLUDE "data/mapHeaders/route12.asm"
+INCLUDE "data/mapObjects/route12.asm"
+Route12Blocks: INCBIN "maps/route12.blk"
+
+INCLUDE "data/mapHeaders/route15.asm"
+INCLUDE "data/mapObjects/route15.asm"
+Route15Blocks: INCBIN "maps/route15.blk"
+
+INCLUDE "data/mapHeaders/route16.asm"
+INCLUDE "data/mapObjects/route16.asm"
+Route16Blocks: INCBIN "maps/route16.blk"
+
+INCLUDE "data/mapHeaders/route18.asm"
+INCLUDE "data/mapObjects/route18.asm"
+Route18Blocks: INCBIN "maps/route18.blk"
+
+ INCBIN "maps/unusedblocks58d7d.blk"
+
+INCLUDE "engine/battle/common_text.asm"
+
+INCLUDE "engine/experience.asm"
+
+INCLUDE "engine/overworld/oaks_aide.asm"
+
+INCLUDE "scripts/route6.asm"
+INCLUDE "scripts/route8.asm"
+INCLUDE "scripts/route10.asm"
+INCLUDE "scripts/route11.asm"
+INCLUDE "scripts/route12.asm"
+INCLUDE "scripts/route15.asm"
+INCLUDE "scripts/route16.asm"
+INCLUDE "scripts/route18.asm"
+
+INCLUDE "data/mapHeaders/fanclub.asm"
+INCLUDE "scripts/fanclub.asm"
+INCLUDE "data/mapObjects/fanclub.asm"
+FanClubBlocks:
+ INCBIN "maps/fanclub.blk"
+
+INCLUDE "data/mapHeaders/silphco2.asm"
+INCLUDE "scripts/silphco2.asm"
+INCLUDE "data/mapObjects/silphco2.asm"
+SilphCo2Blocks:
+ INCBIN "maps/silphco2.blk"
+
+INCLUDE "data/mapHeaders/silphco3.asm"
+INCLUDE "scripts/silphco3.asm"
+INCLUDE "data/mapObjects/silphco3.asm"
+SilphCo3Blocks:
+ INCBIN "maps/silphco3.blk"
+
+INCLUDE "data/mapHeaders/silphco10.asm"
+INCLUDE "scripts/silphco10.asm"
+INCLUDE "data/mapObjects/silphco10.asm"
+SilphCo10Blocks:
+ INCBIN "maps/silphco10.blk"
+
+INCLUDE "data/mapHeaders/lance.asm"
+INCLUDE "scripts/lance.asm"
+INCLUDE "data/mapObjects/lance.asm"
+LanceBlocks:
+ INCBIN "maps/lance.blk"
+
+INCLUDE "data/mapHeaders/halloffameroom.asm"
+INCLUDE "scripts/halloffameroom.asm"
+INCLUDE "data/mapObjects/halloffameroom.asm"
+HallofFameRoomBlocks:
+ INCBIN "maps/halloffameroom.blk"
+
+INCLUDE "engine/overworld/saffron_guards.asm"
+
+
+SECTION "bank17",ROMX,BANK[$17]
+
+SaffronMartBlocks:
+LavenderMartBlocks:
+CeruleanMartBlocks:
+VermilionMartBlocks: INCBIN "maps/vermilionmart.blk"
+
+CopycatsHouse2FBlocks:
+RedsHouse2FBlocks: INCBIN "maps/redshouse2f.blk"
+
+Museum1FBlocks: INCBIN "maps/museum1f.blk"
+
+Museum2FBlocks: INCBIN "maps/museum2f.blk"
+
+SaffronPokecenterBlocks:
+VermilionPokecenterBlocks:
+LavenderPokecenterBlocks:
+PewterPokecenterBlocks: INCBIN "maps/pewterpokecenter.blk"
+
+UndergroundPathEntranceRoute7Blocks:
+UndergroundPathEntranceRoute7CopyBlocks:
+UndergroundPathEntranceRoute6Blocks:
+UndergroundPathEntranceRoute5Blocks: INCBIN "maps/undergroundpathentranceroute5.blk"
+
+Route2GateBlocks:
+ViridianForestEntranceBlocks:
+ViridianForestExitBlocks: INCBIN "maps/viridianforestexit.blk"
+
+INCLUDE "data/mapHeaders/redshouse2f.asm"
+INCLUDE "scripts/redshouse2f.asm"
+INCLUDE "data/mapObjects/redshouse2f.asm"
+
+INCLUDE "engine/predefs17.asm"
+
+INCLUDE "data/mapHeaders/museum1f.asm"
+INCLUDE "scripts/museum1f.asm"
+INCLUDE "data/mapObjects/museum1f.asm"
+
+INCLUDE "data/mapHeaders/museum2f.asm"
+INCLUDE "scripts/museum2f.asm"
+INCLUDE "data/mapObjects/museum2f.asm"
+
+INCLUDE "data/mapHeaders/pewtergym.asm"
+INCLUDE "scripts/pewtergym.asm"
+INCLUDE "data/mapObjects/pewtergym.asm"
+PewterGymBlocks: INCBIN "maps/pewtergym.blk"
+
+INCLUDE "data/mapHeaders/pewterpokecenter.asm"
+INCLUDE "scripts/pewterpokecenter.asm"
+INCLUDE "data/mapObjects/pewterpokecenter.asm"
+
+INCLUDE "data/mapHeaders/ceruleanpokecenter.asm"
+INCLUDE "scripts/ceruleanpokecenter.asm"
+INCLUDE "data/mapObjects/ceruleanpokecenter.asm"
+CeruleanPokecenterBlocks: INCBIN "maps/ceruleanpokecenter.blk"
+
+INCLUDE "data/mapHeaders/ceruleangym.asm"
+INCLUDE "scripts/ceruleangym.asm"
+INCLUDE "data/mapObjects/ceruleangym.asm"
+CeruleanGymBlocks: INCBIN "maps/ceruleangym.blk"
+
+INCLUDE "data/mapHeaders/ceruleanmart.asm"
+INCLUDE "scripts/ceruleanmart.asm"
+INCLUDE "data/mapObjects/ceruleanmart.asm"
+
+INCLUDE "data/mapHeaders/lavenderpokecenter.asm"
+INCLUDE "scripts/lavenderpokecenter.asm"
+INCLUDE "data/mapObjects/lavenderpokecenter.asm"
+
+INCLUDE "data/mapHeaders/lavendermart.asm"
+INCLUDE "scripts/lavendermart.asm"
+INCLUDE "data/mapObjects/lavendermart.asm"
+
+INCLUDE "data/mapHeaders/vermilionpokecenter.asm"
+INCLUDE "scripts/vermilionpokecenter.asm"
+INCLUDE "data/mapObjects/vermilionpokecenter.asm"
+
+INCLUDE "data/mapHeaders/vermilionmart.asm"
+INCLUDE "scripts/vermilionmart.asm"
+INCLUDE "data/mapObjects/vermilionmart.asm"
+
+INCLUDE "data/mapHeaders/vermiliongym.asm"
+INCLUDE "scripts/vermiliongym.asm"
+INCLUDE "data/mapObjects/vermiliongym.asm"
+VermilionGymBlocks: INCBIN "maps/vermiliongym.blk"
+
+INCLUDE "data/mapHeaders/copycatshouse2f.asm"
+INCLUDE "scripts/copycatshouse2f.asm"
+INCLUDE "data/mapObjects/copycatshouse2f.asm"
+
+INCLUDE "data/mapHeaders/fightingdojo.asm"
+INCLUDE "scripts/fightingdojo.asm"
+INCLUDE "data/mapObjects/fightingdojo.asm"
+FightingDojoBlocks: INCBIN "maps/fightingdojo.blk"
+
+INCLUDE "data/mapHeaders/saffrongym.asm"
+INCLUDE "scripts/saffrongym.asm"
+INCLUDE "data/mapObjects/saffrongym.asm"
+SaffronGymBlocks: INCBIN "maps/saffrongym.blk"
+
+INCLUDE "data/mapHeaders/saffronmart.asm"
+INCLUDE "scripts/saffronmart.asm"
+INCLUDE "data/mapObjects/saffronmart.asm"
+
+INCLUDE "data/mapHeaders/silphco1.asm"
+INCLUDE "scripts/silphco1.asm"
+INCLUDE "data/mapObjects/silphco1.asm"
+SilphCo1Blocks: INCBIN "maps/silphco1.blk"
+
+INCLUDE "data/mapHeaders/saffronpokecenter.asm"
+INCLUDE "scripts/saffronpokecenter.asm"
+INCLUDE "data/mapObjects/saffronpokecenter.asm"
+
+INCLUDE "data/mapHeaders/viridianforestexit.asm"
+INCLUDE "scripts/viridianforestexit.asm"
+INCLUDE "data/mapObjects/viridianforestexit.asm"
+
+INCLUDE "data/mapHeaders/route2gate.asm"
+INCLUDE "scripts/route2gate.asm"
+INCLUDE "data/mapObjects/route2gate.asm"
+
+INCLUDE "data/mapHeaders/viridianforestentrance.asm"
+INCLUDE "scripts/viridianforestentrance.asm"
+INCLUDE "data/mapObjects/viridianforestentrance.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute5.asm"
+INCLUDE "scripts/undergroundpathentranceroute5.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute5.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute6.asm"
+INCLUDE "scripts/undergroundpathentranceroute6.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute6.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute7.asm"
+INCLUDE "scripts/undergroundpathentranceroute7.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute7.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute7copy.asm"
+INCLUDE "scripts/undergroundpathentranceroute7copy.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute7copy.asm"
+
+INCLUDE "data/mapHeaders/silphco9.asm"
+INCLUDE "scripts/silphco9.asm"
+INCLUDE "data/mapObjects/silphco9.asm"
+SilphCo9Blocks: INCBIN "maps/silphco9.blk"
+
+INCLUDE "data/mapHeaders/victoryroad1.asm"
+INCLUDE "scripts/victoryroad1.asm"
+INCLUDE "data/mapObjects/victoryroad1.asm"
+VictoryRoad1Blocks: INCBIN "maps/victoryroad1.blk"
+
+INCLUDE "engine/predefs17_2.asm"
+
+INCLUDE "engine/hidden_object_functions17.asm"
+
+
+SECTION "bank18",ROMX,BANK[$18]
+
+ViridianForestBlocks: INCBIN "maps/viridianforest.blk"
+UndergroundPathNSBlocks: INCBIN "maps/undergroundpathns.blk"
+UndergroundPathWEBlocks: INCBIN "maps/undergroundpathwe.blk"
+
+ INCBIN "maps/unusedblocks60258.blk"
+
+SSAnne10Blocks:
+SSAnne9Blocks: INCBIN "maps/ssanne9.blk"
+
+INCLUDE "data/mapHeaders/pokemontower1.asm"
+INCLUDE "scripts/pokemontower1.asm"
+INCLUDE "data/mapObjects/pokemontower1.asm"
+PokemonTower1Blocks: INCBIN "maps/pokemontower1.blk"
+
+INCLUDE "data/mapHeaders/pokemontower2.asm"
+INCLUDE "scripts/pokemontower2.asm"
+INCLUDE "data/mapObjects/pokemontower2.asm"
+PokemonTower2Blocks: INCBIN "maps/pokemontower2.blk"
+
+INCLUDE "data/mapHeaders/pokemontower3.asm"
+INCLUDE "scripts/pokemontower3.asm"
+INCLUDE "data/mapObjects/pokemontower3.asm"
+PokemonTower3Blocks: INCBIN "maps/pokemontower3.blk"
+
+INCLUDE "data/mapHeaders/pokemontower4.asm"
+INCLUDE "scripts/pokemontower4.asm"
+INCLUDE "data/mapObjects/pokemontower4.asm"
+PokemonTower4Blocks: INCBIN "maps/pokemontower4.blk"
+
+INCLUDE "data/mapHeaders/pokemontower5.asm"
+INCLUDE "scripts/pokemontower5.asm"
+INCLUDE "data/mapObjects/pokemontower5.asm"
+PokemonTower5Blocks: INCBIN "maps/pokemontower5.blk"
+
+INCLUDE "data/mapHeaders/pokemontower6.asm"
+INCLUDE "scripts/pokemontower6.asm"
+INCLUDE "data/mapObjects/pokemontower6.asm"
+PokemonTower6Blocks: INCBIN "maps/pokemontower6.blk"
+
+ INCBIN "maps/unusedblocks60cef.blk"
+
+INCLUDE "data/mapHeaders/pokemontower7.asm"
+INCLUDE "scripts/pokemontower7.asm"
+INCLUDE "data/mapObjects/pokemontower7.asm"
+PokemonTower7Blocks: INCBIN "maps/pokemontower7.blk"
+
+INCLUDE "data/mapHeaders/celadonmart1.asm"
+INCLUDE "scripts/celadonmart1.asm"
+INCLUDE "data/mapObjects/celadonmart1.asm"
+CeladonMart1Blocks: INCBIN "maps/celadonmart1.blk"
+
+INCLUDE "engine/overworld/cinnabar_lab.asm"
+
+INCLUDE "data/mapHeaders/viridianforest.asm"
+INCLUDE "scripts/viridianforest.asm"
+INCLUDE "data/mapObjects/viridianforest.asm"
+
+INCLUDE "data/mapHeaders/ssanne1.asm"
+INCLUDE "scripts/ssanne1.asm"
+INCLUDE "data/mapObjects/ssanne1.asm"
+SSAnne1Blocks: INCBIN "maps/ssanne1.blk"
+
+INCLUDE "data/mapHeaders/ssanne2.asm"
+INCLUDE "scripts/ssanne2.asm"
+INCLUDE "data/mapObjects/ssanne2.asm"
+SSAnne2Blocks: INCBIN "maps/ssanne2.blk"
+
+INCLUDE "data/mapHeaders/ssanne4.asm"
+INCLUDE "scripts/ssanne4.asm"
+INCLUDE "data/mapObjects/ssanne4.asm"
+SSAnne4Blocks: INCBIN "maps/ssanne4.blk"
+
+INCLUDE "data/mapHeaders/ssanne5.asm"
+INCLUDE "scripts/ssanne5.asm"
+INCLUDE "data/mapObjects/ssanne5.asm"
+SSAnne5Blocks: INCBIN "maps/ssanne5.blk"
+
+INCLUDE "data/mapHeaders/ssanne6.asm"
+INCLUDE "scripts/ssanne6.asm"
+INCLUDE "data/mapObjects/ssanne6.asm"
+SSAnne6Blocks: INCBIN "maps/ssanne6.blk"
+
+INCLUDE "data/mapHeaders/ssanne7.asm"
+INCLUDE "scripts/ssanne7.asm"
+INCLUDE "data/mapObjects/ssanne7.asm"
+SSAnne7Blocks: INCBIN "maps/ssanne7.blk"
+
+INCLUDE "data/mapHeaders/ssanne8.asm"
+INCLUDE "scripts/ssanne8.asm"
+INCLUDE "data/mapObjects/ssanne8.asm"
+SSAnne8Blocks: INCBIN "maps/ssanne8.blk"
+
+INCLUDE "data/mapHeaders/ssanne9.asm"
+INCLUDE "scripts/ssanne9.asm"
+INCLUDE "data/mapObjects/ssanne9.asm"
+
+INCLUDE "data/mapHeaders/ssanne10.asm"
+INCLUDE "scripts/ssanne10.asm"
+INCLUDE "data/mapObjects/ssanne10.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathns.asm"
+INCLUDE "scripts/undergroundpathns.asm"
+INCLUDE "data/mapObjects/undergroundpathns.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathwe.asm"
+INCLUDE "scripts/undergroundpathwe.asm"
+INCLUDE "data/mapObjects/undergroundpathwe.asm"
+
+INCLUDE "data/mapHeaders/diglettscave.asm"
+INCLUDE "scripts/diglettscave.asm"
+INCLUDE "data/mapObjects/diglettscave.asm"
+DiglettsCaveBlocks: INCBIN "maps/diglettscave.blk"
+
+INCLUDE "data/mapHeaders/silphco11.asm"
+INCLUDE "scripts/silphco11.asm"
+INCLUDE "data/mapObjects/silphco11.asm"
+SilphCo11Blocks: INCBIN "maps/silphco11.blk"
+
+INCLUDE "engine/hidden_object_functions18.asm"
+
+
+SECTION "bank19",ROMX,BANK[$19]
+
+Overworld_GFX: INCBIN "gfx/tilesets/overworld.t2.2bpp"
+Overworld_Block: INCBIN "gfx/blocksets/overworld.bst"
+
+RedsHouse1_GFX:
+RedsHouse2_GFX: INCBIN "gfx/tilesets/reds_house.t7.2bpp"
+RedsHouse1_Block:
+RedsHouse2_Block: INCBIN "gfx/blocksets/reds_house.bst"
+
+House_GFX: INCBIN "gfx/tilesets/house.t2.2bpp"
+House_Block: INCBIN "gfx/blocksets/house.bst"
+Mansion_GFX: INCBIN "gfx/tilesets/mansion.t2.2bpp"
+Mansion_Block: INCBIN "gfx/blocksets/mansion.bst"
+ShipPort_GFX: INCBIN "gfx/tilesets/ship_port.t2.2bpp"
+ShipPort_Block: INCBIN "gfx/blocksets/ship_port.bst"
+Interior_GFX: INCBIN "gfx/tilesets/interior.t1.2bpp"
+Interior_Block: INCBIN "gfx/blocksets/interior.bst"
+Plateau_GFX: INCBIN "gfx/tilesets/plateau.t10.2bpp"
+Plateau_Block: INCBIN "gfx/blocksets/plateau.bst"
+
+
+SECTION "bank1A",ROMX,BANK[$1A]
+
+INCLUDE "engine/battle/decrement_pp.asm"
+
+Version_GFX:
+IF DEF(_RED)
+ INCBIN "gfx/red/redgreenversion.1bpp" ; 10 tiles
+ENDC
+IF DEF(_BLUE)
+ INCBIN "gfx/blue/blueversion.1bpp" ; 8 tiles
+ENDC
+
+Dojo_GFX:
+Gym_GFX: INCBIN "gfx/tilesets/gym.2bpp"
+Dojo_Block:
+Gym_Block: INCBIN "gfx/blocksets/gym.bst"
+
+Mart_GFX:
+Pokecenter_GFX: INCBIN "gfx/tilesets/pokecenter.2bpp"
+Mart_Block:
+Pokecenter_Block: INCBIN "gfx/blocksets/pokecenter.bst"
+
+ForestGate_GFX:
+Museum_GFX:
+Gate_GFX: INCBIN "gfx/tilesets/gate.t1.2bpp"
+ForestGate_Block:
+Museum_Block:
+Gate_Block: INCBIN "gfx/blocksets/gate.bst"
+
+Forest_GFX: INCBIN "gfx/tilesets/forest.2bpp"
+Forest_Block: INCBIN "gfx/blocksets/forest.bst"
+Facility_GFX: INCBIN "gfx/tilesets/facility.2bpp"
+Facility_Block: INCBIN "gfx/blocksets/facility.bst"
+
+
+SECTION "bank1B",ROMX,BANK[$1B]
+
+Cemetery_GFX: INCBIN "gfx/tilesets/cemetery.t4.2bpp"
+Cemetery_Block: INCBIN "gfx/blocksets/cemetery.bst"
+Cavern_GFX: INCBIN "gfx/tilesets/cavern.t14.2bpp"
+Cavern_Block: INCBIN "gfx/blocksets/cavern.bst"
+Lobby_GFX: INCBIN "gfx/tilesets/lobby.t2.2bpp"
+Lobby_Block: INCBIN "gfx/blocksets/lobby.bst"
+Ship_GFX: INCBIN "gfx/tilesets/ship.t6.2bpp"
+Ship_Block: INCBIN "gfx/blocksets/ship.bst"
+Lab_GFX: INCBIN "gfx/tilesets/lab.t4.2bpp"
+Lab_Block: INCBIN "gfx/blocksets/lab.bst"
+Club_GFX: INCBIN "gfx/tilesets/club.t5.2bpp"
+Club_Block: INCBIN "gfx/blocksets/club.bst"
+Underground_GFX: INCBIN "gfx/tilesets/underground.t7.2bpp"
+Underground_Block: INCBIN "gfx/blocksets/underground.bst"
+
+
+SECTION "bank1C",ROMX,BANK[$1C]
+
+INCLUDE "engine/gamefreak.asm"
+INCLUDE "engine/hall_of_fame.asm"
+INCLUDE "engine/overworld/healing_machine.asm"
+INCLUDE "engine/overworld/player_animations.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"
+INCLUDE "engine/palettes.asm"
+INCLUDE "engine/save.asm"
+
+
+SECTION "bank1D",ROMX,BANK[$1D]
+
+CopycatsHouse1FBlocks: INCBIN "maps/copycatshouse1f.blk"
+
+CinnabarMartBlocks:
+PewterMartBlocks: INCBIN "maps/pewtermart.blk"
+
+FuchsiaHouse1Blocks: INCBIN "maps/fuchsiahouse1.blk"
+
+CinnabarPokecenterBlocks:
+FuchsiaPokecenterBlocks: INCBIN "maps/fuchsiapokecenter.blk"
+
+CeruleanHouse2Blocks: INCBIN "maps/ceruleanhouse2.blk"
+
+INCLUDE "engine/HoF_room_pc.asm"
+
+INCLUDE "engine/status_ailments.asm"
+
+INCLUDE "engine/items/itemfinder.asm"
+
+INCLUDE "scripts/ceruleancity2.asm"
+
+INCLUDE "data/mapHeaders/viridiangym.asm"
+INCLUDE "scripts/viridiangym.asm"
+INCLUDE "data/mapObjects/viridiangym.asm"
+ViridianGymBlocks: INCBIN "maps/viridiangym.blk"
+
+INCLUDE "data/mapHeaders/pewtermart.asm"
+INCLUDE "scripts/pewtermart.asm"
+INCLUDE "data/mapObjects/pewtermart.asm"
+
+INCLUDE "data/mapHeaders/unknowndungeon1.asm"
+INCLUDE "scripts/unknowndungeon1.asm"
+INCLUDE "data/mapObjects/unknowndungeon1.asm"
+UnknownDungeon1Blocks: INCBIN "maps/unknowndungeon1.blk"
+
+INCLUDE "data/mapHeaders/ceruleanhouse2.asm"
+INCLUDE "scripts/ceruleanhouse2.asm"
+INCLUDE "data/mapObjects/ceruleanhouse2.asm"
+
+INCLUDE "engine/menu/vending_machine.asm"
+
+INCLUDE "data/mapHeaders/fuchsiahouse1.asm"
+INCLUDE "scripts/fuchsiahouse1.asm"
+INCLUDE "data/mapObjects/fuchsiahouse1.asm"
+
+INCLUDE "data/mapHeaders/fuchsiapokecenter.asm"
+INCLUDE "scripts/fuchsiapokecenter.asm"
+INCLUDE "data/mapObjects/fuchsiapokecenter.asm"
+
+INCLUDE "data/mapHeaders/fuchsiahouse2.asm"
+INCLUDE "scripts/fuchsiahouse2.asm"
+INCLUDE "data/mapObjects/fuchsiahouse2.asm"
+FuchsiaHouse2Blocks: INCBIN "maps/fuchsiahouse2.blk"
+
+INCLUDE "data/mapHeaders/safarizoneentrance.asm"
+INCLUDE "scripts/safarizoneentrance.asm"
+INCLUDE "data/mapObjects/safarizoneentrance.asm"
+SafariZoneEntranceBlocks: INCBIN "maps/safarizoneentrance.blk"
+
+INCLUDE "data/mapHeaders/fuchsiagym.asm"
+INCLUDE "scripts/fuchsiagym.asm"
+INCLUDE "data/mapObjects/fuchsiagym.asm"
+FuchsiaGymBlocks: INCBIN "maps/fuchsiagym.blk"
+
+INCLUDE "data/mapHeaders/fuchsiameetingroom.asm"
+INCLUDE "scripts/fuchsiameetingroom.asm"
+INCLUDE "data/mapObjects/fuchsiameetingroom.asm"
+FuchsiaMeetingRoomBlocks: INCBIN "maps/fuchsiameetingroom.blk"
+
+INCLUDE "data/mapHeaders/cinnabargym.asm"
+INCLUDE "scripts/cinnabargym.asm"
+INCLUDE "data/mapObjects/cinnabargym.asm"
+CinnabarGymBlocks: INCBIN "maps/cinnabargym.blk"
+
+INCLUDE "data/mapHeaders/lab1.asm"
+INCLUDE "scripts/lab1.asm"
+INCLUDE "data/mapObjects/lab1.asm"
+Lab1Blocks: INCBIN "maps/lab1.blk"
+
+INCLUDE "data/mapHeaders/lab2.asm"
+INCLUDE "scripts/lab2.asm"
+INCLUDE "data/mapObjects/lab2.asm"
+Lab2Blocks: INCBIN "maps/lab2.blk"
+
+INCLUDE "data/mapHeaders/lab3.asm"
+INCLUDE "scripts/lab3.asm"
+INCLUDE "data/mapObjects/lab3.asm"
+Lab3Blocks: INCBIN "maps/lab3.blk"
+
+INCLUDE "data/mapHeaders/lab4.asm"
+INCLUDE "scripts/lab4.asm"
+INCLUDE "data/mapObjects/lab4.asm"
+Lab4Blocks: INCBIN "maps/lab4.blk"
+
+INCLUDE "data/mapHeaders/cinnabarpokecenter.asm"
+INCLUDE "scripts/cinnabarpokecenter.asm"
+INCLUDE "data/mapObjects/cinnabarpokecenter.asm"
+
+INCLUDE "data/mapHeaders/cinnabarmart.asm"
+INCLUDE "scripts/cinnabarmart.asm"
+INCLUDE "data/mapObjects/cinnabarmart.asm"
+
+INCLUDE "data/mapHeaders/copycatshouse1f.asm"
+INCLUDE "scripts/copycatshouse1f.asm"
+INCLUDE "data/mapObjects/copycatshouse1f.asm"
+
+INCLUDE "data/mapHeaders/gary.asm"
+INCLUDE "scripts/gary.asm"
+INCLUDE "data/mapObjects/gary.asm"
+GaryBlocks: INCBIN "maps/gary.blk"
+
+INCLUDE "data/mapHeaders/lorelei.asm"
+INCLUDE "scripts/lorelei.asm"
+INCLUDE "data/mapObjects/lorelei.asm"
+LoreleiBlocks: INCBIN "maps/lorelei.blk"
+
+INCLUDE "data/mapHeaders/bruno.asm"
+INCLUDE "scripts/bruno.asm"
+INCLUDE "data/mapObjects/bruno.asm"
+BrunoBlocks: INCBIN "maps/bruno.blk"
+
+INCLUDE "data/mapHeaders/agatha.asm"
+INCLUDE "scripts/agatha.asm"
+INCLUDE "data/mapObjects/agatha.asm"
+AgathaBlocks: INCBIN "maps/agatha.blk"
+
+INCLUDE "engine/menu/league_pc.asm"
+
+INCLUDE "engine/overworld/hidden_items.asm"
+
+
+SECTION "bank1E",ROMX,BANK[$1E]
+
+INCLUDE "engine/battle/animations.asm"
+
+INCLUDE "engine/overworld/cut2.asm"
+
+INCLUDE "engine/overworld/ssanne.asm"
+
+RedFishingTilesFront: INCBIN "gfx/red_fishing_tile_front.2bpp"
+RedFishingTilesBack: INCBIN "gfx/red_fishing_tile_back.2bpp"
+RedFishingTilesSide: INCBIN "gfx/red_fishing_tile_side.2bpp"
+RedFishingRodTiles: INCBIN "gfx/red_fishingrod_tiles.2bpp"
+
+INCLUDE "data/animations.asm"
+
+INCLUDE "engine/evolution.asm"
+
+INCLUDE "engine/overworld/elevator.asm"
+
+INCLUDE "engine/items/tm_prices.asm"
+
+IF DEF(_OPTION_BEACH_HOUSE)
+SECTION "bank3C",ROMX[$4314],BANK[$3C]
+
+BeachHouse_GFX:
+ INCBIN "gfx/tilesets/beachhouse.2bpp"
+
+BeachHouse_Block:
+ INCBIN "gfx/blocksets/beachhouse.bst"
+ENDC
+
+SECTION "bank3d",ROMX,BANK[$3D]
+
+INCLUDE "engine/random.asm"
diff --git a/wram.asm b/wram.asm
index b0586b11..7d642d2e 100755
--- a/wram.asm
+++ b/wram.asm
@@ -1,2297 +1,2305 @@
-
-INCLUDE "constants.asm"
-
-flag_array: MACRO
- ds ((\1) + 7) / 8
-ENDM
-
-box_struct_length EQU 25 + NUM_MOVES * 2
-box_struct: MACRO
-\1Species:: db
-\1HP:: dw
-\1BoxLevel:: db
-\1Status:: db
-\1Type::
-\1Type1:: db
-\1Type2:: db
-\1CatchRate:: db
-\1Moves:: ds NUM_MOVES
-\1OTID:: dw
-\1Exp:: ds 3
-\1HPExp:: dw
-\1AttackExp:: dw
-\1DefenseExp:: dw
-\1SpeedExp:: dw
-\1SpecialExp:: dw
-\1DVs:: ds 2
-\1PP:: ds NUM_MOVES
-ENDM
-
-party_struct: MACRO
- box_struct \1
-\1Level:: db
-\1Stats::
-\1MaxHP:: dw
-\1Attack:: dw
-\1Defense:: dw
-\1Speed:: dw
-\1Special:: dw
-ENDM
-
-battle_struct: MACRO
-\1Species:: db
-\1HP:: dw
-\1BoxLevel:: db
-\1Status:: db
-\1Type::
-\1Type1:: db
-\1Type2:: db
-\1CatchRate:: db
-\1Moves:: ds NUM_MOVES
-\1DVs:: ds 2
-\1Level:: db
-\1MaxHP:: dw
-\1Attack:: dw
-\1Defense:: dw
-\1Speed:: dw
-\1Special:: dw
-\1PP:: ds NUM_MOVES
-ENDM
-
-
-SECTION "WRAM Bank 0", WRAM0
-
-wc000:: ds 1
-wc001:: ds 1
-wc002:: ds 1
-wc003:: ds 1
-wc004:: ds 1
-wc005:: ds 1
-wc006:: ds 8
-wc00e:: ds 4
-wc012:: ds 4
-wc016:: ds 16
-wc026:: ds 1
-wc027:: ds 1
-wc028:: ds 2
-wc02a:: ds 1
-wc02b:: ds 1
-wc02c:: ds 1
-wc02d:: ds 1
-wc02e:: ds 8
-wc036:: ds 8
-wc03e:: ds 8
-wc046:: ds 8
-wc04e:: ds 8
-wc056:: ds 8
-wc05e:: ds 8
-wc066:: ds 8
-wc06e:: ds 8
-wc076:: ds 8
-wc07e:: ds 8
-wc086:: ds 8
-wc08e:: ds 8
-wc096:: ds 8
-wc09e:: ds 8
-wc0a6:: ds 8
-wc0ae:: ds 8
-wc0b6:: ds 8
-wc0be:: ds 8
-wc0c6:: ds 8
-wc0ce:: ds 1
-wc0cf:: ds 1
-wc0d0:: ds 1
-wc0d1:: ds 1
-wc0d2:: ds 1
-wc0d3:: ds 1
-wc0d4:: ds 1
-wc0d5:: ds 1
-wc0d6:: ds 8
-wc0de:: ds 8
-wc0e6:: ds 1
-wc0e7:: ds 1
-wc0e8:: ds 1
-wc0e9:: ds 1
-wc0ea:: ds 1
-wc0eb:: ds 1
-wc0ec:: ds 1
-wc0ed:: ds 1
-wc0ee:: ds 1
-wc0ef:: ds 1
-wc0f0:: ds 1
-wc0f1:: ds 1
-wc0f2:: ds 14
-
-
-SECTION "Sprite State Data", WRAM0[$c100]
-
-wSpriteStateData1:: ; c100
-; data for all sprites on the current map
-; holds info for 16 sprites with $10 bytes each
-; player sprite is always sprite 0
-; C1x0: picture ID (fixed, loaded at map init)
-; C1x1: movement status (0: uninitialized, 1: ready, 2: delayed, 3: moving)
-; C1x2: sprite image index (changed on update, $ff if off screen, includes facing direction, progress in walking animation and a sprite-specific offset)
-; C1x3: Y screen position delta (-1,0 or 1; added to c1x4 on each walking animation update)
-; C1x4: Y screen position (in pixels, always 4 pixels above grid which makes sprites appear to be in the center of a tile)
-; C1x5: X screen position delta (-1,0 or 1; added to c1x6 on each walking animation update)
-; C1x6: X screen position (in pixels, snaps to grid if not currently walking)
-; C1x7: intra-animation-frame counter (counting upwards to 4 until c1x8 is incremented)
-; C1x8: animation frame counter (increased every 4 updates, hold four states (totalling to 16 walking frames)
-; C1x9: facing direction (0: down, 4: up, 8: left, $c: right)
-; C1xA
-; C1xB
-; C1xC
-; C1xD
-; C1xE
-; C1xF
- ds $10 * $10
-
-
-SECTION "Sprite State Data 2", WRAM0[$c200]
-
-wSpriteStateData2:: ; c200
-; more data for all sprites on the current map
-; holds info for 16 sprites with $10 bytes each
-; player sprite is always sprite 0
-; C2x0: walk animation counter (counting from $10 backwards when moving)
-; C2x1:
-; C2x2: Y displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged)
-; C2x3: X displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged)
-; C2x4: Y position (in 2x2 tile grid steps, topmost 2x2 tile has value 4)
-; C2x5: X position (in 2x2 tile grid steps, leftmost 2x2 tile has value 4)
-; C2x6: movement byte 1 (determines whether a sprite can move, $ff:not moving, $fe:random movements, others unknown)
-; C2x7: (?) (set to $80 when in grass, else $0; may be used to draw grass above the sprite)
-; C2x8: delay until next movement (counted downwards, status (c1x1) is set to ready if reached 0)
-; C2x9
-; C2xA
-; C2xB
-; C2xC
-; C2xD
-; C2xE: sprite image base offset (in video ram, player always has value 1, used to compute c1x2)
-; C2xF
- ds $10 * $10
-
-
-SECTION "OAM Buffer", WRAM0[$c300]
-
-wOAMBuffer:: ; c300
-; buffer for OAM data. Copied to OAM by DMA
- ds 4 * 40
-
-wTileMap:: ; c3a0
-; buffer for tiles that are visible on screen (20 columns by 18 rows)
- ds 20 * 18
-
-wSerialPartyMonsPatchList:: ; c508
-; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer
-
-wTileMapBackup:: ; c508
-; buffer for temporarily saving and restoring current screen's tiles
-; (e.g. if menus are drawn on top)
-; ds 20 * 18
-
- ds 200
-
-wSerialEnemyMonsPatchList:: ; c5d0
-; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer
- ds 200
-
- ds 80
-
-wTempPic::
-wOverworldMap:: ; c6e8
- ds 1300
-
-wScreenEdgeTiles:: ; cbfc
-; the tiles of the row or column to be redrawn by RedrawExposedScreenEdge
- ds 20 * 2
-
-; coordinates of the position of the cursor for the top menu item (id 0)
-wTopMenuItemY:: ; cc24
- ds 1
-wTopMenuItemX:: ; cc25
- ds 1
-
-wCurrentMenuItem:: ; cc26
-; the id of the currently selected menu item
-; the top item has id 0, the one below that has id 1, etc.
-; note that the "top item" means the top item currently visible on the screen
-; add this value to [wListScrollOffset] to get the item's position within the list
- ds 1
-
-wTileBehindCursor:: ; cc27
-; the tile that was behind the menu cursor's current location
- ds 1
-
-wMaxMenuItem:: ; cc28
-; id of the bottom menu item
- ds 1
-
-wMenuWatchedKeys:: ; cc29
-; bit mask of keys that the menu will respond to
- ds 1
-
-wLastMenuItem:: ; cc2a
-; id of previously selected menu item
- ds 1
-
-wcc2b:: ds 1
-wcc2c:: ds 1
-wcc2d:: ds 1
-
-wPlayerMoveListIndex:: ; cc2e
- ds 1
-
-wPlayerMonNumber:: ; cc2f
- ds 1
-
-wMenuCursorLocation:: ; cc30
-; the address of the menu cursor's current location within wTileMap
- ds 2
-
- ds 2
-
-wMenuJoypadPollCount:: ; cc34
-; how many times should HandleMenuInput poll the joypad state before it returns?
- ds 1
-
-wMenuItemToSwap:: ; cc35
-; id of menu item selected for swapping (counts from 1) (0 means that no menu item has been selected for swapping)
- ds 1
-
-wListScrollOffset:: ; cc36
-; offset of the current top menu item from the beginning of the list
-; keeps track of what section of the list is on screen
- ds 1
-
-wcc37:: ds 1
-
-wTradeCenterPointerTableIndex:: ; cc38
- ds 1
-
- ds 1
-
-wcc3a:: ds 1
-wcc3b:: ds 1
-
-wDoNotWaitForButtonPressAfterDisplayingText:: ; cc3c
-; if non-zero, skip waiting for a button press after displaying text in DisplayTextID
- ds 1
-
-wSerialSyncAndExchangeNybbleReceiveData:: ; cc3d
-; the final received nybble is stored here by Serial_SyncAndExchangeNybble
-
-wSerialExchangeNybbleTempReceiveData:: ; cc3d
-; temporary nybble used by Serial_ExchangeNybble
-
-wLinkMenuSelectionReceiveBuffer:: ; cc3d
-; two byte buffer
-; the received menu selection is stored twice
-
-wcc3d:: ds 1
-
-wSerialExchangeNybbleReceiveData:: ; cc3e
-; the final received nybble is stored here by Serial_ExchangeNybble
- ds 1
-
- ds 3
-
-wSerialExchangeNybbleSendData:: ; cc42
-; this nybble is sent when using Serial_SyncAndExchangeNybble or Serial_ExchangeNybble
-
-wLinkMenuSelectionSendBuffer:: ; cc42
-; two byte buffer
-; the menu selection byte is stored twice before sending
-
- ds 5
-
-wLinkTimeoutCounter:: ; cc47
-; 1 byte
-
-wUnknownSerialCounter:: ; cc47
-; 2 bytes
-
-wcc47:: ds 1
-wcc48:: ds 1
-
-wWhichTradeMonSelectionMenu:: ; cc49
-; $00 = player mons
-; $01 = enemy mons
-
-wcc49:: ds 1
-
-wMenuWrappingEnabled:: ; cc4a
-; set to 1 if you can go from the bottom to the top or top to bottom of a menu
-; set to 0 if you can't go past the top or bottom of the menu
- ds 1
-
-wcc4b:: ds 2
-wcc4d:: ds 1
-
-wPredefID:: ; cc4e
- ds 1
-wPredefRegisters:: ; cc4f
- ds 6
-
-wTrainerHeaderFlagBit:: ; cc55
- ds 1
-
- ds 1
-
-wNPCMovementScriptPointerTableNum:: ; cc57
-; which NPC movement script pointer is being used
-; 0 if an NPC movement script is not running
- ds 1
-
-wNPCMovementScriptBank:: ; cc58
-; ROM bank of current NPC movement script
- ds 1
-
- ds 2
-
-wHallOfFame:: ; cc5b
-wBoostExpByExpAll:: ; cc5b
-wAnimationType:: ; cc5b
-; values between 0-6. Shake screen horizontally, shake screen vertically, blink Pokemon...
-
-wcc5b:: ds 1
-wcc5c:: ds 1
-wcc5d:: ds 1
-wcc5e:: ds 13
-
-wcc6b:: ds 14
-wcc79:: ds 30
-
-wNPCMovementDirections2:: ; cc97
-
-wSwitchPartyMonTempBuffer:: ; cc97
-; temporary buffer when swapping party mon data
- ds 10
-
-wcca1:: ds 49
-
-wRLEByteCount:: ; ccd2
- ds 1
-
-wSimulatedJoypadStatesEnd:: ; ccd3
-; this is the end of the joypad states
-; the list starts above this address and extends downwards in memory until here
-; overloaded with below labels
-
-wccd3:: ds 1
-wccd4:: ds 1
-
-; if [ccd5] != 1, the second AI layer is not applied
-wAILayer2Encouragement:: ; ccd5
- ds 1
- ds 1
-
-; current HP of player and enemy substitutes
-wPlayerSubstituteHP:: ; ccd7
- ds 1
-wEnemySubstituteHP:: ; ccd8
- ds 1
-
-wccd9:: ds 2
-
-wMoveMenuType:: ; ccdb
-; 0=regular, 1=mimic, 2=above message box (relearn, heal pp..)
- ds 1
-
-wPlayerSelectedMove:: ; ccdc
- ds 1
-wEnemySelectedMove:: ; ccdd
- ds 1
-
-wLinkBattleRandomNumberListIndex:: ; ccde
- ds 1
-
-wAICount:: ; ccdf
-; number of times remaining that AI action can occur
- ds 1
-
- ds 2
-
-wEnemyMoveListIndex:: ; cce2
- ds 1
-
-wcce3:: ds 1
-wcce4:: ds 1
-
-wTotalPayDayMoney:: ; cce5
-; total amount of money made using Pay Day during the current battle
- ds 3
-
-wSafariEscapeFactor:: ; cce8
- ds 1
-wSafariBaitFactor:: ; cce9
- ds 1;
-
- ds 1
-
-wcceb:: ds 1
-wccec:: ds 1
-
-wMonIsDisobedient:: ds 1 ; cced
-
-wPlayerDisabledMoveNumber:: ds 1 ; ccee
-wEnemyDisabledMoveNumber:: ds 1 ; ccef
-
-wccf0:: ds 1
-
-wPlayerUsedMove:: ds 1 ; ccf1
-wEnemyUsedMove:: ds 1 ; ccf2
-
-wccf3:: ds 1
-
-wMoveDidntMiss:: ds 1 ; ccf4
-
-wPartyFoughtCurrentEnemyFlags:: ; ccf5
-; flags that indicate which party members have fought the current enemy mon
- flag_array 6
-
-wccf6:: ds 1
-wccf7:: ds 14
-
-wUnknownSlotVar:: ; cd05
-
-wEnemyNumHits:: ; cd05
-; number of hits by enemy in attacks like Double Slap, etc.
-
-wEnemyBideAccumulatedDamage:: ; cd05
-; the amount of damage accumulated by the enemy while biding (2 bytes)
-
-ds 10
-
-wInGameTradeGiveMonSpecies:: ; cd0f
-
-wPlayerMonUnmodifiedLevel:: ; cd0f
- ds 1
-
-wInGameTradeTextPointerTablePointer:: ; cd10
-
-wPlayerMonUnmodifiedMaxHP:: ; cd10
- ds 2
-
-wInGameTradeTextPointerTableIndex:: ; cd12
-
-wPlayerMonUnmodifiedAttack:: ; cd12
- ds 1
-wInGameTradeGiveMonName:: ; cd13
- ds 1
-wPlayerMonUnmodifiedDefense:: ; cd14
- ds 2
-wPlayerMonUnmodifiedSpeed:: ; cd16
- ds 2
-wPlayerMonUnmodifiedSpecial:: ; cd18
- ds 2
-
-; stat modifiers for the player's current pokemon
-; value can range from 1 - 13 ($1 to $D)
-; 7 is normal
-
-wPlayerMonStatMods::
-wPlayerMonAttackMod:: ; cd1a
- ds 1
-wPlayerMonDefenseMod:: ; cd1b
- ds 1
-wPlayerMonSpeedMod:: ; cd1c
- ds 1
-wPlayerMonSpecialMod:: ; cd1d
- ds 1
-
-wInGameTradeReceiveMonName:: ; cd1e
-
-wPlayerMonAccuracyMod:: ; cd1e
- ds 1
-wPlayerMonEvasionMod:: ; cd1f
- ds 1
-
- ds 3
-
-wEnemyMonUnmodifiedLevel:: ; cd23
- ds 1
-wEnemyMonUnmodifiedMaxHP:: ; cd24
- ds 2
-wEnemyMonUnmodifiedAttack:: ; cd26
- ds 2
-wEnemyMonUnmodifiedDefense:: ; cd28
- ds 1
-
-wInGameTradeMonNick:: ; cd29
- ds 1
-
-wEnemyMonUnmodifiedSpeed:: ; cd2a
- ds 2
-wEnemyMonUnmodifiedSpecial:: ; cd2c
- ds 1
-
-wEngagedTrainerClass:: ; cd2d
- ds 1
-wEngagedTrainerSet:: ; cd2e
-; ds 1
-
-; stat modifiers for the enemy's current pokemon
-; value can range from 1 - 13 ($1 to $D)
-; 7 is normal
-
-wEnemyMonStatMods::
-wEnemyMonAttackMod:: ; cd2e
- ds 1
-wEnemyMonDefenseMod:: ; cd2f
- ds 1
-wEnemyMonSpeedMod:: ; cd30
- ds 1
-wEnemyMonSpecialMod:: ; cd31
- ds 1
-wEnemyMonAccuracyMod:: ; cd32
- ds 1
-wEnemyMonEvasionMod:: ; cd33
- ds 1
-
-wInGameTradeReceiveMonSpecies::
- ds 1
-
- ds 2
-
-wNPCMovementDirections2Index:: ; cd37
-
-wcd37:: ds 1
-
-wSimulatedJoypadStatesIndex:: ; cd38
-; the next simulated joypad state is at wSimulatedJoypadStatesEnd plus this value minus 1
-; 0 if the joypad state is not being simulated
- ds 1
-
-wWastedByteCD39:: ; cd39
-; written to but nothing ever reads it
- ds 1
-
-wWastedByteCD3A:: ; cd3a
-; written to but nothing ever reads it
- ds 1
-
-wOverrideSimulatedJoypadStatesMask:: ; cd3b
-; mask indicating which real button presses can override simulated ones
-; XXX is it ever not 0?
- ds 1
-
- ds 1
-
-wTradedPlayerMonSpecies:: ; cd3d
-
-wTradingWhichPlayerMon:: ; cd3d
-
-wChangeBoxSavedMapTextPointer:: ; cd3d
-
-wFlyAnimUsingCoordList:: ; cd3d
-
-wPlayerSpinInPlaceAnimFrameDelay:: ; cd3d
-
-wPlayerSpinWhileMovingUpOrDownAnimDeltaY:: ; cd3d
-
-wHiddenObjectFunctionArgument:: ; cd3d
-
-wSubtrahend:: ; cd3d
-; subtract (BCD) wSubtrahend, wSubtrahend+1, wSubtrahend+2
-
-wWhichTrade:: ; cd3d
-; which entry from TradeMons to select
-
-wTrainerSpriteOffset:: ; cd3d
- ds 1
-
-wTradedEnemyMonSpecies:: ; cd3e
-
-wTradingWhichEnemyMon:: ; cd3e
-
-wFlyAnimCounter:: ; cd3e
-
-wPlayerSpinInPlaceAnimFrameDelayDelta:: ; cd3e
-
-wPlayerSpinWhileMovingUpOrDownAnimMaxY:: ; cd3e
-
-wHiddenObjectFunctionRomBank:: ; cd3e
-
-wTrainerEngageDistance:: ; cd3e
- ds 1
-
-wNameOfPlayerMonToBeTraded:: ; cd3f
-
-wFlyAnimBirdSpriteImageIndex:: ; cd3f
-
-wPlayerSpinInPlaceAnimFrameDelayEndValue:: ; cd3f
-
-wPlayerSpinWhileMovingUpOrDownAnimFrameDelay:: ; cd3f
-
-wHiddenObjectIndex:: ; cd3f
-
-wTrainerFacingDirection:: ; cd3f
-wcd3f::
- ds 1
-
-wPlayerSpinInPlaceAnimSoundID:: ; cd40
-
-wHiddenObjectY:: ; cd40
-
-wTrainerScreenY:: ; cd40
- ds 1
-
-wTradedPlayerMonOT:: ; cd41
-
-wHiddenObjectX:: ; cd41
-
-wTrainerScreenX:: ; cd41
- ds 1
-
-wcd42:: ds 1
-wcd43:: ds 1
-wcd44:: ds 1
-wcd45:: ds 1
-wcd46:: ds 1
-wcd47:: ds 1
-wcd48:: ds 1
-wcd49:: ds 1
-wcd4a:: ds 1
-wcd4b:: ds 1
-
-wTradedPlayerMonOTID:: ; cd4c
-
-wcd4c:: ds 1
-wcd4d:: ds 1
-
-wTradedEnemyMonOT:: ; cd4e
-
-wcd4e:: ds 1
-wcd4f:: ds 1
-wcd50:: ds 9
-
-wTradedEnemyMonOTID:: ; cd59
- ds 2
-
-wcd5b:: ds 1
-wcd5c:: ds 1
-
-wMonPartySpriteSpecies:: ; cd5d
- ds 1
-
-wLeftGBMonSpecies:: ; cd5e
-; in the trade animation, the mon that leaves the left gameboy
- ds 1
-
-wRightGBMonSpecies:: ; cd5f
-; in the trade animation, the mon that leaves the right gameboy
- ds 1
-
-wFlags_0xcd60:: ; cd60
-; bit 0: is player engaged by trainer (to avoid being engaged by multiple trainers simultaneously)
-; bit 1: boulder dust animation (from using Strength) pending
-; bit 5: don't play sound when A or B is pressed in menu
-; bit 6: tried pushing against boulder once (you need to push twice before it will move)
- ds 1
-
- ds 9
-
-wcd6a:: ds 1
-
-wJoyIgnore:: ; cd6b
-; Set buttons are ignored.
- ds 1
-
-wcd6c:: ds 1
-wcd6d:: ds 4
-wcd71:: ds 1
-wcd72:: ds 5
-wcd77:: ds 1
-wcd78:: ds 9
-
-wSerialOtherGameboyRandomNumberListBlock:: ; cd81
-; buffer for transferring the random number list generated by the other gameboy
-
-wTileMapBackup2:: ; cd81
-; second buffer for temporarily saving and restoring current screen's tiles (e.g. if menus are drawn on top)
- ds 20 * 18
-
-wBuffer:: ; cee9
-; Temporary storage area of 30 bytes.
-wHPBarMaxHP:: ; cee9
- ds 2
-wHPBarOldHP:: ; ceeb
- ds 2
-wHPBarNewHP:: ; ceed
- ds 2
-wHPBarDelta:: ; ceef
- ds 1
-
-wcef0:: ds 1
-wcef1:: ds 12
-
-wHPBarHPDifference:: ; cefd
- ds 1
- ds 7
-
-wcf05:: ds 1
-wcf06:: ds 1
-
-wAnimSoundID:: ; cf07
-; sound ID during battle animations
- ds 1
-
-wcf08:: ds 1
-wcf09:: ds 1
-wcf0a:: ds 1
-wBattleResult:: ; cf0b
-; $00 - win
-; $01 - lose
-; $02 - draw
- ds 1
-
-wAutoTextBoxDrawingControl:: ; cf0c
-; bit 0: if set, DisplayTextID automatically draws a text box
- ds 1
-
-wcf0d:: ds 1
-wcf0e:: ds 1
-wcf0f:: ds 1
-
-wNPCMovementScriptFunctionNum:: ; cf10
-; which script function within the pointer table indicated by
-; wNPCMovementScriptPointerTableNum
- ds 1
-
-wcf11:: ds 1
-
-wPredefParentBank:: ; cf12
- ds 1
-
-wSpriteIndex:: ds 1
-
-wCurSpriteMovement2:: ; cf14
-; movement byte 2 of current sprite
- ds 1
-
- ds 2
-
-wNPCMovementScriptSpriteOffset:: ; cf17
-; sprite offset of sprite being controlled by NPC movement script
- ds 1
-
-wcf18:: ds 2
-
-wOnSGB:: ; cf1b
-; if running on SGB, it's 1, else it's 0
- ds 1
-
-wcf1c:: ds 1
-wcf1d:: ds 1
-wcf1e:: ds 1
-wcf1f:: ds 6
-wcf25:: ds 8
-wcf2d:: ds 1
-wcf2e:: ds 2
-wcf30:: ds 7
-wcf37:: ds 20
-wcf4b:: ds 1
-wcf4c:: ds 1
-wGainBoostedExp:: ; cf4d
- ds 1
- ds 17
-
-wGymCityName:: ; cf5f
-wStringBuffer1:: ; cf5f
- ds 16 + 1
-wGymLeaderName:: ; cf70
-wStringBuffer2:: ; cf70
- ds 16 + 1
-wStringBuffer3:: ; cf81
- ds 9 + 1
-
-wList:: ; cf8b
- ds 2
-
-wcf8d:: ds 1
-wcf8e:: ds 1
-
-wItemPrices:: ; cf8f
- ds 2
-
-wcf91:: ds 1
-
-wWhichPokemon:: ; cf92
-; which pokemon you selected
- ds 1
-
-wcf93:: ds 1
-
-wHPBarType:: ; cf94
-; type of HP bar
-; $00 = enemy HUD in battle
-; $01 = player HUD in battle / status screen
-; $02 = party menu
-
-wListMenuID:: ; cf94
-; ID used by DisplayListMenuID
- ds 1
-
-wcf95:: ds 1
-wcf96:: ds 1
-wcf97:: ds 1
-
-; LoadMonData copies mon data here
-wLoadedMon:: party_struct wLoadedMon ; cf98
-
-wFontLoaded:: ; cfc4
-; bit 0: The space in VRAM that is used to store walk animation tile patterns
-; for the player and NPCs is in use for font tile patterns.
-; This means that NPC movement must be disabled.
-; The other bits are unused.
- ds 1
-
-wWalkCounter:: ; cfc5
-; walk animation counter
- ds 1
-
-wTileInFrontOfPlayer:: ; cfc6
-; background tile number in front of the player (either 1 or 2 steps ahead)
- ds 1
-
-wMusicHeaderPointer:: ; cfc7
-; (the current music channel address - $4000) / 3
- ds 1
-
-wcfc8:: ds 1
-wcfc9:: ds 1
-wcfca:: ds 1
-
-wUpdateSpritesEnabled:: ; cfcb
-; $01 enables UpdateSprites; anything else disables it
- ds 1
-
-W_ENEMYMOVENUM:: ; cfcc
- ds 1
-W_ENEMYMOVEEFFECT:: ; cfcd
- ds 1
-W_ENEMYMOVEPOWER:: ; cfce
- ds 1
-W_ENEMYMOVETYPE:: ; cfcf
- ds 1
-W_ENEMYMOVEACCURACY:: ; cfd0
- ds 1
-W_ENEMYMOVEMAXPP:: ; cfd1
- ds 1
-W_PLAYERMOVENUM:: ; cfd2
- ds 1
-W_PLAYERMOVEEFFECT:: ; cfd3
- ds 1
-W_PLAYERMOVEPOWER:: ; cfd4
- ds 1
-W_PLAYERMOVETYPE:: ; cfd5
- ds 1
-W_PLAYERMOVEACCURACY:: ; cfd6
- ds 1
-W_PLAYERMOVEMAXPP:: ; cfd7
- ds 1
-
-
-wEnemyMonSpecies2:: ; cfd8
- ds 1
-wBattleMonSpecies2:: ; cfd9
- ds 1
-
-wEnemyMonNick:: ds 11 ; cfda
-
-wEnemyMon:: ; cfe5
-; The wEnemyMon struct reaches past 0xcfff,
-; the end of wram bank 0 on cgb.
-; This has no significance on dmg, where wram
-; isn't banked (c000-dfff is contiguous).
-; However, recent versions of rgbds have replaced
-; dmg-style wram with cgb wram banks.
-
-; Until this is fixed, this struct will have
-; to be declared manually.
-
-wEnemyMonSpecies:: db
-wEnemyMonHP:: dw
-wEnemyMonPartyPos::
-wEnemyMonBoxLevel:: db
-wEnemyMonStatus:: db
-wEnemyMonType::
-wEnemyMonType1:: db
-wEnemyMonType2:: db
-wEnemyMonCatchRate_NotReferenced:: db
-wEnemyMonMoves:: ds NUM_MOVES
-wEnemyMonDVs:: ds 2
-wEnemyMonLevel:: db
-wEnemyMonMaxHP:: dw
-wEnemyMonAttack:: dw
-wEnemyMonDefense:: dw
-wEnemyMonSpeed:: dw
-wEnemyMonSpecial:: dw
-wEnemyMonPP:: ds 2 ; NUM_MOVES - 2
-SECTION "WRAM Bank 1", WRAMX, BANK[1]
- ds 2 ; NUM_MOVES - 2
-
-wEnemyMonBaseStats:: ds 5
-wEnemyMonCatchRate:: ds 1
-wEnemyMonBaseExp:: ds 1
-
-wBattleMonNick:: ds 11 ; d009
-wBattleMon:: battle_struct wBattleMon ; d014
-
-
-W_TRAINERCLASS:: ; d031
- ds 1
-
- ds 1
-
-wTrainerPicPointer:: ; wd033
- ds 2
- ds 1
-wd036:: ds 16
-wd046:: ds 1
-wd047:: ds 1
-wd048:: ds 2
-
-W_TRAINERNAME:: ; d04a
-; 13 bytes for the letters of the opposing trainer
-; the name is terminated with $50 with possible
-; unused trailing letters
- ds 13
-
-W_ISINBATTLE:: ; d057
-; no battle, this is 0
-; wild battle, this is 1
-; trainer battle, this is 2
- ds 1
-
-wPartyGainExpFlags:: ; d058
-; flags that indicate which party members should be be given exp when GainExperience is called
- flag_array 6
-
-W_CUROPPONENT:: ; d059
-; in a wild battle, this is the species of pokemon
-; in a trainer battle, this is the trainer class + $C8
- ds 1
-
-W_BATTLETYPE:: ; d05a
-; in normal battle, this is 0
-; in old man battle, this is 1
-; in safari battle, this is 2
- ds 1
-
-wDamageMultipliers:: ; d05b
-; bits 0-6: Effectiveness
- ; $0 = immune
- ; $5 = not very effective
- ; $a = neutral
- ; $14 = super-effective
-; bit 7: STAB
- ds 1
-
-W_LONEATTACKNO:: ; d05c
-; which entry in LoneAttacks to use
-W_GYMLEADERNO:: ; d05c
-; it's actually the same thing as ^
- ds 1
-W_TRAINERNO:: ; d05d
-; which instance of [youngster, lass, etc] is this?
- ds 1
-
-wCriticalHitOrOHKO:: ; d05e
-; $00 = normal attack
-; $01 = critical hit
-; $02 = successful OHKO
-; $ff = failed OHKO
- ds 1
-
-W_MOVEMISSED:: ; d05f
- ds 1
-
-wPlayerStatsToDouble:: ; d060
-; always 0
- ds 1
-
-wPlayerStatsToHalve:: ; d061
-; always 0
- ds 1
-
-W_PLAYERBATTSTATUS1:: ; d062
-; bit 0 - bide
-; bit 1 - thrash / petal dance
-; bit 2 - attacking multiple times (e.g. double kick)
-; bit 3 - flinch
-; bit 4 - charging up for attack
-; bit 5 - using multi-turn move (e.g. wrap)
-; bit 6 - invulnerable to normal attack (using fly/dig)
-; bit 7 - confusion
- ds 1
-
-W_PLAYERBATTSTATUS2:: ; d063
-; bit 0 - X Accuracy effect
-; bit 1 - protected by "mist"
-; bit 2 - focus energy effect
-; bit 4 - has a substitute
-; bit 5 - need to recharge
-; bit 6 - rage
-; bit 7 - leech seeded
- ds 1
-
-W_PLAYERBATTSTATUS3:: ; d064
-; bit 0 - toxic
-; bit 1 - light screen
-; bit 2 - reflect
-; bit 3 - tranformed
- ds 1
-
-wEnemyStatsToDouble:: ; d065
-; always 0
- ds 1
-
-wEnemyStatsToHalve:: ; d066
-; always 0
- ds 1
-
-W_ENEMYBATTSTATUS1:: ; d067
- ds 1
-W_ENEMYBATTSTATUS2:: ; d068
- ds 1
-W_ENEMYBATTSTATUS3:: ; d069
- ds 1
-
-wPlayerNumAttacksLeft::
-; when the player is attacking multiple times, the number of attacks left
- ds 1
-
-W_PLAYERCONFUSEDCOUNTER:: ; wd06b
- ds 1
-
-W_PLAYERTOXICCOUNTER:: ; d06c
- ds 1
-W_PLAYERDISABLEDMOVE:: ; d06d
-; high nibble: which move is disabled (1-4)
-; low nibble: disable turns left
- ds 1
-
- ds 1
-
-wEnemyNumAttacksLeft:: ; d06f
-; when the enemy is attacking multiple times, the number of attacks left
- ds 1
-
-W_ENEMYCONFUSEDCOUNTER:: ; wd070
- ds 1
-
-W_ENEMYTOXICCOUNTER:: ; d071
- ds 1
-W_ENEMYDISABLEDMOVE:: ; d072
-; high nibble: which move is disabled (1-4)
-; low nibble: disable turns left
- ds 1
-
- ds 1
-
-wPlayerNumHits:: ; d074
-; number of hits by player in attacks like Double Slap, etc.
-
-wPlayerBideAccumulatedDamage:: ; d074
-; the amount of damage accumulated by the player while biding (2 bytes)
-
-wUnknownSerialCounter2:: ; d075
-; 2 bytes
-
- ds 4
-
-wEscapedFromBattle::
-; non-zero when an item or move that allows escape from battle was used
- ds 1
-
-wd079::
-wAmountMoneyWon:: ds 1 ; wd079 - wd07b
-wd07a:: ds 1
- ds 1
-
-W_ANIMATIONID:: ; d07c
-; ID number of the current battle animation
- ds 1
-
-wd07d:: ds 1
-wd07e:: ds 3
-
-; base coordinates of frame block
-W_BASECOORDX:: ; d081
- ds 1
-W_BASECOORDY:: ; d082
- ds 1
-
-; low health alarm counter/enable
-; high bit = enable, others = timer to cycle frequencies
-wLowHealthAlarm:: ds 1 ; d083
-
-W_FBTILECOUNTER:: ; d084
-; counts how many tiles of the current frame block have been drawn
- ds 1
-
-wd085:: ds 1
-
-W_SUBANIMFRAMEDELAY:: ; d086
-; duration of each frame of the current subanimation in terms of screen refreshes
- ds 1
-W_SUBANIMCOUNTER:: ; d087
-; counts the number of subentries left in the current subanimation
- ds 1
-
-wd088:: ds 1
-
-W_NUMFBTILES:: ; d089
-; number of tiles in current battle animation frame block
- ds 1
-
-wTradedMonMovingRight:: ; d08a
-; $01 if mon is moving from left gameboy to right gameboy; $00 if vice versa
-
-wd08a:: ds 1
-
-wTownMapSpriteBlinkingCounter:: ; d08b
-
-wPartyMonAnimCounter:: ; d08b
-
-W_SUBANIMTRANSFORM:: ; d08b
-; controls what transformations are applied to the subanimation
-; 01: flip horizontally and vertically
-; 02: flip horizontally and translate downwards 40 pixels
-; 03: translate base coordinates of frame blocks, but don't change their internal coordinates or flip their tiles
-; 04: reverse the subanimation
- ds 1
-
-wEndBattleWinTextPointer:: ; d08c
- ds 2
-
-wEndBattleLoseTextPointer:: ; d08e
- ds 2
-
- ds 2
-
-wEndBattleTextRomBank:: ; d092
- ds 1
-
- ds 1
-
-W_SUBANIMADDRPTR:: ; d094
-; the address _of the address_ of the current subanimation entry
- ds 2
-W_SUBANIMSUBENTRYADDR:: ; d096
-; the address of the current subentry of the current subanimation
- ds 2
-
- ds 2
-
-wd09a:: ds 1
-
-wTownMapSpriteBlinkingEnabled:: ; d09b
-; non-zero when enabled. causes nest locations to blink on and off.
-; the town selection cursor will blink regardless of what this value is
-
-wd09b:: ds 1
-
-W_FBDESTADDR:: ; d09c
-; current destination address in OAM for frame blocks (big endian)
- ds 2
-
-W_FBMODE:: ; d09e
-; controls how the frame blocks are put together to form frames
-; specifically, after finishing drawing the frame block, the frame block's mode determines what happens
-; 00: clean OAM buffer and delay
-; 02: move onto the next frame block with no delay and no cleaning OAM buffer
-; 03: delay, but don't clean OAM buffer
-; 04: delay, without cleaning OAM buffer, and do not advance [W_FBDESTADDR], so that the next frame block will overwrite this one
-; sprite data is written column by column, each byte contains 8 columns (one for ech bit)
-; for 2bpp sprites, pairs of two consecutive bytes (i.e. pairs of consecutive rows of sprite data)
-; contain the upper and lower bit of each of the 8 pixels, respectively
- ds 1
-
-wNewTileBlockID:: ; d09f
-
-wd09f:: ds 1
-wd0a0:: ds 1
-
-W_SPRITECURPOSX:: ; d0a1
- ds 1
-W_SPRITECURPOSY:: ; d0a2
- ds 1
-W_SPRITEWITDH:: ; d0a3
- ds 1
-W_SPRITEHEIGHT:: ; d0a4
- ds 1
-W_SPRITEINPUTCURBYTE:: ; d0a5
-; current input byte
- ds 1
-W_SPRITEINPUTBITCOUNTER:: ; d0a6
-; bit offset of last read input bit
- ds 1
-
-W_SPRITEOUTPUTBITOFFSET:: ; d0a7; determines where in the output byte the two bits are placed. Each byte contains four columns (2bpp data)
-; 3 -> XX000000 1st column
-; 2 -> 00XX0000 2nd column
-; 1 -> 0000XX00 3rd column
-; 0 -> 000000XX 4th column
- ds 1
-
-W_SPRITELOADFLAGS:: ; d0a8
-; bit 0 determines used buffer (0 -> $a188, 1 -> $a310)
-; bit 1 loading last sprite chunk? (there are at most 2 chunks per load operation)
- ds 1
-W_SPRITEUNPACKMODE:: ; d0a9
- ds 1
-W_SPRITEFLIPPED:: ; d0aa
- ds 1
-
-W_SPRITEINPUTPTR:: ; d0ab
-; pointer to next input byte
- ds 2
-W_SPRITEOUTPUTPTR:: ; d0ad
-; pointer to current output byte
- ds 2
-W_SPRITEOUTPUTPTRCACHED:: ; d0af
-; used to revert pointer for different bit offsets
- ds 2
-W_SPRITEDECODETABLE0PTR:: ; d0b1
-; pointer to differential decoding table (assuming initial value 0)
- ds 2
-W_SPRITEDECODETABLE1PTR:: ; d0b3
-; pointer to differential decoding table (assuming initial value 1)
- ds 2
-
-wd0b5:: ds 1
-
-wNameListType:: ; d0b6
- ds 1
-
-wPredefBank:: ; d0b7
- ds 1
-
-W_MONHEADER:: ; d0b8
-W_MONHDEXNUM:: ; d0b8
- ds 1
-
-W_MONHBASESTATS:: ; d0b9
-W_MONHBASEHP:: ; d0b9
- ds 1
-W_MONHBASEATTACK:: ; d0ba
- ds 1
-W_MONHBASEDEFENSE:: ; d0bb
- ds 1
-W_MONHBASESPEED:: ; d0bc
- ds 1
-W_MONHBASESPECIAL:: ; d0bd
- ds 1
-
-W_MONHTYPES:: ; d0be
-W_MONHTYPE1:: ; d0be
- ds 1
-W_MONHTYPE2:: ; d0bf
- ds 1
-
-W_MONHCATCHRATE:: ; d0c0
- ds 1
-W_MONHBASEXP:: ; d0c1
- ds 1
-W_MONHSPRITEDIM:: ; d0c2
- ds 1
-W_MONHFRONTSPRITE:: ; d0c3
- ds 2
-W_MONHBACKSPRITE:: ; d0c5
- ds 2
-
-W_MONHMOVES:: ; d0c7
- ds 4
-
-W_MONHGROWTHRATE:: ; d0cb
- ds 1
-
-W_MONHLEARNSET:: ; d0cc
-; bit field
- flag_array 50 + 5
- ds 1
-
-wd0d4:: ds 3
-
-W_MONHPADDING:: ; d0d7
-
-
-W_DAMAGE:: ; d0d7
- ds 2
-
-ds 2
-
-wRepelRemainingSteps:: ; wd0db
- ds 1
-
-wMoves:: ; wd0dc
-; list of moves for FormatMovesString
- ds 4
-
-wMoveNum:: ; d0e0
- ds 1
-
-wMovesString:: ; d0e1
- ds 56
-
-wd119:: ds 1
-
-wWalkBikeSurfStateCopy:: ; d11a
-; wWalkBikeSurfState is sometimes copied here, but it doesn't seem to be used for anything
- ds 1
-
-wd11b:: ds 1
-wd11c:: ds 1
-wd11d:: ds 1
-wd11e:: ds 1
-wd11f:: ds 1
-
-wNumRunAttempts::
-; number of times the player has tried to run from battle
- ds 1
-
-wd121:: ds 1
-wd122:: ds 2
-wd124:: ds 1
-
-wTextBoxID:: ; d125
- ds 1
-
-wd126:: ds 1
-
-W_CURENEMYLVL:: ; d127
- ds 1
-
-wd128:: ds 1
-wd129:: ds 1
-wd12a:: ds 1
-
-wLinkState:: ; d12b
- ds 1
-
-wTwoOptionMenuID:: ds 1
-wd12d:: ds 1
-wd12e:: ds 1
-wd12f:: ds 1
-wd130:: ds 1
-wd131:: ds 1
-wd132:: ds 1
-wd133:: ds 6
-wd139:: ds 1
-
-wIgnoreInputCounter:: ; d13a
-; counts downward each frame
-; when it hits 0, bit 5 (ignore input bit) of wd730 is reset
- ds 1
-
-wStepCounter:: ; d13b
-; counts down once every step
- ds 1
-
-wNumberOfNoRandomBattleStepsLeft:: ; d13c
-; after a battle, you have at least 3 steps before a random battle can occur
- ds 1
-
-W_PRIZE1:: ; d13d
- ds 1
-W_PRIZE2:: ; d13e
- ds 1
-W_PRIZE3:: ; d13f
- ds 1
-
- ds 1
-
-wSerialRandomNumberListBlock:: ; d141
-; the first 7 bytes are the preamble
-
-wd141:: ds 2
-wd143:: ds 2
-wd145:: ds 3
-
-wLinkBattleRandomNumberList:: ; d148
-; shared list of 9 random numbers, indexed by wLinkBattleRandomNumberListIndex
- ds 10
-
-wSerialPlayerDataBlock:: ; d152
-; the first 6 bytes are the preamble
-
-wd152:: ds 1
-wd153:: ds 3
-wd156:: ds 1
-wd157:: ds 1
-
-
-wPlayerName:: ; d158
- ds 11
-
-wPartyCount:: ds 1 ; d163
-wPartySpecies:: ds PARTY_LENGTH ; d164
-wPartyEnd:: ds 1 ; d16a
-
-wPartyMons::
-wPartyMon1:: party_struct wPartyMon1 ; d16b
-wPartyMon2:: party_struct wPartyMon2 ; d197
-wPartyMon3:: party_struct wPartyMon3 ; d1c3
-wPartyMon4:: party_struct wPartyMon4 ; d1ef
-wPartyMon5:: party_struct wPartyMon5 ; d21b
-wPartyMon6:: party_struct wPartyMon6 ; d247
-
-wPartyMonOT:: ds 11 * PARTY_LENGTH ; d273
-wPartyMonNicks:: ds 11 * PARTY_LENGTH ; d2b5
-
-
-wPokedexOwned:: ; d2f7
- flag_array NUM_POKEMON
-wPokedexOwnedEnd::
-
-wPokedexSeen:: ; d30a
- flag_array NUM_POKEMON
-wPokedexSeenEnd::
-
-
-wNumBagItems:: ; d31d
- ds 1
-wBagItems:: ; d31e
-; item, quantity
- ds 20 * 2
- ds 1 ; end
-
-wPlayerMoney:: ; d347
- ds 3 ; BCD
-
-W_RIVALNAME:: ; d34a
- ds 11
-
-W_OPTIONS:: ; d355
-; bit 7 = battle animation
-; 0: On
-; 1: Off
-; bit 6 = battle style
-; 0: Shift
-; 1: Set
-; bits 0-3 = text speed (number of frames to delay after printing a letter)
-; 1: Fast
-; 3: Medium
-; 5: Slow
- ds 1
-
-W_OBTAINEDBADGES:: ; d356
- ds 1
-
- ds 1
-
-wd358:: ds 1
-
-wPlayerID:: ; d359
- ds 2
-
-wd35b:: ds 1
-wd35c:: ds 1
-
-wMapPalOffset:: ; d35d
-; offset subtracted from FadePal4 to get the background and object palettes for the current map
-; normally, it is 0. it is 6 when Flash is needed, causing FadePal2 to be used instead of FadePal4
- ds 1
-
-W_CURMAP:: ; d35e
- ds 1
-
-wCurrentTileBlockMapViewPointer:: ; d35f
-; pointer to the upper left corner of the current view in the tile block map
- ds 2
-
-W_YCOORD:: ; d361
-; player’s position on the current map
- ds 1
-
-W_XCOORD:: ; d362
- ds 1
-
-W_YBLOCKCOORD:: ; d363
-; player's y position (by block)
- ds 1
-
-W_XBLOCKCOORD:: ; d364
- ds 1
-
-wLastMap:: ; d365
- ds 1
-
-wd366:: ds 1
-
-W_CURMAPTILESET:: ; d367
- ds 1
-
-W_CURMAPHEIGHT:: ; d368
-; blocks
- ds 1
-
-W_CURMAPWIDTH:: ; d369
-; blocks
- ds 1
-
-W_MAPDATAPTR:: ; d36a
- ds 2
-
-W_MAPTEXTPTR:: ; d36c
- ds 2
-
-W_MAPSCRIPTPTR:: ; d36e
- ds 2
-
-W_MAPCONNECTIONS:: ; d370
-; connection byte
- ds 1
-
-W_MAPCONN1PTR:: ; d371
- ds 1
-
-wd372:: ds 1
-wd373:: ds 1
-wd374:: ds 1
-wd375:: ds 1
-wd376:: ds 1
-wd377:: ds 1
-wd378:: ds 1
-wd379:: ds 1
-wd37a:: ds 1
-wd37b:: ds 1
-
-W_MAPCONN2PTR:: ; d37c
- ds 1
-
-wd37d:: ds 1
-wd37e:: ds 1
-wd37f:: ds 1
-wd380:: ds 1
-wd381:: ds 1
-wd382:: ds 1
-wd383:: ds 1
-wd384:: ds 1
-wd385:: ds 1
-wd386:: ds 1
-
-W_MAPCONN3PTR:: ; d387
- ds 1
-
-wd388:: ds 1
-wd389:: ds 1
-wd38a:: ds 1
-wd38b:: ds 1
-wd38c:: ds 1
-wd38d:: ds 1
-wd38e:: ds 1
-wd38f:: ds 1
-wd390:: ds 1
-wd391:: ds 1
-
-W_MAPCONN4PTR:: ; d392
- ds 1
-
-wd393:: ds 1
-wd394:: ds 1
-wd395:: ds 1
-wd396:: ds 1
-wd397:: ds 1
-wd398:: ds 1
-wd399:: ds 1
-wd39a:: ds 1
-wd39b:: ds 1
-wd39c:: ds 1
-
-W_SPRITESET:: ; d39d
-; sprite set for the current map (11 sprite picture ID's)
- ds 11
-
-W_SPRITESETID:: ; d3a8
-; sprite set ID for the current map
- ds 1
-
-wd3a9:: ds 1
-wd3aa:: ds 3
-wd3ad:: ds 1
-
-wNumberOfWarps:: ; d3ae
-; number of warps in current map
- ds 1
-
-wWarpEntries:: ; d3af
-; current map warp entries
- ds 128
-
-wDestinationWarpID:: ; d42f
-; if $ff, the player's coordinates are not updated when entering the map
- ds 1
-
- ds 4
-
-wd435:: ds 1
-wd436:: ds 1
-
- ds 122
-
-wd4b0:: ds 1
-wd4b1:: ds 32
-wd4d1:: ds 16
-
-W_NUMSPRITES:: ; d4e1
-; number of sprites on the current map
- ds 1
-
-; these two variables track the X and Y offset in blocks from the last special warp used
-; they don't seem to be used for anything
-wYOffsetSinceLastSpecialWarp:: ; d4e2
- ds 1
-wXOffsetSinceLastSpecialWarp:: ; d4e3
- ds 1
-
-W_MAPSPRITEDATA:: ; d4e4
-; two bytes per sprite (movement byte 2, text ID)
- ds 32
-
-W_MAPSPRITEEXTRADATA:: ; d504
-; two bytes per sprite (trainer class/item ID, trainer set ID)
- ds 32
-
-wd524:: ds 1
-wd525:: ds 1
-
-wMapViewVRAMPointer:: ; d526
-; the address of the upper left corner of the visible portion of the BG tile map in VRAM
- ds 2
-
-wd528:: ds 1
-wd529:: ds 1
-wd52a:: ds 1
-
-W_TILESETBANK:: ; d52b
- ds 1
-
-W_TILESETBLOCKSPTR:: ; d52c
-; maps blocks (4x4 tiles) to tiles
- ds 2
-
-W_TILESETGFXPTR:: ; d52e
- ds 2
-
-W_TILESETCOLLISIONPTR:: ; d530
-; list of all walkable tiles
- ds 2
-
-W_TILESETTALKINGOVERTILES:: ; d532
- ds 3
-
-W_GRASSTILE:: ; d535
- ds 1
-
- ds 4
-
-wNumBoxItems:: ; d53a
- ds 1
-wBoxItems:: ; d53b
-; item, quantity
- ds 50 * 2
- ds 1 ; end
-
-wd5a0:: ds 2
-wd5a2:: ds 1
-wd5a3:: ds 1
-
-wPlayerCoins:: ; d5a4
- ds 2 ; BCD
-
-W_MISSABLEOBJECTFLAGS:: ; d5a6
-; bit array of missable objects. set = removed
- ds 39
-
-wd5cd:: ds 1
-
-W_MISSABLEOBJECTLIST:: ; d5ce
-; each entry consists of 2 bytes
-; * the sprite ID (depending on the current map)
-; * the missable object index (global, used for W_MISSABLEOBJECTFLAGS)
-; terminated with $FF
- ds 17 * 2
-
-W_GAMEPROGRESSFLAGS:: ; d5f0
-; $c8 bytes
- ds 0
-
-W_OAKSLABCURSCRIPT:: ; d5f0
- ds 1
-W_PALLETTOWNCURSCRIPT:: ; d5f1
- ds 1
- ds 1
-W_BLUESHOUSECURSCRIPT:: ; d5f3
- ds 1
-W_VIRIDIANCITYCURSCRIPT:: ; d5f4
- ds 1
- ds 2
-W_PEWTERCITYCURSCRIPT:: ; d5f7
- ds 1
-W_ROUTE3CURSCRIPT:: ; d5f8
- ds 1
-W_ROUTE4CURSCRIPT:: ; d5f9
- ds 1
- ds 1
-W_VIRIDIANGYMCURSCRIPT:: ; d5fb
- ds 1
-W_PEWTERGYMCURSCRIPT:: ; d5fc
- ds 1
-W_CERULEANGYMCURSCRIPT:: ; d5fd
- ds 1
-W_VERMILIONGYMCURSCRIPT:: ; d5fe
- ds 1
-W_CELADONGYMCURSCRIPT:: ; d5ff
- ds 1
-W_ROUTE6CURSCRIPT:: ; d600
- ds 1
-W_ROUTE8CURSCRIPT:: ; d601
- ds 1
-W_ROUTE24CURSCRIPT:: ; d602
- ds 1
-W_ROUTE25CURSCRIPT:: ; d603
- ds 1
-W_ROUTE9CURSCRIPT:: ; d604
- ds 1
-W_ROUTE10CURSCRIPT:: ; d605
- ds 1
-W_MTMOON1CURSCRIPT:: ; d606
- ds 1
-W_MTMOON3CURSCRIPT:: ; d607
- ds 1
-W_SSANNE8CURSCRIPT:: ; d608
- ds 1
-W_SSANNE9CURSCRIPT:: ; d609
- ds 1
-W_ROUTE22CURSCRIPT:: ; d60a
- ds 1
- ds 1
-W_REDSHOUSE2CURSCRIPT:: ; d60c
- ds 1
-W_VIRIDIANMARKETCURSCRIPT:: ; d60d
- ds 1
-W_ROUTE22GATECURSCRIPT:: ; d60e
- ds 1
-W_CERULEANCITYCURSCRIPT:: ; d60f
- ds 1
- ds 7
-W_SSANNE5CURSCRIPT:: ; d617
- ds 1
-W_VIRIDIANFORESTCURSCRIPT:: ; d618
- ds 1
-W_MUSEUM1FCURSCRIPT:: ; d619
- ds 1
-W_ROUTE13CURSCRIPT:: ; d61a
- ds 1
-W_ROUTE14CURSCRIPT:: ; d61b
- ds 1
-W_ROUTE17CURSCRIPT:: ; d61c
- ds 1
-W_ROUTE19CURSCRIPT:: ; d61d
- ds 1
-W_ROUTE21CURSCRIPT:: ; d61e
- ds 1
-W_SAFARIZONEENTRANCECURSCRIPT:: ; d61f
- ds 1
-W_ROCKTUNNEL2CURSCRIPT:: ; d620
- ds 1
-W_ROCKTUNNEL1CURSCRIPT:: ; d621
- ds 1
- ds 1
-W_ROUTE11CURSCRIPT:: ; d623
- ds 1
-W_ROUTE12CURSCRIPT:: ; d624
- ds 1
-W_ROUTE15CURSCRIPT:: ; d625
- ds 1
-W_ROUTE16CURSCRIPT:: ; d626
- ds 1
-W_ROUTE18CURSCRIPT:: ; d627
- ds 1
-W_ROUTE20CURSCRIPT:: ; d628
- ds 1
-W_SSANNE10CURSCRIPT:: ; d629
- ds 1
-W_VERMILIONCITYCURSCRIPT:: ; d62a
- ds 1
-W_POKEMONTOWER2CURSCRIPT:: ; d62b
- ds 1
-W_POKEMONTOWER3CURSCRIPT:: ; d62c
- ds 1
-W_POKEMONTOWER4CURSCRIPT:: ; d62d
- ds 1
-W_POKEMONTOWER5CURSCRIPT:: ; d62e
- ds 1
-W_POKEMONTOWER6CURSCRIPT:: ; d62f
- ds 1
-W_POKEMONTOWER7CURSCRIPT:: ; d630
- ds 1
-W_ROCKETHIDEOUT1CURSCRIPT:: ; d631
- ds 1
-W_ROCKETHIDEOUT2CURSCRIPT:: ; d632
- ds 1
-W_ROCKETHIDEOUT3CURSCRIPT:: ; d633
- ds 1
-W_ROCKETHIDEOUT4CURSCRIPT:: ; d634
- ds 2
-W_ROUTE6GATECURSCRIPT:: ; d636
- ds 1
-W_ROUTE8GATECURSCRIPT:: ; d637
- ds 2
-W_CINNABARISLANDCURSCRIPT:: ; d639
- ds 1
-W_MANSION1CURSCRIPT:: ; d63a
- ds 2
-W_MANSION2CURSCRIPT:: ; d63c
- ds 1
-W_MANSION3CURSCRIPT:: ; d63d
- ds 1
-W_MANSION4CURSCRIPT:: ; d63e
- ds 1
-W_VICTORYROAD2CURSCRIPT:: ; d63f
- ds 1
-W_VICTORYROAD3CURSCRIPT:: ; d640
- ds 2
-W_FIGHTINGDOJOCURSCRIPT:: ; d642
- ds 1
-W_SILPHCO2CURSCRIPT:: ; d643
- ds 1
-W_SILPHCO3CURSCRIPT:: ; d644
- ds 1
-W_SILPHCO4CURSCRIPT:: ; d645
- ds 1
-W_SILPHCO5CURSCRIPT:: ; d646
- ds 1
-W_SILPHCO6CURSCRIPT:: ; d647
- ds 1
-W_SILPHCO7CURSCRIPT:: ; d648
- ds 1
-W_SILPHCO8CURSCRIPT:: ; d649
- ds 1
-W_SILPHCO9CURSCRIPT:: ; d64a
- ds 1
-W_HALLOFFAMEROOMCURSCRIPT:: ; d64b
- ds 1
-W_GARYCURSCRIPT:: ; d64c
- ds 1
-W_LORELEICURSCRIPT:: ; d64d
- ds 1
-W_BRUNOCURSCRIPT:: ; d64e
- ds 1
-W_AGATHACURSCRIPT:: ; d64f
- ds 1
-W_UNKNOWNDUNGEON3CURSCRIPT:: ; d650
- ds 1
-W_VICTORYROAD1CURSCRIPT:: ; d651
- ds 1
- ds 1
-W_LANCECURSCRIPT:: ; d653
- ds 1
- ds 4
-W_SILPHCO10CURSCRIPT:: ; d658
- ds 1
-W_SILPHCO11CURSCRIPT:: ; d659
- ds 1
- ds 1
-W_FUCHSIAGYMCURSCRIPT:: ; d65b
- ds 1
-W_SAFFRONGYMCURSCRIPT:: ; d65c
- ds 1
- ds 1
-W_CINNABARGYMCURSCRIPT:: ; d65e
- ds 1
-W_CELADONGAMECORNERCURSCRIPT:: ; d65f
- ds 1
-W_ROUTE16GATECURSCRIPT:: ; d660
- ds 1
-W_BILLSHOUSECURSCRIPT:: ; d661
- ds 1
-W_ROUTE5GATECURSCRIPT:: ; d662
- ds 1
-W_POWERPLANTCURSCRIPT:: ; d663
-; overload
- ds 0
-W_ROUTE7GATECURSCRIPT:: ; d663
-; overload
- ds 1
- ds 1
-W_SSANNE2CURSCRIPT:: ; d665
- ds 1
-W_SEAFOAMISLANDS4CURSCRIPT:: ; d666
- ds 1
-W_ROUTE23CURSCRIPT:: ; d667
- ds 1
-W_SEAFOAMISLANDS5CURSCRIPT:: ; d668
- ds 1
-W_ROUTE18GATECURSCRIPT:: ; d669
- ds 1
-
- ds 134
-
-wd6f0:: ds 14
-wd6fe:: ds 2
-
-wWalkBikeSurfState:: ; d700
-; $00 = walking
-; $01 = biking
-; $02 = surfing
- ds 1
-
- ds 10
-
-W_TOWNVISITEDFLAG:: ; d70b
- flag_array 13
-
-wSafariSteps:: ; d70d
-; starts at 502
- ds 2
-
-W_FOSSILITEM:: ; d70f
-; item given to cinnabar lab
- ds 1
-
-W_FOSSILMON:: ; d710
-; mon that will result from the item
- ds 1
-
- ds 2
-
-W_ENEMYMONORTRAINERCLASS:: ; d713
-; trainer classes start at $c8
- ds 1
-
-wPlayerJumpingYScreenCoordsIndex:: ; d714
- ds 1
-
-W_RIVALSTARTER:: ; d715
- ds 1
-
- ds 1
-
-W_PLAYERSTARTER:: ; d717
- ds 1
-
-wBoulderSpriteIndex:: ; d718
-; sprite index of the boulder the player is trying to push
- ds 1
-
-wLastBlackoutMap:: ; d719
- ds 1
-
-wDestinationMap:: ; d71a
-; destination map (for certain types of special warps, not ordinary walking)
- ds 1
-
-wd71b:: ds 1
-
-wTileInFrontOfBoulderAndBoulderCollisionResult:: ; d71c
-; used to store the tile in front of the boulder when trying to push a boulder
-; also used to store the result of the collision check ($ff for a collision and $00 for no collision)
- ds 1
-
-wDungeonWarpDestinationMap:: ; d71d
-; destination map for dungeon warps
- ds 1
-
-wWhichDungeonWarp:: ; d71e
-; which dungeon warp within the source map was used
- ds 1
-
-wd71f:: ds 9
-
-wd728::
-; bit 0: using Strength outside of battle
- ds 1
-
- ds 1
-
-wd72a:: ds 2
-
-wd72c:: ; d72c
-; bit 0: if not set, the 3 minimum steps between random battles have passed
- ds 1
-
-wd72d:: ds 1
-wd72e:: ds 2
-
-wd730::
-; bit 0: NPC sprite being moved by script
-; bit 5: ignore joypad input
-; bit 6: print text with no delay between each letter
-; bit 7: set if joypad states are being simulated in the overworld
- ds 1
-
- ds 1
-
-wd732:: ; d732
-; bit 0: play time being counted
-; bit 1: remnant of debug mode? not set by the game code.
-; if it is set
-; 1. skips most of Prof. Oak's speech, and uses NINTEN as the player's name and SONY as the rival's name
-; 2. does not have the player start in floor two of the playyer's house (instead sending them to [wLastMap])
-; 3. allows wild battles to be avoided by holding down B
-; bit 2: the target warp is a fly warp (bit 3 set or blacked out) or a dungeon warp (bit 4 set)
-; bit 3: used warp pad, escape rope, dig, teleport, or fly, so the target warp is a "fly warp"
-; bit 4: jumped into hole (Pokemon Mansion, Seafoam Islands, Victory Road) or went down waterfall (Seafoam Islands), so the target warp is a "dungeon warp"
-; bit 5: currently being forced to ride bike (cycling road)
-; bit 6: map destination is [wLastBlackoutMap] (usually the last used pokemon center, but could be the player's house)
- ds 1
-
-W_FLAGS_D733:: ; d733
-; bit 4: use variable [W_CURMAPSCRIPT] instead of the provided index for next frame's map script (used to start battle when talking to trainers)
-; bit 7: used fly out of battle
- ds 1
-
-wd734:: ds 2
-
-wd736:: ; d736
-; bit 0: check if the player is standing on a door and make him walk down a step if so
-; bit 1: the player is currently stepping down from a door
-; bit 2: standing on a warp
-; bit 6: jumping down a ledge
- ds 1
-
-wCompletedInGameTradeFlags:: ; d737
- ds 2
-
- ds 2
-
-wd73b:: ds 1
-wd73c:: ds 3
-
-wCardKeyDoorY:: ; d73f
- ds 1
-
-wCardKeyDoorX:: ; d740
- ds 1
-
- ds 2
-
-wd743:: ds 1
-wd744:: ds 3
-wd747:: ds 3
-wd74a:: ds 1
-
-wd74b:: ; d74b
-; bit 0: Prof. Oak has lead the player to the north end of his lab
-; bit 1: Prof. Oak has asked the player to choose a pokemon
-; bit 2: the player and the rival have received their pokemon
-; bit 3: the player has battled the rival in Oak's lab
-; bit 4: Prof. Oak has given the player 5 pokeballs
-; bit 5: received pokedex
- ds 1
-
-wd74c:: ds 2
-wd74e:: ds 3
-wd751:: ds 1
-wd752:: ds 2
-wd754:: ds 1
-wd755:: ds 5
-wd75a:: ds 1
-wd75b:: ds 3
-wd75e:: ds 1
-wd75f:: ds 5
-wd764:: ds 1
-wd765:: ds 1
-wd766:: ds 1
-wd767:: ds 1
-wd768:: ds 1
-wd769:: ds 3
-wd76c:: ds 5
-wd771:: ds 2
-wd773:: ds 4
-wd777:: ds 1
-wd778:: ds 4
-wd77c:: ds 1
-wd77d:: ds 1
-wd77e:: ds 5
-wd783:: ds 11
-wd78e:: ds 2
-wd790:: ds 2
-wd792:: ds 4
-wd796:: ds 2
-wd798:: ds 2
-wd79a:: ds 1
-wd79b:: ds 1
-wd79c:: ds 5
-wd7a1:: ds 2
-wd7a3:: ds 12
-wd7af:: ds 2
-wd7b1:: ds 2
-wd7b3:: ds 1
-wd7b4:: ds 5
-wd7b9:: ds 4
-wd7bd:: ds 2
-wd7bf:: ds 3
-wd7c2:: ds 1
-wd7c3:: ds 2
-wd7c5:: ds 1
-wd7c6:: ds 3
-wd7c9:: ds 4
-wd7cd:: ds 2
-wd7cf:: ds 2
-wd7d1:: ds 1
-wd7d2:: ds 1
-wd7d3:: ds 2
-wd7d5:: ds 1
-wd7d6:: ds 1
-wd7d7:: ds 1
-wd7d8:: ds 1
-wd7d9:: ds 2
-wd7db:: ds 2
-wd7dd:: ds 2
-wd7df:: ds 1
-wd7e0:: ds 1
-wd7e1:: ds 2
-wd7e3:: ds 2
-wd7e5:: ds 2
-wd7e7:: ds 1
-wd7e8:: ds 1
-wd7e9:: ds 2
-wd7eb:: ds 2
-wd7ed:: ds 1
-wd7ee:: ds 1
-wd7ef:: ds 1
-wd7f0:: ds 1
-wd7f1:: ds 1
-wd7f2:: ds 1
-wd7f3:: ds 2
-wd7f5:: ds 1
-wd7f6:: ds 9
-wd7ff:: ds 4
-wd803:: ds 2
-wd805:: ds 2
-wd807:: ds 2
-wd809:: ds 10
-wd813:: ds 2
-wd815:: ds 1
-wd816:: ds 1
-wd817:: ds 2
-wd819:: ds 2
-wd81b:: ds 10
-wd825:: ds 1
-wd826:: ds 1
-wd827:: ds 1
-wd828:: ds 1
-wd829:: ds 1
-wd82a:: ds 1
-wd82b:: ds 1
-wd82c:: ds 1
-wd82d:: ds 1
-wd82e:: ds 1
-wd82f:: ds 1
-wd830:: ds 1
-wd831:: ds 1
-wd832:: ds 1
-wd833:: ds 1
-wd834:: ds 1
-wd835:: ds 1
-wd836:: ds 1
-wd837:: ds 1
-wd838:: ds 15
-wd847:: ds 2
-wd849:: ds 2
-wd84b:: ds 12
-wd857:: ds 8
-wd85f:: ds 4
-wd863:: ds 1
-wd864:: ds 1
-wd865:: ds 1
-wd866:: ds 1
-wd867:: ds 2
-wd869:: ds 20
-wd87d:: ds 2
-wd87f:: ds 1
-wd880:: ds 1
-wd881:: ds 1
-wd882:: ds 5
-
-wLinkEnemyTrainerName:: ; d887
-; linked game's trainer name
-
-W_GRASSRATE:: ; d887
- ds 1
-
-W_GRASSMONS:: ; d888
- ds 20
-
-
-wEnemyPartyCount:: ds 1 ; d89c
-wEnemyPartyMons:: ds PARTY_LENGTH + 1 ; d89d
-
-wEnemyMons:: ; d8a4
-wEnemyMon1:: party_struct wEnemyMon1
-wEnemyMon2:: party_struct wEnemyMon2
-wEnemyMon3:: party_struct wEnemyMon3
-wEnemyMon4:: party_struct wEnemyMon4
-wEnemyMon5:: party_struct wEnemyMon5
-wEnemyMon6:: party_struct wEnemyMon6
-
-wEnemyMonOT:: ds 11 * PARTY_LENGTH ; d9ac
-wEnemyMonNicks:: ds 11 * PARTY_LENGTH ; d9ee
-
-
-W_TRAINERHEADERPTR:: ; da30
- ds 2
-
- ds 6
-
-wda38:: ds 1
-
-W_CURMAPSCRIPT:: ; da39
-; index of current map script, mostly used as index for function pointer array
-; mostly copied from map-specific map script pointer and wirtten back later
- ds 1
-
- ds 6
-
-W_PLAYTIMEHOURS:: ; da40
- ds 2
-W_PLAYTIMEMINUTES:: ; da42
- ds 2
-W_PLAYTIMESECONDS:: ; da44
- ds 1
-W_PLAYTIMEFRAMES:: ; da45
- ds 1
-
-wSafariZoneGameOver:: ; da46
- ds 1
-
-W_NUMSAFARIBALLS:: ; da47
- ds 1
-
-
-W_DAYCARE_IN_USE:: ; da48
-; 0 if no pokemon is in the daycare
-; 1 if pokemon is in the daycare
- ds 1
-
-W_DAYCAREMONNAME:: ds 11 ; da49
-W_DAYCAREMONOT:: ds 11 ; da54
-
-wDayCareMon:: box_struct wDayCareMon ; da5f
-
-
-W_NUMINBOX:: ds 1 ; da80
-wBoxSpecies:: ds MONS_PER_BOX + 1
-
-wBoxMons::
-wBoxMon1:: box_struct wBoxMon1 ; da96
-wBoxMon2:: ds box_struct_length * (MONS_PER_BOX + -1) ; dab7
-
-wBoxMonOT:: ds 11 * MONS_PER_BOX ; dd2a
-wBoxMonNicks:: ds 11 * MONS_PER_BOX ; de06
-wBoxMonNicksEnd:: ; dee2
-
-
-SECTION "Stack", WRAMX[$dfff], BANK[1]
-wStack:: ; dfff
- ds -$100
-
-
-INCLUDE "sram.asm"
+
+INCLUDE "constants.asm"
+
+flag_array: MACRO
+ ds ((\1) + 7) / 8
+ENDM
+
+box_struct_length EQU 25 + NUM_MOVES * 2
+box_struct: MACRO
+\1Species:: db
+\1HP:: dw
+\1BoxLevel:: db
+\1Status:: db
+\1Type::
+\1Type1:: db
+\1Type2:: db
+\1CatchRate:: db
+\1Moves:: ds NUM_MOVES
+\1OTID:: dw
+\1Exp:: ds 3
+\1HPExp:: dw
+\1AttackExp:: dw
+\1DefenseExp:: dw
+\1SpeedExp:: dw
+\1SpecialExp:: dw
+\1DVs:: ds 2
+\1PP:: ds NUM_MOVES
+ENDM
+
+party_struct: MACRO
+ box_struct \1
+\1Level:: db
+\1Stats::
+\1MaxHP:: dw
+\1Attack:: dw
+\1Defense:: dw
+\1Speed:: dw
+\1Special:: dw
+ENDM
+
+battle_struct: MACRO
+\1Species:: db
+\1HP:: dw
+\1BoxLevel:: db
+\1Status:: db
+\1Type::
+\1Type1:: db
+\1Type2:: db
+\1CatchRate:: db
+\1Moves:: ds NUM_MOVES
+\1DVs:: ds 2
+\1Level:: db
+\1MaxHP:: dw
+\1Attack:: dw
+\1Defense:: dw
+\1Speed:: dw
+\1Special:: dw
+\1PP:: ds NUM_MOVES
+ENDM
+
+
+SECTION "WRAM Bank 0", WRAM0
+
+wc000:: ds 1
+wc001:: ds 1
+wc002:: ds 1
+wc003:: ds 1
+wc004:: ds 1
+wc005:: ds 1
+wc006:: ds 8
+wc00e:: ds 4
+wc012:: ds 4
+wc016:: ds 16
+wc026:: ds 1
+wc027:: ds 1
+wc028:: ds 2
+wc02a:: ds 1
+wc02b:: ds 1
+wc02c:: ds 1
+wc02d:: ds 1
+wc02e:: ds 8
+wc036:: ds 8
+wc03e:: ds 8
+wc046:: ds 8
+wc04e:: ds 8
+wc056:: ds 8
+wc05e:: ds 8
+wc066:: ds 8
+wc06e:: ds 8
+wc076:: ds 8
+wc07e:: ds 8
+wc086:: ds 8
+wc08e:: ds 8
+wc096:: ds 8
+wc09e:: ds 8
+wc0a6:: ds 8
+wc0ae:: ds 8
+wc0b6:: ds 8
+wc0be:: ds 8
+wc0c6:: ds 8
+wc0ce:: ds 1
+wc0cf:: ds 1
+wc0d0:: ds 1
+wc0d1:: ds 1
+wc0d2:: ds 1
+wc0d3:: ds 1
+wc0d4:: ds 1
+wc0d5:: ds 1
+wc0d6:: ds 8
+wc0de:: ds 8
+wc0e6:: ds 1
+wc0e7:: ds 1
+wc0e8:: ds 1
+wc0e9:: ds 1
+wc0ea:: ds 1
+wc0eb:: ds 1
+wc0ec:: ds 1
+wc0ed:: ds 1
+wc0ee:: ds 1
+wc0ef:: ds 1
+wc0f0:: ds 1
+wc0f1:: ds 1
+wc0f2:: ds 14
+
+
+SECTION "Sprite State Data", WRAM0[$c100]
+
+wSpriteStateData1:: ; c100
+; data for all sprites on the current map
+; holds info for 16 sprites with $10 bytes each
+; player sprite is always sprite 0
+; C1x0: picture ID (fixed, loaded at map init)
+; C1x1: movement status (0: uninitialized, 1: ready, 2: delayed, 3: moving)
+; C1x2: sprite image index (changed on update, $ff if off screen, includes facing direction, progress in walking animation and a sprite-specific offset)
+; C1x3: Y screen position delta (-1,0 or 1; added to c1x4 on each walking animation update)
+; C1x4: Y screen position (in pixels, always 4 pixels above grid which makes sprites appear to be in the center of a tile)
+; C1x5: X screen position delta (-1,0 or 1; added to c1x6 on each walking animation update)
+; C1x6: X screen position (in pixels, snaps to grid if not currently walking)
+; C1x7: intra-animation-frame counter (counting upwards to 4 until c1x8 is incremented)
+; C1x8: animation frame counter (increased every 4 updates, hold four states (totalling to 16 walking frames)
+; C1x9: facing direction (0: down, 4: up, 8: left, $c: right)
+; C1xA
+; C1xB
+; C1xC
+; C1xD
+; C1xE
+; C1xF
+ ds $10 * $10
+
+
+SECTION "Sprite State Data 2", WRAM0[$c200]
+
+wSpriteStateData2:: ; c200
+; more data for all sprites on the current map
+; holds info for 16 sprites with $10 bytes each
+; player sprite is always sprite 0
+; C2x0: walk animation counter (counting from $10 backwards when moving)
+; C2x1:
+; C2x2: Y displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged)
+; C2x3: X displacement (initialized at 8, supposed to keep moving sprites from moving too far, but bugged)
+; C2x4: Y position (in 2x2 tile grid steps, topmost 2x2 tile has value 4)
+; C2x5: X position (in 2x2 tile grid steps, leftmost 2x2 tile has value 4)
+; C2x6: movement byte 1 (determines whether a sprite can move, $ff:not moving, $fe:random movements, others unknown)
+; C2x7: (?) (set to $80 when in grass, else $0; may be used to draw grass above the sprite)
+; C2x8: delay until next movement (counted downwards, status (c1x1) is set to ready if reached 0)
+; C2x9
+; C2xA
+; C2xB
+; C2xC
+; C2xD
+; C2xE: sprite image base offset (in video ram, player always has value 1, used to compute c1x2)
+; C2xF
+ ds $10 * $10
+
+
+SECTION "OAM Buffer", WRAM0[$c300]
+
+wOAMBuffer:: ; c300
+; buffer for OAM data. Copied to OAM by DMA
+ ds 4 * 40
+
+wTileMap:: ; c3a0
+; buffer for tiles that are visible on screen (20 columns by 18 rows)
+ ds 20 * 18
+
+wSerialPartyMonsPatchList:: ; c508
+; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer
+
+wTileMapBackup:: ; c508
+; buffer for temporarily saving and restoring current screen's tiles
+; (e.g. if menus are drawn on top)
+; ds 20 * 18
+
+ ds 200
+
+wSerialEnemyMonsPatchList:: ; c5d0
+; list of indexes to patch with SERIAL_NO_DATA_BYTE after transfer
+ ds 200
+
+ ds 80
+
+wTempPic::
+wOverworldMap:: ; c6e8
+ ds 1300
+
+wScreenEdgeTiles:: ; cbfc
+; the tiles of the row or column to be redrawn by RedrawExposedScreenEdge
+ ds 20 * 2
+
+; coordinates of the position of the cursor for the top menu item (id 0)
+wTopMenuItemY:: ; cc24
+ ds 1
+wTopMenuItemX:: ; cc25
+ ds 1
+
+wCurrentMenuItem:: ; cc26
+; the id of the currently selected menu item
+; the top item has id 0, the one below that has id 1, etc.
+; note that the "top item" means the top item currently visible on the screen
+; add this value to [wListScrollOffset] to get the item's position within the list
+ ds 1
+
+wTileBehindCursor:: ; cc27
+; the tile that was behind the menu cursor's current location
+ ds 1
+
+wMaxMenuItem:: ; cc28
+; id of the bottom menu item
+ ds 1
+
+wMenuWatchedKeys:: ; cc29
+; bit mask of keys that the menu will respond to
+ ds 1
+
+wLastMenuItem:: ; cc2a
+; id of previously selected menu item
+ ds 1
+
+wcc2b:: ds 1
+wcc2c:: ds 1
+wcc2d:: ds 1
+
+wPlayerMoveListIndex:: ; cc2e
+ ds 1
+
+wPlayerMonNumber:: ; cc2f
+ ds 1
+
+wMenuCursorLocation:: ; cc30
+; the address of the menu cursor's current location within wTileMap
+ ds 2
+
+ ds 2
+
+wMenuJoypadPollCount:: ; cc34
+; how many times should HandleMenuInput poll the joypad state before it returns?
+ ds 1
+
+wMenuItemToSwap:: ; cc35
+; id of menu item selected for swapping (counts from 1) (0 means that no menu item has been selected for swapping)
+ ds 1
+
+wListScrollOffset:: ; cc36
+; offset of the current top menu item from the beginning of the list
+; keeps track of what section of the list is on screen
+ ds 1
+
+wcc37:: ds 1
+
+wTradeCenterPointerTableIndex:: ; cc38
+ ds 1
+
+ ds 1
+
+wcc3a:: ds 1
+wcc3b:: ds 1
+
+wDoNotWaitForButtonPressAfterDisplayingText:: ; cc3c
+; if non-zero, skip waiting for a button press after displaying text in DisplayTextID
+ ds 1
+
+wSerialSyncAndExchangeNybbleReceiveData:: ; cc3d
+; the final received nybble is stored here by Serial_SyncAndExchangeNybble
+
+wSerialExchangeNybbleTempReceiveData:: ; cc3d
+; temporary nybble used by Serial_ExchangeNybble
+
+wLinkMenuSelectionReceiveBuffer:: ; cc3d
+; two byte buffer
+; the received menu selection is stored twice
+
+wcc3d:: ds 1
+
+wSerialExchangeNybbleReceiveData:: ; cc3e
+; the final received nybble is stored here by Serial_ExchangeNybble
+ ds 1
+
+ ds 3
+
+wSerialExchangeNybbleSendData:: ; cc42
+; this nybble is sent when using Serial_SyncAndExchangeNybble or Serial_ExchangeNybble
+
+wLinkMenuSelectionSendBuffer:: ; cc42
+; two byte buffer
+; the menu selection byte is stored twice before sending
+
+ ds 5
+
+wLinkTimeoutCounter:: ; cc47
+; 1 byte
+
+wUnknownSerialCounter:: ; cc47
+; 2 bytes
+
+wcc47:: ds 1
+wcc48:: ds 1
+
+wWhichTradeMonSelectionMenu:: ; cc49
+; $00 = player mons
+; $01 = enemy mons
+
+wcc49:: ds 1
+
+wMenuWrappingEnabled:: ; cc4a
+; set to 1 if you can go from the bottom to the top or top to bottom of a menu
+; set to 0 if you can't go past the top or bottom of the menu
+ ds 1
+
+wcc4b:: ds 2
+wcc4d:: ds 1
+
+wPredefID:: ; cc4e
+ ds 1
+wPredefRegisters:: ; cc4f
+ ds 6
+
+wTrainerHeaderFlagBit:: ; cc55
+ ds 1
+
+ ds 1
+
+wNPCMovementScriptPointerTableNum:: ; cc57
+; which NPC movement script pointer is being used
+; 0 if an NPC movement script is not running
+ ds 1
+
+wNPCMovementScriptBank:: ; cc58
+; ROM bank of current NPC movement script
+ ds 1
+
+ ds 2
+
+wHallOfFame:: ; cc5b
+wBoostExpByExpAll:: ; cc5b
+wAnimationType:: ; cc5b
+; values between 0-6. Shake screen horizontally, shake screen vertically, blink Pokemon...
+
+wcc5b:: ds 1
+wcc5c:: ds 1
+wcc5d:: ds 1
+wcc5e:: ds 13
+
+wcc6b:: ds 14
+wcc79:: ds 30
+
+wNPCMovementDirections2:: ; cc97
+
+wSwitchPartyMonTempBuffer:: ; cc97
+; temporary buffer when swapping party mon data
+ ds 10
+
+wcca1:: ds 49
+
+wRLEByteCount:: ; ccd2
+ ds 1
+
+wSimulatedJoypadStatesEnd:: ; ccd3
+; this is the end of the joypad states
+; the list starts above this address and extends downwards in memory until here
+; overloaded with below labels
+
+wccd3:: ds 1
+wccd4:: ds 1
+
+; if [ccd5] != 1, the second AI layer is not applied
+wAILayer2Encouragement:: ; ccd5
+ ds 1
+ ds 1
+
+; current HP of player and enemy substitutes
+wPlayerSubstituteHP:: ; ccd7
+ ds 1
+wEnemySubstituteHP:: ; ccd8
+ ds 1
+
+wccd9:: ds 2
+
+wMoveMenuType:: ; ccdb
+; 0=regular, 1=mimic, 2=above message box (relearn, heal pp..)
+ ds 1
+
+wPlayerSelectedMove:: ; ccdc
+ ds 1
+wEnemySelectedMove:: ; ccdd
+ ds 1
+
+wLinkBattleRandomNumberListIndex:: ; ccde
+ ds 1
+
+wAICount:: ; ccdf
+; number of times remaining that AI action can occur
+ ds 1
+
+ ds 2
+
+wEnemyMoveListIndex:: ; cce2
+ ds 1
+
+wcce3:: ds 1
+wcce4:: ds 1
+
+wTotalPayDayMoney:: ; cce5
+; total amount of money made using Pay Day during the current battle
+ ds 3
+
+wSafariEscapeFactor:: ; cce8
+ ds 1
+wSafariBaitFactor:: ; cce9
+ ds 1;
+
+ ds 1
+
+wcceb:: ds 1
+wccec:: ds 1
+
+wMonIsDisobedient:: ds 1 ; cced
+
+wPlayerDisabledMoveNumber:: ds 1 ; ccee
+wEnemyDisabledMoveNumber:: ds 1 ; ccef
+
+wccf0:: ds 1
+
+wPlayerUsedMove:: ds 1 ; ccf1
+wEnemyUsedMove:: ds 1 ; ccf2
+
+wccf3:: ds 1
+
+wMoveDidntMiss:: ds 1 ; ccf4
+
+wPartyFoughtCurrentEnemyFlags:: ; ccf5
+; flags that indicate which party members have fought the current enemy mon
+ flag_array 6
+
+wccf6:: ds 1
+wccf7:: ds 14
+
+wUnknownSlotVar:: ; cd05
+
+wEnemyNumHits:: ; cd05
+; number of hits by enemy in attacks like Double Slap, etc.
+
+wEnemyBideAccumulatedDamage:: ; cd05
+; the amount of damage accumulated by the enemy while biding (2 bytes)
+
+ds 10
+
+wInGameTradeGiveMonSpecies:: ; cd0f
+
+wPlayerMonUnmodifiedLevel:: ; cd0f
+ ds 1
+
+wInGameTradeTextPointerTablePointer:: ; cd10
+
+wPlayerMonUnmodifiedMaxHP:: ; cd10
+ ds 2
+
+wInGameTradeTextPointerTableIndex:: ; cd12
+
+wPlayerMonUnmodifiedAttack:: ; cd12
+ ds 1
+wInGameTradeGiveMonName:: ; cd13
+ ds 1
+wPlayerMonUnmodifiedDefense:: ; cd14
+ ds 2
+wPlayerMonUnmodifiedSpeed:: ; cd16
+ ds 2
+wPlayerMonUnmodifiedSpecial:: ; cd18
+ ds 2
+
+; stat modifiers for the player's current pokemon
+; value can range from 1 - 13 ($1 to $D)
+; 7 is normal
+
+wPlayerMonStatMods::
+wPlayerMonAttackMod:: ; cd1a
+ ds 1
+wPlayerMonDefenseMod:: ; cd1b
+ ds 1
+wPlayerMonSpeedMod:: ; cd1c
+ ds 1
+wPlayerMonSpecialMod:: ; cd1d
+ ds 1
+
+wInGameTradeReceiveMonName:: ; cd1e
+
+wPlayerMonAccuracyMod:: ; cd1e
+ ds 1
+wPlayerMonEvasionMod:: ; cd1f
+ ds 1
+
+ ds 3
+
+wEnemyMonUnmodifiedLevel:: ; cd23
+ ds 1
+wEnemyMonUnmodifiedMaxHP:: ; cd24
+ ds 2
+wEnemyMonUnmodifiedAttack:: ; cd26
+ ds 2
+wEnemyMonUnmodifiedDefense:: ; cd28
+ ds 1
+
+wInGameTradeMonNick:: ; cd29
+ ds 1
+
+wEnemyMonUnmodifiedSpeed:: ; cd2a
+ ds 2
+wEnemyMonUnmodifiedSpecial:: ; cd2c
+ ds 1
+
+wEngagedTrainerClass:: ; cd2d
+ ds 1
+wEngagedTrainerSet:: ; cd2e
+; ds 1
+
+; stat modifiers for the enemy's current pokemon
+; value can range from 1 - 13 ($1 to $D)
+; 7 is normal
+
+wEnemyMonStatMods::
+wEnemyMonAttackMod:: ; cd2e
+ ds 1
+wEnemyMonDefenseMod:: ; cd2f
+ ds 1
+wEnemyMonSpeedMod:: ; cd30
+ ds 1
+wEnemyMonSpecialMod:: ; cd31
+ ds 1
+wEnemyMonAccuracyMod:: ; cd32
+ ds 1
+wEnemyMonEvasionMod:: ; cd33
+ ds 1
+
+wInGameTradeReceiveMonSpecies::
+ ds 1
+
+ ds 2
+
+wNPCMovementDirections2Index:: ; cd37
+
+wcd37:: ds 1
+
+wSimulatedJoypadStatesIndex:: ; cd38
+; the next simulated joypad state is at wSimulatedJoypadStatesEnd plus this value minus 1
+; 0 if the joypad state is not being simulated
+ ds 1
+
+wWastedByteCD39:: ; cd39
+; written to but nothing ever reads it
+ ds 1
+
+wWastedByteCD3A:: ; cd3a
+; written to but nothing ever reads it
+ ds 1
+
+wOverrideSimulatedJoypadStatesMask:: ; cd3b
+; mask indicating which real button presses can override simulated ones
+; XXX is it ever not 0?
+ ds 1
+
+ ds 1
+
+wTradedPlayerMonSpecies:: ; cd3d
+
+wTradingWhichPlayerMon:: ; cd3d
+
+wChangeBoxSavedMapTextPointer:: ; cd3d
+
+wFlyAnimUsingCoordList:: ; cd3d
+
+wPlayerSpinInPlaceAnimFrameDelay:: ; cd3d
+
+wPlayerSpinWhileMovingUpOrDownAnimDeltaY:: ; cd3d
+
+wHiddenObjectFunctionArgument:: ; cd3d
+
+wSubtrahend:: ; cd3d
+; subtract (BCD) wSubtrahend, wSubtrahend+1, wSubtrahend+2
+
+wWhichTrade:: ; cd3d
+; which entry from TradeMons to select
+
+wTrainerSpriteOffset:: ; cd3d
+ ds 1
+
+wTradedEnemyMonSpecies:: ; cd3e
+
+wTradingWhichEnemyMon:: ; cd3e
+
+wFlyAnimCounter:: ; cd3e
+
+wPlayerSpinInPlaceAnimFrameDelayDelta:: ; cd3e
+
+wPlayerSpinWhileMovingUpOrDownAnimMaxY:: ; cd3e
+
+wHiddenObjectFunctionRomBank:: ; cd3e
+
+wTrainerEngageDistance:: ; cd3e
+ ds 1
+
+wNameOfPlayerMonToBeTraded:: ; cd3f
+
+wFlyAnimBirdSpriteImageIndex:: ; cd3f
+
+wPlayerSpinInPlaceAnimFrameDelayEndValue:: ; cd3f
+
+wPlayerSpinWhileMovingUpOrDownAnimFrameDelay:: ; cd3f
+
+wHiddenObjectIndex:: ; cd3f
+
+wTrainerFacingDirection:: ; cd3f
+wcd3f::
+ ds 1
+
+wPlayerSpinInPlaceAnimSoundID:: ; cd40
+
+wHiddenObjectY:: ; cd40
+
+wTrainerScreenY:: ; cd40
+ ds 1
+
+wTradedPlayerMonOT:: ; cd41
+
+wHiddenObjectX:: ; cd41
+
+wTrainerScreenX:: ; cd41
+ ds 1
+
+wcd42:: ds 1
+wcd43:: ds 1
+wcd44:: ds 1
+wcd45:: ds 1
+wcd46:: ds 1
+wcd47:: ds 1
+wcd48:: ds 1
+wcd49:: ds 1
+wcd4a:: ds 1
+wcd4b:: ds 1
+
+wTradedPlayerMonOTID:: ; cd4c
+
+wcd4c:: ds 1
+wcd4d:: ds 1
+
+wTradedEnemyMonOT:: ; cd4e
+
+wcd4e:: ds 1
+wcd4f:: ds 1
+wcd50:: ds 9
+
+wTradedEnemyMonOTID:: ; cd59
+ ds 2
+
+wcd5b:: ds 1
+wcd5c:: ds 1
+
+wMonPartySpriteSpecies:: ; cd5d
+ ds 1
+
+wLeftGBMonSpecies:: ; cd5e
+; in the trade animation, the mon that leaves the left gameboy
+ ds 1
+
+wRightGBMonSpecies:: ; cd5f
+; in the trade animation, the mon that leaves the right gameboy
+ ds 1
+
+wFlags_0xcd60:: ; cd60
+; bit 0: is player engaged by trainer (to avoid being engaged by multiple trainers simultaneously)
+; bit 1: boulder dust animation (from using Strength) pending
+; bit 5: don't play sound when A or B is pressed in menu
+; bit 6: tried pushing against boulder once (you need to push twice before it will move)
+ ds 1
+
+ ds 9
+
+wcd6a:: ds 1
+
+wJoyIgnore:: ; cd6b
+; Set buttons are ignored.
+ ds 1
+
+wcd6c:: ds 1
+wcd6d:: ds 4
+wcd71:: ds 1
+wcd72:: ds 5
+wcd77:: ds 1
+wcd78:: ds 9
+
+wSerialOtherGameboyRandomNumberListBlock:: ; cd81
+; buffer for transferring the random number list generated by the other gameboy
+
+wTileMapBackup2:: ; cd81
+; second buffer for temporarily saving and restoring current screen's tiles (e.g. if menus are drawn on top)
+ ds 20 * 18
+
+wBuffer:: ; cee9
+; Temporary storage area of 30 bytes.
+wHPBarMaxHP:: ; cee9
+ ds 2
+wHPBarOldHP:: ; ceeb
+ ds 2
+wHPBarNewHP:: ; ceed
+ ds 2
+wHPBarDelta:: ; ceef
+ ds 1
+
+wcef0:: ds 1
+wcef1:: ds 12
+
+wHPBarHPDifference:: ; cefd
+ ds 1
+ ds 7
+
+wcf05:: ds 1
+wcf06:: ds 1
+
+wAnimSoundID:: ; cf07
+; sound ID during battle animations
+ ds 1
+
+wcf08:: ds 1
+wcf09:: ds 1
+wcf0a:: ds 1
+wBattleResult:: ; cf0b
+; $00 - win
+; $01 - lose
+; $02 - draw
+ ds 1
+
+wAutoTextBoxDrawingControl:: ; cf0c
+; bit 0: if set, DisplayTextID automatically draws a text box
+ ds 1
+
+wcf0d:: ds 1
+wcf0e:: ds 1
+wcf0f:: ds 1
+
+wNPCMovementScriptFunctionNum:: ; cf10
+; which script function within the pointer table indicated by
+; wNPCMovementScriptPointerTableNum
+ ds 1
+
+wcf11:: ds 1
+
+wPredefParentBank:: ; cf12
+ ds 1
+
+wSpriteIndex:: ds 1
+
+wCurSpriteMovement2:: ; cf14
+; movement byte 2 of current sprite
+ ds 1
+
+ ds 2
+
+wNPCMovementScriptSpriteOffset:: ; cf17
+; sprite offset of sprite being controlled by NPC movement script
+ ds 1
+
+wcf18:: ds 2
+
+wOnSGB:: ; cf1b
+; if running on SGB, it's 1, else it's 0
+ ds 1
+
+wcf1c:: ds 1
+wcf1d:: ds 1
+wcf1e:: ds 1
+wcf1f:: ds 6
+wcf25:: ds 8
+wcf2d:: ds 1
+wcf2e:: ds 2
+wcf30:: ds 7
+wcf37:: ds 20
+wcf4b:: ds 1
+wcf4c:: ds 1
+wGainBoostedExp:: ; cf4d
+ ds 1
+ ds 17
+
+wGymCityName:: ; cf5f
+wStringBuffer1:: ; cf5f
+ ds 16 + 1
+wGymLeaderName:: ; cf70
+wStringBuffer2:: ; cf70
+ ds 16 + 1
+wStringBuffer3:: ; cf81
+ ds 9 + 1
+
+wList:: ; cf8b
+ ds 2
+
+wcf8d:: ds 1
+wcf8e:: ds 1
+
+wItemPrices:: ; cf8f
+ ds 2
+
+wcf91:: ds 1
+
+wWhichPokemon:: ; cf92
+; which pokemon you selected
+ ds 1
+
+wcf93:: ds 1
+
+wHPBarType:: ; cf94
+; type of HP bar
+; $00 = enemy HUD in battle
+; $01 = player HUD in battle / status screen
+; $02 = party menu
+
+wListMenuID:: ; cf94
+; ID used by DisplayListMenuID
+ ds 1
+
+wcf95:: ds 1
+wcf96:: ds 1
+wcf97:: ds 1
+
+; LoadMonData copies mon data here
+wLoadedMon:: party_struct wLoadedMon ; cf98
+
+wFontLoaded:: ; cfc4
+; bit 0: The space in VRAM that is used to store walk animation tile patterns
+; for the player and NPCs is in use for font tile patterns.
+; This means that NPC movement must be disabled.
+; The other bits are unused.
+ ds 1
+
+wWalkCounter:: ; cfc5
+; walk animation counter
+ ds 1
+
+wTileInFrontOfPlayer:: ; cfc6
+; background tile number in front of the player (either 1 or 2 steps ahead)
+ ds 1
+
+wMusicHeaderPointer:: ; cfc7
+; (the current music channel address - $4000) / 3
+ ds 1
+
+wcfc8:: ds 1
+wcfc9:: ds 1
+wcfca:: ds 1
+
+wUpdateSpritesEnabled:: ; cfcb
+; $01 enables UpdateSprites; anything else disables it
+ ds 1
+
+W_ENEMYMOVENUM:: ; cfcc
+ ds 1
+W_ENEMYMOVEEFFECT:: ; cfcd
+ ds 1
+W_ENEMYMOVEPOWER:: ; cfce
+ ds 1
+W_ENEMYMOVETYPE:: ; cfcf
+ ds 1
+W_ENEMYMOVEACCURACY:: ; cfd0
+ ds 1
+W_ENEMYMOVEMAXPP:: ; cfd1
+ ds 1
+W_PLAYERMOVENUM:: ; cfd2
+ ds 1
+W_PLAYERMOVEEFFECT:: ; cfd3
+ ds 1
+W_PLAYERMOVEPOWER:: ; cfd4
+ ds 1
+W_PLAYERMOVETYPE:: ; cfd5
+ ds 1
+W_PLAYERMOVEACCURACY:: ; cfd6
+ ds 1
+W_PLAYERMOVEMAXPP:: ; cfd7
+ ds 1
+
+
+wEnemyMonSpecies2:: ; cfd8
+ ds 1
+wBattleMonSpecies2:: ; cfd9
+ ds 1
+
+wEnemyMonNick:: ds 11 ; cfda
+
+wEnemyMon:: ; cfe5
+; The wEnemyMon struct reaches past 0xcfff,
+; the end of wram bank 0 on cgb.
+; This has no significance on dmg, where wram
+; isn't banked (c000-dfff is contiguous).
+; However, recent versions of rgbds have replaced
+; dmg-style wram with cgb wram banks.
+
+; Until this is fixed, this struct will have
+; to be declared manually.
+
+wEnemyMonSpecies:: db
+wEnemyMonHP:: dw
+wEnemyMonPartyPos::
+wEnemyMonBoxLevel:: db
+wEnemyMonStatus:: db
+wEnemyMonType::
+wEnemyMonType1:: db
+wEnemyMonType2:: db
+wEnemyMonCatchRate_NotReferenced:: db
+wEnemyMonMoves:: ds NUM_MOVES
+wEnemyMonDVs:: ds 2
+wEnemyMonLevel:: db
+wEnemyMonMaxHP:: dw
+wEnemyMonAttack:: dw
+wEnemyMonDefense:: dw
+wEnemyMonSpeed:: dw
+wEnemyMonSpecial:: dw
+wEnemyMonPP:: ds 2 ; NUM_MOVES - 2
+SECTION "WRAM Bank 1", WRAMX, BANK[1]
+ ds 2 ; NUM_MOVES - 2
+
+wEnemyMonBaseStats:: ds 5
+wEnemyMonCatchRate:: ds 1
+wEnemyMonBaseExp:: ds 1
+
+wBattleMonNick:: ds 11 ; d009
+wBattleMon:: battle_struct wBattleMon ; d014
+
+
+W_TRAINERCLASS:: ; d031
+ ds 1
+
+ ds 1
+
+wTrainerPicPointer:: ; wd033
+ ds 2
+ ds 1
+wd036:: ds 16
+wd046:: ds 1
+wd047:: ds 1
+wd048:: ds 2
+
+W_TRAINERNAME:: ; d04a
+; 13 bytes for the letters of the opposing trainer
+; the name is terminated with $50 with possible
+; unused trailing letters
+ ds 13
+
+W_ISINBATTLE:: ; d057
+; no battle, this is 0
+; wild battle, this is 1
+; trainer battle, this is 2
+ ds 1
+
+wPartyGainExpFlags:: ; d058
+; flags that indicate which party members should be be given exp when GainExperience is called
+ flag_array 6
+
+W_CUROPPONENT:: ; d059
+; in a wild battle, this is the species of pokemon
+; in a trainer battle, this is the trainer class + $C8
+ ds 1
+
+W_BATTLETYPE:: ; d05a
+; in normal battle, this is 0
+; in old man battle, this is 1
+; in safari battle, this is 2
+ ds 1
+
+wDamageMultipliers:: ; d05b
+; bits 0-6: Effectiveness
+ ; $0 = immune
+ ; $5 = not very effective
+ ; $a = neutral
+ ; $14 = super-effective
+; bit 7: STAB
+ ds 1
+
+W_LONEATTACKNO:: ; d05c
+; which entry in LoneAttacks to use
+W_GYMLEADERNO:: ; d05c
+; it's actually the same thing as ^
+ ds 1
+W_TRAINERNO:: ; d05d
+; which instance of [youngster, lass, etc] is this?
+ ds 1
+
+wCriticalHitOrOHKO:: ; d05e
+; $00 = normal attack
+; $01 = critical hit
+; $02 = successful OHKO
+; $ff = failed OHKO
+ ds 1
+
+W_MOVEMISSED:: ; d05f
+ ds 1
+
+wPlayerStatsToDouble:: ; d060
+; always 0
+ ds 1
+
+wPlayerStatsToHalve:: ; d061
+; always 0
+ ds 1
+
+W_PLAYERBATTSTATUS1:: ; d062
+; bit 0 - bide
+; bit 1 - thrash / petal dance
+; bit 2 - attacking multiple times (e.g. double kick)
+; bit 3 - flinch
+; bit 4 - charging up for attack
+; bit 5 - using multi-turn move (e.g. wrap)
+; bit 6 - invulnerable to normal attack (using fly/dig)
+; bit 7 - confusion
+ ds 1
+
+W_PLAYERBATTSTATUS2:: ; d063
+; bit 0 - X Accuracy effect
+; bit 1 - protected by "mist"
+; bit 2 - focus energy effect
+; bit 4 - has a substitute
+; bit 5 - need to recharge
+; bit 6 - rage
+; bit 7 - leech seeded
+ ds 1
+
+W_PLAYERBATTSTATUS3:: ; d064
+; bit 0 - toxic
+; bit 1 - light screen
+; bit 2 - reflect
+; bit 3 - tranformed
+ ds 1
+
+wEnemyStatsToDouble:: ; d065
+; always 0
+ ds 1
+
+wEnemyStatsToHalve:: ; d066
+; always 0
+ ds 1
+
+W_ENEMYBATTSTATUS1:: ; d067
+ ds 1
+W_ENEMYBATTSTATUS2:: ; d068
+ ds 1
+W_ENEMYBATTSTATUS3:: ; d069
+ ds 1
+
+wPlayerNumAttacksLeft::
+; when the player is attacking multiple times, the number of attacks left
+ ds 1
+
+W_PLAYERCONFUSEDCOUNTER:: ; wd06b
+ ds 1
+
+W_PLAYERTOXICCOUNTER:: ; d06c
+ ds 1
+W_PLAYERDISABLEDMOVE:: ; d06d
+; high nibble: which move is disabled (1-4)
+; low nibble: disable turns left
+ ds 1
+
+ ds 1
+
+wEnemyNumAttacksLeft:: ; d06f
+; when the enemy is attacking multiple times, the number of attacks left
+ ds 1
+
+W_ENEMYCONFUSEDCOUNTER:: ; wd070
+ ds 1
+
+W_ENEMYTOXICCOUNTER:: ; d071
+ ds 1
+W_ENEMYDISABLEDMOVE:: ; d072
+; high nibble: which move is disabled (1-4)
+; low nibble: disable turns left
+ ds 1
+
+ ds 1
+
+wPlayerNumHits:: ; d074
+; number of hits by player in attacks like Double Slap, etc.
+
+wPlayerBideAccumulatedDamage:: ; d074
+; the amount of damage accumulated by the player while biding (2 bytes)
+
+wUnknownSerialCounter2:: ; d075
+; 2 bytes
+
+ ds 4
+
+wEscapedFromBattle::
+; non-zero when an item or move that allows escape from battle was used
+ ds 1
+
+wd079::
+wAmountMoneyWon:: ds 1 ; wd079 - wd07b
+wd07a:: ds 1
+ ds 1
+
+W_ANIMATIONID:: ; d07c
+; ID number of the current battle animation
+ ds 1
+
+wd07d:: ds 1
+wd07e:: ds 3
+
+; base coordinates of frame block
+W_BASECOORDX:: ; d081
+ ds 1
+W_BASECOORDY:: ; d082
+ ds 1
+
+; low health alarm counter/enable
+; high bit = enable, others = timer to cycle frequencies
+wLowHealthAlarm:: ds 1 ; d083
+
+W_FBTILECOUNTER:: ; d084
+; counts how many tiles of the current frame block have been drawn
+ ds 1
+
+wd085:: ds 1
+
+W_SUBANIMFRAMEDELAY:: ; d086
+; duration of each frame of the current subanimation in terms of screen refreshes
+ ds 1
+W_SUBANIMCOUNTER:: ; d087
+; counts the number of subentries left in the current subanimation
+ ds 1
+
+wd088:: ds 1
+
+W_NUMFBTILES:: ; d089
+; number of tiles in current battle animation frame block
+ ds 1
+
+wTradedMonMovingRight:: ; d08a
+; $01 if mon is moving from left gameboy to right gameboy; $00 if vice versa
+
+wd08a:: ds 1
+
+wTownMapSpriteBlinkingCounter:: ; d08b
+
+wPartyMonAnimCounter:: ; d08b
+
+W_SUBANIMTRANSFORM:: ; d08b
+; controls what transformations are applied to the subanimation
+; 01: flip horizontally and vertically
+; 02: flip horizontally and translate downwards 40 pixels
+; 03: translate base coordinates of frame blocks, but don't change their internal coordinates or flip their tiles
+; 04: reverse the subanimation
+ ds 1
+
+wEndBattleWinTextPointer:: ; d08c
+ ds 2
+
+wEndBattleLoseTextPointer:: ; d08e
+ ds 2
+
+ ds 2
+
+wEndBattleTextRomBank:: ; d092
+ ds 1
+
+ ds 1
+
+W_SUBANIMADDRPTR:: ; d094
+; the address _of the address_ of the current subanimation entry
+ ds 2
+W_SUBANIMSUBENTRYADDR:: ; d096
+; the address of the current subentry of the current subanimation
+ ds 2
+
+ ds 2
+
+wd09a:: ds 1
+
+wTownMapSpriteBlinkingEnabled:: ; d09b
+; non-zero when enabled. causes nest locations to blink on and off.
+; the town selection cursor will blink regardless of what this value is
+
+wd09b:: ds 1
+
+W_FBDESTADDR:: ; d09c
+; current destination address in OAM for frame blocks (big endian)
+ ds 2
+
+W_FBMODE:: ; d09e
+; controls how the frame blocks are put together to form frames
+; specifically, after finishing drawing the frame block, the frame block's mode determines what happens
+; 00: clean OAM buffer and delay
+; 02: move onto the next frame block with no delay and no cleaning OAM buffer
+; 03: delay, but don't clean OAM buffer
+; 04: delay, without cleaning OAM buffer, and do not advance [W_FBDESTADDR], so that the next frame block will overwrite this one
+; sprite data is written column by column, each byte contains 8 columns (one for ech bit)
+; for 2bpp sprites, pairs of two consecutive bytes (i.e. pairs of consecutive rows of sprite data)
+; contain the upper and lower bit of each of the 8 pixels, respectively
+ ds 1
+
+wNewTileBlockID:: ; d09f
+
+wd09f:: ds 1
+wd0a0:: ds 1
+
+W_SPRITECURPOSX:: ; d0a1
+ ds 1
+W_SPRITECURPOSY:: ; d0a2
+ ds 1
+W_SPRITEWITDH:: ; d0a3
+ ds 1
+W_SPRITEHEIGHT:: ; d0a4
+ ds 1
+W_SPRITEINPUTCURBYTE:: ; d0a5
+; current input byte
+ ds 1
+W_SPRITEINPUTBITCOUNTER:: ; d0a6
+; bit offset of last read input bit
+ ds 1
+
+W_SPRITEOUTPUTBITOFFSET:: ; d0a7; determines where in the output byte the two bits are placed. Each byte contains four columns (2bpp data)
+; 3 -> XX000000 1st column
+; 2 -> 00XX0000 2nd column
+; 1 -> 0000XX00 3rd column
+; 0 -> 000000XX 4th column
+ ds 1
+
+W_SPRITELOADFLAGS:: ; d0a8
+; bit 0 determines used buffer (0 -> $a188, 1 -> $a310)
+; bit 1 loading last sprite chunk? (there are at most 2 chunks per load operation)
+ ds 1
+W_SPRITEUNPACKMODE:: ; d0a9
+ ds 1
+W_SPRITEFLIPPED:: ; d0aa
+ ds 1
+
+W_SPRITEINPUTPTR:: ; d0ab
+; pointer to next input byte
+ ds 2
+W_SPRITEOUTPUTPTR:: ; d0ad
+; pointer to current output byte
+ ds 2
+W_SPRITEOUTPUTPTRCACHED:: ; d0af
+; used to revert pointer for different bit offsets
+ ds 2
+W_SPRITEDECODETABLE0PTR:: ; d0b1
+; pointer to differential decoding table (assuming initial value 0)
+ ds 2
+W_SPRITEDECODETABLE1PTR:: ; d0b3
+; pointer to differential decoding table (assuming initial value 1)
+ ds 2
+
+wd0b5:: ds 1
+
+wNameListType:: ; d0b6
+ ds 1
+
+wPredefBank:: ; d0b7
+ ds 1
+
+W_MONHEADER:: ; d0b8
+W_MONHDEXNUM:: ; d0b8
+ ds 1
+
+W_MONHBASESTATS:: ; d0b9
+W_MONHBASEHP:: ; d0b9
+ ds 1
+W_MONHBASEATTACK:: ; d0ba
+ ds 1
+W_MONHBASEDEFENSE:: ; d0bb
+ ds 1
+W_MONHBASESPEED:: ; d0bc
+ ds 1
+W_MONHBASESPECIAL:: ; d0bd
+ ds 1
+
+W_MONHTYPES:: ; d0be
+W_MONHTYPE1:: ; d0be
+ ds 1
+W_MONHTYPE2:: ; d0bf
+ ds 1
+
+W_MONHCATCHRATE:: ; d0c0
+ ds 1
+W_MONHBASEXP:: ; d0c1
+ ds 1
+W_MONHSPRITEDIM:: ; d0c2
+ ds 1
+W_MONHFRONTSPRITE:: ; d0c3
+ ds 2
+W_MONHBACKSPRITE:: ; d0c5
+ ds 2
+
+W_MONHMOVES:: ; d0c7
+ ds 4
+
+W_MONHGROWTHRATE:: ; d0cb
+ ds 1
+
+W_MONHLEARNSET:: ; d0cc
+; bit field
+ flag_array 50 + 5
+ ds 1
+
+wd0d4:: ds 3
+
+W_MONHPADDING:: ; d0d7
+
+
+W_DAMAGE:: ; d0d7
+ ds 2
+
+ds 2
+
+wRepelRemainingSteps:: ; wd0db
+ ds 1
+
+wMoves:: ; wd0dc
+; list of moves for FormatMovesString
+ ds 4
+
+wMoveNum:: ; d0e0
+ ds 1
+
+wMovesString:: ; d0e1
+ ds 56
+
+wd119:: ds 1
+
+wWalkBikeSurfStateCopy:: ; d11a
+; wWalkBikeSurfState is sometimes copied here, but it doesn't seem to be used for anything
+ ds 1
+
+wd11b:: ds 1
+wd11c:: ds 1
+wd11d:: ds 1
+wd11e:: ds 1
+wd11f:: ds 1
+
+wNumRunAttempts::
+; number of times the player has tried to run from battle
+ ds 1
+
+wd121:: ds 1
+wd122:: ds 2
+wd124:: ds 1
+
+wTextBoxID:: ; d125
+ ds 1
+
+wd126:: ds 1
+
+W_CURENEMYLVL:: ; d127
+ ds 1
+
+wd128:: ds 1
+wd129:: ds 1
+wd12a:: ds 1
+
+wLinkState:: ; d12b
+ ds 1
+
+wTwoOptionMenuID:: ds 1
+wd12d:: ds 1
+wd12e:: ds 1
+wd12f:: ds 1
+wd130:: ds 1
+wd131:: ds 1
+wd132:: ds 1
+wd133:: ds 6
+wd139:: ds 1
+
+wIgnoreInputCounter:: ; d13a
+; counts downward each frame
+; when it hits 0, bit 5 (ignore input bit) of wd730 is reset
+ ds 1
+
+wStepCounter:: ; d13b
+; counts down once every step
+ ds 1
+
+wNumberOfNoRandomBattleStepsLeft:: ; d13c
+; after a battle, you have at least 3 steps before a random battle can occur
+ ds 1
+
+W_PRIZE1:: ; d13d
+ ds 1
+W_PRIZE2:: ; d13e
+ ds 1
+W_PRIZE3:: ; d13f
+ ds 1
+
+ ds 1
+
+wSerialRandomNumberListBlock:: ; d141
+; the first 7 bytes are the preamble
+
+wd141:: ds 2
+wd143:: ds 2
+wd145:: ds 3
+
+wLinkBattleRandomNumberList:: ; d148
+; shared list of 9 random numbers, indexed by wLinkBattleRandomNumberListIndex
+ ds 10
+
+wSerialPlayerDataBlock:: ; d152
+; the first 6 bytes are the preamble
+
+wd152:: ds 1
+wd153:: ds 3
+wd156:: ds 1
+wd157:: ds 1
+
+
+wPlayerName:: ; d158
+ ds 11
+
+wPartyCount:: ds 1 ; d163
+wPartySpecies:: ds PARTY_LENGTH ; d164
+wPartyEnd:: ds 1 ; d16a
+
+wPartyMons::
+wPartyMon1:: party_struct wPartyMon1 ; d16b
+wPartyMon2:: party_struct wPartyMon2 ; d197
+wPartyMon3:: party_struct wPartyMon3 ; d1c3
+wPartyMon4:: party_struct wPartyMon4 ; d1ef
+wPartyMon5:: party_struct wPartyMon5 ; d21b
+wPartyMon6:: party_struct wPartyMon6 ; d247
+
+wPartyMonOT:: ds 11 * PARTY_LENGTH ; d273
+wPartyMonNicks:: ds 11 * PARTY_LENGTH ; d2b5
+
+
+wPokedexOwned:: ; d2f7
+ flag_array NUM_POKEMON
+wPokedexOwnedEnd::
+
+wPokedexSeen:: ; d30a
+ flag_array NUM_POKEMON
+wPokedexSeenEnd::
+
+
+wNumBagItems:: ; d31d
+ ds 1
+wBagItems:: ; d31e
+; item, quantity
+ ds 20 * 2
+ ds 1 ; end
+
+wPlayerMoney:: ; d347
+ ds 3 ; BCD
+
+W_RIVALNAME:: ; d34a
+ ds 11
+
+W_OPTIONS:: ; d355
+; bit 7 = battle animation
+; 0: On
+; 1: Off
+; bit 6 = battle style
+; 0: Shift
+; 1: Set
+; bits 0-3 = text speed (number of frames to delay after printing a letter)
+; 1: Fast
+; 3: Medium
+; 5: Slow
+ ds 1
+
+W_OBTAINEDBADGES:: ; d356
+ ds 1
+
+ ds 1
+
+wd358:: ds 1
+
+wPlayerID:: ; d359
+ ds 2
+
+wd35b:: ds 1
+wd35c:: ds 1
+
+wMapPalOffset:: ; d35d
+; offset subtracted from FadePal4 to get the background and object palettes for the current map
+; normally, it is 0. it is 6 when Flash is needed, causing FadePal2 to be used instead of FadePal4
+ ds 1
+
+W_CURMAP:: ; d35e
+ ds 1
+
+wCurrentTileBlockMapViewPointer:: ; d35f
+; pointer to the upper left corner of the current view in the tile block map
+ ds 2
+
+W_YCOORD:: ; d361
+; player’s position on the current map
+ ds 1
+
+W_XCOORD:: ; d362
+ ds 1
+
+W_YBLOCKCOORD:: ; d363
+; player's y position (by block)
+ ds 1
+
+W_XBLOCKCOORD:: ; d364
+ ds 1
+
+wLastMap:: ; d365
+ ds 1
+
+wd366:: ds 1
+
+W_CURMAPTILESET:: ; d367
+ ds 1
+
+W_CURMAPHEIGHT:: ; d368
+; blocks
+ ds 1
+
+W_CURMAPWIDTH:: ; d369
+; blocks
+ ds 1
+
+W_MAPDATAPTR:: ; d36a
+ ds 2
+
+W_MAPTEXTPTR:: ; d36c
+ ds 2
+
+W_MAPSCRIPTPTR:: ; d36e
+ ds 2
+
+W_MAPCONNECTIONS:: ; d370
+; connection byte
+ ds 1
+
+W_MAPCONN1PTR:: ; d371
+ ds 1
+
+wd372:: ds 1
+wd373:: ds 1
+wd374:: ds 1
+wd375:: ds 1
+wd376:: ds 1
+wd377:: ds 1
+wd378:: ds 1
+wd379:: ds 1
+wd37a:: ds 1
+wd37b:: ds 1
+
+W_MAPCONN2PTR:: ; d37c
+ ds 1
+
+wd37d:: ds 1
+wd37e:: ds 1
+wd37f:: ds 1
+wd380:: ds 1
+wd381:: ds 1
+wd382:: ds 1
+wd383:: ds 1
+wd384:: ds 1
+wd385:: ds 1
+wd386:: ds 1
+
+W_MAPCONN3PTR:: ; d387
+ ds 1
+
+wd388:: ds 1
+wd389:: ds 1
+wd38a:: ds 1
+wd38b:: ds 1
+wd38c:: ds 1
+wd38d:: ds 1
+wd38e:: ds 1
+wd38f:: ds 1
+wd390:: ds 1
+wd391:: ds 1
+
+W_MAPCONN4PTR:: ; d392
+ ds 1
+
+wd393:: ds 1
+wd394:: ds 1
+wd395:: ds 1
+wd396:: ds 1
+wd397:: ds 1
+wd398:: ds 1
+wd399:: ds 1
+wd39a:: ds 1
+wd39b:: ds 1
+wd39c:: ds 1
+
+W_SPRITESET:: ; d39d
+; sprite set for the current map (11 sprite picture ID's)
+ ds 11
+
+W_SPRITESETID:: ; d3a8
+; sprite set ID for the current map
+ ds 1
+
+wd3a9:: ds 1
+wd3aa:: ds 3
+wd3ad:: ds 1
+
+wNumberOfWarps:: ; d3ae
+; number of warps in current map
+ ds 1
+
+wWarpEntries:: ; d3af
+; current map warp entries
+ ds 128
+
+wDestinationWarpID:: ; d42f
+; if $ff, the player's coordinates are not updated when entering the map
+ ds 1
+
+wd430:: ds 1 ; d430
+wd431:: ds 1 ; d431
+
+ ds 3
+
+wd435:: ds 1
+wd436:: ds 1
+
+ ds 60
+
+wd472:: ds 1
+wd473:: ds 1
+
+ ds 61
+
+wd4b0:: ds 1
+wd4b1:: ds 32
+wd4d1:: ds 16
+
+W_NUMSPRITES:: ; d4e1
+; number of sprites on the current map
+ ds 1
+
+; these two variables track the X and Y offset in blocks from the last special warp used
+; they don't seem to be used for anything
+wYOffsetSinceLastSpecialWarp:: ; d4e2
+ ds 1
+wXOffsetSinceLastSpecialWarp:: ; d4e3
+ ds 1
+
+W_MAPSPRITEDATA:: ; d4e4
+; two bytes per sprite (movement byte 2, text ID)
+ ds 32
+
+W_MAPSPRITEEXTRADATA:: ; d504
+; two bytes per sprite (trainer class/item ID, trainer set ID)
+ ds 32
+
+wd524:: ds 1
+wd525:: ds 1
+
+wMapViewVRAMPointer:: ; d526
+; the address of the upper left corner of the visible portion of the BG tile map in VRAM
+ ds 2
+
+wd528:: ds 1
+wd529:: ds 1
+wd52a:: ds 1
+
+W_TILESETBANK:: ; d52b
+ ds 1
+
+W_TILESETBLOCKSPTR:: ; d52c
+; maps blocks (4x4 tiles) to tiles
+ ds 2
+
+W_TILESETGFXPTR:: ; d52e
+ ds 2
+
+W_TILESETCOLLISIONPTR:: ; d530
+; list of all walkable tiles
+ ds 2
+
+W_TILESETTALKINGOVERTILES:: ; d532
+ ds 3
+
+W_GRASSTILE:: ; d535
+ ds 1
+
+ ds 4
+
+wNumBoxItems:: ; d53a
+ ds 1
+wBoxItems:: ; d53b
+; item, quantity
+ ds 50 * 2
+ ds 1 ; end
+
+wd5a0:: ds 2
+wd5a2:: ds 1
+wd5a3:: ds 1
+
+wPlayerCoins:: ; d5a4
+ ds 2 ; BCD
+
+W_MISSABLEOBJECTFLAGS:: ; d5a6
+; bit array of missable objects. set = removed
+ ds 39
+
+wd5cd:: ds 1
+
+W_MISSABLEOBJECTLIST:: ; d5ce
+; each entry consists of 2 bytes
+; * the sprite ID (depending on the current map)
+; * the missable object index (global, used for W_MISSABLEOBJECTFLAGS)
+; terminated with $FF
+ ds 17 * 2
+
+W_GAMEPROGRESSFLAGS:: ; d5f0
+; $c8 bytes
+ ds 0
+
+W_OAKSLABCURSCRIPT:: ; d5f0
+ ds 1
+W_PALLETTOWNCURSCRIPT:: ; d5f1
+ ds 1
+ ds 1
+W_BLUESHOUSECURSCRIPT:: ; d5f3
+ ds 1
+W_VIRIDIANCITYCURSCRIPT:: ; d5f4
+ ds 1
+ ds 2
+W_PEWTERCITYCURSCRIPT:: ; d5f7
+ ds 1
+W_ROUTE3CURSCRIPT:: ; d5f8
+ ds 1
+W_ROUTE4CURSCRIPT:: ; d5f9
+ ds 1
+ ds 1
+W_VIRIDIANGYMCURSCRIPT:: ; d5fb
+ ds 1
+W_PEWTERGYMCURSCRIPT:: ; d5fc
+ ds 1
+W_CERULEANGYMCURSCRIPT:: ; d5fd
+ ds 1
+W_VERMILIONGYMCURSCRIPT:: ; d5fe
+ ds 1
+W_CELADONGYMCURSCRIPT:: ; d5ff
+ ds 1
+W_ROUTE6CURSCRIPT:: ; d600
+ ds 1
+W_ROUTE8CURSCRIPT:: ; d601
+ ds 1
+W_ROUTE24CURSCRIPT:: ; d602
+ ds 1
+W_ROUTE25CURSCRIPT:: ; d603
+ ds 1
+W_ROUTE9CURSCRIPT:: ; d604
+ ds 1
+W_ROUTE10CURSCRIPT:: ; d605
+ ds 1
+W_MTMOON1CURSCRIPT:: ; d606
+ ds 1
+W_MTMOON3CURSCRIPT:: ; d607
+ ds 1
+W_SSANNE8CURSCRIPT:: ; d608
+ ds 1
+W_SSANNE9CURSCRIPT:: ; d609
+ ds 1
+W_ROUTE22CURSCRIPT:: ; d60a
+ ds 1
+ ds 1
+W_REDSHOUSE2CURSCRIPT:: ; d60c
+ ds 1
+W_VIRIDIANMARKETCURSCRIPT:: ; d60d
+ ds 1
+W_ROUTE22GATECURSCRIPT:: ; d60e
+ ds 1
+W_CERULEANCITYCURSCRIPT:: ; d60f
+ ds 1
+ ds 7
+W_SSANNE5CURSCRIPT:: ; d617
+ ds 1
+W_VIRIDIANFORESTCURSCRIPT:: ; d618
+ ds 1
+W_MUSEUM1FCURSCRIPT:: ; d619
+ ds 1
+W_ROUTE13CURSCRIPT:: ; d61a
+ ds 1
+W_ROUTE14CURSCRIPT:: ; d61b
+ ds 1
+W_ROUTE17CURSCRIPT:: ; d61c
+ ds 1
+W_ROUTE19CURSCRIPT:: ; d61d
+ ds 1
+W_ROUTE21CURSCRIPT:: ; d61e
+ ds 1
+W_SAFARIZONEENTRANCECURSCRIPT:: ; d61f
+ ds 1
+W_ROCKTUNNEL2CURSCRIPT:: ; d620
+ ds 1
+W_ROCKTUNNEL1CURSCRIPT:: ; d621
+ ds 1
+ ds 1
+W_ROUTE11CURSCRIPT:: ; d623
+ ds 1
+W_ROUTE12CURSCRIPT:: ; d624
+ ds 1
+W_ROUTE15CURSCRIPT:: ; d625
+ ds 1
+W_ROUTE16CURSCRIPT:: ; d626
+ ds 1
+W_ROUTE18CURSCRIPT:: ; d627
+ ds 1
+W_ROUTE20CURSCRIPT:: ; d628
+ ds 1
+W_SSANNE10CURSCRIPT:: ; d629
+ ds 1
+W_VERMILIONCITYCURSCRIPT:: ; d62a
+ ds 1
+W_POKEMONTOWER2CURSCRIPT:: ; d62b
+ ds 1
+W_POKEMONTOWER3CURSCRIPT:: ; d62c
+ ds 1
+W_POKEMONTOWER4CURSCRIPT:: ; d62d
+ ds 1
+W_POKEMONTOWER5CURSCRIPT:: ; d62e
+ ds 1
+W_POKEMONTOWER6CURSCRIPT:: ; d62f
+ ds 1
+W_POKEMONTOWER7CURSCRIPT:: ; d630
+ ds 1
+W_ROCKETHIDEOUT1CURSCRIPT:: ; d631
+ ds 1
+W_ROCKETHIDEOUT2CURSCRIPT:: ; d632
+ ds 1
+W_ROCKETHIDEOUT3CURSCRIPT:: ; d633
+ ds 1
+W_ROCKETHIDEOUT4CURSCRIPT:: ; d634
+ ds 2
+W_ROUTE6GATECURSCRIPT:: ; d636
+ ds 1
+W_ROUTE8GATECURSCRIPT:: ; d637
+ ds 2
+W_CINNABARISLANDCURSCRIPT:: ; d639
+ ds 1
+W_MANSION1CURSCRIPT:: ; d63a
+ ds 2
+W_MANSION2CURSCRIPT:: ; d63c
+ ds 1
+W_MANSION3CURSCRIPT:: ; d63d
+ ds 1
+W_MANSION4CURSCRIPT:: ; d63e
+ ds 1
+W_VICTORYROAD2CURSCRIPT:: ; d63f
+ ds 1
+W_VICTORYROAD3CURSCRIPT:: ; d640
+ ds 2
+W_FIGHTINGDOJOCURSCRIPT:: ; d642
+ ds 1
+W_SILPHCO2CURSCRIPT:: ; d643
+ ds 1
+W_SILPHCO3CURSCRIPT:: ; d644
+ ds 1
+W_SILPHCO4CURSCRIPT:: ; d645
+ ds 1
+W_SILPHCO5CURSCRIPT:: ; d646
+ ds 1
+W_SILPHCO6CURSCRIPT:: ; d647
+ ds 1
+W_SILPHCO7CURSCRIPT:: ; d648
+ ds 1
+W_SILPHCO8CURSCRIPT:: ; d649
+ ds 1
+W_SILPHCO9CURSCRIPT:: ; d64a
+ ds 1
+W_HALLOFFAMEROOMCURSCRIPT:: ; d64b
+ ds 1
+W_GARYCURSCRIPT:: ; d64c
+ ds 1
+W_LORELEICURSCRIPT:: ; d64d
+ ds 1
+W_BRUNOCURSCRIPT:: ; d64e
+ ds 1
+W_AGATHACURSCRIPT:: ; d64f
+ ds 1
+W_UNKNOWNDUNGEON3CURSCRIPT:: ; d650
+ ds 1
+W_VICTORYROAD1CURSCRIPT:: ; d651
+ ds 1
+ ds 1
+W_LANCECURSCRIPT:: ; d653
+ ds 1
+ ds 4
+W_SILPHCO10CURSCRIPT:: ; d658
+ ds 1
+W_SILPHCO11CURSCRIPT:: ; d659
+ ds 1
+ ds 1
+W_FUCHSIAGYMCURSCRIPT:: ; d65b
+ ds 1
+W_SAFFRONGYMCURSCRIPT:: ; d65c
+ ds 1
+ ds 1
+W_CINNABARGYMCURSCRIPT:: ; d65e
+ ds 1
+W_CELADONGAMECORNERCURSCRIPT:: ; d65f
+ ds 1
+W_ROUTE16GATECURSCRIPT:: ; d660
+ ds 1
+W_BILLSHOUSECURSCRIPT:: ; d661
+ ds 1
+W_ROUTE5GATECURSCRIPT:: ; d662
+ ds 1
+W_POWERPLANTCURSCRIPT:: ; d663
+; overload
+ ds 0
+W_ROUTE7GATECURSCRIPT:: ; d663
+; overload
+ ds 1
+ ds 1
+W_SSANNE2CURSCRIPT:: ; d665
+ ds 1
+W_SEAFOAMISLANDS4CURSCRIPT:: ; d666
+ ds 1
+W_ROUTE23CURSCRIPT:: ; d667
+ ds 1
+W_SEAFOAMISLANDS5CURSCRIPT:: ; d668
+ ds 1
+W_ROUTE18GATECURSCRIPT:: ; d669
+ ds 1
+
+ ds 134
+
+wd6f0:: ds 14
+wd6fe:: ds 2
+
+wWalkBikeSurfState:: ; d700
+; $00 = walking
+; $01 = biking
+; $02 = surfing
+ ds 1
+
+ ds 10
+
+W_TOWNVISITEDFLAG:: ; d70b
+ flag_array 13
+
+wSafariSteps:: ; d70d
+; starts at 502
+ ds 2
+
+W_FOSSILITEM:: ; d70f
+; item given to cinnabar lab
+ ds 1
+
+W_FOSSILMON:: ; d710
+; mon that will result from the item
+ ds 1
+
+ ds 2
+
+W_ENEMYMONORTRAINERCLASS:: ; d713
+; trainer classes start at $c8
+ ds 1
+
+wPlayerJumpingYScreenCoordsIndex:: ; d714
+ ds 1
+
+W_RIVALSTARTER:: ; d715
+ ds 1
+
+ ds 1
+
+W_PLAYERSTARTER:: ; d717
+ ds 1
+
+wBoulderSpriteIndex:: ; d718
+; sprite index of the boulder the player is trying to push
+ ds 1
+
+wLastBlackoutMap:: ; d719
+ ds 1
+
+wDestinationMap:: ; d71a
+; destination map (for certain types of special warps, not ordinary walking)
+ ds 1
+
+wd71b:: ds 1
+
+wTileInFrontOfBoulderAndBoulderCollisionResult:: ; d71c
+; used to store the tile in front of the boulder when trying to push a boulder
+; also used to store the result of the collision check ($ff for a collision and $00 for no collision)
+ ds 1
+
+wDungeonWarpDestinationMap:: ; d71d
+; destination map for dungeon warps
+ ds 1
+
+wWhichDungeonWarp:: ; d71e
+; which dungeon warp within the source map was used
+ ds 1
+
+wd71f:: ds 9
+
+wd728::
+; bit 0: using Strength outside of battle
+ ds 1
+
+ ds 1
+
+wd72a:: ds 2
+
+wd72c:: ; d72c
+; bit 0: if not set, the 3 minimum steps between random battles have passed
+ ds 1
+
+wd72d:: ds 1
+wd72e:: ds 2
+
+wd730::
+; bit 0: NPC sprite being moved by script
+; bit 5: ignore joypad input
+; bit 6: print text with no delay between each letter
+; bit 7: set if joypad states are being simulated in the overworld
+ ds 1
+
+ ds 1
+
+wd732:: ; d732
+; bit 0: play time being counted
+; bit 1: remnant of debug mode? not set by the game code.
+; if it is set
+; 1. skips most of Prof. Oak's speech, and uses NINTEN as the player's name and SONY as the rival's name
+; 2. does not have the player start in floor two of the playyer's house (instead sending them to [wLastMap])
+; 3. allows wild battles to be avoided by holding down B
+; bit 2: the target warp is a fly warp (bit 3 set or blacked out) or a dungeon warp (bit 4 set)
+; bit 3: used warp pad, escape rope, dig, teleport, or fly, so the target warp is a "fly warp"
+; bit 4: jumped into hole (Pokemon Mansion, Seafoam Islands, Victory Road) or went down waterfall (Seafoam Islands), so the target warp is a "dungeon warp"
+; bit 5: currently being forced to ride bike (cycling road)
+; bit 6: map destination is [wLastBlackoutMap] (usually the last used pokemon center, but could be the player's house)
+ ds 1
+
+W_FLAGS_D733:: ; d733
+; bit 4: use variable [W_CURMAPSCRIPT] instead of the provided index for next frame's map script (used to start battle when talking to trainers)
+; bit 7: used fly out of battle
+ ds 1
+
+wd734:: ds 2
+
+wd736:: ; d736
+; bit 0: check if the player is standing on a door and make him walk down a step if so
+; bit 1: the player is currently stepping down from a door
+; bit 2: standing on a warp
+; bit 6: jumping down a ledge
+ ds 1
+
+wCompletedInGameTradeFlags:: ; d737
+ ds 2
+
+ ds 2
+
+wd73b:: ds 1
+wd73c:: ds 3
+
+wCardKeyDoorY:: ; d73f
+ ds 1
+
+wCardKeyDoorX:: ; d740
+ ds 1
+
+ ds 2
+
+wd743:: ds 1
+wd744:: ds 3
+wd747:: ds 3
+wd74a:: ds 1
+
+wd74b:: ; d74b
+; bit 0: Prof. Oak has lead the player to the north end of his lab
+; bit 1: Prof. Oak has asked the player to choose a pokemon
+; bit 2: the player and the rival have received their pokemon
+; bit 3: the player has battled the rival in Oak's lab
+; bit 4: Prof. Oak has given the player 5 pokeballs
+; bit 5: received pokedex
+ ds 1
+
+wd74c:: ds 2
+wd74e:: ds 3
+wd751:: ds 1
+wd752:: ds 2
+wd754:: ds 1
+wd755:: ds 5
+wd75a:: ds 1
+wd75b:: ds 3
+wd75e:: ds 1
+wd75f:: ds 5
+wd764:: ds 1
+wd765:: ds 1
+wd766:: ds 1
+wd767:: ds 1
+wd768:: ds 1
+wd769:: ds 3
+wd76c:: ds 5
+wd771:: ds 2
+wd773:: ds 4
+wd777:: ds 1
+wd778:: ds 4
+wd77c:: ds 1
+wd77d:: ds 1
+wd77e:: ds 5
+wd783:: ds 11
+wd78e:: ds 2
+wd790:: ds 2
+wd792:: ds 4
+wd796:: ds 2
+wd798:: ds 2
+wd79a:: ds 1
+wd79b:: ds 1
+wd79c:: ds 5
+wd7a1:: ds 2
+wd7a3:: ds 12
+wd7af:: ds 2
+wd7b1:: ds 2
+wd7b3:: ds 1
+wd7b4:: ds 5
+wd7b9:: ds 4
+wd7bd:: ds 2
+wd7bf:: ds 3
+wd7c2:: ds 1
+wd7c3:: ds 2
+wd7c5:: ds 1
+wd7c6:: ds 3
+wd7c9:: ds 4
+wd7cd:: ds 2
+wd7cf:: ds 2
+wd7d1:: ds 1
+wd7d2:: ds 1
+wd7d3:: ds 2
+wd7d5:: ds 1
+wd7d6:: ds 1
+wd7d7:: ds 1
+wd7d8:: ds 1
+wd7d9:: ds 2
+wd7db:: ds 2
+wd7dd:: ds 2
+wd7df:: ds 1
+wd7e0:: ds 1
+wd7e1:: ds 2
+wd7e3:: ds 2
+wd7e5:: ds 2
+wd7e7:: ds 1
+wd7e8:: ds 1
+wd7e9:: ds 2
+wd7eb:: ds 2
+wd7ed:: ds 1
+wd7ee:: ds 1
+wd7ef:: ds 1
+wd7f0:: ds 1
+wd7f1:: ds 1
+wd7f2:: ds 1
+wd7f3:: ds 2
+wd7f5:: ds 1
+wd7f6:: ds 9
+wd7ff:: ds 4
+wd803:: ds 2
+wd805:: ds 2
+wd807:: ds 2
+wd809:: ds 10
+wd813:: ds 2
+wd815:: ds 1
+wd816:: ds 1
+wd817:: ds 2
+wd819:: ds 2
+wd81b:: ds 10
+wd825:: ds 1
+wd826:: ds 1
+wd827:: ds 1
+wd828:: ds 1
+wd829:: ds 1
+wd82a:: ds 1
+wd82b:: ds 1
+wd82c:: ds 1
+wd82d:: ds 1
+wd82e:: ds 1
+wd82f:: ds 1
+wd830:: ds 1
+wd831:: ds 1
+wd832:: ds 1
+wd833:: ds 1
+wd834:: ds 1
+wd835:: ds 1
+wd836:: ds 1
+wd837:: ds 1
+wd838:: ds 15
+wd847:: ds 2
+wd849:: ds 2
+wd84b:: ds 12
+wd857:: ds 8
+wd85f:: ds 4
+wd863:: ds 1
+wd864:: ds 1
+wd865:: ds 1
+wd866:: ds 1
+wd867:: ds 2
+wd869:: ds 20
+wd87d:: ds 2
+wd87f:: ds 1
+wd880:: ds 1
+wd881:: ds 1
+wd882:: ds 5
+
+wLinkEnemyTrainerName:: ; d887
+; linked game's trainer name
+
+W_GRASSRATE:: ; d887
+ ds 1
+
+W_GRASSMONS:: ; d888
+ ds 20
+
+
+wEnemyPartyCount:: ds 1 ; d89c
+wEnemyPartyMons:: ds PARTY_LENGTH + 1 ; d89d
+
+wEnemyMons:: ; d8a4
+wEnemyMon1:: party_struct wEnemyMon1
+wEnemyMon2:: party_struct wEnemyMon2
+wEnemyMon3:: party_struct wEnemyMon3
+wEnemyMon4:: party_struct wEnemyMon4
+wEnemyMon5:: party_struct wEnemyMon5
+wEnemyMon6:: party_struct wEnemyMon6
+
+wEnemyMonOT:: ds 11 * PARTY_LENGTH ; d9ac
+wEnemyMonNicks:: ds 11 * PARTY_LENGTH ; d9ee
+
+
+W_TRAINERHEADERPTR:: ; da30
+ ds 2
+
+ ds 6
+
+wda38:: ds 1
+
+W_CURMAPSCRIPT:: ; da39
+; index of current map script, mostly used as index for function pointer array
+; mostly copied from map-specific map script pointer and wirtten back later
+ ds 1
+
+ ds 6
+
+W_PLAYTIMEHOURS:: ; da40
+ ds 2
+W_PLAYTIMEMINUTES:: ; da42
+ ds 2
+W_PLAYTIMESECONDS:: ; da44
+ ds 1
+W_PLAYTIMEFRAMES:: ; da45
+ ds 1
+
+wSafariZoneGameOver:: ; da46
+ ds 1
+
+W_NUMSAFARIBALLS:: ; da47
+ ds 1
+
+
+W_DAYCARE_IN_USE:: ; da48
+; 0 if no pokemon is in the daycare
+; 1 if pokemon is in the daycare
+ ds 1
+
+W_DAYCAREMONNAME:: ds 11 ; da49
+W_DAYCAREMONOT:: ds 11 ; da54
+
+wDayCareMon:: box_struct wDayCareMon ; da5f
+
+
+W_NUMINBOX:: ds 1 ; da80
+wBoxSpecies:: ds MONS_PER_BOX + 1
+
+wBoxMons::
+wBoxMon1:: box_struct wBoxMon1 ; da96
+wBoxMon2:: ds box_struct_length * (MONS_PER_BOX + -1) ; dab7
+
+wBoxMonOT:: ds 11 * MONS_PER_BOX ; dd2a
+wBoxMonNicks:: ds 11 * MONS_PER_BOX ; de06
+wBoxMonNicksEnd:: ; dee2
+
+
+SECTION "Stack", WRAMX[$dfff], BANK[1]
+wStack:: ; dfff
+ ds -$100
+
+
+INCLUDE "sram.asm"
diff --git a/yellow/bank3c/overworld.asm b/yellow/bank3c/overworld.asm
index 7ecac223..30a50431 100644
--- a/yellow/bank3c/overworld.asm
+++ b/yellow/bank3c/overworld.asm
@@ -1,195 +1,243 @@
-SECTION "bank3c",ROMX[$401c],BANK[$3c]
-_AdvancePlayerSprite:: ; f010c (3c:f010c)
- ld a,[wSpriteStateData1 + 3] ; delta Y
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
- ld c,a
- ld hl,wWalkCounter ; walking animation counter
- dec [hl]
- jr nz,.afterUpdateMapCoords
-; if it's the end of the animation, update the player's map coordinates
- ld a,[W_YCOORD]
- add b
- ld [W_YCOORD],a
- ld a,[W_XCOORD]
- add c
- ld [W_XCOORD],a
-.afterUpdateMapCoords
- ld a,[wWalkCounter] ; walking animation counter
- cp a,$07
- jp nz,.scrollBackgroundAndSprites
-; if this is the first iteration of the animation
- ld a,c
- cp a,$01
- jr nz,.checkIfMovingWest
-; moving east
- ld a,[wMapViewVRAMPointer]
- ld e,a
- and a,$e0
- ld d,a
- ld a,e
- add a,$02
- and a,$1f
- or d
- ld [wMapViewVRAMPointer],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingWest
- cp a,$ff
- jr nz,.checkIfMovingSouth
-; moving west
- ld a,[wMapViewVRAMPointer]
- ld e,a
- and a,$e0
- ld d,a
- ld a,e
- sub a,$02
- and a,$1f
- or d
- ld [wMapViewVRAMPointer],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingSouth
- ld a,b
- cp a,$01
- jr nz,.checkIfMovingNorth
-; moving south
- ld a,[wMapViewVRAMPointer]
- add a,$40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
- inc a
- and a,$03
- or a,$98
- ld [wMapViewVRAMPointer + 1],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingNorth
- cp a,$ff
- jr nz,.adjustXCoordWithinBlock
-; moving north
- ld a,[wMapViewVRAMPointer]
- sub a,$40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
- dec a
- and a,$03
- or a,$98
- ld [wMapViewVRAMPointer + 1],a
-.adjustXCoordWithinBlock
- ld a,c
- and a
- jr z,.pointlessJump ; mistake?
-.pointlessJump
- ld hl,W_XBLOCKCOORD
- ld a,[hl]
- add c
- ld [hl],a
- cp a,$02
- jr nz,.checkForMoveToWestBlock
-; moved into the tile block to the east
- xor a
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
- inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
- call MoveTileBlockMapPointerEast
- jr .updateMapView
-.checkForMoveToWestBlock
- cp a,$ff
- jr nz,.adjustYCoordWithinBlock
-; moved into the tile block to the west
- ld a,$01
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
- dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
- call MoveTileBlockMapPointerWest
- jr .updateMapView
-.adjustYCoordWithinBlock
- ld hl,W_YBLOCKCOORD
- ld a,[hl]
- add b
- ld [hl],a
- cp a,$02
- jr nz,.checkForMoveToNorthBlock
-; moved into the tile block to the south
- xor a
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
- inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[W_CURMAPWIDTH]
- call MoveTileBlockMapPointerSouth
- jr .updateMapView
-.checkForMoveToNorthBlock
- cp a,$ff
- jr nz,.updateMapView
-; moved into the tile block to the north
- ld a,$01
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
- dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[W_CURMAPWIDTH]
- call MoveTileBlockMapPointerNorth
-.updateMapView
- call LoadCurrentMapView
- ld a,[wSpriteStateData1 + 3] ; delta Y
- cp a,$01
- jr nz,.checkIfMovingNorth2
-; if moving south
- call ScheduleSouthRowRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingNorth2
- cp a,$ff
- jr nz,.checkIfMovingEast2
-; if moving north
- call ScheduleNorthRowRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingEast2
- ld a,[wSpriteStateData1 + 5] ; delta X
- cp a,$01
- jr nz,.checkIfMovingWest2
-; if moving east
- call ScheduleEastColumnRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingWest2
- cp a,$ff
- jr nz,.scrollBackgroundAndSprites
-; if moving west
- call ScheduleWestColumnRedraw
-.scrollBackgroundAndSprites
- ld a,[wSpriteStateData1 + 3] ; delta Y
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
- ld c,a
- sla b
- sla c
- ld a,[hSCY]
- add b
- ld [hSCY],a ; update background scroll Y
- ld a,[hSCX]
- add c
- ld [hSCX],a ; update background scroll X
-; shift all the sprites in the direction opposite of the player's motion
-; so that the player appears to move relative to them
- ld hl,wSpriteStateData1 + $14
- ld a,[W_NUMSPRITES] ; number of sprites
- and a ; are there any sprites?
- jr z,.done
- ld e,a
-.spriteShiftLoop
- ld a,[hl]
- sub b
- ld [hli],a
- inc l
- ld a,[hl]
- sub c
- ld [hl],a
- ld a,$0e
- add l
- ld l,a
- dec e
- jr nz,.spriteShiftLoop
-.done
- ret
+SECTION "bank3c",ROMX[$410c],BANK[$3c]
+_AdvancePlayerSprite:: ; f010c (3c:410c)
+ ld a,[wSpriteStateData1 + 3] ; delta Y
+ ld b,a
+ ld a,[wSpriteStateData1 + 5] ; delta X
+ ld c,a
+ ld hl,wWalkCounter ; walking animation counter
+ dec [hl]
+ jr nz,.afterUpdateMapCoords
+; if it's the end of the animation, update the player's map coordinates
+ ld a,[W_YCOORD]
+ add b
+ ld [W_YCOORD],a
+ ld a,[W_XCOORD]
+ add c
+ ld [W_XCOORD],a
+.afterUpdateMapCoords
+ ld a,[wWalkCounter] ; walking animation counter
+ cp a,$07
+ jp nz,.scrollBackgroundAndSprites
+; if this is the first iteration of the animation
+ ld a,c
+ cp a,$01
+ jr nz,.checkIfMovingWest
+; moving east
+ ld a,[wMapViewVRAMPointer]
+ ld e,a
+ and a,$e0
+ ld d,a
+ ld a,e
+ add a,$02
+ and a,$1f
+ or d
+ ld [wMapViewVRAMPointer],a
+ jr .adjustXCoordWithinBlock
+.checkIfMovingWest
+ cp a,$ff
+ jr nz,.checkIfMovingSouth
+; moving west
+ ld a,[wMapViewVRAMPointer]
+ ld e,a
+ and a,$e0
+ ld d,a
+ ld a,e
+ sub a,$02
+ and a,$1f
+ or d
+ ld [wMapViewVRAMPointer],a
+ jr .adjustXCoordWithinBlock
+.checkIfMovingSouth
+ ld a,b
+ cp a,$01
+ jr nz,.checkIfMovingNorth
+; moving south
+ ld a,[wMapViewVRAMPointer]
+ add a,$40
+ ld [wMapViewVRAMPointer],a
+ jr nc,.adjustXCoordWithinBlock
+ ld a,[wMapViewVRAMPointer + 1]
+ inc a
+ and a,$03
+ or a,$98
+ ld [wMapViewVRAMPointer + 1],a
+ jr .adjustXCoordWithinBlock
+.checkIfMovingNorth
+ cp a,$ff
+ jr nz,.adjustXCoordWithinBlock
+; moving north
+ ld a,[wMapViewVRAMPointer]
+ sub a,$40
+ ld [wMapViewVRAMPointer],a
+ jr nc,.adjustXCoordWithinBlock
+ ld a,[wMapViewVRAMPointer + 1]
+ dec a
+ and a,$03
+ or a,$98
+ ld [wMapViewVRAMPointer + 1],a
+.adjustXCoordWithinBlock
+ ld a,c
+ and a
+ jr z,.pointlessJump ; mistake?
+.pointlessJump
+ ld hl,W_XBLOCKCOORD
+ ld a,[hl]
+ add c
+ ld [hl],a
+ cp a,$02
+ jr nz,.checkForMoveToWestBlock
+; moved into the tile block to the east
+ xor a
+ ld [hl],a
+ ld hl,wXOffsetSinceLastSpecialWarp
+ inc [hl]
+ ld de,wCurrentTileBlockMapViewPointer
+ call MoveTileBlockMapPointerEast
+ jr .updateMapView
+.checkForMoveToWestBlock
+ cp a,$ff
+ jr nz,.adjustYCoordWithinBlock
+; moved into the tile block to the west
+ ld a,$01
+ ld [hl],a
+ ld hl,wXOffsetSinceLastSpecialWarp
+ dec [hl]
+ ld de,wCurrentTileBlockMapViewPointer
+ call MoveTileBlockMapPointerWest
+ jr .updateMapView
+.adjustYCoordWithinBlock
+ ld hl,W_YBLOCKCOORD
+ ld a,[hl]
+ add b
+ ld [hl],a
+ cp a,$02
+ jr nz,.checkForMoveToNorthBlock
+; moved into the tile block to the south
+ xor a
+ ld [hl],a
+ ld hl,wYOffsetSinceLastSpecialWarp
+ inc [hl]
+ ld de,wCurrentTileBlockMapViewPointer
+ ld a,[W_CURMAPWIDTH]
+ call MoveTileBlockMapPointerSouth
+ jr .updateMapView
+.checkForMoveToNorthBlock
+ cp a,$ff
+ jr nz,.updateMapView
+; moved into the tile block to the north
+ ld a,$01
+ ld [hl],a
+ ld hl,wYOffsetSinceLastSpecialWarp
+ dec [hl]
+ ld de,wCurrentTileBlockMapViewPointer
+ ld a,[W_CURMAPWIDTH]
+ call MoveTileBlockMapPointerNorth
+.updateMapView
+ call LoadCurrentMapView
+ ld a,[wSpriteStateData1 + 3] ; delta Y
+ cp a,$01
+ jr nz,.checkIfMovingNorth2
+; if moving south
+ call ScheduleSouthRowRedraw
+ jr .scrollBackgroundAndSprites
+.checkIfMovingNorth2
+ cp a,$ff
+ jr nz,.checkIfMovingEast2
+; if moving north
+ call ScheduleNorthRowRedraw
+ jr .scrollBackgroundAndSprites
+.checkIfMovingEast2
+ ld a,[wSpriteStateData1 + 5] ; delta X
+ cp a,$01
+ jr nz,.checkIfMovingWest2
+; if moving east
+ call ScheduleEastColumnRedraw
+ jr .scrollBackgroundAndSprites
+.checkIfMovingWest2
+ cp a,$ff
+ jr nz,.scrollBackgroundAndSprites
+; if moving west
+ call ScheduleWestColumnRedraw
+.scrollBackgroundAndSprites
+ ld a,[wSpriteStateData1 + 3] ; delta Y
+ ld b,a
+ ld a,[wSpriteStateData1 + 5] ; delta X
+ ld c,a
+ sla b
+ sla c
+ ld a,[hSCY]
+ add b
+ ld [hSCY],a ; update background scroll Y
+ ld a,[hSCX]
+ add c
+ ld [hSCX],a ; update background scroll X
+; shift all the sprites in the direction opposite of the player's motion
+; so that the player appears to move relative to them
+ ld hl,wSpriteStateData1 + $14
+ ld a,[W_NUMSPRITES] ; number of sprites
+ and a ; are there any sprites?
+ jr z,.done
+ ld e,a
+.spriteShiftLoop
+ ld a,[hl]
+ sub b
+ ld [hli],a
+ inc l
+ ld a,[hl]
+ sub c
+ ld [hl],a
+ ld a,$0e
+ add l
+ ld l,a
+ dec e
+ jr nz,.spriteShiftLoop
+.done
+ ret
+
+MoveTileBlockMapPointerEast:: ; 0e65 (0:0e65)
+ ld a,[de]
+ add a,$01
+ ld [de],a
+ ret nc
+ inc de
+ ld a,[de]
+ inc a
+ ld [de],a
+ ret
+
+MoveTileBlockMapPointerWest:: ; 0e6f (0:0e6f)
+ ld a,[de]
+ sub a,$01
+ ld [de],a
+ ret nc
+ inc de
+ ld a,[de]
+ dec a
+ ld [de],a
+ ret
+
+MoveTileBlockMapPointerSouth:: ; 0e79 (0:0e79)
+ add a,$06
+ ld b,a
+ ld a,[de]
+ add b
+ ld [de],a
+ ret nc
+ inc de
+ ld a,[de]
+ inc a
+ ld [de],a
+ ret
+
+MoveTileBlockMapPointerNorth:: ; 0e85 (0:0e85)
+ add a,$06
+ ld b,a
+ ld a,[de]
+ sub b
+ ld [de],a
+ ret nc
+ inc de
+ ld a,[de]
+ dec a
+ ld [de],a
+ ret \ No newline at end of file
diff --git a/yellow/bank3d/random.asm b/yellow/bank3d/random.asm
index b7fb0edd..c7245c3e 100644
--- a/yellow/bank3d/random.asm
+++ b/yellow/bank3d/random.asm
@@ -1,15 +1,15 @@
-SECTION "bank3d",ROMX[$67DC],BANK[$3D]
-
-Random_::
-; Generate a random 16-bit value.
- ld a, [rDIV]
- ld b, a
- ld a, [hRandomAdd]
- adc b
- ld [hRandomAdd], a
- ld a, [rDIV]
- ld b, a
- ld a, [hRandomSub]
- sbc b
- ld [hRandomSub], a
- ret
+SECTION "bank3d",ROMX[$67DC],BANK[$3D]
+
+Random_::
+; Generate a random 16-bit value.
+ ld a, [rDIV]
+ ld b, a
+ ld a, [hRandomAdd]
+ adc b
+ ld [hRandomAdd], a
+ ld a, [rDIV]
+ ld b, a
+ ld a, [hRandomSub]
+ sbc b
+ ld [hRandomSub], a
+ ret
diff --git a/yellow/bank3f/main.asm b/yellow/bank3f/main.asm
index ff2aa7a0..736ac8ae 100644
--- a/yellow/bank3f/main.asm
+++ b/yellow/bank3f/main.asm
@@ -1,11 +1,11 @@
-; asm to be added
-
-Func_fc5fa:: ; fc5fa (3f:45fa)
-
-Func_fc65b:: ; fc65b (3f:465b)
-
-Func_fc69a:: ; fc69a (3f:469a)
-
-Func_fcc08:: ; fcc08 (3f:4c08)
-
-Func_fcf0c:: ; fcf0c (3f:4f0c)
+; asm to be added
+
+Func_fc5fa:: ; fc5fa (3f:45fa)
+
+Func_fc65b:: ; fc65b (3f:465b)
+
+Func_fc69a:: ; fc69a (3f:469a)
+
+Func_fcc08:: ; fcc08 (3f:4c08)
+
+Func_fcf0c:: ; fcf0c (3f:4f0c)