This commit is contained in:
dannye 2021-03-23 00:53:43 -05:00
commit e8dd755e18
3702 changed files with 163333 additions and 159040 deletions

View file

@ -0,0 +1,18 @@
GetQuantityOfItemInBag:
; In: b = item ID
; Out: b = how many of that item are in the bag
call GetPredefRegisters
ld hl, wNumBagItems
.loop
inc hl
ld a, [hli]
cp $ff
jr z, .notInBag
cp b
jr nz, .loop
ld a, [hl]
ld b, a
ret
.notInBag
ld b, 0
ret

View file

@ -4,7 +4,7 @@
; [wcf91] = item ID
; [wItemQuantity] = item quantity
; sets carry flag if successful, unsets carry flag if unsuccessful
AddItemToInventory_:
AddItemToInventory_::
ld a, [wItemQuantity] ; a = item quantity
push af
push bc
@ -12,10 +12,10 @@ AddItemToInventory_:
push hl
push hl
ld d, PC_ITEM_CAPACITY ; how many items the PC can hold
ld a, wNumBagItems & $FF
ld a, LOW(wNumBagItems)
cp l
jr nz, .checkIfInventoryFull
ld a, wNumBagItems >> 8
ld a, HIGH(wNumBagItems)
cp h
jr nz, .checkIfInventoryFull
; if the destination is the bag
@ -27,7 +27,7 @@ AddItemToInventory_:
ld a, [hli]
and a
jr z, .addNewItem
.loop
.notAtEndOfInventory
ld a, [hli]
ld b, a ; b = ID of current item in table
ld a, [wcf91] ; a = ID of item being added
@ -36,7 +36,7 @@ AddItemToInventory_:
inc hl
ld a, [hl]
cp $ff ; is it the end of the table?
jr nz, .loop
jr nz, .notAtEndOfInventory
.addNewItem ; add an item not yet in the inventory
pop hl
ld a, d
@ -73,7 +73,7 @@ AddItemToInventory_:
; if so, store 99 in the current slot and store the rest in a new slot
ld a, 99
ld [hli], a
jp .loop
jp .notAtEndOfInventory
.increaseItemQuantityFailed
pop hl
and a
@ -97,7 +97,7 @@ AddItemToInventory_:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [wWhichPokemon] = index (within the inventory) of the item to remove
; [wItemQuantity] = quantity to remove
RemoveItemFromInventory_:
RemoveItemFromInventory_::
push hl
inc hl
ld a, [wWhichPokemon] ; index (within the inventory) of the item being removed

453
engine/items/items.asm → engine/items/item_effects.asm Executable file → Normal file
View file

