diff options
author | U-Daniel-PC\Daniel <corrnondacqb@yahoo.com> | 2015-06-04 23:15:09 -0500 |
---|---|---|
committer | U-Daniel-PC\Daniel <corrnondacqb@yahoo.com> | 2015-06-04 23:15:09 -0500 |
commit | f558d784a87d7b56b2cacfc2f543f63237ad8183 (patch) | |
tree | 0708fe686eb1d94d6b94bcba78b05f6d6616b1f9 | |
parent | 6faafde364d4f21a2c88d4d60617f98b5d41a5b2 (diff) |
EOL Windows->UNIX
-rwxr-xr-x | engine/items/items.asm | 5744 | ||||
-rwxr-xr-x | engine/overworld/map_sprites.asm | 880 | ||||
-rw-r--r-- | home.asm | 9844 | ||||
-rw-r--r-- | home/audio.asm | 372 | ||||
-rw-r--r-- | home/init.asm | 272 | ||||
-rw-r--r-- | home/overworld.asm | 4584 | ||||
-rw-r--r-- | macros.asm | 1220 | ||||
-rwxr-xr-x | main.asm | 13366 | ||||
-rwxr-xr-x | wram.asm | 4610 | ||||
-rw-r--r-- | yellow/bank3c/overworld.asm | 482 | ||||
-rw-r--r-- | yellow/bank3d/random.asm | 30 | ||||
-rw-r--r-- | yellow/bank3f/main.asm | 434 |
12 files changed, 20919 insertions, 20919 deletions
diff --git a/engine/items/items.asm b/engine/items/items.asm index beb85cde..c6f098dc 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -1,2872 +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 ; 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
+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 54312c6f..747a0a45 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" @@ -1,4922 +1,4922 @@ -
-; 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:: ; 10ba (0:10ba)
-; 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:: ; 10d5 (0:10d5)
- 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:: ; 10f8 (0:10f8)
-; 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:: ; 1132 (0:1132)
- ld hl, LoadMonData_
- ld b, BANK(LoadMonData_) ; 1:442b
- jp Bankswitch
-
-
-Func_137a:: ; 113a (0:113a)
-; 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:: ; 1144 (0:1144)
- ld a, 1
- ld [W_SPRITEFLIPPED], a
-
-LoadFrontSpriteByMonIndex:: ; 1149 (0:1149)
- 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(Func_f6203)
- call BankswitchCommon
- xor a
- ld [$ffe1], a
- call Func_f6203
- xor a
- ld [W_SPRITEFLIPPED], a
- pop af
- jp BankswitchCommon
-
-PlayCry:: ; 118b (0:118b)
-; Play monster a's cry.
- push bc
- ld b,a
- ld a,[wLowHealthAlarm]
- push af
- xor a
- ld [wLowHealthAlarm],a
- ld a,b
- call Func_11a5
- call PlaySound
- call WaitForSoundToFinish
- pop af
- ld [wLowHealthAlarm],a
- pop bc
- ret
-
-GetCryData:: ; 11a5 (0:11a5)
-; 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:: ; 11c8 (0:11c8)
- ld a,[hTilesetType]
- push af
- xor a
- ld [hTilesetType],a
- call GBPalWhiteOutWithDelay3
- call ClearSprites
- call PartyMenuInit
- call DrawPartyMenu
- jp HandlePartyMenuInput
-
-GoBackToPartyMenu:: ; 11dd (0:11dd)
- ld a,[hTilesetType]
- push af
- xor a
- ld [hTilesetType],a
- call PartyMenuInit
- call RedrawPartyMenu
- jp HandlePartyMenuInput
-
-PartyMenuInit:: ; 11ec (0:11ec)
- 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:: ; 1226 (0:1226)
- ld a,1
- ld [wMenuWrappingEnabled],a
- ld a,$40
- ld [wd09b],a
- call HandleMenuInputPokemonSelection
- push af ; save hJoy5 OR wMenuWrapping enabled, if no inputs were selected within a certain period of time
- bit 1,a ; was B button pressed?
- ld a,$0
- ld [wd09b],a
- ld a,[wCurrentMenuItem]
- ld [wcc2b],a
- jr nz,.asm_1258
- ld a,[wCurrentMenuItem]
- ld [wWhichPokemon],a
- callab Func_fce18 ; 3f:4e18
- jr nc,.asm_1258
- call Func_154a
- jr nz,.asm_128f
-.asm_1258
- pop af
- call PlaceUnfilledArrowMenuCursor
- ld b,a
- ld hl,wd730
- res 6,[hl] ; turn on letter printing delay
- ld a,[wMenuItemToSwap]
- and a
- jp nz,.swappingPokemon
- pop af ; double 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
-.asm_128f
- pop af
- ld hl,PartyMenuText_12cc
- call PrintText
- xor a
- ld [wMenuItemToSwap],a
- pop af
- ld [hTilesetType],a
-.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 ; 4:5e98
- xor a
- ld [wMenuItemToSwap],a
- ld [wd07d],a
- call RedrawPartyMenu
- jp HandlePartyMenuInput
-.handleSwap
- ld a,[wCurrentMenuItem]
- ld [wWhichPokemon],a
- callba SwitchPartyMon ; 4:61c5
- jp HandlePartyMenuInput
-
-PartyMenuText_12cc:: ; 12cc (0:12cc)
- TX_FAR _PartyMenuText_12cc ; 28:411b
- db "@"
-
-DrawPartyMenu:: ; 12d1 (0:12d1)
- ld hl, DrawPartyMenu_ ; 4:5875
- jr DrawPartyMenuCommon
-
-RedrawPartyMenu:: ; 12d6 (0:12d6)
- ld hl, RedrawPartyMenu_ ; 4:5886
-
-DrawPartyMenuCommon:: ; 12d9 (0:12d9)
- ld b, BANK(RedrawPartyMenu_)
- jp Bankswitch
-
-; prints a pokemon's status condition
-; INPUT:
-; de = address of status condition
-; hl = destination address
-PrintStatusCondition:: ; 12de (0:12de)
- 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: ; 12f3 (0:12f3)
- homecall_jump_sf PrintStatusAilment
-
-; function to print pokemon level, leaving off the ":L" if the level is at least 100
-; INPUT:
-; hl = destination address
-; [wLoadedMonLevel] = level
-PrintLevel:: ; 1303 (0:1303)
- 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:: ; 1313 (0:1313)
- ld a,$6e ; ":L" tile ID
- ld [hli],a
- ld c,3 ; number of digits
- ld a,[wLoadedMonLevel] ; level
-
-PrintLevelCommon:: ; 131b (0:131b)
- ld [wd11e],a
- ld de,wd11e
- ld b,$41 ; no leading zeroes, left-aligned, one byte
- jp PrintNumber
-
-Func_1326:: ; 1326 (0:132)
-; 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:: ; 132f (0:132f)
- ld a,[H_LOADEDROMBANK]
- push af
- switchbank BaseStats
- 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
-.done
- ld a,[wd0b5]
- ld [W_MONHDEXNUM],a
- pop af
- ld [wd11e],a
- pop hl
- pop de
- pop bc
- pop af
- call BankswitchCommon
- ret
-
-; copy party pokemon's name to wcd6d
-GetPartyMonName2:: ; 1394 (0:1394)
- ld a,[wWhichPokemon] ; index within party
- ld hl,wPartyMonNicks
-
-; this is called more often
-GetPartyMonName:: ; 139a (0:139a)
- 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:: ; 13ad (0:13ad)
- 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:: ; 13e4 (0:13e4)
- 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:: ; 1407 (0:1407)
- 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 ; 23f8
-
-; de: destination location
-LoadMonFrontSprite:: ; 143e (0:143e)
- 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
- ld a,$0
- call SwitchSRAMBankAndLatchClockData
- 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)
- call PrepareRTCDataAndDisableSRAM
- pop de
- jp InterlaceMergeSpriteBuffers ; 14c7
-
-; 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:: ; 149f (0:149f)
- 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:: ; 14bc (0:14bc)
- 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:: ; 14c7 (0:14c7)
- ld a,$0
- 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
- call CopyVideoDataLCDEnabled
- jp PrepareRTCDataAndDisableSRAM
-
-Func_1510:: ; 1510 (0:1510)
- push hl
- ld hl,wd430
- set 7,[hl]
- ld hl,wSpriteStateData1 + $f2 ; pikachu data?
- ld [hl],$ff
- pop hl
- ret
-
-Func_151d:: ; 151d (0:151d)
- push hl
- ld hl,wd430
- res 7,[hl]
- pop hl
- ret
-
-Func_1525:: ; 1525 (0:1525)
- push hl
- ld hl,wd430
- res 3,[hl]
- pop hl
- ret
-
-Func_152d:: ; 152d (0:152d)
- push hl
- ld hl,wd430
- set 3,[hl]
- ld hl,wSpriteStateData1 + $f2 ; pikachu data?
- ld [hl],$ff
- pop hl
- ret
-
-Func_153a:: ; 153a (0:153a)
- push hl
- ld hl,wd430
- set 1,[hl]
- pop hl
- ret
-
-Func_1542:: ; 1542 (0:1542)
- push hl
- ld hl,wd430
- res 1,[hl]
- pop hl
- ret
-
-Func_154a:: ; 154a (0:154a)
- push hl
- ld hl,wd430
- bit 1,[hl]
- pop hl
- ret
-
-Func_1552:: ; 1552 (0:1552)
- ld a,[hl]
- dec a
- swap a
- ld [$ff93],a
- homecall Func_fc6d5 ; 3f:46d5
- ret
-
-Func_1568:: ; 1568 (0:1568)
- ld b,$0
- ld c,a
-.asm_156b
- inc b
- ld a,[hli]
- cp $ff
- jr z,.asm_1578
- cp c
- jr nz,.asm_156b
- dec b
- dec hl
- scf
- ret
-.asm_1578
- dec b
- dec hl
- and a
- ret
-
-Func_157c:: ; 157c (0:157c)
- push hl
- push bc
- ld a,[H_LOADEDROMBANK]
- push af
- ld a,[wd44a]
- call BankswitchCommon
- ld hl,wd44b
- ld c,[hl]
- inc hl
- ld b,[hl]
- ld a,[bc]
- inc bc
- ld [hl],b
- dec hl
- ld [hl],c
- ld c,a
- pop af
- call BankswitchCommon
- ld a,c
- pop bc
- pop hl
- ret
-
-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:: ; 35c3 (0:35c3)
-; 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]
-
-SwitchSRAMBankAndLatchClockData:: ; 3e99 (0:3e99)
- push af
- ld a,$1
- ld [$6000],a
- ld a,SRAM_ENABLE
- ld [$0],a
- pop af
- ld [$4000],a
- ret
-
-PrepareRTCDataAndDisableSRAM:: ; 3eac (0:3eac)
- push af
- ld a,$0
- ld [$6000],a
- ld [$0],a
- pop af
- ret
-
-; 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 0,a ; pressed A key?
- jr z,.checkOtherKeys
- 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:: ; 3b6d (0:3b6d)
- 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
- ld bc,40
- push af
- ld a,[hFlags_0xFFFA]
- bit 1,a ; is the menu double spaced?
- jr z,.doubleSpaced1
- ld bc,20
-.doubleSpaced1
- 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
- ld bc,40
- push af
- ld a,[hFlags_0xFFFA]
- bit 1,a ; is the menu double spaced?
- jr z,.doubleSpaced2
- ld bc,20
-.doubleSpaced2
- 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:: ; 3bd9 (0:3bd9)
- 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:: ; 3be6 (0:3be6)
- 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
+ +; 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:: ; 10ba (0:10ba) +; 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:: ; 10d5 (0:10d5) + 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:: ; 10f8 (0:10f8) +; 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:: ; 1132 (0:1132) + ld hl, LoadMonData_ + ld b, BANK(LoadMonData_) ; 1:442b + jp Bankswitch + + +Func_137a:: ; 113a (0:113a) +; 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:: ; 1144 (0:1144) + ld a, 1 + ld [W_SPRITEFLIPPED], a + +LoadFrontSpriteByMonIndex:: ; 1149 (0:1149) + 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(Func_f6203) + call BankswitchCommon + xor a + ld [$ffe1], a + call Func_f6203 + xor a + ld [W_SPRITEFLIPPED], a + pop af + jp BankswitchCommon + +PlayCry:: ; 118b (0:118b) +; Play monster a's cry. + push bc + ld b,a + ld a,[wLowHealthAlarm] + push af + xor a + ld [wLowHealthAlarm],a + ld a,b + call Func_11a5 + call PlaySound + call WaitForSoundToFinish + pop af + ld [wLowHealthAlarm],a + pop bc + ret + +GetCryData:: ; 11a5 (0:11a5) +; 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:: ; 11c8 (0:11c8) + ld a,[hTilesetType] + push af + xor a + ld [hTilesetType],a + call GBPalWhiteOutWithDelay3 + call ClearSprites + call PartyMenuInit + call DrawPartyMenu + jp HandlePartyMenuInput + +GoBackToPartyMenu:: ; 11dd (0:11dd) + ld a,[hTilesetType] + push af + xor a + ld [hTilesetType],a + call PartyMenuInit + call RedrawPartyMenu + jp HandlePartyMenuInput + +PartyMenuInit:: ; 11ec (0:11ec) + 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:: ; 1226 (0:1226) + ld a,1 + ld [wMenuWrappingEnabled],a + ld a,$40 + ld [wd09b],a + call HandleMenuInputPokemonSelection + push af ; save hJoy5 OR wMenuWrapping enabled, if no inputs were selected within a certain period of time + bit 1,a ; was B button pressed? + ld a,$0 + ld [wd09b],a + ld a,[wCurrentMenuItem] + ld [wcc2b],a + jr nz,.asm_1258 + ld a,[wCurrentMenuItem] + ld [wWhichPokemon],a + callab Func_fce18 ; 3f:4e18 + jr nc,.asm_1258 + call Func_154a + jr nz,.asm_128f +.asm_1258 + pop af + call PlaceUnfilledArrowMenuCursor + ld b,a + ld hl,wd730 + res 6,[hl] ; turn on letter printing delay + ld a,[wMenuItemToSwap] + and a + jp nz,.swappingPokemon + pop af ; double 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 +.asm_128f + pop af + ld hl,PartyMenuText_12cc + call PrintText + xor a + ld [wMenuItemToSwap],a + pop af + ld [hTilesetType],a +.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 ; 4:5e98 + xor a + ld [wMenuItemToSwap],a + ld [wd07d],a + call RedrawPartyMenu + jp HandlePartyMenuInput +.handleSwap + ld a,[wCurrentMenuItem] + ld [wWhichPokemon],a + callba SwitchPartyMon ; 4:61c5 + jp HandlePartyMenuInput + +PartyMenuText_12cc:: ; 12cc (0:12cc) + TX_FAR _PartyMenuText_12cc ; 28:411b + db "@" + +DrawPartyMenu:: ; 12d1 (0:12d1) + ld hl, DrawPartyMenu_ ; 4:5875 + jr DrawPartyMenuCommon + +RedrawPartyMenu:: ; 12d6 (0:12d6) + ld hl, RedrawPartyMenu_ ; 4:5886 + +DrawPartyMenuCommon:: ; 12d9 (0:12d9) + ld b, BANK(RedrawPartyMenu_) + jp Bankswitch + +; prints a pokemon's status condition +; INPUT: +; de = address of status condition +; hl = destination address +PrintStatusCondition:: ; 12de (0:12de) + 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: ; 12f3 (0:12f3) + homecall_jump_sf PrintStatusAilment + +; function to print pokemon level, leaving off the ":L" if the level is at least 100 +; INPUT: +; hl = destination address +; [wLoadedMonLevel] = level +PrintLevel:: ; 1303 (0:1303) + 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:: ; 1313 (0:1313) + ld a,$6e ; ":L" tile ID + ld [hli],a + ld c,3 ; number of digits + ld a,[wLoadedMonLevel] ; level + +PrintLevelCommon:: ; 131b (0:131b) + ld [wd11e],a + ld de,wd11e + ld b,$41 ; no leading zeroes, left-aligned, one byte + jp PrintNumber + +Func_1326:: ; 1326 (0:132) +; 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:: ; 132f (0:132f) + ld a,[H_LOADEDROMBANK] + push af + switchbank BaseStats + 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 +.done + ld a,[wd0b5] + ld [W_MONHDEXNUM],a + pop af + ld [wd11e],a + pop hl + pop de + pop bc + pop af + call BankswitchCommon + ret + +; copy party pokemon's name to wcd6d +GetPartyMonName2:: ; 1394 (0:1394) + ld a,[wWhichPokemon] ; index within party + ld hl,wPartyMonNicks + +; this is called more often +GetPartyMonName:: ; 139a (0:139a) + 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:: ; 13ad (0:13ad) + 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:: ; 13e4 (0:13e4) + 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:: ; 1407 (0:1407) + 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 ; 23f8 + +; de: destination location +LoadMonFrontSprite:: ; 143e (0:143e) + 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 + ld a,$0 + call SwitchSRAMBankAndLatchClockData + 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) + call PrepareRTCDataAndDisableSRAM + pop de + jp InterlaceMergeSpriteBuffers ; 14c7 + +; 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:: ; 149f (0:149f) + 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:: ; 14bc (0:14bc) + 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:: ; 14c7 (0:14c7) + ld a,$0 + 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 + call CopyVideoDataLCDEnabled + jp PrepareRTCDataAndDisableSRAM + +Func_1510:: ; 1510 (0:1510) + push hl + ld hl,wd430 + set 7,[hl] + ld hl,wSpriteStateData1 + $f2 ; pikachu data? + ld [hl],$ff + pop hl + ret + +Func_151d:: ; 151d (0:151d) + push hl + ld hl,wd430 + res 7,[hl] + pop hl + ret + +Func_1525:: ; 1525 (0:1525) + push hl + ld hl,wd430 + res 3,[hl] + pop hl + ret + +Func_152d:: ; 152d (0:152d) + push hl + ld hl,wd430 + set 3,[hl] + ld hl,wSpriteStateData1 + $f2 ; pikachu data? + ld [hl],$ff + pop hl + ret + +Func_153a:: ; 153a (0:153a) + push hl + ld hl,wd430 + set 1,[hl] + pop hl + ret + +Func_1542:: ; 1542 (0:1542) + push hl + ld hl,wd430 + res 1,[hl] + pop hl + ret + +Func_154a:: ; 154a (0:154a) + push hl + ld hl,wd430 + bit 1,[hl] + pop hl + ret + +Func_1552:: ; 1552 (0:1552) + ld a,[hl] + dec a + swap a + ld [$ff93],a + homecall Func_fc6d5 ; 3f:46d5 + ret + +Func_1568:: ; 1568 (0:1568) + ld b,$0 + ld c,a +.asm_156b + inc b + ld a,[hli] + cp $ff + jr z,.asm_1578 + cp c + jr nz,.asm_156b + dec b + dec hl + scf + ret +.asm_1578 + dec b + dec hl + and a + ret + +Func_157c:: ; 157c (0:157c) + push hl + push bc + ld a,[H_LOADEDROMBANK] + push af + ld a,[wd44a] + call BankswitchCommon + ld hl,wd44b + ld c,[hl] + inc hl + ld b,[hl] + ld a,[bc] + inc bc + ld [hl],b + dec hl + ld [hl],c + ld c,a + pop af + call BankswitchCommon + ld a,c + pop bc + pop hl + ret + +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:: ; 35c3 (0:35c3) +; 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] + +SwitchSRAMBankAndLatchClockData:: ; 3e99 (0:3e99) + push af + ld a,$1 + ld [$6000],a + ld a,SRAM_ENABLE + ld [$0],a + pop af + ld [$4000],a + ret + +PrepareRTCDataAndDisableSRAM:: ; 3eac (0:3eac) + push af + ld a,$0 + ld [$6000],a + ld [$0],a + pop af + ret + +; 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 0,a ; pressed A key? + jr z,.checkOtherKeys + 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:: ; 3b6d (0:3b6d) + 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 + ld bc,40 + push af + ld a,[hFlags_0xFFFA] + bit 1,a ; is the menu double spaced? + jr z,.doubleSpaced1 + ld bc,20 +.doubleSpaced1 + 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 + ld bc,40 + push af + ld a,[hFlags_0xFFFA] + bit 1,a ; is the menu double spaced? + jr z,.doubleSpaced2 + ld bc,20 +.doubleSpaced2 + 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:: ; 3bd9 (0:3bd9) + 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:: ; 3be6 (0:3be6) + 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 e062c8da..abdfec54 100644 --- a/home/audio.asm +++ b/home/audio.asm @@ -1,186 +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
-
-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
+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 701a4bb8..202bd110 100644 --- a/home/init.asm +++ b/home/init.asm @@ -1,136 +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
- jp StopAllMusic
+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 508e243a..b3008903 100644 --- a/home/overworld.asm +++ b/home/overworld.asm @@ -1,2293 +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:: ; 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]
- switchbank SpecialWarpIn ; also Bank(SpecialEnterMap)
- callab ResetStatusAndHalveMoneyOnBlackout ; 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, _AdvancePlayerSprite ; 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 MapHeaderPointers ; 3f:41f2
- push de
- ld a,[W_CURMAP]
- ld e,a
- ld d,$0
- ld hl,MapHeaderPointers
- 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
+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] + switchbank SpecialWarpIn ; also Bank(SpecialEnterMap) + callab ResetStatusAndHalveMoneyOnBlackout ; 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, _AdvancePlayerSprite ; 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 MapHeaderPointers ; 3f:41f2 + push de + ld a,[W_CURMAP] + ld e,a + ld d,$0 + ld hl,MapHeaderPointers + 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 @@ -1,610 +1,610 @@ -
-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_jump_sf: MACRO
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(\1)
- call BankswitchCommon
- call \1
- pop bc
- 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
+ +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_jump_sf: MACRO + ld a, [H_LOADEDROMBANK] + push af + ld a, BANK(\1) + call BankswitchCommon + call \1 + pop bc + 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 @@ -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"
-
-SECTION "bank3c",ROMX,BANK[$3C]
-
-INCLUDE "yellow/bank3c/main.asm"
-
-SECTION "bank3d",ROMX,BANK[$3D]
-
-INCLUDE "yellow/bank3d/random.asm"
-
-SECTION "bank3e",ROMX,BANK[$3E]
-
-SECTION "bank3f",ROMX,BANK[$3F]
-
+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" + +SECTION "bank3c",ROMX,BANK[$3C] + +INCLUDE "yellow/bank3c/main.asm" + +SECTION "bank3d",ROMX,BANK[$3D] + +INCLUDE "yellow/bank3d/random.asm" + +SECTION "bank3e",ROMX,BANK[$3E] + +SECTION "bank3f",ROMX,BANK[$3F] + INCLUDE "yellow/bank3f/main.asm"
\ No newline at end of file @@ -1,2305 +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
-
-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"
+ +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 e601ff52..778244d6 100644 --- a/yellow/bank3c/overworld.asm +++ b/yellow/bank3c/overworld.asm @@ -1,242 +1,242 @@ -_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
+_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 c7245c3e..b7fb0edd 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 7bebe09c..b51d19b1 100644 --- a/yellow/bank3f/main.asm +++ b/yellow/bank3f/main.asm @@ -1,217 +1,217 @@ -INCLUDE "yellow/bank3f/data/map_songs.asm"
-INCLUDE "yellow/bank3f/data/map_header_pointers.asm"
-INCLUDE "yellow/bank3f/data/map_header_banks.asm"
-
-Func_fc4dd:: ; fc4dd (3f:44dd)
-; possibly to test if pika should be out?
- ld a,[wd430]
- bit 5,a
- jr nz,.asm_fc4f8 ; 3f:44f8
- ld a,[wd430]
- bit 7,a
- jr nz,.asm_fc4f8
- call Func_fcdb8
- jr nc,.asm_fc4f8
- ld a,[wWalkBikeSurfState]
- and a
- jr nz,.asm_fc4f8
- scf
- ret
-.asm_fc4f8
- and a
- ret
-
-Func_fc5fa:: ; fc5fa (3f:44fa)
- ld hl,wd430
- bit 4,[hl]
- res 4,[hl]
- jr nz,.asm_fc515
- call Func_1542
- call Func_fc523
- ld a,$ff
- ld [wSpriteStateData1 + $f2],a
- call Func_fcb84
- call Func_fc5bc
- ret
-
-.asm_fc515
- call Func_fc53f
- xor a
- ld [wd431],a
- ld a,[wSpriteStateData1 + $9]
- ld [wSpriteStateData1 + $f9],a
- ret
-
-Func_fc523:: ; fc523 (3f:4523)
- ld hl,wSpriteStateData1 + $f0
- call Func_fc52c
- ld hl,wSpriteStateData2 + $f0
-Func_fc52c:: ; fc52c (3f:4523)
- ld bc,$10
- xor a
- call FillMemory
- ret
-
-Func_fc534:: ; fc534 (3f:4534)
- call Func_fc53f
- call Func_fc5bc
- xor a
- ld [wd431],a
- ret
-
-Func_fc53f:: ; fc53f (3f:453f)
- ld bc,wSpriteStateData1 + $10
- ld a,[W_YCOORD]
- add $4
- ld e,a
- ld a,[W_XCOORD]
- add $4
- ld d,a
- ld a,[wd431]
- and a
- jr z,.asm_fc5aa
- cp $1
- jr z,.asm_fc59e
- cp $2
- jr z,.asm_fc584
- cp $3
- jr z,.asm_fc5aa
- cp $4
- jr z,.asm_fc5a4
- cp $5
- jr z,.asm_fc5a7
- cp $6
- jr z,.asm_fc5a1
- cp $7
- jr z,.asm_fc572
- jr .asm_fc59e
-
-.asm_fc572
- ld a,[wSpriteStateData1 + $9]
- and a ; SPRITE_FACING_DOWN
- jr z,.asm_fc5a4
- cp SPRITE_FACING_UP
- jr z,.asm_fc5a7
- cp SPRITE_FACING_LEFT
- jr z,.asm_fc5a1
- cp SPRITE_FACING_RIGHT
- jr z,.asm_fc59e
-.asm_fc584
- ld a,[wSpriteStateData1 + $9]
- and a
- jr nz,.asm_fc58d
- dec e
- jr .asm_fc5aa
-.asm_fc58d
- cp SPRITE_FACING_UP
- jr nz,.asm_fc594
- inc e
- jr .asm_fc5aa
-.asm_fc594
- cp SPRITE_FACING_LEFT
- jr nz,.asm_fc59b
- inc d
- jr .asm_fc5aa
-.asm_fc59b
- dec d
- jr .asm_fc5aa
-.asm_fc59e
- inc d
- jr .asm_fc5aa
-.asm_fc5a1
- dec d
- jr .asm_fc5aa
-.asm_fc5a4
- inc e
- jr .asm_fc5aa
-.asm_fc5a7
- dec e
- jr .asm_fc5aa ; useless jr
-.asm_fc5aa
- ld hl,$104
- add hl,bc
- ld [hl],e
- inc hl
- ld [hl],d
- inc hl
-Func_fc4b2:: ; fc4b2 (3f:44b2)
- ld [hl],$fe
- push hl
- ld hl,wd472
- set 5,[hl]
- pop hl
- ret
-
-Func_fc5bc:: ; fc5bc (3f:45bc)
- ld a,$49
- ld [wSpriteStateData1 + $f0],a
- ld a,$ff
- ld [wSpriteStateData1 + $f2],a
- ld a,[wd431]
- and a
- jr z,.asm_fc5e4
- cp $1
- jr z,.asm_fc5e4
- cp $3
- jr z,.asm_fc5eb
- cp $4
- jr z,.asm_fc5e4
- cp $6
- jr z,.asm_fc5e4
- cp $7
- jr z,.asm_fc5f1
- call Func_fc4b2
- ret
-
-.asm_fc5e4
- ld a,[wSpriteStateData1 + $9]
- ld [wSpriteStateData1 + $f9],a
- ret
-.asm_fc5eb
- ld a,$0
- ld [wSpriteStateData1 + $f9],a
- ret
-.asm_fc5f1
- ld a,[wSpriteStateData1 + $9]
- xor $4
- ld [wSpriteStateData1 + $f9],a
- ret
-
-Func_fc5fa:: ; fc5fa (3f:45fa)
- ld a,[W_CURMAP]
- cp OAKS_LAB
- jr z,.asm_fc63d
- cp ROUTE_22_GATE
- jr z,.asm_fc62d
- cp MT_MOON_2
- jr z,.asm_fc635
- cp ROCK_TUNNEL_1
- jr z,.asm_fc645
- ld a,[W_CURMAP]
- ld hl,Pointer_fc46b
- call Func_1568 ; similar to IsInArray, but not the same
- jr c,.asm_fc639
- ld a,[W_CURMAP]
- ld hl,Pointer_fc653
- call Func_1568
- jr nc,.asm_fc641
- ld a,[wSpriteStateData1 + $9]
- and a
- jr nz,.asm_fc641
- ld a,$3
- jr .asm_fc647
-
-.asm_fc62d
- ld a,[wSpriteStateData1 + $9]
- and a
- jr z,.asm_fc645
- jr .asm_fc641
-.asm_fc635
-
-Func_fc65b:: ; fc65b (3f:465b)
-
-Func_fc69a:: ; fc69a (3f:469a)
-
-Func_fcc08:: ; fcc08 (3f:4c08)
-
-Func_fcf0c:: ; fcf0c (3f:4f0c)
+INCLUDE "yellow/bank3f/data/map_songs.asm" +INCLUDE "yellow/bank3f/data/map_header_pointers.asm" +INCLUDE "yellow/bank3f/data/map_header_banks.asm" + +Func_fc4dd:: ; fc4dd (3f:44dd) +; possibly to test if pika should be out? + ld a,[wd430] + bit 5,a + jr nz,.asm_fc4f8 ; 3f:44f8 + ld a,[wd430] + bit 7,a + jr nz,.asm_fc4f8 + call Func_fcdb8 + jr nc,.asm_fc4f8 + ld a,[wWalkBikeSurfState] + and a + jr nz,.asm_fc4f8 + scf + ret +.asm_fc4f8 + and a + ret + +Func_fc5fa:: ; fc5fa (3f:44fa) + ld hl,wd430 + bit 4,[hl] + res 4,[hl] + jr nz,.asm_fc515 + call Func_1542 + call Func_fc523 + ld a,$ff + ld [wSpriteStateData1 + $f2],a + call Func_fcb84 + call Func_fc5bc + ret + +.asm_fc515 + call Func_fc53f + xor a + ld [wd431],a + ld a,[wSpriteStateData1 + $9] + ld [wSpriteStateData1 + $f9],a + ret + +Func_fc523:: ; fc523 (3f:4523) + ld hl,wSpriteStateData1 + $f0 + call Func_fc52c + ld hl,wSpriteStateData2 + $f0 +Func_fc52c:: ; fc52c (3f:4523) + ld bc,$10 + xor a + call FillMemory + ret + +Func_fc534:: ; fc534 (3f:4534) + call Func_fc53f + call Func_fc5bc + xor a + ld [wd431],a + ret + +Func_fc53f:: ; fc53f (3f:453f) + ld bc,wSpriteStateData1 + $10 + ld a,[W_YCOORD] + add $4 + ld e,a + ld a,[W_XCOORD] + add $4 + ld d,a + ld a,[wd431] + and a + jr z,.asm_fc5aa + cp $1 + jr z,.asm_fc59e + cp $2 + jr z,.asm_fc584 + cp $3 + jr z,.asm_fc5aa + cp $4 + jr z,.asm_fc5a4 + cp $5 + jr z,.asm_fc5a7 + cp $6 + jr z,.asm_fc5a1 + cp $7 + jr z,.asm_fc572 + jr .asm_fc59e + +.asm_fc572 + ld a,[wSpriteStateData1 + $9] + and a ; SPRITE_FACING_DOWN + jr z,.asm_fc5a4 + cp SPRITE_FACING_UP + jr z,.asm_fc5a7 + cp SPRITE_FACING_LEFT + jr z,.asm_fc5a1 + cp SPRITE_FACING_RIGHT + jr z,.asm_fc59e +.asm_fc584 + ld a,[wSpriteStateData1 + $9] + and a + jr nz,.asm_fc58d + dec e + jr .asm_fc5aa +.asm_fc58d + cp SPRITE_FACING_UP + jr nz,.asm_fc594 + inc e + jr .asm_fc5aa +.asm_fc594 + cp SPRITE_FACING_LEFT + jr nz,.asm_fc59b + inc d + jr .asm_fc5aa +.asm_fc59b + dec d + jr .asm_fc5aa +.asm_fc59e + inc d + jr .asm_fc5aa +.asm_fc5a1 + dec d + jr .asm_fc5aa +.asm_fc5a4 + inc e + jr .asm_fc5aa +.asm_fc5a7 + dec e + jr .asm_fc5aa ; useless jr +.asm_fc5aa + ld hl,$104 + add hl,bc + ld [hl],e + inc hl + ld [hl],d + inc hl +Func_fc4b2:: ; fc4b2 (3f:44b2) + ld [hl],$fe + push hl + ld hl,wd472 + set 5,[hl] + pop hl + ret + +Func_fc5bc:: ; fc5bc (3f:45bc) + ld a,$49 + ld [wSpriteStateData1 + $f0],a + ld a,$ff + ld [wSpriteStateData1 + $f2],a + ld a,[wd431] + and a + jr z,.asm_fc5e4 + cp $1 + jr z,.asm_fc5e4 + cp $3 + jr z,.asm_fc5eb + cp $4 + jr z,.asm_fc5e4 + cp $6 + jr z,.asm_fc5e4 + cp $7 + jr z,.asm_fc5f1 + call Func_fc4b2 + ret + +.asm_fc5e4 + ld a,[wSpriteStateData1 + $9] + ld [wSpriteStateData1 + $f9],a + ret +.asm_fc5eb + ld a,$0 + ld [wSpriteStateData1 + $f9],a + ret +.asm_fc5f1 + ld a,[wSpriteStateData1 + $9] + xor $4 + ld [wSpriteStateData1 + $f9],a + ret + +Func_fc5fa:: ; fc5fa (3f:45fa) + ld a,[W_CURMAP] + cp OAKS_LAB + jr z,.asm_fc63d + cp ROUTE_22_GATE + jr z,.asm_fc62d + cp MT_MOON_2 + jr z,.asm_fc635 + cp ROCK_TUNNEL_1 + jr z,.asm_fc645 + ld a,[W_CURMAP] + ld hl,Pointer_fc46b + call Func_1568 ; similar to IsInArray, but not the same + jr c,.asm_fc639 + ld a,[W_CURMAP] + ld hl,Pointer_fc653 + call Func_1568 + jr nc,.asm_fc641 + ld a,[wSpriteStateData1 + $9] + and a + jr nz,.asm_fc641 + ld a,$3 + jr .asm_fc647 + +.asm_fc62d + ld a,[wSpriteStateData1 + $9] + and a + jr z,.asm_fc645 + jr .asm_fc641 +.asm_fc635 + +Func_fc65b:: ; fc65b (3f:465b) + +Func_fc69a:: ; fc69a (3f:469a) + +Func_fcc08:: ; fcc08 (3f:4c08) + +Func_fcf0c:: ; fcf0c (3f:4f0c) |