@ -1,8 +1,8 @@
UseItem_:
UseItem_::
ld a, 1
ld [wActionResultOrTookBattleTurn], a ; initialise to success value
ld a, [wcf91] ;contains item_ID
cp HM_01
cp HM01
jp nc, ItemUseTMHM
ld hl, ItemUsePtrTable
dec a
@ -16,6 +16,7 @@ UseItem_:
jp hl
ItemUsePtrTable:
; entries correspond to item ids
dw ItemUseBall ; MASTER_BALL
dw ItemUseBall ; ULTRA_BALL
dw ItemUseBall ; GREAT_BALL
@ -147,7 +148,7 @@ ItemUseBall:
; If the player is fighting an unidentified ghost, set the value that indicates
; the Pokémon can't be caught and skip the capture calculations.
callab IsGhostBattle
callfar IsGhostBattle
ld b, $10 ; can't be caught value
jp z, .setAnimData
@ -169,7 +170,7 @@ ItemUseBall:
cp POKEMON_TOWER_6F
jr nz, .loop
ld a, [wEnemyMonSpecies2]
cp MAROWAK
cp RESTLESS_SOUL
ld b, $10 ; can't be caught value
jp z, .setAnimData
@ -239,14 +240,14 @@ ItemUseBall:
; Calculate MaxHP * 255.
xor a
ld [H_MULTIPLICAND], a
ldh [hMultiplicand], a
ld hl, wEnemyMonMaxHP
ld a, [hli]
ld [H_MULTIPLICAND + 1], a
ldh [hMultiplicand + 1], a
ld a, [hl]
ld [H_MULTIPLICAND + 2], a
ldh [hMultiplicand + 2], a
ld a, 255
ld [H_MULTIPLIER], a
ldh [hMultiplier], a
call Multiply
; Determine BallFactor. It's 8 for Great Balls and 12 for the others.
@ -260,7 +261,7 @@ ItemUseBall:
; Note that the results of all division operations are floored.
; Calculate (MaxHP * 255) / BallFactor.
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 4 ; number of bytes in dividend
call Divide
@ -281,17 +282,17 @@ ItemUseBall:
.skip2
; Let W = ((MaxHP * 255) / BallFactor) / max(HP / 4, 1). Calculate W.
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 4
call Divide
; If W > 255, store 255 in [H_QUOTIENT + 3].
; Let X = min(W, 255) = [H_QUOTIENT + 3].
ld a, [H_QUOTIENT + 2]
; If W > 255, store 255 in [hQuotient + 3].
; Let X = min(W, 255) = [hQuotient + 3].
ldh a, [hQuotient + 2]
and a
jr z, .skip3
ld a, 255
ld [H_QUOTIENT + 3], a
ldh [hQuotient + 3], a
.skip3
pop bc ; b = Rand1 - Status
@ -302,7 +303,7 @@ ItemUseBall:
jr c, .failedToCapture
; If W > 255, the ball captures the Pokémon.
ld a, [H_QUOTIENT + 2]
ldh a, [hQuotient + 2]
and a
jr nz, .captured
@ -310,7 +311,7 @@ ItemUseBall:
; If Rand2 > X, the ball fails to capture the Pokémon.
ld b, a
ld a, [H_QUOTIENT + 3]
ldh a, [hQuotient + 3]
cp b
jr c, .failedToCapture
@ -318,17 +319,17 @@ ItemUseBall:
jr .skipShakeCalculations
.failedToCapture
ld a, [H_QUOTIENT + 3]
ldh a, [hQuotient + 3]
ld [wPokeBallCaptureCalcTemp], a ; Save X.
; Calculate CatchRate * 100.
xor a
ld [H_MULTIPLICAND], a
ld [H_MULTIPLICAND + 1], a
ldh [hMultiplicand], a
ldh [hMultiplicand + 1], a
ld a, [wEnemyMonActualCatchRate]
ld [H_MULTIPLICAND + 2], a
ldh [hMultiplicand + 2], a
ld a, 100
ld [H_MULTIPLIER], a
ldh [hMultiplier], a
call Multiply
; Determine BallFactor2.
@ -349,26 +350,26 @@ ItemUseBall:
.skip4
; Let Y = (CatchRate * 100) / BallFactor2. Calculate Y.
ld a, b
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 4
call Divide
; If Y > 255, there are 3 shakes.
; Note that this shouldn't be possible.
; The maximum value of Y is (255 * 100) / 150 = 170.
ld a, [H_QUOTIENT + 2]
ldh a, [hQuotient + 2]
and a
ld b, $63 ; 3 shakes
jr nz, .setAnimData
; Calculate X * Y.
ld a, [wPokeBallCaptureCalcTemp]
ld [H_MULTIPLIER], a
ldh [hMultiplier], a
call Multiply
; Calculate (X * Y) / 255.
ld a, 255
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 4
call Divide
@ -386,19 +387,19 @@ ItemUseBall:
.addAilmentValue
; If the Pokémon has a status ailment, add Status2.
ld a, [H_QUOTIENT + 3]
ldh a, [hQuotient + 3]
add b
ld [H_QUOTIENT + 3], a
ldh [hQuotient + 3], a
.skip5
; Finally determine the number of shakes.
; Let Z = ((X * Y) / 255) + Status2 = [H_QUOTIENT + 3].
; Let Z = ((X * Y) / 255) + Status2 = [hQuotient + 3].
; The number of shakes depend on the range Z is in.
; 0 ≤ Z < 10: 0 shakes (the ball misses)
; 10 ≤ Z < 30: 1 shake
; 30 ≤ Z < 70: 2 shakes
; 70 ≤ Z: 3 shakes
ld a, [H_QUOTIENT + 3]
ldh a, [hQuotient + 3]
cp 10
ld b, $20
jr c, .setAnimData
@ -422,7 +423,7 @@ ItemUseBall:
ld a, TOSS_ANIM
ld [wAnimationID], a
xor a
ld [H_WHOSETURN], a
ldh [hWhoseTurn], a
ld [wAnimationType], a
ld [wDamageMultipliers], a
ld a, [wWhichPokemon]
@ -495,7 +496,7 @@ ItemUseBall:
ld [wcf91], a
ld a, [wEnemyMonLevel]
ld [wCurEnemyLVL], a
callab LoadEnemyMonData
callfar LoadEnemyMonData
pop af
ld [wcf91], a
pop hl
@ -586,53 +587,53 @@ ItemUseBall:
ItemUseBallText00:
;"It dodged the thrown ball!"
;"This pokemon can't be caught"
TX_FAR _ItemUseBallText00
db "@"
text_far _ItemUseBallText00
text_end
ItemUseBallText01:
;"You missed the pokemon!"
TX_FAR _ItemUseBallText01
db "@"
text_far _ItemUseBallText01
text_end
ItemUseBallText02:
;"Darn! The pokemon broke free!"
TX_FAR _ItemUseBallText02
db "@"
text_far _ItemUseBallText02
text_end
ItemUseBallText03:
;"Aww! It appeared to be caught!"
TX_FAR _ItemUseBallText03
db "@"
text_far _ItemUseBallText03
text_end
ItemUseBallText04:
;"Shoot! It was so close too!"
TX_FAR _ItemUseBallText04
db "@"
text_far _ItemUseBallText04
text_end
ItemUseBallText05:
;"All right! {MonName} was caught!"
;play sound
TX_FAR _ItemUseBallText05
TX_SFX_CAUGHT_MON
TX_BLINK
db "@"
text_far _ItemUseBallText05
sound_caught_mon
text_promptbutton
text_end
ItemUseBallText07:
;"X was transferred to Bill's PC"
TX_FAR _ItemUseBallText07
db "@"
text_far _ItemUseBallText07
text_end
ItemUseBallText08:
;"X was transferred to someone's PC"
TX_FAR _ItemUseBallText08
db "@"
text_far _ItemUseBallText08
text_end
ItemUseBallText06:
;"New DEX data will be added..."
;play sound
TX_FAR _ItemUseBallText06
TX_SFX_DEX_PAGE_ADDED
TX_BLINK
db "@"
text_far _ItemUseBallText06
sound_dex_page_added
text_promptbutton
text_end
ItemUseTownMap:
ld a, [wIsInBattle]
and a
jp nz, ItemUseNotTime
jpba DisplayTownMap
farjp DisplayTownMap
ItemUseBicycle:
ld a, [wIsInBattle]
@ -656,7 +657,7 @@ ItemUseBicycle:
jp nc, NoCyclingAllowedHere
call ItemUseReloadOverworldData
xor a ; no keys pressed
ld [hJoyHeld], a ; current joypad state
ldh [hJoyHeld], a ; current joypad state
inc a
ld [wWalkBikeSurfState], a ; change player state to bicycling
ld hl, GotOnBicycleText
@ -687,11 +688,11 @@ ItemUseSurfboard:
jp PrintText
.tryToStopSurfing
xor a
ld [hSpriteIndexOrTextID], a
ldh [hSpriteIndexOrTextID], a
ld d, 16 ; talking range in pixels (normal range)
call IsSpriteInFrontOfPlayer2
res 7, [hl]
ld a, [hSpriteIndexOrTextID]
ldh a, [hSpriteIndexOrTextID]
and a ; is there a sprite in the way?
jr nz, .cannotStopSurfing
ld hl, TilePairCollisionsWater
@ -745,12 +746,12 @@ ItemUseSurfboard:
ret
SurfingGotOnText:
TX_FAR _SurfingGotOnText
db "@"
text_far _SurfingGotOnText
text_end
SurfingNoPlaceToGetOffText:
TX_FAR _SurfingNoPlaceToGetOffText
db "@"
text_far _SurfingNoPlaceToGetOffText
text_end
ItemUsePokedex:
predef_jump ShowPokedexMenu
@ -778,7 +779,7 @@ ItemUseEvoStone:
ld a, SFX_HEAL_AILMENT
call PlaySoundWaitForCurrent
call WaitForSoundToFinish
callab TryEvolvingMon ; try to evolve pokemon
callfar TryEvolvingMon ; try to evolve pokemon
ld a, [wEvolutionOccurred]
and a
jr z, .noEffect
@ -990,7 +991,7 @@ ItemUseMedicine:
.notFullHP ; if the pokemon's current HP doesn't equal its max HP
xor a
ld [wDanger], a ;disable low health alarm
ld [wChannelSoundIDs + Ch4], a
ld [wChannelSoundIDs + Ch5], a
push hl
push de
ld bc, wPartyMon1MaxHP - (wPartyMon1HP + 1)
@ -1018,18 +1019,18 @@ ItemUseMedicine:
call AddNTimes
ld a, [hli]
ld [wHPBarMaxHP + 1], a
ld [H_DIVIDEND], a
ldh [hDividend], a
ld a, [hl]
ld [wHPBarMaxHP], a
ld [H_DIVIDEND + 1], a
ldh [hDividend + 1], a
ld a, 5
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 2 ; number of bytes
call Divide ; get 1/5 of max HP of pokemon that used Softboiled
ld bc, (wPartyMon1HP + 1) - (wPartyMon1MaxHP + 1)
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]
ldh a, [hQuotient + 3]
push af
ld b, a
ld a, [hl]
@ -1037,28 +1038,28 @@ ItemUseMedicine:
sub b
ld [hld], a
ld [wHPBarNewHP], a
ld a, [H_QUOTIENT + 2]
ldh a, [hQuotient + 2]
ld b, a
ld a, [hl]
ld [wHPBarOldHP+1], a
sbc b
ld [hl], a
ld [wHPBarNewHP+1], a
coord hl, 4, 1
hlcoord 4, 1
ld a, [wWhichPokemon]
ld bc, 2 * SCREEN_WIDTH
call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
ld a, SFX_HEAL_HP
call PlaySoundWaitForCurrent
ld a, [hFlags_0xFFF6]
ldh a, [hUILayoutFlags]
set 0, a
ld [hFlags_0xFFF6], a
ldh [hUILayoutFlags], a
ld a, $02
ld [wHPBarType], a
predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
ld a, [hFlags_0xFFF6]
ldh a, [hUILayoutFlags]
res 0, a
ld [hFlags_0xFFF6], a
ldh [hUILayoutFlags], a
pop af
ld b, a ; store heal amount (1/5 of max HP)
ld hl, wHPBarOldHP + 1
@ -1200,15 +1201,15 @@ ItemUseMedicine:
jr z, .playStatusAilmentCuringSound
ld a, SFX_HEAL_HP
call PlaySoundWaitForCurrent
ld a, [hFlags_0xFFF6]
ldh a, [hUILayoutFlags]
set 0, a
ld [hFlags_0xFFF6], a
ldh [hUILayoutFlags], a
ld a, $02
ld [wHPBarType], a
predef UpdateHPBar2 ; animate the HP bar lengthening
ld a, [hFlags_0xFFF6]
ldh a, [hUILayoutFlags]
res 0, a
ld [hFlags_0xFFF6], a
ldh [hUILayoutFlags], a
ld a, REVIVE_MSG
ld [wPartyMenuTypeOrMessageID], a
ld a, [wcf91]
@ -1224,13 +1225,13 @@ ItemUseMedicine:
call PlaySoundWaitForCurrent
.showHealingItemMessage
xor a
ld [H_AUTOBGTRANSFERENABLED], a
ldh [hAutoBGTransferEnabled], 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
ldh [hAutoBGTransferEnabled], a
ld c, 50
call DelayFrames
call WaitForTextScrollButtonPress
@ -1341,17 +1342,17 @@ ItemUseMedicine:
push hl
push de
ld d, a
callab CalcExperience ; calculate experience for next level and store it at $ff96
callfar CalcExperience ; calculate experience for next level and store it at hExperience
pop de
pop hl
ld bc, wPartyMon1Exp - wPartyMon1Level
add hl, bc ; hl now points to MSB of experience
; update experience to minimum for new level
ld a, [hExperience]
ldh a, [hExperience]
ld [hli], a
ld a, [hExperience + 1]
ldh a, [hExperience + 1]
ld [hli], a
ld a, [hExperience + 2]
ldh a, [hExperience + 2]
ld [hl], a
pop hl
ld a, [wWhichPokemon]
@ -1400,14 +1401,14 @@ ItemUseMedicine:
ld [wMonDataLocation], a
call LoadMonData
ld d, $01
callab PrintStatsBox ; display new stats text box
callfar PrintStatsBox ; display new stats text box
call WaitForTextScrollButtonPress ; wait for button press
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
predef LearnMoveFromLevelUp ; learn level up move, if any
xor a
ld [wForceEvolution], a
callab TryEvolvingMon ; evolve pokemon, if appropriate
callfar TryEvolvingMon ; evolve pokemon, if appropriate
ld a, $01
ld [wUpdateSpritesEnabled], a
pop af
@ -1417,12 +1418,12 @@ ItemUseMedicine:
jp RemoveUsedItem
VitaminStatRoseText:
TX_FAR _VitaminStatRoseText
db "@"
text_far _VitaminStatRoseText
text_end
VitaminNoEffectText:
TX_FAR _VitaminNoEffectText
db "@"
text_far _VitaminNoEffectText
text_end
VitaminText:
db "HEALTH@"
@ -1459,7 +1460,7 @@ BaitRockCommon:
ld [wAnimationID], a
xor a
ld [wAnimationType], a
ld [H_WHOSETURN], a
ldh [hWhoseTurn], 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
@ -1479,12 +1480,12 @@ BaitRockCommon:
jp DelayFrames
ThrewBaitText:
TX_FAR _ThrewBaitText
db "@"
text_far _ThrewBaitText
text_end
ThrewRockText:
TX_FAR _ThrewRockText
db "@"
text_far _ThrewRockText
text_end
; also used for Dig out-of-battle effect
ItemUseEscapeRope:
@ -1525,9 +1526,7 @@ ItemUseEscapeRope:
.notUsable
jp ItemUseNotTime
EscapeRopeTilesets:
db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
db $ff ; terminator
INCLUDE "data/tilesets/escape_rope_tilesets.asm"
ItemUseRepel:
ld b, 100
@ -1574,7 +1573,7 @@ ItemUseCardKey:
ld b, a
.loop
ld a, [hli]
cp $ff
cp -1
jp z, ItemUseNotTime
cp b
jr nz, .nextEntry1
@ -1601,46 +1600,7 @@ ItemUseCardKey:
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:
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:
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:
db SILPH_CO_11F,$08,$09,$14
db SILPH_CO_11F,$09,$09,$15
db $ff
INCLUDE "data/events/card_key_coords.asm"
ItemUsePokedoll:
ld a, [wIsInBattle]
@ -1698,8 +1658,8 @@ ItemUseXStat:
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
ldh [hWhoseTurn], a ; set turn to player's turn
farcall StatModifierUpEffect ; do stat increase move
pop hl
pop af
ld [hld], a ; restore [wPlayerMoveEffect]
@ -1775,9 +1735,9 @@ ItemUsePokeflute:
and $80
jr nz, .skipMusic
call WaitForSoundToFinish ; wait for sound to end
;callba Music_PokeFluteInBattle ; play in-battle pokeflute music ; XXX
;farcall Music_PokeFluteInBattle ; play in-battle pokeflute music ; XXX
.musicWaitLoop ; wait for music to finish playing
ld a, [wChannelSoundIDs + Ch6]
ld a, [wChannelSoundIDs + Ch7]
and a ; music off?
jr nz, .musicWaitLoop
.skipMusic
@ -1810,42 +1770,36 @@ WakeUpEntireParty:
jr nz, .loop
ret
; Format:
; 00: Y
; 01: X
Route12SnorlaxFluteCoords:
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
dbmapcoord 9, 62 ; one space West of Snorlax
dbmapcoord 10, 61 ; one space North of Snorlax
dbmapcoord 10, 63 ; one space South of Snorlax
dbmapcoord 11, 62 ; one space East of Snorlax
db -1 ; end
; Format:
; 00: Y
; 01: X
Route16SnorlaxFluteCoords:
db 10,27 ; one space East of Snorlax
db 10,25 ; one space West of Snorlax
db $ff ; terminator
dbmapcoord 27, 10 ; one space East of Snorlax
dbmapcoord 25, 10 ; one space West of Snorlax
db -1 ; end
PlayedFluteNoEffectText:
TX_FAR _PlayedFluteNoEffectText
db "@"
text_far _PlayedFluteNoEffectText
text_end
FluteWokeUpText:
TX_FAR _FluteWokeUpText
db "@"
text_far _FluteWokeUpText
text_end
PlayedFluteHadEffectText:
TX_FAR _PlayedFluteHadEffectText
TX_BLINK
TX_ASM
text_far _PlayedFluteHadEffectText
text_promptbutton
text_asm
ld a, [wIsInBattle]
and a
jr nz, .done
; play out-of-battle pokeflute music
ld a, $ff
call PlaySound ; turn off music
ld a, SFX_STOP_ALL_MUSIC
call PlaySound
ld a, SFX_POKEFLUTE
ld c, 0 ; BANK(SFX_Pokeflute)
call PlaySound
@ -1862,8 +1816,8 @@ ItemUseCoinCase:
jp PrintText
CoinCaseNumCoinsText:
TX_FAR _CoinCaseNumCoinsText
db "@"
text_far _CoinCaseNumCoinsText
text_end
ItemUseOldRod:
call FishingInit
@ -1898,7 +1852,7 @@ ItemUseGoodRod:
xor 1
jr RodResponse
INCLUDE "data/good_rod.asm"
INCLUDE "data/wild/good_rod.asm"
ItemUseSuperRod:
call FishingInit
@ -1924,7 +1878,7 @@ RodResponse:
push af
push hl
ld [hl], 0
callba FishingAnim
farcall FishingAnim
pop hl
pop af
ld [hl], a
@ -1965,7 +1919,7 @@ ItemUseItemfinder:
and a
jp nz, ItemUseNotTime
call ItemUseReloadOverworldData
callba HiddenItemNear ; check for hidden items
farcall HiddenItemNear ; check for hidden items
ld hl, ItemfinderFoundNothingText
jr nc, .printText ; if no hidden items
ld c, 4
@ -1981,12 +1935,12 @@ ItemUseItemfinder:
jp PrintText
ItemfinderFoundItemText:
TX_FAR _ItemfinderFoundItemText
db "@"
text_far _ItemfinderFoundItemText
text_end
ItemfinderFoundNothingText:
TX_FAR _ItemfinderFoundNothingText
db "@"
text_far _ItemfinderFoundNothingText
text_end
ItemUsePPUp:
ld a, [wIsInBattle]
@ -2021,7 +1975,7 @@ ItemUsePPRestore:
call PrintText
xor a
ld [wPlayerMoveListIndex], a
callab MoveSelectionMenu ; move selection menu
callfar MoveSelectionMenu ; move selection menu
ld a, 0
ld [wPlayerMoveListIndex], a
jr nz, .chooseMon
@ -2170,24 +2124,24 @@ ItemUsePPRestore:
ret
RaisePPWhichTechniqueText:
TX_FAR _RaisePPWhichTechniqueText
db "@"
text_far _RaisePPWhichTechniqueText
text_end
RestorePPWhichTechniqueText:
TX_FAR _RestorePPWhichTechniqueText
db "@"
text_far _RestorePPWhichTechniqueText
text_end
PPMaxedOutText:
TX_FAR _PPMaxedOutText
db "@"
text_far _PPMaxedOutText
text_end
PPIncreasedText:
TX_FAR _PPIncreasedText
db "@"
text_far _PPIncreasedText
text_end
PPRestoredText:
TX_FAR _PPRestoredText
db "@"
text_far _PPRestoredText
text_end
; for items that can't be used from the Item menu
UnusableItem:
@ -2198,10 +2152,10 @@ ItemUseTMHM:
and a
jp nz, ItemUseNotTime
ld a, [wcf91]
sub TM_01
sub TM01 ; underflows below 0 for HM items (before TM items)
push af
jr nc, .skipAdding
add 55 ; if item is an HM, add 55
add NUM_TMS + NUM_HMS ; adjust HM IDs to come after TM IDs
.skipAdding
inc a
ld [wd11e], a
@ -2218,7 +2172,7 @@ ItemUseTMHM:
call PrintText
ld hl, TeachMachineMoveText
call PrintText
coord hl, 14, 7
hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@ -2275,7 +2229,7 @@ ItemUseTMHM:
call PrintText
jr .chooseMon
.checkIfAlreadyLearnedMove
callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
callfar CheckIfMoveIsKnown ; check if the pokemon already knows the move
jr c, .chooseMon
predef LearnMove ; teach move
pop af
@ -2291,20 +2245,20 @@ ItemUseTMHM:
jp RemoveUsedItem
BootedUpTMText:
TX_FAR _BootedUpTMText
db "@"
text_far _BootedUpTMText
text_end
BootedUpHMText:
TX_FAR _BootedUpHMText
db "@"
text_far _BootedUpHMText
text_end
TeachMachineMoveText:
TX_FAR _TeachMachineMoveText
db "@"
text_far _TeachMachineMoveText
text_end
MonCannotLearnMachineMoveText:
TX_FAR _MonCannotLearnMachineMoveText
db "@"
text_far _MonCannotLearnMachineMoveText
text_end
PrintItemUseTextAndRemoveItem:
ld hl, ItemUseText00
@ -2361,54 +2315,54 @@ ItemUseFailed:
jp PrintText
ItemUseNotTimeText:
TX_FAR _ItemUseNotTimeText
db "@"
text_far _ItemUseNotTimeText
text_end
ItemUseNotYoursToUseText:
TX_FAR _ItemUseNotYoursToUseText
db "@"
text_far _ItemUseNotYoursToUseText
text_end
ItemUseNoEffectText:
TX_FAR _ItemUseNoEffectText
db "@"
text_far _ItemUseNoEffectText
text_end
ThrowBallAtTrainerMonText1:
TX_FAR _ThrowBallAtTrainerMonText1
db "@"
text_far _ThrowBallAtTrainerMonText1
text_end
ThrowBallAtTrainerMonText2:
TX_FAR _ThrowBallAtTrainerMonText2
db "@"
text_far _ThrowBallAtTrainerMonText2
text_end
NoCyclingAllowedHereText:
TX_FAR _NoCyclingAllowedHereText
db "@"
text_far _NoCyclingAllowedHereText
text_end
NoSurfingHereText:
TX_FAR _NoSurfingHereText
db "@"
text_far _NoSurfingHereText
text_end
BoxFullCannotThrowBallText:
TX_FAR _BoxFullCannotThrowBallText
db "@"
text_far _BoxFullCannotThrowBallText
text_end
ItemUseText00:
TX_FAR _ItemUseText001
TX_LINE
TX_FAR _ItemUseText002
db "@"
text_far _ItemUseText001
text_low
text_far _ItemUseText002
text_end
GotOnBicycleText:
TX_FAR _GotOnBicycleText1
TX_LINE
TX_FAR _GotOnBicycleText2
db "@"
text_far _GotOnBicycleText1
text_low
text_far _GotOnBicycleText2
text_end
GotOffBicycleText:
TX_FAR _GotOffBicycleText1
TX_LINE
TX_FAR _GotOffBicycleText2
db "@"
text_far _GotOffBicycleText1
text_low
text_far _GotOffBicycleText2
text_end
; 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
@ -2460,13 +2414,13 @@ RestoreBonusPP:
AddBonusPP:
push bc
ld a, [de] ; normal max PP of move
ld [H_DIVIDEND + 3], a
ldh [hDividend + 3], a
xor a
ld [H_DIVIDEND], a
ld [H_DIVIDEND + 1], a
ld [H_DIVIDEND + 2], a
ldh [hDividend], a
ldh [hDividend + 1], a
ldh [hDividend + 2], a
ld a, 5
ld [H_DIVISOR], a
ldh [hDivisor], a
ld b, 4
call Divide
ld a, [hl] ; move PP
@ -2477,7 +2431,7 @@ AddBonusPP:
srl a
ld c, a ; c = number of PP Ups used
.loop
ld a, [H_QUOTIENT + 3]
ldh a, [hQuotient + 3]
cp 8 ; is the amount greater than or equal to 8?
jr c, .addAmount
ld a, 7 ; cap the amount at 7
@ -2585,7 +2539,7 @@ GetSelectedMoveOffset2:
; [wItemQuantity] = quantity to toss
; OUTPUT:
; clears carry flag if the item is tossed, sets carry flag if not
TossItem_:
TossItem_::
push hl
ld a, [wcf91]
call IsItemHM
@ -2604,7 +2558,7 @@ TossItem_:
call CopyStringToCF4B ; copy name to wcf4b
ld hl, IsItOKToTossItemText
call PrintText
coord hl, 14, 7
hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@ -2636,16 +2590,16 @@ TossItem_:
ret
ThrewAwayItemText:
TX_FAR _ThrewAwayItemText
db "@"
text_far _ThrewAwayItemText
text_end
IsItOKToTossItemText:
TX_FAR _IsItOKToTossItemText
db "@"
text_far _IsItOKToTossItemText
text_end
TooImportantToTossText:
TX_FAR _TooImportantToTossText
db "@"
text_far _TooImportantToTossText
text_end
; checks if an item is a key item
; INPUT:
@ -2654,11 +2608,11 @@ TooImportantToTossText:
; [wIsKeyItem] = result
; 00: item is not key item
; 01: item is key item
IsKeyItem_:
IsKeyItem_::
ld a, $01
ld [wIsKeyItem], a
ld a, [wcf91]
cp HM_01 ; is the item an HM or TM?
cp HM01 ; is the item an HM or TM?
jr nc, .checkIfItemIsHM
; if the item is not an HM or TM
push af
@ -2683,7 +2637,7 @@ IsKeyItem_:
ld [wIsKeyItem], a
ret
INCLUDE "data/key_items.asm"
INCLUDE "data/items/key_items.asm"
SendNewMonToBox:
ld de, wNumInBox
@ -2817,15 +2771,15 @@ SendNewMonToBox:
push de
ld a, [wCurEnemyLVL]
ld d, a
callab CalcExperience
callfar CalcExperience
pop de
ld a, [hExperience]
ldh a, [hExperience]
ld [de], a
inc de
ld a, [hExperience + 1]
ldh a, [hExperience + 1]
ld [de], a
inc de
ld a, [hExperience + 2]
ldh a, [hExperience + 2]
ld [de], a
inc de
xor a
@ -2878,10 +2832,7 @@ IsNextTileShoreOrWater:
and a
ret
; tilesets with water
WaterTilesets:
db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
db $ff ; terminator
INCLUDE "data/tilesets/water_tilesets.asm"
ReadSuperRodData:
; return e = 2 if no fish on this map
@ -2928,7 +2879,7 @@ ReadSuperRodData:
ld e, $1 ; $1 if there's a bite
ret
INCLUDE "data/super_rod.asm"
INCLUDE "data/wild/super_rod.asm"
; reloads map view and processes sprite data
; for items that cause the overworld to be displayed

0
engine/items/itemfinder.asm Executable file → Normal file
View file

View file

@ -0,0 +1,17 @@
; subtracts the amount the player paid from their money
; OUTPUT: carry = 0(success) or 1(fail because there is not enough money)
SubtractAmountPaidFromMoney_::
ld de, wPlayerMoney
ld hl, hMoney ; total price of items
ld c, 3 ; length of money in bytes
call StringCmp
ret c
ld de, wPlayerMoney + 2
ld hl, hMoney + 2 ; 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

14
engine/items/tm_prices.asm Executable file → Normal file
View file

@ -1,9 +1,9 @@
GetMachinePrice:
GetMachinePrice::
; Input: [wcf91] = Item Id of a TM
; Output: Stores the TM price at hItemPrice
ld a, [wcf91] ; a contains TM item id
sub TM_01
ret c
sub TM01 ; underflows below 0 for HM items (before TM items)
ret c ; HMs are priceless
ld d, a
ld hl, TechnicalMachinePrices
srl a
@ -16,10 +16,10 @@ GetMachinePrice:
swap a
.highNybbleIsPrice
and $f0
ld [hItemPrice + 1], a
ldh [hItemPrice + 1], a
xor a
ld [hItemPrice], a
ld [hItemPrice + 2], a
ldh [hItemPrice], a
ldh [hItemPrice + 2], a
ret
INCLUDE "data/tm_prices.asm"
INCLUDE "data/items/tm_prices.asm"

4
engine/items/tmhm.asm Executable file → Normal file
View file

@ -22,5 +22,5 @@ CheckIfMoveIsKnown:
ret
AlreadyKnowsText:
TX_FAR _AlreadyKnowsText
db "@"
text_far _AlreadyKnowsText
text_end

2
engine/items/tms.asm Executable file → Normal file
View file

@ -33,4 +33,4 @@ TMToMove:
ld [wd11e], a
ret
INCLUDE "data/tms.asm"
INCLUDE "data/moves/tmhm_moves.asm"

620
engine/items/town_map.asm Normal file
View file

@ -0,0 +1,620 @@
NOT_VISITED EQU $fe
DisplayTownMap:
call LoadTownMap
ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
push hl
ld a, $1
ldh [hJoy7], a
ld a, [wCurMap]
push af
ld b, $0
call DrawPlayerOrBirdSprite ; player sprite
hlcoord 1, 0
ld de, wcd6d
call PlaceString
ld hl, wOAMBuffer
ld de, wTileMapBackup
ld bc, $10
call CopyData
ld hl, vSprites tile $04
ld de, TownMapCursor
lb bc, BANK(TownMapCursor), (TownMapCursorEnd - TownMapCursor) / $8
call CopyVideoDataDouble
xor a
ld [wWhichTownMapLocation], a
pop af
jr .enterLoop
.townMapLoop
hlcoord 0, 0
lb bc, 1, 20
call ClearScreenArea
ld hl, TownMapOrder
ld a, [wWhichTownMapLocation]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
.enterLoop
ld de, wTownMapCoords
call LoadTownMapEntry
ld a, [de]
push hl
call TownMapCoordsToOAMCoords
ld a, $4
ld [wOAMBaseTile], a
ld hl, wOAMBuffer + $10
call WriteTownMapSpriteOAM ; town map cursor sprite
pop hl
ld de, wcd6d
.copyMapName
ld a, [hli]
ld [de], a
inc de
cp $50
jr nz, .copyMapName
hlcoord 1, 0
ld de, wcd6d
call PlaceString
ld hl, wOAMBuffer + $10
ld de, wTileMapBackup + 16
ld bc, $10
call CopyData
.inputLoop
call TownMapSpriteBlinkingAnimation
call JoypadLowSensitivity
ldh a, [hJoy5]
ld b, a
and A_BUTTON | B_BUTTON | D_UP | D_DOWN
jr z, .inputLoop
ld a, SFX_TINK
call PlaySound
bit 6, b
jr nz, .pressedUp
bit 7, b
jr nz, .pressedDown
xor a
ld [wTownMapSpriteBlinkingEnabled], a
ldh [hJoy7], a
ld [wAnimCounter], a
call ExitTownMap
pop hl
pop af
ld [hl], a
ret
.pressedUp
ld a, [wWhichTownMapLocation]
inc a
cp TownMapOrderEnd - TownMapOrder ; number of list items + 1
jr nz, .noOverflow
xor a
.noOverflow
ld [wWhichTownMapLocation], a
jp .townMapLoop
.pressedDown
ld a, [wWhichTownMapLocation]
dec a
cp -1
jr nz, .noUnderflow
ld a, TownMapOrderEnd - TownMapOrder - 1 ; number of list items
.noUnderflow
ld [wWhichTownMapLocation], a
jp .townMapLoop
INCLUDE "data/maps/town_map_order.asm"
TownMapCursor:
INCBIN "gfx/town_map/town_map_cursor.1bpp"
TownMapCursorEnd:
LoadTownMap_Nest:
call LoadTownMap
ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
push hl
call DisplayWildLocations
call GetMonName
hlcoord 1, 0
call PlaceString
ld h, b
ld l, c
ld de, MonsNestText
call PlaceString
call WaitForTextScrollButtonPress
call ExitTownMap
pop hl
pop af
ld [hl], a
ret
MonsNestText:
db "'s NEST@"
LoadTownMap_Fly::
call ClearSprites
call LoadTownMap
call LoadPlayerSpriteGraphics
call LoadFontTilePatterns
ld de, BirdSprite
ld hl, vSprites tile $04
lb bc, BANK(BirdSprite), 12
call CopyVideoData
ld de, TownMapUpArrow
ld hl, vChars1 tile $6d
lb bc, BANK(TownMapUpArrow), (TownMapUpArrowEnd - TownMapUpArrow) / $8
call CopyVideoDataDouble
call BuildFlyLocationsList
ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
push hl
hlcoord 0, 0
ld de, ToText
call PlaceString
ld a, [wCurMap]
ld b, $0
call DrawPlayerOrBirdSprite
ld hl, wFlyLocationsList
decoord 18, 0
.townMapFlyLoop
ld a, " "
ld [de], a
push hl
push hl
hlcoord 3, 0
lb bc, 1, 15
call ClearScreenArea
pop hl
ld a, [hl]
ld b, $4
call DrawPlayerOrBirdSprite ; draw bird sprite
hlcoord 3, 0
ld de, wcd6d
call PlaceString
ld c, 15
call DelayFrames
hlcoord 18, 0
ld [hl], "▲"
hlcoord 19, 0
ld [hl], "▼"
pop hl
.inputLoop
push hl
call DelayFrame
call JoypadLowSensitivity
ldh a, [hJoy5]
ld b, a
pop hl
and A_BUTTON | B_BUTTON | D_UP | D_DOWN
jr z, .inputLoop
bit 0, b
jr nz, .pressedA
ld a, SFX_TINK
call PlaySound
bit 6, b
jr nz, .pressedUp
bit 7, b
jr nz, .pressedDown
jr .pressedB
.pressedA
ld a, SFX_HEAL_AILMENT
call PlaySound
ld a, [hl]
ld [wDestinationMap], a
ld hl, wd732
set 3, [hl]
inc hl
set 7, [hl]
.pressedB
xor a
ld [wTownMapSpriteBlinkingEnabled], a
call GBPalWhiteOutWithDelay3
pop hl
pop af
ld [hl], a
ret
.pressedUp
decoord 18, 0
inc hl
ld a, [hl]
cp $ff
jr z, .wrapToStartOfList
cp NOT_VISITED
jr z, .pressedUp ; skip past unvisited towns
jp .townMapFlyLoop
.wrapToStartOfList
ld hl, wFlyLocationsList
jp .townMapFlyLoop
.pressedDown
decoord 19, 0
dec hl
ld a, [hl]
cp $ff
jr z, .wrapToEndOfList
cp NOT_VISITED
jr z, .pressedDown ; skip past unvisited towns
jp .townMapFlyLoop
.wrapToEndOfList
ld hl, wFlyLocationsList + NUM_CITY_MAPS
jr .pressedDown
ToText:
db "To@"
BuildFlyLocationsList:
ld hl, wFlyLocationsList - 1
ld [hl], $ff
inc hl
ld a, [wTownVisitedFlag]
ld e, a
ld a, [wTownVisitedFlag + 1]
ld d, a
lb bc, 0, NUM_CITY_MAPS
.loop
srl d
rr e
ld a, NOT_VISITED
jr nc, .notVisited
ld a, b ; store the map number of the town if it has been visited
.notVisited
ld [hl], a
inc hl
inc b
dec c
jr nz, .loop
ld [hl], $ff
ret
TownMapUpArrow:
INCBIN "gfx/town_map/up_arrow.1bpp"
TownMapUpArrowEnd:
LoadTownMap:
call GBPalWhiteOutWithDelay3
call ClearScreen
call UpdateSprites
hlcoord 0, 0
ld b, $12
ld c, $12
call TextBoxBorder
call DisableLCD
ld hl, WorldMapTileGraphics
ld de, vChars2 tile $60
ld bc, WorldMapTileGraphicsEnd - WorldMapTileGraphics
ld a, BANK(WorldMapTileGraphics)
call FarCopyData2
ld hl, MonNestIcon
ld de, vSprites tile $04
ld bc, MonNestIconEnd - MonNestIcon
ld a, BANK(MonNestIcon)
call FarCopyDataDouble
hlcoord 0, 0
ld de, CompressedMap
.nextTile
ld a, [de]
and a
jr z, .done
ld b, a
and $f
ld c, a
ld a, b
swap a
and $f
add $60
.writeRunLoop
ld [hli], a
dec c
jr nz, .writeRunLoop
inc de
jr .nextTile
.done
call EnableLCD
ld b, SET_PAL_TOWN_MAP
call RunPaletteCommand
call Delay3
call GBPalNormal
xor a
ld [wAnimCounter], a
inc a
ld [wTownMapSpriteBlinkingEnabled], a
ret
CompressedMap:
INCBIN "gfx/town_map/town_map.rle"
ExitTownMap:
; clear town map graphics data and load usual graphics data
xor a
ld [wTownMapSpriteBlinkingEnabled], a
call GBPalWhiteOut
call ClearScreen
call ClearSprites
call LoadPlayerSpriteGraphics
call LoadFontTilePatterns
call UpdateSprites
jp RunDefaultPaletteCommand
DrawPlayerOrBirdSprite:
; a = map number
; b = OAM base tile
push af
ld a, b
ld [wOAMBaseTile], a
pop af
ld de, wTownMapCoords
call LoadTownMapEntry
ld a, [de]
push hl
call TownMapCoordsToOAMCoords
call WritePlayerOrBirdSpriteOAM
pop hl
ld de, wcd6d
.loop
ld a, [hli]
ld [de], a
inc de
cp "@"
jr nz, .loop
ld hl, wOAMBuffer
ld de, wTileMapBackup
ld bc, $a0
jp CopyData
DisplayWildLocations:
farcall FindWildLocationsOfMon
call ZeroOutDuplicatesInList
ld hl, wOAMBuffer
ld de, wTownMapCoords
.loop
ld a, [de]
cp $ff
jr z, .exitLoop
and a
jr z, .nextEntry
push hl
call LoadTownMapEntry
pop hl
ld a, [de]
cp $19 ; Cerulean Cave's coordinates
jr z, .nextEntry ; skip Cerulean Cave
call TownMapCoordsToOAMCoords
ld a, $4 ; nest icon tile no.
ld [hli], a
xor a
ld [hli], a
.nextEntry
inc de
jr .loop
.exitLoop
ld a, l
and a ; were any OAM entries written?
jr nz, .drawPlayerSprite
; if no OAM entries were written, print area unknown text
hlcoord 1, 7
ld b, 2
ld c, 15
call TextBoxBorder
hlcoord 2, 9
ld de, AreaUnknownText
call PlaceString
jr .done
.drawPlayerSprite
ld a, [wCurMap]
ld b, $0
call DrawPlayerOrBirdSprite
.done
ld hl, wOAMBuffer
ld de, wTileMapBackup
ld bc, $a0
jp CopyData
AreaUnknownText:
db " AREA UNKNOWN@"
TownMapCoordsToOAMCoords:
; in: lower nybble of a = x, upper nybble of a = y
; out: b and [hl] = (y * 8) + 24, c and [hl+1] = (x * 8) + 24
push af
and $f0
srl a
add 24
ld b, a
ld [hli], a
pop af
and $f
swap a
srl a
add 24
ld c, a
ld [hli], a
ret
WritePlayerOrBirdSpriteOAM:
ld a, [wOAMBaseTile]
and a
ld hl, wOAMBuffer + $90 ; for player sprite
jr z, WriteTownMapSpriteOAM
ld hl, wOAMBuffer + $80 ; for bird sprite
WriteTownMapSpriteOAM:
push hl
; Subtract 4 from c (X coord) and 4 from b (Y coord). However, the carry from c
; is added to b, so the net result is that only 3 is subtracted from b.
lb hl, -4, -4
add hl, bc
ld b, h
ld c, l
pop hl
WriteAsymmetricMonPartySpriteOAM:
; Writes 4 OAM blocks for a helix mon party sprite, since it does not have
; a vertical line of symmetry.
lb de, 2, 2
.loop
push de
push bc
.innerLoop
ld a, b
ld [hli], a
ld a, c
ld [hli], a
ld a, [wOAMBaseTile]
ld [hli], a
inc a
ld [wOAMBaseTile], a
xor a
ld [hli], a
inc d
ld a, 8
add c
ld c, a
dec e
jr nz, .innerLoop
pop bc
pop de
ld a, 8
add b
ld b, a
dec d
jr nz, .loop
ret
WriteSymmetricMonPartySpriteOAM:
; Writes 4 OAM blocks for a mon party sprite other than a helix. All the
; sprites other than the helix one have a vertical line of symmetry which allows
; the X-flip OAM bit to be used so that only 2 rather than 4 tile patterns are
; needed.
xor a
ld [wSymmetricSpriteOAMAttributes], a
lb de, 2, 2
.loop
push de
push bc
.innerLoop
ld a, b
ld [hli], a ; Y
ld a, c
ld [hli], a ; X
ld a, [wOAMBaseTile]
ld [hli], a ; tile
ld a, [wSymmetricSpriteOAMAttributes]
ld [hli], a ; attributes
xor (1 << OAM_X_FLIP)
ld [wSymmetricSpriteOAMAttributes], a
inc d
ld a, 8
add c
ld c, a
dec e
jr nz, .innerLoop
pop bc
pop de
push hl
ld hl, wOAMBaseTile
inc [hl]
inc [hl]
pop hl
ld a, 8
add b
ld b, a
dec d
jr nz, .loop
ret
ZeroOutDuplicatesInList:
; replace duplicate bytes in the list of wild pokemon locations with 0
ld de, wBuffer
.loop
ld a, [de]
inc de
cp $ff
ret z
ld c, a
ld l, e
ld h, d
.zeroDuplicatesLoop
ld a, [hl]
cp $ff
jr z, .loop
cp c
jr nz, .skipZeroing
xor a
ld [hl], a
.skipZeroing
inc hl
jr .zeroDuplicatesLoop
LoadTownMapEntry:
; in: a = map number
; out: lower nybble of [de] = x, upper nybble of [de] = y, hl = address of name
cp FIRST_INDOOR_MAP
jr c, .external
ld bc, 4
ld hl, InternalMapEntries
.loop
cp [hl]
jr c, .foundEntry
add hl, bc
jr .loop
.foundEntry
inc hl
jr .readEntry
.external
ld hl, ExternalMapEntries
ld c, a
ld b, 0
add hl, bc
add hl, bc
add hl, bc
.readEntry
ld a, [hli]
ld [de], a
ld a, [hli]
ld h, [hl]
ld l, a
ret
INCLUDE "data/maps/town_map_entries.asm"
INCLUDE "data/maps/names.asm"
MonNestIcon:
INCBIN "gfx/town_map/mon_nest_icon.1bpp"
MonNestIconEnd:
TownMapSpriteBlinkingAnimation::
ld a, [wAnimCounter]
inc a
cp 25
jr z, .hideSprites
cp 50
jr nz, .done
; show sprites when the counter reaches 50
ld hl, wTileMapBackup
ld de, wOAMBuffer
ld bc, $90
call CopyData
xor a
jr .done
.hideSprites
ld hl, wOAMBuffer
ld b, $24
ld de, $4
.hideSpritesLoop
ld [hl], $a0
add hl, de
dec b
jr nz, .hideSpritesLoop
ld a, 25
.done
ld [wAnimCounter], a
jp DelayFrame