ref: 93e12d200300c7320640922fe6bcebe64f942eda
parent: 2650bcffad179be1a874bfaadccb0bb554d28096
author: pikalaxalt <PikalaxALT@gmail.com>
date: Sun Mar 27 08:47:28 EDT 2016
Split up banks 1-3 of main.asm
--- a/battle/anim_commands.asm
+++ b/battle/anim_commands.asm
@@ -980,7 +980,7 @@
GetSubstitutePic: ; cc64c
ld hl, sScratch
- ld bc, $310
+ ld bc, (7 * 7) tiles
.loop
xor a
ld [hli], a
@@ -994,16 +994,16 @@
jr z, .player
ld hl, MonsterSpriteGFX + 0 tiles
- ld de, sScratch + $13 tiles
+ ld de, sScratch + (2 * 7 + 5) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 1 tiles
- ld de, sScratch + $1a tiles
+ ld de, sScratch + (3 * 7 + 5) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 2 tiles
- ld de, sScratch + $14 tiles
+ ld de, sScratch + (2 * 7 + 6) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 3 tiles
- ld de, sScratch + $1b tiles
+ ld de, sScratch + (3 * 7 + 6) tiles
call .CopyTile
ld hl, VTiles2 tile $00
@@ -1014,16 +1014,16 @@
.player
ld hl, MonsterSpriteGFX + 4 tiles
- ld de, sScratch + $10 tiles
+ ld de, sScratch + (2 * 6 + 4) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 5 tiles
- ld de, sScratch + $16 tiles
+ ld de, sScratch + (3 * 6 + 4) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 6 tiles
- ld de, sScratch + $11 tiles
+ ld de, sScratch + (2 * 6 + 5) tiles
call .CopyTile
ld hl, MonsterSpriteGFX + 7 tiles
- ld de, sScratch + $17 tiles
+ ld de, sScratch + (3 * 6 + 5) tiles
call .CopyTile
ld hl, VTiles2 tile $31
--- a/battle/effect_commands.asm
+++ b/battle/effect_commands.asm
@@ -7873,7 +7873,7 @@
ld [hl], a
ld [de], a
call _CheckBattleScene
- jr c, .mobile
+ jr c, .no_anim
xor a
ld [wNumHits], a
@@ -7883,7 +7883,7 @@
call LoadAnim
jr .finish
-.mobile
+.no_anim
call BattleCommand_RaiseSubNoAnim
.finish
ld hl, MadeSubstituteText
--- a/constants/battle_tower_constants.asm
+++ b/constants/battle_tower_constants.asm
@@ -19,8 +19,8 @@
const BATTLETOWERACTION_11 ; store 0 in 5:aa8d
const BATTLETOWERACTION_12 ; store 1 in 5:aa8d
const BATTLETOWERACTION_13 ; check 5:aa8d
- const BATTLETOWERACTION_14 ; if save file is yours: bit 0, [sbe4f]
- const BATTLETOWERACTION_15 ; set 0, [sbe4f]
+ const BATTLETOWERACTION_14 ; if save file is yours: bit 0, [s1_be4f]
+ const BATTLETOWERACTION_15 ; set 0, [s1_be4f]
const BATTLETOWERACTION_16 ; update time in SRAM bank 5
const BATTLETOWERACTION_17 ; check time in SRAM bank 5
const BATTLETOWERACTION_18 ; level check
--- /dev/null
+++ b/engine/billspctop.asm
@@ -1,0 +1,388 @@
+_BillsPC: ; e3fd
+ call .CheckCanUsePC
+ ret c
+ call .LogIn
+ call .UseBillsPC
+ jp .LogOut
+
+.CheckCanUsePC: ; e40a (3:640a)
+ ld a, [PartyCount]
+ and a
+ ret nz
+ ld hl, .Text_GottaHavePokemon
+ call MenuTextBoxBackup
+ scf
+ ret
+
+.Text_GottaHavePokemon: ; 0xe417
+ ; You gotta have #MON to call!
+ text_jump UnknownText_0x1c1006
+ db "@"
+
+.LogIn: ; e41c (3:641c)
+ xor a
+ ld [hBGMapMode], a
+ call LoadStandardMenuDataHeader
+ call ClearPCItemScreen
+ ld hl, Options
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ ld hl, .Text_What
+ call PrintText
+ pop af
+ ld [Options], a
+ call LoadFontsBattleExtra
+ ret
+
+.Text_What: ; 0xe43a
+ ; What?
+ text_jump UnknownText_0x1c1024
+ db "@"
+
+.LogOut: ; e43f (3:643f)
+ call CloseSubmenu
+ ret
+
+.UseBillsPC: ; e443 (3:6443)
+ ld hl, .MenuDataHeader
+ call LoadMenuDataHeader
+ ld a, $1
+.loop
+ ld [wMenuCursorBuffer], a
+ call SetPalettes
+ xor a
+ ld [wWhichIndexSet], a
+ ld [hBGMapMode], a
+ call DoNthMenu
+ jr c, .cancel
+ ld a, [wMenuCursorBuffer]
+ push af
+ ld a, [MenuSelection]
+ ld hl, .Jumptable
+ rst JumpTable
+ pop bc
+ ld a, b
+ jr nc, .loop
+.cancel
+ call CloseWindow
+ ret
+
+.MenuDataHeader: ; 0xe46f
+ db $40 ; flags
+ db 00, 00 ; start coords
+ db 17, 19 ; end coords
+ dw .MenuData2
+ db 1 ; default option
+
+.MenuData2: ; 0xe477
+ db $80 ; flags
+ db 0 ; items
+ dw .items
+ dw PlaceMenuStrings
+ dw .strings
+
+.strings: ; e47f
+ db "WITHDRAW <PK><MN>@"
+ db "DEPOSIT <PK><MN>@"
+ db "CHANGE BOX@"
+ db "MOVE <PK><MN> W/O MAIL@"
+ db "SEE YA!@"
+
+.Jumptable: ; e4ba (3:64ba)
+ dw BillsPC_WithdrawMenu
+ dw BillsPC_DepositMenu
+ dw BillsPC_ChangeBoxMenu
+ dw BillsPC_MovePKMNMenu
+ dw BillsPC_SeeYa
+
+.items: ; e4c4
+ db 5
+ db 0 ; WITHDRAW
+ db 1; DEPOSIT
+ db 2 ; CHANGE BOX
+ db 3 ; MOVE PKMN
+ db 4 ; SEE YA!
+ db -1
+
+BillsPC_SeeYa: ; e4cb
+ scf
+ ret
+
+BillsPC_MovePKMNMenu: ; e4cd
+ call LoadStandardMenuDataHeader
+ callba IsAnyMonHoldingMail
+ jr nc, .no_mail
+ ld hl, .Text_MonHoldingMail
+ call PrintText
+ jr .quit
+
+.no_mail
+ callba StartMovePkmnWOMail_SaveGame
+ jr c, .quit
+ callba _MovePKMNWithoutMail
+ call ReturnToMapFromSubmenu
+ call ClearPCItemScreen
+
+.quit
+ call CloseWindow
+ and a
+ ret
+
+.Text_MonHoldingMail: ; 0xe4f9
+ ; There is a #MON holding MAIL. Please remove the MAIL.
+ text_jump UnknownText_0x1c102b
+ db "@"
+
+BillsPC_DepositMenu: ; e4fe (3:64fe)
+ call LoadStandardMenuDataHeader
+ callba _DepositPKMN
+ call ReturnToMapFromSubmenu
+ call ClearPCItemScreen
+ call CloseWindow
+ and a
+ ret
+
+Functione512: ; unused
+ ld a, [PartyCount]
+ and a
+ jr z, .no_pkmn
+ cp 2
+ jr c, .only_one_pkmn
+ and a
+ ret
+
+.no_pkmn
+ ld hl, .Text_NoPKMN
+ call MenuTextBoxBackup
+ scf
+ ret
+
+.only_one_pkmn
+ ld hl, .Text_ItsYourLastPKMN
+ call MenuTextBoxBackup
+ scf
+ ret
+
+.Text_NoPKMN: ; 0xe52e
+ ; You don't have a single #MON!
+ text_jump UnknownText_0x1c1062
+ db "@"
+
+.Text_ItsYourLastPKMN: ; 0xe533
+ ; You can't deposit your last #MON!
+ text_jump UnknownText_0x1c1080
+ db "@"
+
+CheckCurPartyMonFainted: ; e538
+ ld hl, PartyMon1HP
+ ld de, PARTYMON_STRUCT_LENGTH
+ ld b, $0
+.loop
+ ld a, [CurPartyMon]
+ cp b
+ jr z, .skip
+ ld a, [hli]
+ or [hl]
+ jr nz, .notfainted
+ dec hl
+
+.skip
+ inc b
+ ld a, [PartyCount]
+ cp b
+ jr z, .done
+ add hl, de
+ jr .loop
+
+.done
+ scf
+ ret
+
+.notfainted
+ and a
+ ret
+
+BillsPC_WithdrawMenu: ; e559 (3:6559)
+ call LoadStandardMenuDataHeader
+ callba _WithdrawPKMN
+ call ReturnToMapFromSubmenu
+ call ClearPCItemScreen
+ call CloseWindow
+ and a
+ ret
+
+Functione56d: ; unused
+ ld a, [PartyCount]
+ cp PARTY_LENGTH
+ jr nc, .asm_e576
+ and a
+ ret
+
+.asm_e576
+ ld hl, UnknownText_0xe57e
+ call MenuTextBoxBackup
+ scf
+ ret
+
+UnknownText_0xe57e: ; 0xe57e
+ ; You can't take any more #MON.
+ text_jump UnknownText_0x1c10a2
+ db "@"
+
+BillsPC_ChangeBoxMenu: ; e583 (3:6583)
+ callba _ChangeBox
+ and a
+ ret
+
+ClearPCItemScreen: ; e58b
+ call DisableSpriteUpdates
+ xor a
+ ld [hBGMapMode], a
+ call ClearBGPalettes
+ call ClearSprites
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ hlcoord 0,0
+ lb bc, 10, 18
+ call TextBox
+ hlcoord 0,12
+ lb bc, 4, 18
+ call TextBox
+ call WaitBGMap2
+ call SetPalettes ; load regular palettes?
+ ret
+
+CopyBoxmonToTempMon: ; e5bb
+ ld a, [CurPartyMon]
+ ld hl, sBoxMon1Species
+ ld bc, BOXMON_STRUCT_LENGTH
+ call AddNTimes
+ ld de, TempMonSpecies
+ ld bc, BOXMON_STRUCT_LENGTH
+ ld a, BANK(sBoxMon1Species)
+ call GetSRAMBank
+ call CopyBytes
+ call CloseSRAM
+ ret
+
+Functione5d9: ; unreferenced
+ ld a, [wCurBox]
+ cp b
+ jr z, .same_box
+ ld a, b
+ ld hl, .BoxAddrs
+ ld bc, 3
+ call AddNTimes
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop af
+ jr .okay
+
+.same_box
+ ld a, BANK(sBoxCount)
+ ld hl, sBoxCount
+
+.okay
+ call GetSRAMBank
+ ld a, [hl]
+ ld bc, 1 + MONS_PER_BOX + 1
+ add hl, bc
+ ld b, a
+ ld c, $0
+ ld de, wc608
+ ld a, b
+ and a
+ jr z, .empty_box
+.loop
+ push hl
+ push bc
+ ld a, c
+ ld bc, 0
+ add hl, bc
+ ld bc, BOXMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hl]
+ ld [de], a
+ inc de
+ ld [CurSpecies], a
+ call GetBaseData
+ pop bc
+ pop hl
+
+ push hl
+ push bc
+ ld a, c
+ ld bc, MONS_PER_BOX * (BOXMON_STRUCT_LENGTH + NAME_LENGTH)
+ add hl, bc
+ call SkipNames
+ call CopyBytes
+ pop bc
+ pop hl
+
+ push hl
+ push bc
+ ld a, c
+ ld bc, MON_LEVEL
+ add hl, bc
+ ld bc, BOXMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hl]
+ ld [de], a
+ inc de
+ pop bc
+ pop hl
+
+ push hl
+ push bc
+ ld a, c
+ ld bc, MON_DVS
+ add hl, bc
+ ld bc, BOXMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hli]
+ and $f0
+ ld b, a
+ ld a, [hl]
+ and $f0
+ swap a
+ or b
+ ld b, a
+ ld a, [BaseGender]
+ cp b
+ ld a, $1
+ jr c, .okay2
+ xor a
+.okay2
+ ld [de], a
+ inc de
+ pop bc
+ pop hl
+
+ inc c
+ dec b
+ jr nz, .loop
+.empty_box
+ call CloseSRAM
+ ret
+
+.BoxAddrs: ; e66e
+ dba sBox1
+ dba sBox2
+ dba sBox3
+ dba sBox4
+ dba sBox5
+ dba sBox6
+ dba sBox7
+ dba sBox8
+ dba sBox9
+ dba sBox10
+ dba sBox11
+ dba sBox12
+ dba sBox13
+ dba sBox14
--- /dev/null
+++ b/engine/health.asm
@@ -1,0 +1,110 @@
+HealParty: ; c658
+ xor a
+ ld [CurPartyMon], a
+ ld hl, PartySpecies
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .done
+ cp EGG
+ jr z, .next
+
+ push hl
+ call HealPartyMon
+ pop hl
+
+.next
+ ld a, [CurPartyMon]
+ inc a
+ ld [CurPartyMon], a
+ jr .loop
+
+.done
+ ret
+
+HealPartyMon: ; c677
+ ld a, MON_SPECIES
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+
+ ld hl, MON_STATUS
+ add hl, de
+ xor a
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, MON_MAXHP
+ add hl, de
+
+ ; bc = MON_HP
+ ld b, h
+ ld c, l
+ dec bc
+ dec bc
+
+ ld a, [hli]
+ ld [bc], a
+ inc bc
+ ld a, [hl]
+ ld [bc], a
+
+ callba RestoreAllPP
+ ret
+
+ComputeHPBarPixels: ; c699
+; e = bc * (6 * 8) / de
+ ld a, b
+ or c
+ jr z, .zero
+ push hl
+ xor a
+ ld [hMultiplicand + 0], a
+ ld a, b
+ ld [hMultiplicand + 1], a
+ ld a, c
+ ld [hMultiplicand + 2], a
+ ld a, 6 * 8
+ ld [hMultiplier], a
+ call Multiply
+ ; We need de to be under 256 because hDivisor is only 1 byte.
+ ld a, d
+ and a
+ jr z, .divide
+ ; divide de and hProduct by 4
+ srl d
+ rr e
+ srl d
+ rr e
+ ld a, [hProduct + 2]
+ ld b, a
+ ld a, [hProduct + 3]
+ srl b
+ rr a
+ srl b
+ rr a
+ ld [hDividend + 3], a
+ ld a, b
+ ld [hDividend + 2], a
+.divide
+ ld a, e
+ ld [hDivisor], a
+ ld b, 4
+ call Divide
+ ld a, [hQuotient + 2]
+ ld e, a
+ pop hl
+ and a
+ ret nz
+ ld e, 1
+ ret
+
+.zero
+ ld e, 0
+ ret
+
+AnimateHPBar: ; c6e0
+ call WaitBGMap
+ call _AnimateHPBar
+ call WaitBGMap
+ ret
--- /dev/null
+++ b/engine/items.asm
@@ -1,0 +1,584 @@
+_ReceiveItem:: ; d1d5
+ call DoesHLEqualNumItems
+ jp nz, PutItemInPocket
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets: ; d1e9
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Item: ; d1f1
+ ld h, d
+ ld l, e
+ jp PutItemInPocket
+
+.KeyItem: ; d1f6
+ ld h, d
+ ld l, e
+ jp ReceiveKeyItem
+
+.Ball: ; d1fb
+ ld hl, NumBalls
+ jp PutItemInPocket
+
+.TMHM: ; d201
+ ld h, d
+ ld l, e
+ ld a, [CurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp ReceiveTMHM
+
+_TossItem:: ; d20d
+ call DoesHLEqualNumItems
+ jr nz, .remove
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball ; d228
+ ld hl, NumBalls
+ jp RemoveItemFromPocket
+
+.TMHM ; d22e
+ ld h, d
+ ld l, e
+ ld a, [CurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp TossTMHM
+
+.KeyItem ; d23a
+ ld h, d
+ ld l, e
+ jp TossKeyItem
+
+.Item ; d23f
+ ld h, d
+ ld l, e
+
+.remove
+ jp RemoveItemFromPocket
+
+_CheckItem:: ; d244
+ call DoesHLEqualNumItems
+ jr nz, .nope
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball ; d25f
+ ld hl, NumBalls
+ jp CheckTheItem
+
+.TMHM ; d265
+ ld h, d
+ ld l, e
+ ld a, [CurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp CheckTMHM
+
+.KeyItem ; d271
+ ld h, d
+ ld l, e
+ jp CheckKeyItems
+
+.Item ; d276
+ ld h, d
+ ld l, e
+
+.nope
+ jp CheckTheItem
+
+DoesHLEqualNumItems: ; d27b
+ ld a, l
+ cp NumItems % $100
+ ret nz
+ ld a, h
+ cp NumItems / $100
+ ret
+
+GetPocketCapacity: ; d283
+ ld c, MAX_ITEMS
+ ld a, e
+ cp NumItems % $100
+ jr nz, .not_bag
+ ld a, d
+ cp NumItems / $100
+ ret z
+
+.not_bag
+ ld c, MAX_PC_ITEMS
+ ld a, e
+ cp PCItems % $100
+ jr nz, .not_pc
+ ld a, d
+ cp PCItems / $100
+ ret z
+
+.not_pc
+ ld c, MAX_BALLS
+ ret
+
+PutItemInPocket: ; d29c
+ ld d, h
+ ld e, l
+ inc hl
+ ld a, [CurItem]
+ ld c, a
+ ld b, 0
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .terminator
+ cp c
+ jr nz, .next
+ ld a, 99
+ sub [hl]
+ add b
+ ld b, a
+ ld a, [wItemQuantityChangeBuffer]
+ cp b
+ jr z, .ok
+ jr c, .ok
+
+.next
+ inc hl
+ jr .loop
+
+.terminator
+ call GetPocketCapacity
+ ld a, [de]
+ cp c
+ jr c, .ok
+ and a
+ ret
+
+.ok
+ ld h, d
+ ld l, e
+ ld a, [CurItem]
+ ld c, a
+ ld a, [wItemQuantityChangeBuffer]
+ ld [wItemQuantityBuffer], a
+.loop2
+ inc hl
+ ld a, [hli]
+ cp -1
+ jr z, .terminator2
+ cp c
+ jr nz, .loop2
+ ld a, [wItemQuantityBuffer]
+ add [hl]
+ cp 100
+ jr nc, .newstack
+ ld [hl], a
+ jr .done
+
+.newstack
+ ld [hl], 99
+ sub 99
+ ld [wItemQuantityBuffer], a
+ jr .loop2
+
+.terminator2
+ dec hl
+ ld a, [CurItem]
+ ld [hli], a
+ ld a, [wItemQuantityBuffer]
+ ld [hli], a
+ ld [hl], -1
+ ld h, d
+ ld l, e
+ inc [hl]
+
+.done
+ scf
+ ret
+
+RemoveItemFromPocket: ; d2ff
+ ld d, h
+ ld e, l
+ ld a, [hli]
+ ld c, a
+ ld a, [CurItemQuantity]
+ cp c
+ jr nc, .ok ; memory
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld a, [CurItem]
+ cp [hl]
+ inc hl
+ jr z, .skip
+ ld h, d
+ ld l, e
+ inc hl
+
+.ok
+ ld a, [CurItem]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .skip
+ cp -1
+ jr z, .nope
+ inc hl
+ jr .loop
+
+.skip
+ ld a, [wItemQuantityChangeBuffer]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .nope
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ and a
+ jr nz, .yup
+ dec hl
+ ld b, h
+ ld c, l
+ inc hl
+ inc hl
+.loop2
+ ld a, [hli]
+ ld [bc], a
+ inc bc
+ cp -1
+ jr nz, .loop2
+ ld h, d
+ ld l, e
+ dec [hl]
+
+.yup
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+CheckTheItem: ; d349
+ ld a, [CurItem]
+ ld c, a
+.loop
+ inc hl
+ ld a, [hli]
+ cp -1
+ jr z, .done
+ cp c
+ jr nz, .loop
+ scf
+ ret
+
+.done
+ and a
+ ret
+
+ReceiveKeyItem: ; d35a
+ ld hl, NumKeyItems
+ ld a, [hli]
+ cp MAX_KEY_ITEMS
+ jr nc, .nope
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [CurItem]
+ ld [hli], a
+ ld [hl], -1
+ ld hl, NumKeyItems
+ inc [hl]
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+TossKeyItem: ; d374
+ ld a, [wd107]
+ ld e, a
+ ld d, 0
+ ld hl, NumKeyItems
+ ld a, [hl]
+ cp e
+ jr nc, .ok
+ call .Toss
+ ret nc
+ jr .ok2
+
+.ok
+ dec [hl]
+ inc hl
+ add hl, de
+
+.ok2
+ ld d, h
+ ld e, l
+ inc hl
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp -1
+ jr nz, .loop
+ scf
+ ret
+
+.Toss: ; d396
+ ld hl, NumKeyItems
+ ld a, [CurItem]
+ ld c, a
+.loop3
+ inc hl
+ ld a, [hl]
+ cp c
+ jr z, .ok3
+ cp -1
+ jr nz, .loop3
+ xor a
+ ret
+
+.ok3
+ ld a, [NumKeyItems]
+ dec a
+ ld [NumKeyItems], a
+ scf
+ ret
+
+CheckKeyItems: ; d3b1
+ ld a, [CurItem]
+ ld c, a
+ ld hl, KeyItems
+.loop
+ ld a, [hli]
+ cp c
+ jr z, .done
+ cp -1
+ jr nz, .loop
+ and a
+ ret
+
+.done
+ scf
+ ret
+
+ReceiveTMHM: ; d3c4
+ dec c
+ ld b, 0
+ ld hl, TMsHMs
+ add hl, bc
+ ld a, [wItemQuantityChangeBuffer]
+ add [hl]
+ cp 100
+ jr nc, .toomany
+ ld [hl], a
+ scf
+ ret
+
+.toomany
+ and a
+ ret
+
+TossTMHM: ; d3d8
+ dec c
+ ld b, 0
+ ld hl, TMsHMs
+ add hl, bc
+ ld a, [wItemQuantityChangeBuffer]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .nope
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ jr nz, .yup
+ ld a, [wTMHMPocketScrollPosition]
+ and a
+ jr z, .yup
+ dec a
+ ld [wTMHMPocketScrollPosition], a
+
+.yup
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+CheckTMHM: ; d3fb
+ dec c
+ ld b, $0
+ ld hl, TMsHMs
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ scf
+ ret
+
+GetTMHMNumber:: ; d407
+; Return the number of a TM/HM by item id c.
+
+ ld a, c
+
+; Skip any dummy items.
+ cp ITEM_C3 ; TM04-05
+ jr c, .done
+ cp ITEM_DC ; TM28-29
+ jr c, .skip
+
+ dec a
+.skip
+ dec a
+.done
+ sub TM01
+ inc a
+ ld c, a
+ ret
+
+GetNumberedTMHM: ; d417
+; Return the item id of a TM/HM by number c.
+
+ ld a, c
+
+; Skip any gaps.
+ cp ITEM_C3 - (TM01 - 1)
+ jr c, .done
+ cp ITEM_DC - (TM01 - 1) - 1
+ jr c, .skip_one
+
+.skip_two
+ inc a
+.skip_one
+ inc a
+.done
+ add TM01
+ dec a
+ ld c, a
+ ret
+
+_CheckTossableItem:: ; d427
+; Return 1 in wItemAttributeParamBuffer and carry if CurItem can't be removed from the bag.
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit 7, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+CheckSelectableItem: ; d432
+; Return 1 in wItemAttributeParamBuffer and carry if CurItem can't be selected.
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit 6, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+CheckItemPocket:: ; d43d
+; Return the pocket for CurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_POCKET
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+CheckItemContext: ; d448
+; Return the context for CurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+CheckItemMenu: ; d453
+; Return the menu for CurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ swap a
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+GetItemAttr: ; d460
+; Get attribute a of CurItem.
+
+ push hl
+ push bc
+
+ ld hl, ItemAttributes
+ ld c, a
+ ld b, 0
+ add hl, bc
+
+ xor a
+ ld [wItemAttributeParamBuffer], a
+
+ ld a, [CurItem]
+ dec a
+ ld c, a
+ ld a, NUM_ITEMATTRS
+ call AddNTimes
+ ld a, BANK(ItemAttributes)
+ call GetFarByte
+
+ pop bc
+ pop hl
+ ret
+
+ItemAttr_ReturnCarry: ; d47f
+ ld a, 1
+ ld [wItemAttributeParamBuffer], a
+ scf
+ ret
+
+GetItemPrice: ; d486
+; Return the price of CurItem in de.
+ push hl
+ push bc
+ ld a, ITEMATTR_PRICE
+ call GetItemAttr
+ ld e, a
+ ld a, ITEMATTR_PRICE_HI
+ call GetItemAttr
+ ld d, a
+ pop bc
+ pop hl
+ ret
--- a/engine/phone.asm
+++ b/engine/phone.asm
@@ -451,22 +451,20 @@
; 0x90255
Script_SpecialBillCall:: ; 0x90255
- callasm Function9025c
+ callasm .LoadBillScript
jump Script_ReceivePhoneCall
-; 0x9025c
-Function9025c: ; 9025c
+.LoadBillScript
ld e, PHONE_BILL
jp LoadCallerScript
; 90261
UnknownScript_0x90261: ; 0x90261
- callasm Function9026a
+ callasm .LoadElmScript
pause 30
jump Script_ReceivePhoneCall
-; 0x9026a
-Function9026a: ; 9026a
+.LoadElmScript
ld e, PHONE_ELM
jp LoadCallerScript
; 9026f
@@ -493,7 +491,6 @@
ld b, a
call Function90363
ret
-
PhoneCall:: ; 9029a
ld a, b
--- /dev/null
+++ b/engine/player_object.asm
@@ -1,0 +1,856 @@
+BlankScreen: ; 8000
+ call DisableSpriteUpdates
+ xor a
+ ld [hBGMapMode], a
+ call ClearBGPalettes
+ call ClearSprites
+ hlcoord 0, 0
+ ld bc, TileMapEnd - TileMap
+ ld a, " "
+ call ByteFill
+ hlcoord 0, 0, AttrMap
+ ld bc, AttrMapEnd - AttrMap
+ ld a, $7
+ call ByteFill
+ call WaitBGMap2
+ call SetPalettes
+ ret
+
+SpawnPlayer: ; 8029
+ ld a, -1
+ ld [wObjectFollow_Leader], a
+ ld [wObjectFollow_Follower], a
+ ld a, $0
+ ld hl, PlayerObjectTemplate
+ call CopyPlayerObjectTemplate
+ ld b, $0
+ call PlayerSpawn_ConvertCoords
+ ld a, $0
+ call GetMapObject
+ ld hl, MAPOBJECT_COLOR
+ add hl, bc
+ ln e, (1 << 3) | PAL_OW_RED, PERSONTYPE_SCRIPT
+ ld a, [wPlayerSpriteSetupFlags]
+ bit 2, a
+ jr nz, .ok
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .ok
+ ln e, (1 << 3) | PAL_OW_BLUE, PERSONTYPE_SCRIPT
+
+.ok
+ ld [hl], e
+ ld a, $0
+ ld [hMapObjectIndexBuffer], a
+ ld bc, MapObjects
+ ld a, $0
+ ld [hObjectStructIndexBuffer], a
+ ld de, ObjectStructs
+ call CopyMapObjectToObjectStruct
+ ld a, PLAYER
+ ld [wCenteredObject], a
+ ret
+
+PlayerObjectTemplate: ; 8071
+; A dummy map object used to initialize the player object.
+; Shorter than the actual amount copied by two bytes.
+; Said bytes seem to be unused.
+ person_event SPRITE_CHRIS, -4, -4, SPRITEMOVEDATA_PLAYER, 15, 15, -1, -1, 0, PERSONTYPE_SCRIPT, 0, 0, -1
+
+CopyDECoordsToMapObject:: ; 807e
+ push de
+ ld a, b
+ call GetMapObject
+ pop de
+ ld hl, MAPOBJECT_X_COORD
+ add hl, bc
+ ld [hl], d
+ ld hl, MAPOBJECT_Y_COORD
+ add hl, bc
+ ld [hl], e
+ ret
+
+PlayerSpawn_ConvertCoords: ; 808f
+ push bc
+ ld a, [XCoord]
+ add 4
+ ld d, a
+ ld a, [YCoord]
+ add 4
+ ld e, a
+ pop bc
+ call CopyDECoordsToMapObject
+ ret
+
+WritePersonXY:: ; 80a1
+ ld a, b
+ call CheckObjectVisibility
+ ret c
+
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld d, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld e, [hl]
+ ld a, [hMapObjectIndexBuffer]
+ ld b, a
+ call CopyDECoordsToMapObject
+ and a
+ ret
+
+RefreshPlayerCoords: ; 80b8
+ ld a, [XCoord]
+ add 4
+ ld d, a
+ ld hl, PlayerStandingMapX
+ sub [hl]
+ ld [hl], d
+ ld hl, MapObjects + MAPOBJECT_X_COORD
+ ld [hl], d
+ ld hl, PlayerLastMapX
+ ld [hl], d
+ ld d, a
+ ld a, [YCoord]
+ add 4
+ ld e, a
+ ld hl, PlayerStandingMapY
+ sub [hl]
+ ld [hl], e
+ ld hl, MapObjects + MAPOBJECT_Y_COORD
+ ld [hl], e
+ ld hl, PlayerLastMapY
+ ld [hl], e
+ ld e, a
+ ld a, [wObjectFollow_Leader]
+ cp $0
+ ret nz ; wtf
+ ret
+
+CopyObjectStruct:: ; 80e7
+ call CheckObjectMask
+ and a
+ ret nz ; masked
+
+ ld hl, ObjectStructs + OBJECT_STRUCT_LENGTH * 1
+ ld a, 1
+ ld de, OBJECT_STRUCT_LENGTH
+.loop
+ ld [hObjectStructIndexBuffer], a
+ ld a, [hl]
+ and a
+ jr z, .done
+ add hl, de
+ ld a, [hObjectStructIndexBuffer]
+ inc a
+ cp NUM_OBJECT_STRUCTS
+ jr nz, .loop
+ scf
+ ret ; overflow
+
+.done
+ ld d, h
+ ld e, l
+ call CopyMapObjectToObjectStruct
+ ld hl, VramState
+ bit 7, [hl]
+ ret z
+
+ ld hl, OBJECT_FLAGS2
+ add hl, de
+ set 5, [hl]
+ ret
+
+CopyMapObjectToObjectStruct: ; 8116
+ call .CopyMapObjectToTempObject
+ call CopyTempObjectToObjectStruct
+ ret
+
+.CopyMapObjectToTempObject: ; 811d
+ ld a, [hObjectStructIndexBuffer]
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld [hl], a
+
+ ld a, [hMapObjectIndexBuffer]
+ ld [wTempObjectCopyMapObjectIndex], a
+
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopySprite], a
+
+ call GetSpriteVTile
+ ld [wTempObjectCopySpriteVTile], a
+
+ ld a, [hl]
+ call GetSpritePalette
+ ld [wTempObjectCopyPalette], a
+
+ ld hl, MAPOBJECT_COLOR
+ add hl, bc
+ ld a, [hl]
+ and $f0
+ jr z, .skip_color_override
+ swap a
+ and $7 ; OAM_PALETTE
+ ld [wTempObjectCopyPalette], a
+
+.skip_color_override
+ ld hl, MAPOBJECT_MOVEMENT
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopyMovement], a
+
+ ld hl, MAPOBJECT_RANGE
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopyRange], a
+
+ ld hl, MAPOBJECT_X_COORD
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopyX], a
+
+ ld hl, MAPOBJECT_Y_COORD
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopyY], a
+
+ ld hl, MAPOBJECT_RADIUS
+ add hl, bc
+ ld a, [hl]
+ ld [wTempObjectCopyRadius], a
+ ret
+
+InitializeVisibleSprites: ; 8177
+ ld bc, MapObjects + OBJECT_LENGTH
+ ld a, 1
+.loop
+ ld [hMapObjectIndexBuffer], a
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .next
+
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ cp -1
+ jr nz, .next
+
+ ld a, [XCoord]
+ ld d, a
+ ld a, [YCoord]
+ ld e, a
+
+ ld hl, MAPOBJECT_X_COORD
+ add hl, bc
+ ld a, [hl]
+ add 1
+ sub d
+ jr c, .next
+
+ cp MAPOBJECT_SCREEN_WIDTH
+ jr nc, .next
+
+ ld hl, MAPOBJECT_Y_COORD
+ add hl, bc
+ ld a, [hl]
+ add 1
+ sub e
+ jr c, .next
+
+ cp MAPOBJECT_SCREEN_HEIGHT
+ jr nc, .next
+
+ push bc
+ call CopyObjectStruct
+ pop bc
+ jp c, .ret
+
+.next
+ ld hl, OBJECT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ ld a, [hMapObjectIndexBuffer]
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop
+ ret
+
+.ret: ; 81c9
+ ret
+
+CheckObjectEnteringVisibleRange:: ; 81ca
+ nop
+ ld a, [wPlayerStepDirection]
+ cp STANDING
+ ret z
+ ld hl, .dw
+ rst JumpTable
+ ret
+
+.dw: ; 81d6
+ dw .Down
+ dw .Up
+ dw .Left
+ dw .Right
+
+.Up: ; 81de
+ ld a, [YCoord]
+ sub 1
+ jr .Vertical
+
+.Down: ; 81e5
+ ld a, [YCoord]
+ add 9
+.Vertical: ; 81ea
+ ld d, a
+ ld a, [XCoord]
+ ld e, a
+ ld bc, MapObjects + OBJECT_LENGTH
+ ld a, 1
+.loop_v
+ ld [hMapObjectIndexBuffer], a
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .next_v
+ ld hl, MAPOBJECT_Y_COORD
+ add hl, bc
+ ld a, d
+ cp [hl]
+ jr nz, .next_v
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ cp -1
+ jr nz, .next_v
+ ld hl, MAPOBJECT_X_COORD
+ add hl, bc
+ ld a, [hl]
+ add 1
+ sub e
+ jr c, .next_v
+ cp MAPOBJECT_SCREEN_WIDTH
+ jr nc, .next_v
+ push de
+ push bc
+ call CopyObjectStruct
+ pop bc
+ pop de
+
+.next_v
+ ld hl, OBJECT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ ld a, [hMapObjectIndexBuffer]
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop_v
+ ret
+
+.Left: ; 8232
+ ld a, [XCoord]
+ sub 1
+ jr .Horizontal
+
+.Right: ; 8239
+ ld a, [XCoord]
+ add 10
+.Horizontal: ; 823e
+ ld e, a
+ ld a, [YCoord]
+ ld d, a
+ ld bc, MapObjects + OBJECT_LENGTH
+ ld a, 1
+.loop_h
+ ld [hMapObjectIndexBuffer], a
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .next_h
+ ld hl, MAPOBJECT_X_COORD
+ add hl, bc
+ ld a, e
+ cp [hl]
+ jr nz, .next_h
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ cp -1
+ jr nz, .next_h
+ ld hl, MAPOBJECT_Y_COORD
+ add hl, bc
+ ld a, [hl]
+ add 1
+ sub d
+ jr c, .next_h
+ cp MAPOBJECT_SCREEN_HEIGHT
+ jr nc, .next_h
+ push de
+ push bc
+ call CopyObjectStruct
+ pop bc
+ pop de
+
+.next_h
+ ld hl, OBJECT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ ld a, [hMapObjectIndexBuffer]
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop_h
+ ret
+
+CopyTempObjectToObjectStruct: ; 8286
+ ld a, [wTempObjectCopyMapObjectIndex]
+ ld hl, OBJECT_MAP_OBJECT_INDEX
+ add hl, de
+ ld [hl], a
+
+ ld a, [wTempObjectCopyMovement]
+ call CopySpriteMovementData
+
+ ld a, [wTempObjectCopyPalette]
+ ld hl, OBJECT_PALETTE
+ add hl, de
+ or [hl]
+ ld [hl], a
+
+ ld a, [wTempObjectCopyY]
+ call .InitYCoord
+
+ ld a, [wTempObjectCopyX]
+ call .InitXCoord
+
+ ld a, [wTempObjectCopySprite]
+ ld hl, OBJECT_SPRITE
+ add hl, de
+ ld [hl], a
+
+ ld a, [wTempObjectCopySpriteVTile]
+ ld hl, OBJECT_SPRITE_TILE
+ add hl, de
+ ld [hl], a
+
+ ld hl, OBJECT_STEP_TYPE
+ add hl, de
+ ld [hl], STEP_TYPE_00
+
+ ld hl, OBJECT_FACING_STEP
+ add hl, de
+ ld [hl], STANDING
+
+ ld a, [wTempObjectCopyRadius]
+ call .InitRadius
+
+ ld a, [wTempObjectCopyRange]
+ ld hl, OBJECT_RANGE
+ add hl, de
+ ld [hl], a
+
+ and a
+ ret
+
+.InitYCoord: ; 82d5
+ ld hl, OBJECT_INIT_Y
+ add hl, de
+ ld [hl], a
+
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, de
+ ld [hl], a
+
+ ld hl, YCoord
+ sub [hl]
+ and $f
+ swap a
+ ld hl, wFollowNotExactPersonY
+ sub [hl]
+ ld hl, OBJECT_SPRITE_Y
+ add hl, de
+ ld [hl], a
+ ret
+
+.InitXCoord: ; 82f1
+ ld hl, OBJECT_INIT_X
+ add hl, de
+ ld [hl], a
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, de
+ ld [hl], a
+ ld hl, XCoord
+ sub [hl]
+ and $f
+ swap a
+ ld hl, wFollowNotExactPersonX
+ sub [hl]
+ ld hl, OBJECT_SPRITE_X
+ add hl, de
+ ld [hl], a
+ ret
+
+.InitRadius: ; 830d
+ ld h, a
+ inc a
+ and $f
+ ld l, a
+ ld a, h
+ add $10
+ and $f0
+ or l
+ ld hl, OBJECT_RADIUS
+ add hl, de
+ ld [hl], a
+ ret
+
+TrainerWalkToPlayer: ; 831e
+ ld a, [hLastTalked]
+ call InitMovementBuffer
+ ld a, movement_step_sleep_1
+ call AppendToMovementBuffer
+ ld a, [wd03f]
+ dec a
+ jr z, .TerminateStep
+ ld a, [hLastTalked]
+ ld b, a
+ ld c, PLAYER
+ ld d, 1
+ call .GetPathToPlayer
+ call DecrementMovementBufferCount
+
+.TerminateStep
+ ld a, movement_step_end
+ call AppendToMovementBuffer
+ ret
+
+.GetPathToPlayer: ; 8341
+ push de
+ push bc
+; get player object struct, load to de
+ ld a, c
+ call GetMapObject
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ call GetObjectStruct
+ ld d, b
+ ld e, c
+
+; get last talked object struct, load to bc
+ pop bc
+ ld a, b
+ call GetMapObject
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ call GetObjectStruct
+
+; get last talked coords, load to bc
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld a, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld c, [hl]
+ ld b, a
+
+; get player coords, load to de
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, de
+ ld a, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, de
+ ld e, [hl]
+ ld d, a
+
+ pop af
+ call ComputePathToWalkToPlayer
+ ret
+
+Special_SurfStartStep: ; 8379
+ call InitMovementBuffer
+ call .GetMovementData
+ call AppendToMovementBuffer
+ ld a, movement_step_end
+ call AppendToMovementBuffer
+ ret
+
+.GetMovementData: ; 8388
+ ld a, [PlayerDirection]
+ srl a
+ srl a
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, .movement_data
+ add hl, de
+ ld a, [hl]
+ ret
+
+.movement_data
+ slow_step_down
+ slow_step_up
+ slow_step_left
+ slow_step_right
+
+FollowNotExact:: ; 839e
+ push bc
+ ld a, c
+ call CheckObjectVisibility
+ ld d, b
+ ld e, c
+ pop bc
+ ret c
+
+ ld a, b
+ call CheckObjectVisibility
+ ret c
+
+; Person 2 is now in bc, person 1 is now in de
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld a, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld c, [hl]
+ ld b, a
+
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, de
+ ld a, [hl]
+ cp b
+ jr z, .same_x
+ jr c, .to_the_left
+ inc b
+ jr .continue
+
+.to_the_left
+ dec b
+ jr .continue
+
+.same_x
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, de
+ ld a, [hl]
+ cp c
+ jr z, .continue
+ jr c, .below
+ inc c
+ jr .continue
+
+.below
+ dec c
+
+.continue
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, de
+ ld [hl], b
+ ld a, b
+ ld hl, XCoord
+ sub [hl]
+ and $f
+ swap a
+ ld hl, wFollowNotExactPersonX
+ sub [hl]
+ ld hl, OBJECT_SPRITE_X
+ add hl, de
+ ld [hl], a
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, de
+ ld [hl], c
+ ld a, c
+ ld hl, YCoord
+ sub [hl]
+ and $f
+ swap a
+ ld hl, wFollowNotExactPersonY
+ sub [hl]
+ ld hl, OBJECT_SPRITE_Y
+ add hl, de
+ ld [hl], a
+ ld a, [hObjectStructIndexBuffer]
+ ld hl, OBJECT_RANGE
+ add hl, de
+ ld [hl], a
+ ld hl, OBJECT_MOVEMENTTYPE
+ add hl, de
+ ld [hl], SPRITEMOVEDATA_FOLLOWNOTEXACT
+ ld hl, OBJECT_STEP_TYPE
+ add hl, de
+ ld [hl], STEP_TYPE_00
+ ret
+
+GetRelativeFacing:: ; 8417
+; Determines which way map object e would have to turn to face map object d. Returns carry if it's impossible for whatever reason.
+ ld a, d
+ call GetMapObject
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ cp NUM_OBJECT_STRUCTS
+ jr nc, .carry
+ ld d, a
+ ld a, e
+ call GetMapObject
+ ld hl, MAPOBJECT_OBJECT_STRUCT_ID
+ add hl, bc
+ ld a, [hl]
+ cp NUM_OBJECT_STRUCTS
+ jr nc, .carry
+ ld e, a
+ call .GetFacing_e_relativeto_d
+ ret
+
+.carry
+ scf
+ ret
+
+.GetFacing_e_relativeto_d: ; 8439
+; Determines which way object e would have to turn to face object d. Returns carry if it's impossible.
+; load the coordinates of object d into bc
+ ld a, d
+ call GetObjectStruct
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld a, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld c, [hl]
+ ld b, a
+ push bc
+; load the coordinates of object e into de
+ ld a, e
+ call GetObjectStruct
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld d, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld e, [hl]
+ pop bc
+; |x1 - x2|
+ ld a, b
+ sub d
+ jr z, .same_x_1
+ jr nc, .b_right_of_d_1
+ cpl
+ inc a
+
+.b_right_of_d_1
+; |y1 - y2|
+ ld h, a
+ ld a, c
+ sub e
+ jr z, .same_y_1
+ jr nc, .c_below_e_1
+ cpl
+ inc a
+
+.c_below_e_1
+; |y1 - y2| - |x1 - x2|
+ sub h
+ jr c, .same_y_1
+
+.same_x_1
+; compare the y coordinates
+ ld a, c
+ cp e
+ jr z, .same_x_and_y
+ jr c, .c_directly_below_e
+; c directly above e
+ ld d, DOWN
+ and a
+ ret
+
+.c_directly_below_e
+ ld d, UP
+ and a
+ ret
+
+.same_y_1
+ ld a, b
+ cp d
+ jr z, .same_x_and_y
+ jr c, .b_directly_right_of_d
+; b directly left of d
+ ld d, RIGHT
+ and a
+ ret
+
+.b_directly_right_of_d
+ ld d, LEFT
+ and a
+ ret
+
+.same_x_and_y
+ scf
+ ret
+
+QueueFollowerFirstStep: ; 848a
+ call .QueueFirstStep
+ jr c, .same
+ ld [wFollowMovementQueue], a
+ xor a
+ ld [wFollowerMovementQueueLength], a
+ ret
+
+.same
+ ld a, -1
+ ld [wFollowerMovementQueueLength], a
+ ret
+
+.QueueFirstStep
+ ld a, [wObjectFollow_Leader]
+ call GetObjectStruct
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld d, [hl]
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld e, [hl]
+ ld a, [wObjectFollow_Follower]
+ call GetObjectStruct
+ ld hl, OBJECT_NEXT_MAP_X
+ add hl, bc
+ ld a, d
+ cp [hl]
+ jr z, .check_y
+ jr c, .left
+ and a
+ ld a, movement_step_right
+ ret
+
+.left
+ and a
+ ld a, movement_step_left
+ ret
+
+.check_y
+ ld hl, OBJECT_NEXT_MAP_Y
+ add hl, bc
+ ld a, e
+ cp [hl]
+ jr z, .same_xy
+ jr c, .up
+ and a
+ ld a, movement_step_down
+ ret
+
+.up
+ and a
+ ld a, movement_step_up
+ ret
+
+.same_xy
+ scf
+ ret
--- /dev/null
+++ b/engine/printnum.asm
@@ -1,0 +1,300 @@
+_PrintNum:: ; c4c7
+; Print c digits of the b-byte value from de to hl.
+; Allows 2 to 7 digits. For 1-digit numbers, add
+; the value to char "0" instead of calling PrintNum.
+; Some extra flags can be given in bits 5-7 of b.
+; Bit 5: money if set (unless left-aligned without leading zeros)
+; Bit 6: right-aligned if set
+; Bit 7: print leading zeros if set
+
+ push bc
+
+ bit 5, b
+ jr z, .main
+ bit 7, b
+ jr nz, .moneyflag
+ bit 6, b
+ jr z, .main
+
+.moneyflag ; 101xxxxx or 011xxxxx
+ ld a, "¥"
+ ld [hli], a
+ res 5, b ; 100xxxxx or 010xxxxx
+
+.main
+ xor a
+ ld [hPrintNum1], a
+ ld [hPrintNum2], a
+ ld [hPrintNum3], a
+ ld a, b
+ and $f
+ cp 1
+ jr z, .byte
+ cp 2
+ jr z, .word
+; maximum 3 bytes
+.long
+ ld a, [de]
+ ld [hPrintNum2], a
+ inc de
+ ld a, [de]
+ ld [hPrintNum3], a
+ inc de
+ ld a, [de]
+ ld [hPrintNum4], a
+ jr .start
+
+.word
+ ld a, [de]
+ ld [hPrintNum3], a
+ inc de
+ ld a, [de]
+ ld [hPrintNum4], a
+ jr .start
+
+.byte
+ ld a, [de]
+ ld [hPrintNum4], a
+
+.start
+ push de
+
+ ld d, b
+ ld a, c
+ swap a
+ and $f
+ ld e, a
+ ld a, c
+ and $f
+ ld b, a
+ ld c, 0
+ cp 2
+ jr z, .two
+ cp 3
+ jr z, .three
+ cp 4
+ jr z, .four
+ cp 5
+ jr z, .five
+ cp 6
+ jr z, .six
+
+.seven
+ ld a, 1000000 / $10000 % $100
+ ld [hPrintNum5], a
+ ld a, 1000000 / $100 % $100
+ ld [hPrintNum6], a
+ ld a, 1000000 % $100
+ ld [hPrintNum7], a
+ call .PrintDigit
+ call .AdvancePointer
+
+.six
+ ld a, 100000 / $10000 % $100
+ ld [hPrintNum5], a
+ ld a, 100000 / $100 % $100
+ ld [hPrintNum6], a
+ ld a, 100000 % $100
+ ld [hPrintNum7], a
+ call .PrintDigit
+ call .AdvancePointer
+
+.five
+ xor a
+ ld [hPrintNum5], a
+ ld a, 10000 / $100
+ ld [hPrintNum6], a
+ ld a, 10000 % $100
+ ld [hPrintNum7], a
+ call .PrintDigit
+ call .AdvancePointer
+
+.four
+ xor a
+ ld [hPrintNum5], a
+ ld a, 1000 / $100
+ ld [hPrintNum6], a
+ ld a, 1000 % $100
+ ld [hPrintNum7], a
+ call .PrintDigit
+ call .AdvancePointer
+
+.three
+ xor a
+ ld [hPrintNum5], a
+ xor a
+ ld [hPrintNum6], a
+ ld a, 100
+ ld [hPrintNum7], a
+ call .PrintDigit
+ call .AdvancePointer
+
+.two
+ dec e
+ jr nz, .two_skip
+ ld a, "0"
+ ld [hPrintNum1], a
+.two_skip
+
+ ld c, 0
+ ld a, [hPrintNum4]
+.mod_10
+ cp 10
+ jr c, .modded_10
+ sub 10
+ inc c
+ jr .mod_10
+.modded_10
+
+ ld b, a
+ ld a, [hPrintNum1]
+ or c
+ jr nz, .money
+ call .PrintLeadingZero
+ jr .money_leading_zero
+
+.money
+ call .PrintYen
+ push af
+ ld a, "0"
+ add c
+ ld [hl], a
+ pop af
+ ld [hPrintNum1], a
+ inc e
+ dec e
+ jr nz, .money_leading_zero
+ inc hl
+ ld [hl], $f2 ; XXX
+
+.money_leading_zero
+ call .AdvancePointer
+ call .PrintYen
+ ld a, "0"
+ add b
+ ld [hli], a
+
+ pop de
+ pop bc
+ ret
+
+.PrintYen: ; c5ba
+ push af
+ ld a, [hPrintNum1]
+ and a
+ jr nz, .stop
+ bit 5, d
+ jr z, .stop
+ ld a, "¥"
+ ld [hli], a
+ res 5, d
+
+.stop
+ pop af
+ ret
+
+.PrintDigit: ; c5cb (3:45cb)
+ dec e
+ jr nz, .ok
+ ld a, "0"
+ ld [hPrintNum1], a
+.ok
+ ld c, 0
+.loop
+ ld a, [hPrintNum5]
+ ld b, a
+ ld a, [hPrintNum2]
+ ld [hPrintNum8], a
+ cp b
+ jr c, .skip1
+ sub b
+ ld [hPrintNum2], a
+ ld a, [hPrintNum6]
+ ld b, a
+ ld a, [hPrintNum3]
+ ld [hPrintNum9], a
+ cp b
+ jr nc, .skip2
+ ld a, [hPrintNum2]
+ or 0
+ jr z, .skip3
+ dec a
+ ld [hPrintNum2], a
+ ld a, [hPrintNum3]
+.skip2
+ sub b
+ ld [hPrintNum3], a
+ ld a, [hPrintNum7]
+ ld b, a
+ ld a, [hPrintNum4]
+ ld [hPrintNum10], a
+ cp b
+ jr nc, .skip4
+ ld a, [hPrintNum3]
+ and a
+ jr nz, .skip5
+ ld a, [hPrintNum2]
+ and a
+ jr z, .skip6
+ dec a
+ ld [hPrintNum2], a
+ xor a
+.skip5
+ dec a
+ ld [hPrintNum3], a
+ ld a, [hPrintNum4]
+.skip4
+ sub b
+ ld [hPrintNum4], a
+ inc c
+ jr .loop
+.skip6
+ ld a, [hPrintNum9]
+ ld [hPrintNum3], a
+.skip3
+ ld a, [hPrintNum8]
+ ld [hPrintNum2], a
+.skip1
+ ld a, [hPrintNum1]
+ or c
+ jr z, .PrintLeadingZero
+ ld a, [hPrintNum1]
+ and a
+ jr nz, .done
+ bit 5, d
+ jr z, .done
+ ld a, "¥"
+ ld [hli], a
+ res 5, d
+.done
+ ld a, "0"
+ add c
+ ld [hl], a
+ ld [hPrintNum1], a
+ inc e
+ dec e
+ ret nz
+ inc hl
+ ld [hl], "·"
+ ret
+
+.PrintLeadingZero: ; c644
+; prints a leading zero unless they are turned off in the flags
+ bit 7, d ; print leading zeroes?
+ ret z
+ ld [hl], "0"
+ ret
+
+.AdvancePointer: ; c64a
+; increments the pointer unless leading zeroes are not being printed,
+; the number is left-aligned, and no nonzero digits have been printed yet
+ bit 7, d ; print leading zeroes?
+ jr nz, .inc
+ bit 6, d ; left alignment or right alignment?
+ jr z, .inc
+ ld a, [hPrintNum1]
+ and a
+ ret z
+.inc
+ inc hl
+ ret
--- /dev/null
+++ b/engine/sine.asm
@@ -1,0 +1,50 @@
+_Sine:: ; 84d9
+; A simple sine function.
+; Return d * sin(e) in hl.
+
+; e is a signed 6-bit value.
+ ld a, e
+ and %111111
+ cp %100000
+ jr nc, .negative
+
+ call .ApplySineWave
+ ld a, h
+ ret
+
+.negative
+ and %011111
+ call .ApplySineWave
+ ld a, h
+ xor -1
+ inc a
+ ret
+
+.ApplySineWave: ; 84ef
+ ld e, a
+ ld a, d
+ ld d, 0
+ ld hl, .sinewave
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, 0
+
+; Factor amplitude
+.multiply
+ srl a
+ jr nc, .even
+ add hl, de
+.even
+ sla e
+ rl d
+ and a
+ jr nz, .multiply
+ ret
+
+.sinewave: ; 850b
+; A $20-word table representing a sine wave.
+; 90 degrees is index $10 at a base amplitude of $100.
+ sine_wave $100
--- /dev/null
+++ b/event/happiness_egg.asm
@@ -1,0 +1,238 @@
+GetFirstPokemonHappiness: ; 718d
+ ld hl, PartyMon1Happiness
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld de, PartySpecies
+.loop
+ ld a, [de]
+ cp EGG
+ jr nz, .done
+ inc de
+ add hl, bc
+ jr .loop
+
+.done
+ ld [wd265], a
+ ld a, [hl]
+ ld [ScriptVar], a
+ call GetPokemonName
+ jp CopyPokemonName_Buffer1_Buffer3
+
+CheckFirstMonIsEgg: ; 71ac
+ ld a, [PartySpecies]
+ ld [wd265], a
+ cp EGG
+ ld a, $1
+ jr z, .egg
+ xor a
+
+.egg
+ ld [ScriptVar], a
+ call GetPokemonName
+ jp CopyPokemonName_Buffer1_Buffer3
+
+ChangeHappiness: ; 71c2
+; Perform happiness action c on CurPartyMon
+
+ ld a, [CurPartyMon]
+ inc a
+ ld e, a
+ ld d, 0
+ ld hl, PartySpecies - 1
+ add hl, de
+ ld a, [hl]
+ cp EGG
+ ret z
+
+ push bc
+ ld hl, PartyMon1Happiness
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld a, [CurPartyMon]
+ call AddNTimes
+ pop bc
+
+ ld d, h
+ ld e, l
+
+ push de
+ ld a, [de]
+ cp 100
+ ld e, 0
+ jr c, .ok
+ inc e
+ cp 200
+ jr c, .ok
+ inc e
+
+.ok
+ dec c
+ ld b, 0
+ ld hl, .Actions
+rept 3
+ add hl, bc
+endr
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+ cp 100
+ pop de
+
+ ld a, [de]
+ jr nc, .negative
+ add [hl]
+ jr nc, .done
+ ld a, -1
+ jr .done
+
+.negative
+ add [hl]
+ jr c, .done
+ xor a
+
+.done
+ ld [de], a
+ ld a, [wBattleMode]
+ and a
+ ret z
+ ld a, [CurPartyMon]
+ ld b, a
+ ld a, [wPartyMenuCursor]
+ cp b
+ ret nz
+ ld a, [de]
+ ld [BattleMonHappiness], a
+ ret
+
+.Actions
+ db +5, +3, +2 ; Gained a level
+ db +5, +3, +2 ; Vitamin
+ db +1, +1, +0 ; X Item
+ db +3, +2, +1 ; Battled a Gym Leader
+ db +1, +1, +0 ; Learned a move
+ db -1, -1, -1 ; Lost to an enemy
+ db -5, -5, -10 ; Fainted due to poison
+ db -5, -5, -10 ; Lost to a much stronger enemy
+ db +1, +1, +1 ; Haircut (Y1)
+ db +3, +3, +1 ; Haircut (Y2)
+ db +5, +5, +2 ; Haircut (Y3)
+ db +1, +1, +1 ; Haircut (O1)
+ db +3, +3, +1 ; Haircut (O2)
+ db +10, +10, +4 ; Haircut (O3)
+ db -5, -5, -10 ; Used Heal Powder or Energypowder (bitter)
+ db -10, -10, -15 ; Used Energy Root (bitter)
+ db -15, -15, -20 ; Used Revival Herb (bitter)
+ db +3, +3, +1 ; Grooming
+ db +10, +6, +4 ; Gained a level in the place where it was caught
+
+StepHappiness:: ; 725a
+; Raise the party's happiness by 1 point every other step cycle.
+
+ ld hl, wHappinessStepCount
+ ld a, [hl]
+ inc a
+ and 1
+ ld [hl], a
+ ret nz
+
+ ld de, PartyCount
+ ld a, [de]
+ and a
+ ret z
+
+ ld c, a
+ ld hl, PartyMon1Happiness
+.loop
+ inc de
+ ld a, [de]
+ cp EGG
+ jr z, .next
+ inc [hl]
+ jr nz, .next
+ ld [hl], $ff
+
+.next
+ push de
+ ld de, PARTYMON_STRUCT_LENGTH
+ add hl, de
+ pop de
+ dec c
+ jr nz, .loop
+ ret
+
+DaycareStep:: ; 7282
+
+ ld a, [wDaycareMan]
+ bit 0, a
+ jr z, .daycare_lady
+
+ ld a, [wBreedMon1Level] ; level
+ cp 100
+ jr nc, .daycare_lady
+ ld hl, wBreedMon1Exp + 2 ; exp
+ inc [hl]
+ jr nz, .daycare_lady
+ dec hl
+ inc [hl]
+ jr nz, .daycare_lady
+ dec hl
+ inc [hl]
+ ld a, [hl]
+ cp 5242880 / $10000
+ jr c, .daycare_lady
+ ld a, 5242880 / $10000
+ ld [hl], a
+
+.daycare_lady
+ ld a, [wDaycareLady]
+ bit 0, a
+ jr z, .check_egg
+
+ ld a, [wBreedMon2Level] ; level
+ cp 100
+ jr nc, .check_egg
+ ld hl, wBreedMon2Exp + 2 ; exp
+ inc [hl]
+ jr nz, .check_egg
+ dec hl
+ inc [hl]
+ jr nz, .check_egg
+ dec hl
+ inc [hl]
+ ld a, [hl]
+ cp 5242880 / $10000
+ jr c, .check_egg
+ ld a, 5242880 / $10000
+ ld [hl], a
+
+.check_egg
+ ld hl, wDaycareMan
+ bit 5, [hl] ; egg
+ ret z
+ ld hl, wStepsToEgg
+ dec [hl]
+ ret nz
+
+ call Random
+ ld [hl], a
+ callab CheckBreedmonCompatibility
+ ld a, [wd265]
+ cp 230
+ ld b, -1 + 32 percent
+ jr nc, .okay
+ ld a, [wd265]
+ cp 170
+ ld b, 16 percent
+ jr nc, .okay
+ ld a, [wd265]
+ cp 110
+ ld b, 12 percent
+ jr nc, .okay
+ ld b, 4 percent
+
+.okay
+ call Random
+ cp b
+ ret nc
+ ld hl, wDaycareMan
+ res 5, [hl]
+ set 6, [hl]
+ ret
--- /dev/null
+++ b/event/overworld.asm
@@ -1,0 +1,1890 @@
+FieldMoveJumptableReset: ; c6ea
+ xor a
+ ld hl, Buffer1
+ ld bc, 7
+ call ByteFill
+ ret
+
+FieldMoveJumptable: ; c6f5
+ ld a, [Buffer1]
+ rst JumpTable
+ ld [Buffer1], a
+ bit 7, a
+ jr nz, .okay
+ and a
+ ret
+
+.okay
+ and $7f
+ scf
+ ret
+
+GetPartyNick: ; c706
+; write CurPartyMon nickname to StringBuffer1-3
+ ld hl, PartyMonNicknames
+ ld a, BOXMON
+ ld [MonType], a
+ ld a, [CurPartyMon]
+ call GetNick
+ call CopyName1
+; copy text from StringBuffer2 to StringBuffer3
+ ld de, StringBuffer2
+ ld hl, StringBuffer3
+ call CopyName2
+ ret
+
+CheckEngineFlag: ; c721
+; Check engine flag de
+; Return carry if flag is not set
+ ld b, CHECK_FLAG
+ callba EngineFlagAction
+ ld a, c
+ and a
+ jr nz, .isset
+ scf
+ ret
+.isset
+ xor a
+ ret
+
+CheckBadge: ; c731
+; Check engine flag a (ENGINE_ZEPHYRBADGE thru ENGINE_EARTHBADGE)
+; Display "Badge required" text and return carry if the badge is not owned
+ call CheckEngineFlag
+ ret nc
+ ld hl, .BadgeRequiredText
+ call MenuTextBoxBackup ; push text to queue
+ scf
+ ret
+
+.BadgeRequiredText: ; c73d
+ ; Sorry! A new BADGE
+ ; is required.
+ text_jump _BadgeRequiredText
+ db "@"
+
+CheckPartyMove: ; c742
+; Check if a monster in your party has move d.
+
+ ld e, 0
+ xor a
+ ld [CurPartyMon], a
+.loop
+ ld c, e
+ ld b, 0
+ ld hl, PartySpecies
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .no
+ cp a, -1
+ jr z, .no
+ cp a, EGG
+ jr z, .next
+
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, PartyMon1Moves
+ ld a, e
+ call AddNTimes
+ ld b, NUM_MOVES
+.check
+ ld a, [hli]
+ cp d
+ jr z, .yes
+ dec b
+ jr nz, .check
+
+.next
+ inc e
+ jr .loop
+
+.yes
+ ld a, e
+ ld [CurPartyMon], a ; which mon has the move
+ xor a
+ ret
+.no
+ scf
+ ret
+
+FieldMoveFailed: ; c779
+ ld hl, .CantUseHere
+ call MenuTextBoxBackup
+ ret
+
+.CantUseHere: ; 0xc780
+ ; Can't use that here.
+ text_jump UnknownText_0x1c05c8
+ db "@"
+
+CutFunction: ; c785
+ call FieldMoveJumptableReset
+.loop
+ ld hl, .Jumptable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.Jumptable: ; c796 (3:4796)
+
+ dw .CheckAble
+ dw .DoCut
+ dw .FailCut
+
+.CheckAble: ; c79c (3:479c)
+ ld de, ENGINE_HIVEBADGE
+ call CheckBadge
+ jr c, .nohivebadge
+ call CheckMapForSomethingToCut
+ jr c, .nothingtocut
+ ld a, $1
+ ret
+
+.nohivebadge
+ ld a, $80
+ ret
+
+.nothingtocut
+ ld a, $2
+ ret
+
+.DoCut: ; c7b2 (3:47b2)
+ ld hl, Script_CutFromMenu
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailCut: ; c7bb (3:47bb)
+ ld hl, Text_NothingToCut
+ call MenuTextBoxBackup
+ ld a, $80
+ ret
+
+Text_UsedCut: ; 0xc7c4
+ ; used CUT!
+ text_jump UnknownText_0x1c05dd
+ db "@"
+
+Text_NothingToCut: ; 0xc7c9
+ ; There's nothing to CUT here.
+ text_jump UnknownText_0x1c05ec
+ db "@"
+
+CheckMapForSomethingToCut: ; c7ce
+ ; Does the collision data of the facing tile permit cutting?
+ call GetFacingTileCoord
+ ld c, a
+ push de
+ callba CheckCutCollision
+ pop de
+ jr nc, .fail
+ ; Get the location of the current block in OverworldMap.
+ call GetBlockLocation
+ ld c, [hl]
+ ; See if that block contains something that can be cut.
+ push hl
+ ld hl, CutTreeBlockPointers
+ call CheckOverworldTileArrays
+ pop hl
+ jr nc, .fail
+ ; Back up the OverworldMap address to Buffer3
+ ld a, l
+ ld [Buffer3], a
+ ld a, h
+ ld [Buffer4], a
+ ; Back up the replacement tile to Buffer5
+ ld a, b
+ ld [Buffer5], a
+ ; Back up the animation index to Buffer6
+ ld a, c
+ ld [Buffer6], a
+ xor a
+ ret
+
+.fail
+ scf
+ ret
+
+Script_CutFromMenu: ; c7fe
+ reloadmappart
+ special UpdateTimePals
+
+Script_Cut: ; 0xc802
+ callasm GetPartyNick
+ writetext Text_UsedCut
+ reloadmappart
+ callasm CutDownTreeOrGrass
+ closetext
+ end
+
+CutDownTreeOrGrass: ; c810
+ ld hl, Buffer3 ; OverworldMapTile
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [Buffer5] ; ReplacementTile
+ ld [hl], a
+ xor a
+ ld [hBGMapMode], a
+ call OverworldTextModeSwitch
+ call UpdateSprites
+ call DelayFrame
+ ld a, [Buffer6] ; Animation type
+ ld e, a
+ callba OWCutAnimation
+ call BufferScreen
+ call GetMovementPermissions
+ call UpdateSprites
+ call DelayFrame
+ call LoadStandardFont
+ ret
+
+CheckOverworldTileArrays: ; c840
+ ; Input: c contains the tile you're facing
+ ; Output: Replacement tile in b and effect on wild encounters in c, plus carry set.
+ ; Carry is not set if the facing tile cannot be replaced, or if the tileset
+ ; does not contain a tile you can replace.
+
+ ; Dictionary lookup for pointer to tile replacement table
+ push bc
+ ld a, [wTileset]
+ ld de, 3
+ call IsInArray
+ pop bc
+ jr nc, .nope
+ ; Load the pointer
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ; Look up the tile you're facing
+ ld de, 3
+ ld a, c
+ call IsInArray
+ jr nc, .nope
+ ; Load the replacement to b
+ inc hl
+ ld b, [hl]
+ ; Load the animation type parameter to c
+ inc hl
+ ld c, [hl]
+ scf
+ ret
+
+.nope
+ xor a
+ ret
+
+CutTreeBlockPointers: ; c862
+; Which tileset are we in?
+ dbw TILESET_JOHTO_1, .johto1
+ dbw TILESET_JOHTO_2, .johto2
+ dbw TILESET_KANTO, .kanto
+ dbw TILESET_PARK, .park
+ dbw TILESET_ILEX_FOREST, .ilex
+ db -1
+
+.johto1: ; Johto OW
+; Which meta tile are we facing, which should we replace it with, and which animation?
+ db $03, $02, $01 ; grass
+ db $5b, $3c, $00 ; tree
+ db $5f, $3d, $00 ; tree
+ db $63, $3f, $00 ; tree
+ db $67, $3e, $00 ; tree
+ db -1
+
+.johto2: ; Goldenrod area
+ db $03, $02, $01 ; grass
+ db -1
+
+.kanto: ; Kanto OW
+ db $0b, $0a, $01 ; grass
+ db $32, $6d, $00 ; tree
+ db $33, $6c, $00 ; tree
+ db $34, $6f, $00 ; tree
+ db $35, $4c, $00 ; tree
+ db $60, $6e, $00 ; tree
+ db -1
+
+.park: ; National Park
+ db $13, $03, $01 ; grass
+ db $03, $04, $01 ; grass
+ db -1
+
+.ilex: ; Ilex Forest
+ db $0f, $17, $00
+ db -1
+
+WhirlpoolBlockPointers: ; c8a4
+ dbw TILESET_JOHTO_1, .johto
+ db -1
+
+.johto: ; c8a8
+ db $07, $36, $00
+ db -1
+
+OWFlash: ; c8ac
+ call .CheckUseFlash
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.CheckUseFlash: ; c8b5
+; Flash
+ ld de, ENGINE_ZEPHYRBADGE
+ callba CheckBadge
+ jr c, .nozephyrbadge
+ push hl
+ callba SpecialAerodactylChamber
+ pop hl
+ jr c, .useflash
+ ld a, [wTimeOfDayPalset]
+ cp %11111111 ; 3, 3, 3, 3
+ jr nz, .notadarkcave
+.useflash
+ call UseFlash
+ ld a, $81
+ ret
+
+.notadarkcave
+ call FieldMoveFailed
+ ld a, $80
+ ret
+
+.nozephyrbadge
+ ld a, $80
+ ret
+
+UseFlash: ; c8e0
+ ld hl, Script_UseFlash
+ jp QueueScript
+
+Script_UseFlash: ; 0xc8e6
+ reloadmappart
+ special UpdateTimePals
+ writetext UnknownText_0xc8f3
+ callasm BlindingFlash
+ closetext
+ end
+
+UnknownText_0xc8f3: ; 0xc8f3
+ text_jump UnknownText_0x1c0609
+ start_asm
+ call WaitSFX
+ ld de, SFX_FLASH
+ call PlaySFX
+ call WaitSFX
+ ld hl, .BlankText
+ ret
+
+.BlankText: ; 0xc908
+ db "@"
+
+SurfFunction: ; c909
+ call FieldMoveJumptableReset
+.loop
+ ld hl, .Jumptable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.Jumptable: ; c91a (3:491a)
+ dw .TrySurf
+ dw .DoSurf
+ dw .FailSurf
+ dw .AlreadySurfing
+
+.TrySurf: ; c922 (3:4922)
+ ld de, ENGINE_FOGBADGE
+ call CheckBadge
+ jr c, .asm_c956
+ ld hl, BikeFlags
+ bit 1, [hl] ; always on bike
+ jr nz, .cannotsurf
+ ld a, [PlayerState]
+ cp PLAYER_SURF
+ jr z, .alreadyfail
+ cp PLAYER_SURF_PIKA
+ jr z, .alreadyfail
+ call GetFacingTileCoord
+ call GetTileCollision
+ cp $1
+ jr nz, .cannotsurf
+ call CheckDirection
+ jr c, .cannotsurf
+ callba CheckFacingObject
+ jr c, .cannotsurf
+ ld a, $1
+ ret
+.asm_c956
+ ld a, $80
+ ret
+.alreadyfail
+ ld a, $3
+ ret
+.cannotsurf
+ ld a, $2
+ ret
+
+.DoSurf: ; c95f (3:495f)
+ call GetSurfType
+ ld [Buffer2], a ; wd1eb (aliases: MovementType)
+ call GetPartyNick
+ ld hl, SurfFromMenuScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailSurf: ; c971 (3:4971)
+ ld hl, CantSurfText
+ call MenuTextBoxBackup
+ ld a, $80
+ ret
+
+.AlreadySurfing: ; c97a (3:497a)
+ ld hl, AlreadySurfingText
+ call MenuTextBoxBackup
+ ld a, $80
+ ret
+
+SurfFromMenuScript: ; c983
+ special UpdateTimePals
+
+UsedSurfScript: ; c986
+ writetext UsedSurfText ; "used SURF!"
+ waitbutton
+ closetext
+
+ callasm .empty_fn ; empty function
+
+ copybytetovar Buffer2
+ writevarcode VAR_MOVEMENT
+
+ special ReplaceKrisSprite
+ special PlayMapMusic
+; step into the water
+ special Special_SurfStartStep ; (slow_step_x, step_end)
+ applymovement PLAYER, MovementBuffer ; PLAYER, MovementBuffer
+ end
+
+.empty_fn: ; c9a2
+ callba MobileFn_1060bb ; empty
+ ret
+
+UsedSurfText: ; c9a9
+ text_jump _UsedSurfText
+ db "@"
+
+CantSurfText: ; c9ae
+ text_jump _CantSurfText
+ db "@"
+
+AlreadySurfingText: ; c9b3
+ text_jump _AlreadySurfingText
+ db "@"
+
+GetSurfType: ; c9b8
+; Surfing on Pikachu uses an alternate sprite.
+; This is done by using a separate movement type.
+
+ ld a, [CurPartyMon]
+ ld e, a
+ ld d, 0
+ ld hl, PartySpecies
+ add hl, de
+
+ ld a, [hl]
+ cp PIKACHU
+ ld a, PLAYER_SURF_PIKA
+ ret z
+ ld a, PLAYER_SURF
+ ret
+
+CheckDirection: ; c9cb
+; Return carry if a tile permission prevents you
+; from moving in the direction you're facing.
+
+; Get player direction
+ ld a, [PlayerDirection]
+ and a, %00001100 ; bits 2 and 3 contain direction
+ rrca
+ rrca
+ ld e, a
+ ld d, 0
+ ld hl, .Directions
+ add hl, de
+
+; Can you walk in this direction?
+ ld a, [TilePermissions]
+ and [hl]
+ jr nz, .quit
+ xor a
+ ret
+
+.quit
+ scf
+ ret
+
+.Directions
+ db FACE_DOWN
+ db FACE_UP
+ db FACE_LEFT
+ db FACE_RIGHT
+
+TrySurfOW:: ; c9e7
+; Checking a tile in the overworld.
+; Return carry if fail is allowed.
+
+; Don't ask to surf if already fail.
+ ld a, [PlayerState]
+ cp PLAYER_SURF_PIKA
+ jr z, .quit
+ cp PLAYER_SURF
+ jr z, .quit
+
+; Must be facing water.
+ ld a, [EngineBuffer1]
+ call GetTileCollision
+ cp 1 ; surfable
+ jr nz, .quit
+
+; Check tile permissions.
+ call CheckDirection
+ jr c, .quit
+
+ ld de, ENGINE_FOGBADGE
+ call CheckEngineFlag
+ jr c, .quit
+
+ ld d, SURF
+ call CheckPartyMove
+ jr c, .quit
+
+ ld hl, BikeFlags
+ bit 1, [hl] ; always on bike (can't surf)
+ jr nz, .quit
+
+ call GetSurfType
+ ld [MovementType], a
+ call GetPartyNick
+
+ ld a, BANK(AskSurfScript)
+ ld hl, AskSurfScript
+ call CallScript
+
+ scf
+ ret
+
+.quit
+ xor a
+ ret
+
+AskSurfScript: ; ca2c
+ opentext
+ writetext AskSurfText
+ yesorno
+ iftrue UsedSurfScript
+ closetext
+ end
+
+AskSurfText: ; ca36
+ text_jump _AskSurfText ; The water is calm.
+ db "@" ; Want to SURF?
+
+FlyFunction: ; ca3b
+ call FieldMoveJumptableReset
+.loop
+ ld hl, .Jumptable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.Jumptable
+ dw .TryFly
+ dw .DoFly
+ dw .FailFly
+
+.TryFly: ; ca52
+; Fly
+ ld de, ENGINE_STORMBADGE
+ call CheckBadge
+ jr c, .nostormbadge
+ call GetMapPermission
+ call CheckOutdoorMap
+ jr z, .outdoors
+ jr .indoors
+
+.outdoors
+ xor a
+ ld [hMapAnims], a
+ call LoadStandardMenuDataHeader
+ call ClearSprites
+ callba _FlyMap
+ ld a, e
+ cp -1
+ jr z, .illegal
+ cp NUM_SPAWNS
+ jr nc, .illegal
+
+ ld [wd001], a
+ call CloseWindow
+ ld a, $1
+ ret
+
+.nostormbadge
+ ld a, $82
+ ret
+
+.indoors
+ ld a, $2
+ ret
+
+.illegal
+ call CloseWindow
+ call WaitBGMap
+ ld a, $80
+ ret
+
+.DoFly: ; ca94
+ ld hl, .FlyScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailFly: ; ca9d
+ call FieldMoveFailed
+ ld a, $82
+ ret
+
+.FlyScript: ; 0xcaa3
+ reloadmappart
+ callasm HideSprites
+ special UpdateTimePals
+ callasm FlyFromAnim
+ farscall Script_AbortBugContest
+ special WarpToSpawnPoint
+ callasm DelayLoadingNewSprites
+ writecode VAR_MOVEMENT, PLAYER_NORMAL
+ newloadmap MAPSETUP_FLY
+ callasm FlyToAnim
+ special WaitSFX
+ callasm .ReturnFromFly
+ end
+
+.ReturnFromFly: ; cacb
+ callba Function561d
+ call DelayFrame
+ call ReplaceKrisSprite
+ callba LoadOverworldFont
+ ret
+
+WaterfallFunction: ; cade
+ call .TryWaterfall
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.TryWaterfall: ; cae7
+; Waterfall
+ ld de, ENGINE_RISINGBADGE
+ callba CheckBadge
+ ld a, $80
+ ret c
+ call CheckMapCanWaterfall
+ jr c, .failed
+ ld hl, Script_WaterfallFromMenu
+ call QueueScript
+ ld a, $81
+ ret
+
+.failed
+ call FieldMoveFailed
+ ld a, $80
+ ret
+
+CheckMapCanWaterfall: ; cb07
+ ld a, [PlayerDirection]
+ and $c
+ cp FACE_UP
+ jr nz, .failed
+ ld a, [TileUp]
+ call CheckWaterfallTile
+ jr nz, .failed
+ xor a
+ ret
+
+.failed
+ scf
+ ret
+
+Script_WaterfallFromMenu: ; 0xcb1c
+ reloadmappart
+ special UpdateTimePals
+
+Script_UsedWaterfall: ; 0xcb20
+ callasm GetPartyNick
+ writetext .Text_UsedWaterfall
+ waitbutton
+ closetext
+ playsound SFX_BUBBLEBEAM
+.loop
+ applymovement PLAYER, .WaterfallStep
+ callasm .CheckContinueWaterfall
+ iffalse .loop
+ end
+
+.CheckContinueWaterfall: ; cb38
+ xor a
+ ld [ScriptVar], a
+ ld a, [PlayerStandingTile]
+ call CheckWaterfallTile
+ ret z
+ callba MobileFn_1060c1
+ ld a, $1
+ ld [ScriptVar], a
+ ret
+
+.WaterfallStep: ; cb4f
+ turn_waterfall_up
+ step_end
+
+.Text_UsedWaterfall: ; 0xcb51
+ ; used WATERFALL!
+ text_jump UnknownText_0x1c068e
+ db "@"
+
+TryWaterfallOW:: ; cb56
+ ld d, WATERFALL
+ call CheckPartyMove
+ jr c, .failed
+ ld de, ENGINE_RISINGBADGE
+ call CheckEngineFlag
+ jr c, .failed
+ call CheckMapCanWaterfall
+ jr c, .failed
+ ld a, BANK(Script_AskWaterfall)
+ ld hl, Script_AskWaterfall
+ call CallScript
+ scf
+ ret
+
+.failed
+ ld a, BANK(Script_CantDoWaterfall)
+ ld hl, Script_CantDoWaterfall
+ call CallScript
+ scf
+ ret
+
+Script_CantDoWaterfall: ; 0xcb7e
+ jumptext .Text_CantDoWaterfall
+
+.Text_CantDoWaterfall: ; 0xcb81
+ ; Wow, it's a huge waterfall.
+ text_jump UnknownText_0x1c06a3
+ db "@"
+
+Script_AskWaterfall: ; 0xcb86
+ opentext
+ writetext .AskUseWaterfall
+ yesorno
+ iftrue Script_UsedWaterfall
+ closetext
+ end
+
+.AskUseWaterfall: ; 0xcb90
+ ; Do you want to use WATERFALL?
+ text_jump UnknownText_0x1c06bf
+ db "@"
+
+EscapeRopeFunction: ; cb95
+ call FieldMoveJumptableReset
+ ld a, $1
+ jr dig_incave
+
+DigFunction: ; cb9c
+ call FieldMoveJumptableReset
+ ld a, $2
+
+dig_incave
+ ld [Buffer2], a
+.loop
+ ld hl, .DigTable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.DigTable: ; cbb2
+ dw .CheckCanDig
+ dw .DoDig
+ dw .FailDig
+
+.CheckCanDig: ; cbb8
+ call GetMapPermission
+ cp CAVE
+ jr z, .incave
+ cp DUNGEON
+ jr z, .incave
+.fail
+ ld a, $2
+ ret
+
+.incave
+ ld hl, wDigWarp
+ ld a, [hli]
+ and a
+ jr z, .fail
+ ld a, [hli]
+ and a
+ jr z, .fail
+ ld a, [hl]
+ and a
+ jr z, .fail
+ ld a, $1
+ ret
+
+.DoDig: ; cbd8
+ ld hl, wDigWarp
+ ld de, wNextWarp
+ ld bc, 3
+ call CopyBytes
+ call GetPartyNick
+ ld a, [Buffer2]
+ cp $2
+ jr nz, .escaperope
+ ld hl, .UsedDigScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.escaperope
+ callba SpecialKabutoChamber
+ ld hl, .UsedEscapeRopeScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailDig: ; cc06
+ ld a, [Buffer2]
+ cp $2
+ jr nz, .failescaperope
+ ld hl, .Text_CantUseHere
+ call MenuTextBox
+ call WaitPressAorB_BlinkCursor
+ call CloseWindow
+
+.failescaperope
+ ld a, $80
+ ret
+
+.Text_UsedDig: ; 0xcc1c
+ ; used DIG!
+ text_jump UnknownText_0x1c06de
+ db "@"
+
+.Text_UsedEscapeRope: ; 0xcc21
+ ; used an ESCAPE ROPE.
+ text_jump UnknownText_0x1c06ed
+ db "@"
+
+.Text_CantUseHere: ; 0xcc26
+ ; Can't use that here.
+ text_jump UnknownText_0x1c0705
+ db "@"
+
+.UsedEscapeRopeScript: ; 0xcc2b
+ reloadmappart
+ special UpdateTimePals
+ writetext .Text_UsedEscapeRope
+ jump .UsedDigOrEscapeRopeScript
+
+.UsedDigScript: ; 0xcc35
+ reloadmappart
+ special UpdateTimePals
+ writetext .Text_UsedDig
+
+.UsedDigOrEscapeRopeScript: ; 0xcc3c
+ waitbutton
+ closetext
+ playsound SFX_WARP_TO
+ applymovement PLAYER, .DigOut
+ farscall Script_AbortBugContest
+ special WarpToSpawnPoint
+ writecode VAR_MOVEMENT, PLAYER_NORMAL
+ newloadmap MAPSETUP_DOOR
+ playsound SFX_WARP_FROM
+ applymovement PLAYER, .DigReturn
+ end
+
+.DigOut: ; 0xcc59
+ step_dig 32
+ hide_person
+ step_end
+
+.DigReturn: ; 0xcc5d
+ show_person
+ return_dig 32
+ step_end
+
+TeleportFunction: ; cc61
+ call FieldMoveJumptableReset
+.loop
+ ld hl, .Jumptable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.Jumptable: ; cc72
+ dw .TryTeleport
+ dw .DoTeleport
+ dw .FailTeleport
+
+.TryTeleport: ; cc78
+ call GetMapPermission
+ call CheckOutdoorMap
+ jr z, .CheckIfSpawnPoint
+ jr .nope
+
+.CheckIfSpawnPoint
+ ld a, [wLastSpawnMapGroup]
+ ld d, a
+ ld a, [wLastSpawnMapNumber]
+ ld e, a
+ callba IsSpawnPoint
+ jr nc, .nope
+ ld a, c
+ ld [wd001], a
+ ld a, $1
+ ret
+
+.nope
+ ld a, $2
+ ret
+
+.DoTeleport: ; cc9c
+ call GetPartyNick
+ ld hl, .TeleportScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailTeleport: ; cca8
+ ld hl, .Text_CantUseHere
+ call MenuTextBoxBackup
+ ld a, $80
+ ret
+
+.Text_ReturnToLastMonCenter: ; 0xccb1
+ ; Return to the last #MON CENTER.
+ text_jump UnknownText_0x1c071a
+ db "@"
+
+.Text_CantUseHere: ; 0xccb6
+ ; Can't use that here.
+ text_jump UnknownText_0x1c073b
+ db "@"
+
+.TeleportScript: ; 0xccbb
+ reloadmappart
+ special UpdateTimePals
+ writetext .Text_ReturnToLastMonCenter
+ pause 60
+ reloadmappart
+ closetext
+ playsound SFX_WARP_TO
+ applymovement PLAYER, .TeleportFrom
+ farscall Script_AbortBugContest
+ special WarpToSpawnPoint
+ writecode VAR_MOVEMENT, PLAYER_NORMAL
+ newloadmap MAPSETUP_TELEPORT
+ playsound SFX_WARP_FROM
+ applymovement PLAYER, .TeleportTo
+ end
+
+.TeleportFrom: ; cce1
+ teleport_from
+ step_end
+
+.TeleportTo: ; cce3
+ teleport_to
+ step_end
+
+StrengthFunction: ; cce5
+ call .TryStrength
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.TryStrength: ; ccee
+; Strength
+ ld de, ENGINE_PLAINBADGE
+ call CheckBadge
+ jr c, .Failed
+ jr .UseStrength
+
+.AlreadyUsing: ; unreferenced
+ ld hl, .JumpText
+ call MenuTextBoxBackup
+ ld a, $80
+ ret
+
+.JumpText: ; 0xcd01
+ text_jump UnknownText_0x1c0751
+ db "@"
+
+.Failed: ; cd06
+ ld a, $80
+ ret
+
+.UseStrength: ; cd09
+ ld hl, Script_StrengthFromMenu
+ call QueueScript
+ ld a, $81
+ ret
+
+SetStrengthFlag: ; cd12
+ ld hl, BikeFlags
+ set 0, [hl]
+ ld a, [CurPartyMon]
+ ld e, a
+ ld d, 0
+ ld hl, PartySpecies
+ add hl, de
+ ld a, [hl]
+ ld [Buffer6], a
+ call GetPartyNick
+ ret
+
+Script_StrengthFromMenu: ; 0xcd29
+ reloadmappart
+ special UpdateTimePals
+
+Script_UsedStrength: ; 0xcd2d
+ callasm SetStrengthFlag
+ writetext .UsedStrength
+ copybytetovar Buffer6
+ cry 0
+ pause 3
+ writetext .StrengthAllowedItToMoveBoulders
+ closetext
+ end
+
+.UsedStrength: ; 0xcd41
+ text_jump UnknownText_0x1c0774
+ db "@"
+
+.StrengthAllowedItToMoveBoulders: ; 0xcd46
+ text_jump UnknownText_0x1c0788
+ db "@"
+
+AskStrengthScript:
+ callasm TryStrengthOW
+ iffalse .AskStrength
+ if_equal $1, .DontMeetRequirements
+ jump .AlreadyUsedStrength
+
+.DontMeetRequirements: ; 0xcd59
+ jumptext UnknownText_0xcd73
+
+.AlreadyUsedStrength: ; 0xcd5c
+ jumptext UnknownText_0xcd6e
+
+.AskStrength: ; 0xcd5f
+ opentext
+ writetext UnknownText_0xcd69
+ yesorno
+ iftrue Script_UsedStrength
+ closetext
+ end
+
+UnknownText_0xcd69: ; 0xcd69
+ ; A #MON may be able to move this. Want to use STRENGTH?
+ text_jump UnknownText_0x1c07a0
+ db "@"
+
+UnknownText_0xcd6e: ; 0xcd6e
+ ; Boulders may now be moved!
+ text_jump UnknownText_0x1c07d8
+ db "@"
+
+UnknownText_0xcd73: ; 0xcd73
+ ; A #MON may be able to move this.
+ text_jump UnknownText_0x1c07f4
+ db "@"
+
+TryStrengthOW: ; cd78
+ ld d, STRENGTH
+ call CheckPartyMove
+ jr c, .nope
+
+ ld de, ENGINE_PLAINBADGE
+ call CheckEngineFlag
+ jr c, .nope
+
+ ld hl, BikeFlags
+ bit 0, [hl]
+ jr z, .already_using
+
+ ld a, 2
+ jr .done
+
+.nope
+ ld a, 1
+ jr .done
+
+.already_using
+ xor a
+ jr .done
+
+.done
+ ld [ScriptVar], a
+ ret
+
+WhirlpoolFunction: ; cd9d
+ call FieldMoveJumptableReset
+.loop
+ ld hl, Jumptable_cdae
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+Jumptable_cdae: ; cdae
+ dw .TryWhirlpool
+ dw .DoWhirlpool
+ dw .FailWhirlpool
+
+.TryWhirlpool: ; cdb4
+ ld de, ENGINE_GLACIERBADGE
+ call CheckBadge
+ jr c, .noglacierbadge
+ call TryWhirlpoolMenu
+ jr c, .failed
+ ld a, $1
+ ret
+
+.failed
+ ld a, $2
+ ret
+
+.noglacierbadge
+ ld a, $80
+ ret
+
+.DoWhirlpool: ; cdca
+ ld hl, Script_WhirlpoolFromMenu
+ call QueueScript
+ ld a, $81
+ ret
+
+.FailWhirlpool: ; cdd3
+ call FieldMoveFailed
+ ld a, $80
+ ret
+
+Text_UsedWhirlpool: ; 0xcdd9
+ ; used WHIRLPOOL!
+ text_jump UnknownText_0x1c0816
+ db "@"
+
+TryWhirlpoolMenu: ; cdde
+ call GetFacingTileCoord
+ ld c, a
+ push de
+ call CheckWhirlpoolTile
+ pop de
+ jr c, .failed
+ call GetBlockLocation
+ ld c, [hl]
+ push hl
+ ld hl, WhirlpoolBlockPointers
+ call CheckOverworldTileArrays
+ pop hl
+ jr nc, .failed
+ ld a, l
+ ld [Buffer3], a
+ ld a, h
+ ld [Buffer4], a
+ ld a, b
+ ld [Buffer5], a
+ ld a, c
+ ld [Buffer6], a
+ xor a
+ ret
+
+.failed
+ scf
+ ret
+
+Script_WhirlpoolFromMenu: ; 0xce0b
+ reloadmappart
+ special UpdateTimePals
+
+Script_UsedWhirlpool: ; 0xce0f
+ callasm GetPartyNick
+ writetext Text_UsedWhirlpool
+ reloadmappart
+ callasm DisappearWhirlpool
+ closetext
+ end
+
+DisappearWhirlpool: ; ce1d
+ ld hl, Buffer3
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [Buffer5]
+ ld [hl], a
+ xor a
+ ld [hBGMapMode], a
+ call OverworldTextModeSwitch
+ ld a, [Buffer6]
+ ld e, a
+ callba PlayWhirlpoolSound
+ call BufferScreen
+ call GetMovementPermissions
+ ret
+
+TryWhirlpoolOW:: ; ce3e
+ ld d, WHIRLPOOL
+ call CheckPartyMove
+ jr c, .failed
+ ld de, ENGINE_GLACIERBADGE
+ call CheckEngineFlag
+ jr c, .failed
+ call TryWhirlpoolMenu
+ jr c, .failed
+ ld a, BANK(Script_AskWhirlpoolOW)
+ ld hl, Script_AskWhirlpoolOW
+ call CallScript
+ scf
+ ret
+
+.failed
+ ld a, BANK(Script_MightyWhirlpool)
+ ld hl, Script_MightyWhirlpool
+ call CallScript
+ scf
+ ret
+
+Script_MightyWhirlpool: ; 0xce66
+ jumptext .MightyWhirlpoolText
+
+.MightyWhirlpoolText: ; 0xce69
+ text_jump UnknownText_0x1c082b
+ db "@"
+
+Script_AskWhirlpoolOW: ; 0xce6e
+ opentext
+ writetext UnknownText_0xce78
+ yesorno
+ iftrue Script_UsedWhirlpool
+ closetext
+ end
+
+UnknownText_0xce78: ; 0xce78
+ text_jump UnknownText_0x1c0864
+ db "@"
+
+HeadbuttFunction: ; ce7d
+ call TryHeadbuttFromMenu
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+TryHeadbuttFromMenu: ; ce86
+ call GetFacingTileCoord
+ call CheckHeadbuttTreeTile
+ jr nz, .no_tree
+
+ ld hl, HeadbuttFromMenuScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.no_tree
+ call FieldMoveFailed
+ ld a, $80
+ ret
+
+UnknownText_0xce9d: ; 0xce9d
+ ; did a HEADBUTT!
+ text_jump UnknownText_0x1c0897
+ db "@"
+
+UnknownText_0xcea2: ; 0xcea2
+ ; Nope. Nothing…
+ text_jump UnknownText_0x1c08ac
+ db "@"
+
+HeadbuttFromMenuScript: ; 0xcea7
+ reloadmappart
+ special UpdateTimePals
+
+HeadbuttScript: ; 0xceab
+ callasm GetPartyNick
+ writetext UnknownText_0xce9d
+
+ reloadmappart
+ callasm ShakeHeadbuttTree
+
+ callasm TreeMonEncounter
+ iffalse .no_battle
+ closetext
+ randomwildmon
+ startbattle
+ reloadmapafterbattle
+ end
+
+.no_battle
+ writetext UnknownText_0xcea2
+ waitbutton
+ closetext
+ end
+
+TryHeadbuttOW:: ; cec9
+ ld d, HEADBUTT
+ call CheckPartyMove
+ jr c, .no
+
+ ld a, BANK(AskHeadbuttScript)
+ ld hl, AskHeadbuttScript
+ call CallScript
+ scf
+ ret
+
+.no
+ xor a
+ ret
+
+AskHeadbuttScript: ; 0xcedc
+ opentext
+ writetext UnknownText_0xcee6
+ yesorno
+ iftrue HeadbuttScript
+ closetext
+ end
+
+UnknownText_0xcee6: ; 0xcee6
+ ; A #MON could be in this tree. Want to HEADBUTT it?
+ text_jump UnknownText_0x1c08bc
+ db "@"
+
+RockSmashFunction: ; ceeb
+ call TryRockSmashFromMenu
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+TryRockSmashFromMenu: ; cef4
+ call GetFacingObject
+ jr c, .no_rock
+ ld a, d
+ cp $18
+ jr nz, .no_rock
+
+ ld hl, RockSmashFromMenuScript
+ call QueueScript
+ ld a, $81
+ ret
+
+.no_rock
+ call FieldMoveFailed
+ ld a, $80
+ ret
+
+GetFacingObject: ; cf0d
+ callba CheckFacingObject
+ jr nc, .fail
+
+ ld a, [hObjectStructIndexBuffer]
+ call GetObjectStruct
+ ld hl, OBJECT_MAP_OBJECT_INDEX
+ add hl, bc
+ ld a, [hl]
+ ld [hLastTalked], a
+ call GetMapObject
+ ld hl, MAPOBJECT_MOVEMENT
+ add hl, bc
+ ld a, [hl]
+ ld d, a
+ and a
+ ret
+
+.fail
+ scf
+ ret
+
+RockSmashFromMenuScript: ; 0xcf2e
+ reloadmappart
+ special UpdateTimePals
+
+RockSmashScript: ; cf32
+ callasm GetPartyNick
+ writetext UnknownText_0xcf58
+ closetext
+ special WaitSFX
+ playsound SFX_STRENGTH
+ earthquake 84
+ applymovement2 MovementData_0xcf55
+ disappear -2
+
+ callasm RockMonEncounter
+ copybytetovar TempWildMonSpecies
+ iffalse .done
+ randomwildmon
+ startbattle
+ reloadmapafterbattle
+.done
+ end
+
+MovementData_0xcf55: ; 0xcf55
+ rock_smash 10
+ step_end
+
+UnknownText_0xcf58: ; 0xcf58
+ text_jump UnknownText_0x1c08f0
+ db "@"
+
+AskRockSmashScript: ; 0xcf5d
+ callasm HasRockSmash
+ if_equal 1, .no
+
+ opentext
+ writetext UnknownText_0xcf77
+ yesorno
+ iftrue RockSmashScript
+ closetext
+ end
+.no
+ jumptext UnknownText_0xcf72
+
+UnknownText_0xcf72: ; 0xcf72
+ ; Maybe a #MON can break this.
+ text_jump UnknownText_0x1c0906
+ db "@"
+
+UnknownText_0xcf77: ; 0xcf77
+ ; This rock looks breakable. Want to use ROCK SMASH?
+ text_jump UnknownText_0x1c0924
+ db "@"
+
+HasRockSmash: ; cf7c
+ ld d, ROCK_SMASH
+ call CheckPartyMove
+ jr nc, .yes
+.no
+ ld a, 1
+ jr .done
+.yes
+ xor a
+ jr .done
+.done
+ ld [ScriptVar], a
+ ret
+
+FishFunction: ; cf8e
+ ld a, e
+ push af
+ call FieldMoveJumptableReset
+ pop af
+ ld [Buffer2], a
+.loop
+ ld hl, .FishTable
+ call FieldMoveJumptable
+ jr nc, .loop
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.FishTable: ; cfa5
+ dw .TryFish
+ dw .FishNoBite
+ dw .FishGotSomething
+ dw .FailFish
+ dw .FishNoFish
+
+.TryFish: ; cfaf
+ ld a, [PlayerState]
+ cp PLAYER_SURF
+ jr z, .fail
+ cp PLAYER_SURF_PIKA
+ jr z, .fail
+ call GetFacingTileCoord
+ call GetTileCollision
+ cp $1
+ jr z, .facingwater
+.fail
+ ld a, $3
+ ret
+
+.facingwater
+ call GetFishingGroup
+ and a
+ jr nz, .goodtofish
+ ld a, $4
+ ret
+
+.goodtofish
+ ld d, a
+ ld a, [Buffer2]
+ ld e, a
+ callba Fish
+ ld a, d
+ and a
+ jr z, .nonibble
+ ld [TempWildMonSpecies], a
+ ld a, e
+ ld [CurPartyLevel], a
+ ld a, BATTLETYPE_FISH
+ ld [BattleType], a
+ ld a, $2
+ ret
+
+.nonibble
+ ld a, $1
+ ret
+
+.FailFish: ; cff1
+ ld a, $80
+ ret
+
+.FishGotSomething: ; cff4
+ ld a, $1
+ ld [Buffer6], a
+ ld hl, Script_GotABite
+ call QueueScript
+ ld a, $81
+ ret
+
+.FishNoBite: ; d002
+ ld a, $2
+ ld [Buffer6], a
+ ld hl, Script_NotEvenANibble
+ call QueueScript
+ ld a, $81
+ ret
+
+.FishNoFish: ; d010
+ ld a, $0
+ ld [Buffer6], a
+ ld hl, Script_NotEvenANibble2
+ call QueueScript
+ ld a, $81
+ ret
+
+Script_NotEvenANibble: ; 0xd01e
+ scall Script_FishCastRod
+ writetext UnknownText_0xd0a9
+ jump Script_NotEvenANibble_FallThrough
+
+Script_NotEvenANibble2: ; 0xd027
+ scall Script_FishCastRod
+ writetext UnknownText_0xd0a9
+
+Script_NotEvenANibble_FallThrough: ; 0xd02d
+ loademote EMOTE_SHADOW
+ callasm PutTheRodAway
+ closetext
+ end
+
+Script_GotABite: ; 0xd035
+ scall Script_FishCastRod
+ callasm Fishing_CheckFacingUp
+ iffalse .NotFacingUp
+ applymovement PLAYER, .Movement_FacingUp
+ jump .FightTheHookedPokemon
+
+.NotFacingUp: ; 0xd046
+ applymovement PLAYER, .Movement_NotFacingUp
+
+.FightTheHookedPokemon: ; 0xd04a
+ pause 40
+ applymovement PLAYER, .Movement_RestoreRod
+ writetext UnknownText_0xd0a4
+ callasm PutTheRodAway
+ closetext
+ randomwildmon
+ startbattle
+ reloadmapafterbattle
+ end
+
+.Movement_NotFacingUp: ; d05c
+ fish_got_bite
+ fish_got_bite
+ fish_got_bite
+ fish_got_bite
+ show_emote
+ step_end
+
+.Movement_FacingUp: ; d062
+ fish_got_bite
+ fish_got_bite
+ fish_got_bite
+ fish_got_bite
+ step_sleep_1
+ show_emote
+ step_end
+
+.Movement_RestoreRod: ; d069
+ hide_emote
+ fish_cast_rod
+ step_end
+
+Fishing_CheckFacingUp: ; d06c
+ ld a, [PlayerDirection]
+ and $c
+ cp OW_UP
+ ld a, $1
+ jr z, .up
+ xor a
+
+.up
+ ld [ScriptVar], a
+ ret
+
+Script_FishCastRod: ; 0xd07c
+ reloadmappart
+ loadvar hBGMapMode, $0
+ special UpdateTimePals
+ loademote EMOTE_ROD
+ callasm LoadFishingGFX
+ loademote EMOTE_SHOCK
+ applymovement PLAYER, MovementData_0xd093
+ pause 40
+ end
+
+MovementData_0xd093: ; d093
+ fish_cast_rod
+ step_end
+
+PutTheRodAway: ; d095
+ xor a
+ ld [hBGMapMode], a
+ ld a, $1
+ ld [PlayerAction], a
+ call UpdateSprites
+ call ReplaceKrisSprite
+ ret
+
+UnknownText_0xd0a4: ; 0xd0a4
+ ; Oh! A bite!
+ text_jump UnknownText_0x1c0958
+ db "@"
+
+UnknownText_0xd0a9: ; 0xd0a9
+ ; Not even a nibble!
+ text_jump UnknownText_0x1c0965
+ db "@"
+
+UnknownText_0xd0ae: ; unused
+ ; Looks like there's nothing here.
+ text_jump UnknownText_0x1c0979
+ db "@"
+
+BikeFunction: ; d0b3
+ call .TryBike
+ and $7f
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.TryBike: ; d0bc
+ call .CheckEnvironment
+ jr c, .CannotUseBike
+ ld a, [PlayerState]
+ cp PLAYER_NORMAL
+ jr z, .GetOnBike
+ cp PLAYER_BIKE
+ jr z, .GetOffBike
+ jr .CannotUseBike
+
+.GetOnBike
+ ld hl, Script_GetOnBike
+ ld de, Script_GetOnBike_Register
+ call .CheckIfRegistered
+ call QueueScript
+ xor a
+ ld [MusicFade], a
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ call MaxVolume
+ ld de, MUSIC_BICYCLE
+ ld a, e
+ ld [wMapMusic], a
+ call PlayMusic
+ ld a, $1
+ ret
+
+.GetOffBike
+ ld hl, BikeFlags
+ bit 1, [hl]
+ jr nz, .CantGetOffBike
+ ld hl, Script_GetOffBike
+ ld de, Script_GetOffBike_Register
+ call .CheckIfRegistered
+ ld a, BANK(Script_GetOffBike)
+ jr .done
+
+.CantGetOffBike
+ ld hl, Script_CantGetOffBike
+ jr .done
+
+.CannotUseBike
+ ld a, $0
+ ret
+
+.done
+ call QueueScript
+ ld a, $1
+ ret
+
+.CheckIfRegistered: ; d119
+ ld a, [wUsingItemWithSelect]
+ and a
+ ret z
+ ld h, d
+ ld l, e
+ ret
+
+.CheckEnvironment: ; d121
+ call GetMapPermission
+ call CheckOutdoorMap
+ jr z, .ok
+ cp CAVE
+ jr z, .ok
+ cp GATE
+ jr z, .ok
+ jr .nope
+
+.ok
+ call GetPlayerStandingTile
+ and $f ; can't use our bike in a wall or on water
+ jr nz, .nope
+ xor a
+ ret
+
+.nope
+ scf
+ ret
+
+Script_GetOnBike: ; 0xd13e
+ reloadmappart
+ special UpdateTimePals
+ writecode VAR_MOVEMENT, PLAYER_BIKE
+ writetext GotOnTheBikeText
+ waitbutton
+ closetext
+ special ReplaceKrisSprite
+ end
+
+Script_GetOnBike_Register: ; 0xd14e
+ writecode VAR_MOVEMENT, PLAYER_BIKE
+ closetext
+ special ReplaceKrisSprite
+ end
+
+; XXX
+ nop
+ ret
+
+Script_GetOffBike: ; 0xd158
+ reloadmappart
+ special UpdateTimePals
+ writecode VAR_MOVEMENT, PLAYER_NORMAL
+ writetext GotOffTheBikeText
+ waitbutton
+
+FinishGettingOffBike:
+ closetext
+ special ReplaceKrisSprite
+ special PlayMapMusic
+ end
+
+Script_GetOffBike_Register: ; 0xd16b
+ writecode VAR_MOVEMENT, PLAYER_NORMAL
+ jump FinishGettingOffBike
+
+Script_CantGetOffBike: ; 0xd171
+ writetext .CantGetOffBikeText
+ waitbutton
+ closetext
+ end
+
+.CantGetOffBikeText: ; 0xd177
+ ; You can't get off here!
+ text_jump UnknownText_0x1c099a
+ db "@"
+
+GotOnTheBikeText: ; 0xd17c
+ ; got on the @ .
+ text_jump UnknownText_0x1c09b2
+ db "@"
+
+GotOffTheBikeText: ; 0xd181
+ ; got off the @ .
+ text_jump UnknownText_0x1c09c7
+ db "@"
+
+TryCutOW:: ; d186
+ ld d, CUT
+ call CheckPartyMove
+ jr c, .cant_cut
+
+ ld de, ENGINE_HIVEBADGE
+ call CheckEngineFlag
+ jr c, .cant_cut
+
+ ld a, BANK(AskCutScript)
+ ld hl, AskCutScript
+ call CallScript
+ scf
+ ret
+
+.cant_cut
+ ld a, BANK(CantCutScript)
+ ld hl, CantCutScript
+ call CallScript
+ scf
+ ret
+
+AskCutScript: ; 0xd1a9
+ opentext
+ writetext UnknownText_0xd1c8
+ yesorno
+ iffalse .script_d1b8
+ callasm .CheckMap
+ iftrue Script_Cut
+.script_d1b8
+ closetext
+ end
+
+.CheckMap: ; d1ba
+ xor a
+ ld [ScriptVar], a
+ call CheckMapForSomethingToCut
+ ret c
+ ld a, TRUE
+ ld [ScriptVar], a
+ ret
+
+UnknownText_0xd1c8: ; 0xd1c8
+ text_jump UnknownText_0x1c09dd
+ db "@"
+
+CantCutScript: ; 0xd1cd
+ jumptext UnknownText_0xd1d0
+
+UnknownText_0xd1d0: ; 0xd1d0
+ text_jump UnknownText_0x1c0a05
+ db "@"
--- /dev/null
+++ b/event/special.asm
@@ -1,0 +1,231 @@
+SpecialGiveShuckle: ; 7305
+
+; Adding to the party.
+ xor a
+ ld [MonType], a
+
+; Level 15 Shuckle.
+ ld a, SHUCKLE
+ ld [CurPartySpecies], a
+ ld a, 15
+ ld [CurPartyLevel], a
+
+ predef TryAddMonToParty
+ jr nc, .NotGiven
+
+; Caught data.
+ ld b, 0
+ callba SetGiftPartyMonCaughtData
+
+; Holding a Berry.
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld a, [PartyCount]
+ dec a
+ push af
+ push bc
+ ld hl, PartyMon1Item
+ call AddNTimes
+ ld [hl], BERRY
+ pop bc
+ pop af
+
+; OT ID.
+ ld hl, PartyMon1ID
+ call AddNTimes
+ ld a, $2
+ ld [hli], a
+ ld [hl], $6
+
+; Nickname.
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMonNicknames
+ call SkipNames
+ ld de, SpecialShuckleNick
+ call CopyName2
+
+; OT.
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMonOT
+ call SkipNames
+ ld de, SpecialShuckleOT
+ call CopyName2
+
+; Engine flag for this event.
+ ld hl, DailyFlags
+ set 5, [hl]
+; setflag ENGINE_SHUCKLE_GIVEN
+ ld a, 1
+ ld [ScriptVar], a
+ ret
+
+.NotGiven
+ xor a
+ ld [ScriptVar], a
+ ret
+
+SpecialShuckleOT:
+ db "MANIA@"
+SpecialShuckleNick:
+ db "SHUCKIE@"
+
+SpecialReturnShuckle: ; 737e
+ callba SelectMonFromParty
+ jr c, .refused
+
+ ld a, [CurPartySpecies]
+ cp SHUCKLE
+ jr nz, .DontReturn
+
+ ld a, [CurPartyMon]
+ ld hl, PartyMon1ID
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+
+; OT ID
+ ld a, [hli]
+ cp 00518 / $100
+ jr nz, .DontReturn
+ ld a, [hl]
+ cp 00518 % $100
+ jr nz, .DontReturn
+
+; OT
+ ld a, [CurPartyMon]
+ ld hl, PartyMonOT
+ call SkipNames
+ ld de, SpecialShuckleOT
+.CheckOT
+ ld a, [de]
+ cp [hl]
+ jr nz, .DontReturn
+ cp "@"
+ jr z, .done
+ inc de
+ inc hl
+ jr .CheckOT
+
+.done
+ callba CheckCurPartyMonFainted
+ jr c, .fainted
+ ld a, [CurPartyMon]
+ ld hl, PartyMon1Happiness
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hl]
+ cp 150
+ ld a, $3
+ jr nc, .HappyToStayWithYou
+ xor a ; take from pc
+ ld [wPokemonWithdrawDepositParameter], a
+ callab RemoveMonFromPartyOrBox
+ ld a, $2
+.HappyToStayWithYou
+ ld [ScriptVar], a
+ ret
+
+.refused
+ ld a, $1
+ ld [ScriptVar], a
+ ret
+
+.DontReturn
+ xor a
+ ld [ScriptVar], a
+ ret
+
+.fainted
+ ld a, $4
+ ld [ScriptVar], a
+ ret
+
+Special_BillsGrandfather: ; 73f7
+ callba SelectMonFromParty
+ jr c, .cancel
+ ld a, [CurPartySpecies]
+ ld [ScriptVar], a
+ ld [wNamedObjectIndexBuffer], a
+ call GetPokemonName
+ jp CopyPokemonName_Buffer1_Buffer3
+
+.cancel
+ xor a
+ ld [ScriptVar], a
+ ret
+
+Special_YoungerHaircutBrother: ; 7413
+ ld hl, Data_YoungerHaircutBrother
+ jr MassageOrHaircut
+
+Special_OlderHaircutBrother: ; 7418
+ ld hl, Data_OlderHaircutBrother
+ jr MassageOrHaircut
+
+Special_DaisyMassage: ; 741d
+ ld hl, Data_DaisyMassage
+
+MassageOrHaircut: ; 7420
+ push hl
+ callba SelectMonFromParty
+ pop hl
+ jr c, .nope
+ ld a, [CurPartySpecies]
+ cp EGG
+ jr z, .egg
+ push hl
+ call GetCurNick
+ call CopyPokemonName_Buffer1_Buffer3
+ pop hl
+ call Random
+; Bug: Subtracting $ff from $ff fails to set c.
+; This can result in overflow into the next data array.
+; In the case of getting a massage from Daisy, we bleed
+; into CopyPokemonName_Buffer1_Buffer3, which passes
+; $d0 to ChangeHappiness and returns $73 to the script.
+; The end result is that there is a 0.4% chance your
+; Pokemon's happiness will not change at all.
+.loop
+ sub [hl]
+ jr c, .ok
+rept 3
+ inc hl
+endr
+ jr .loop
+
+.ok
+ inc hl
+ ld a, [hli]
+ ld [ScriptVar], a
+ ld c, [hl]
+ call ChangeHappiness
+ ret
+
+.nope
+ xor a
+ ld [ScriptVar], a
+ ret
+
+.egg
+ ld a, 1
+ ld [ScriptVar], a
+ ret
+
+Data_YoungerHaircutBrother: ; 7459
+ db $4c, 2, HAPPINESS_YOUNGCUT1 ; 30% chance
+ db $80, 3, HAPPINESS_YOUNGCUT2 ; 20% chance
+ db $ff, 4, HAPPINESS_YOUNGCUT3 ; 50% chance
+
+Data_OlderHaircutBrother: ; 7462
+ db $9a, 2, HAPPINESS_OLDERCUT1 ; 60% chance
+ db $4c, 3, HAPPINESS_OLDERCUT2 ; 10% chance
+ db $ff, 4, HAPPINESS_OLDERCUT3 ; 30% chance
+
+Data_DaisyMassage: ; 746b
+ db $ff, 2, HAPPINESS_MASSAGE ; 99.6% chance
+
+CopyPokemonName_Buffer1_Buffer3: ; 746e
+ ld hl, StringBuffer1
+ ld de, StringBuffer3
+ ld bc, PKMN_NAME_LENGTH
+ jp CopyBytes
--- a/home/map.asm
+++ b/home/map.asm
@@ -1812,7 +1812,7 @@
add 6
ld c, a
ld b, 0
- ld hl, wc801
+ ld hl, OverworldMap + 1
add hl, bc
ld a, e
srl a
--- a/items/item_effects.asm
+++ b/items/item_effects.asm
@@ -338,11 +338,13 @@
; catch rate than BRN/PSN/PAR, which in turn provide a higher catch rate than
; no status effect at all. But instead, it makes BRN/PSN/PAR provide no
; benefit.
+; Uncomment the line below to fix this.
ld b, a
ld a, [EnemyMonStatus]
and 1 << FRZ | SLP
ld c, 10
jr nz, .addstatus
+ ; ld a, [EnemyMonStatus]
and a
ld c, 5
jr nz, .addstatus
@@ -3315,3 +3317,5 @@
add hl, bc
ret
; f971
+
+INCLUDE "items/pokeball_wobble.asm"
--- /dev/null
+++ b/items/pokeball_wobble.asm
@@ -1,0 +1,88 @@
+GetPokeBallWobble: ; f971 (3:7971)
+; Returns whether a Poke Ball will wobble in the catch animation.
+; Whether a Pokemon is caught is determined beforehand.
+
+ push de
+
+ ld a, [rSVBK]
+ ld d, a
+ push de
+
+ ld a, 1 ; BANK(Buffer2)
+ ld [rSVBK], a
+
+ ld a, [Buffer2]
+ inc a
+ ld [Buffer2], a
+
+; Wobble up to 3 times.
+ cp 3 + 1
+ jr z, .finished
+
+ ld a, [wWildMon]
+ and a
+ ld c, 0 ; next
+ jr nz, .done
+
+ ld hl, .WobbleProbabilities
+ ld a, [Buffer1]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp b
+ jr nc, .checkwobble
+ inc hl
+ jr .loop
+
+.checkwobble
+ ld b, [hl]
+ call Random
+ cp b
+ ld c, 0 ; next
+ jr c, .done
+ ld c, 2 ; escaped
+ jr .done
+
+.finished
+ ld a, [wWildMon]
+ and a
+ ld c, 1 ; caught
+ jr nz, .done
+ ld c, 2 ; escaped
+
+.done
+ pop de
+ ld e, a
+ ld a, d
+ ld [rSVBK], a
+ ld a, e
+ pop de
+ ret
+
+.WobbleProbabilities: ; f9ba
+; catch rate, chance of wobbling / 255
+; nLeft/255 = (nRight/255) ** 4
+ db 1, 63
+ db 2, 75
+ db 3, 84
+ db 4, 90
+ db 5, 95
+ db 7, 103
+ db 10, 113
+ db 15, 126
+ db 20, 134
+ db 30, 149
+ db 40, 160
+ db 50, 169
+ db 60, 177
+ db 80, 191
+ db 100, 201
+ db 120, 211
+ db 140, 220
+ db 160, 227
+ db 180, 234
+ db 200, 240
+ db 220, 246
+ db 240, 251
+ db 254, 253
+ db 255, 255
--- a/main.asm
+++ b/main.asm
@@ -238,478 +238,9 @@
ItemAttributes: ; 67c1
INCLUDE "items/item_attributes.asm"
INCLUDE "engine/npc_movement.asm"
+INCLUDE "event/happiness_egg.asm"
+INCLUDE "event/special.asm"
-GetFirstPokemonHappiness: ; 718d
- ld hl, PartyMon1Happiness
- ld bc, PARTYMON_STRUCT_LENGTH
- ld de, PartySpecies
-.loop
- ld a, [de]
- cp EGG
- jr nz, .done
- inc de
- add hl, bc
- jr .loop
-
-.done
- ld [wd265], a
- ld a, [hl]
- ld [ScriptVar], a
- call GetPokemonName
- jp CopyPokemonName_Buffer1_Buffer3
-
-CheckFirstMonIsEgg: ; 71ac
- ld a, [PartySpecies]
- ld [wd265], a
- cp EGG
- ld a, $1
- jr z, .egg
- xor a
-
-.egg
- ld [ScriptVar], a
- call GetPokemonName
- jp CopyPokemonName_Buffer1_Buffer3
-
-ChangeHappiness: ; 71c2
-; Perform happiness action c on CurPartyMon
-
- ld a, [CurPartyMon]
- inc a
- ld e, a
- ld d, 0
- ld hl, PartySpecies - 1
- add hl, de
- ld a, [hl]
- cp EGG
- ret z
-
- push bc
- ld hl, PartyMon1Happiness
- ld bc, PARTYMON_STRUCT_LENGTH
- ld a, [CurPartyMon]
- call AddNTimes
- pop bc
-
- ld d, h
- ld e, l
-
- push de
- ld a, [de]
- cp 100
- ld e, 0
- jr c, .ok
- inc e
- cp 200
- jr c, .ok
- inc e
-
-.ok
- dec c
- ld b, 0
- ld hl, .Actions
-rept 3
- add hl, bc
-endr
- ld d, 0
- add hl, de
- ld a, [hl]
- cp 100
- pop de
-
- ld a, [de]
- jr nc, .negative
- add [hl]
- jr nc, .done
- ld a, -1
- jr .done
-
-.negative
- add [hl]
- jr c, .done
- xor a
-
-.done
- ld [de], a
- ld a, [wBattleMode]
- and a
- ret z
- ld a, [CurPartyMon]
- ld b, a
- ld a, [wPartyMenuCursor]
- cp b
- ret nz
- ld a, [de]
- ld [BattleMonHappiness], a
- ret
-
-.Actions
- db +5, +3, +2 ; Gained a level
- db +5, +3, +2 ; Vitamin
- db +1, +1, +0 ; X Item
- db +3, +2, +1 ; Battled a Gym Leader
- db +1, +1, +0 ; Learned a move
- db -1, -1, -1 ; Lost to an enemy
- db -5, -5, -10 ; Fainted due to poison
- db -5, -5, -10 ; Lost to a much stronger enemy
- db +1, +1, +1 ; Haircut (Y1)
- db +3, +3, +1 ; Haircut (Y2)
- db +5, +5, +2 ; Haircut (Y3)
- db +1, +1, +1 ; Haircut (O1)
- db +3, +3, +1 ; Haircut (O2)
- db +10, +10, +4 ; Haircut (O3)
- db -5, -5, -10 ; Used Heal Powder or Energypowder (bitter)
- db -10, -10, -15 ; Used Energy Root (bitter)
- db -15, -15, -20 ; Used Revival Herb (bitter)
- db +3, +3, +1 ; Grooming
- db +10, +6, +4 ; Gained a level in the place where it was caught
-
-StepHappiness:: ; 725a
-; Raise the party's happiness by 1 point every other step cycle.
-
- ld hl, wHappinessStepCount
- ld a, [hl]
- inc a
- and 1
- ld [hl], a
- ret nz
-
- ld de, PartyCount
- ld a, [de]
- and a
- ret z
-
- ld c, a
- ld hl, PartyMon1Happiness
-.loop
- inc de
- ld a, [de]
- cp EGG
- jr z, .next
- inc [hl]
- jr nz, .next
- ld [hl], $ff
-
-.next
- push de
- ld de, PARTYMON_STRUCT_LENGTH
- add hl, de
- pop de
- dec c
- jr nz, .loop
- ret
-
-DaycareStep:: ; 7282
-
- ld a, [wDaycareMan]
- bit 0, a
- jr z, .daycare_lady
-
- ld a, [wBreedMon1Level] ; level
- cp 100
- jr nc, .daycare_lady
- ld hl, wBreedMon1Exp + 2 ; exp
- inc [hl]
- jr nz, .daycare_lady
- dec hl
- inc [hl]
- jr nz, .daycare_lady
- dec hl
- inc [hl]
- ld a, [hl]
- cp 5242880 / $10000
- jr c, .daycare_lady
- ld a, 5242880 / $10000
- ld [hl], a
-
-.daycare_lady
- ld a, [wDaycareLady]
- bit 0, a
- jr z, .check_egg
-
- ld a, [wBreedMon2Level] ; level
- cp 100
- jr nc, .check_egg
- ld hl, wBreedMon2Exp + 2 ; exp
- inc [hl]
- jr nz, .check_egg
- dec hl
- inc [hl]
- jr nz, .check_egg
- dec hl
- inc [hl]
- ld a, [hl]
- cp 5242880 / $10000
- jr c, .check_egg
- ld a, 5242880 / $10000
- ld [hl], a
-
-.check_egg
- ld hl, wDaycareMan
- bit 5, [hl] ; egg
- ret z
- ld hl, wStepsToEgg
- dec [hl]
- ret nz
-
- call Random
- ld [hl], a
- callab CheckBreedmonCompatibility
- ld a, [wd265]
- cp 230
- ld b, -1 + 32 percent
- jr nc, .okay
- ld a, [wd265]
- cp 170
- ld b, 16 percent
- jr nc, .okay
- ld a, [wd265]
- cp 110
- ld b, 12 percent
- jr nc, .okay
- ld b, 4 percent
-
-.okay
- call Random
- cp b
- ret nc
- ld hl, wDaycareMan
- res 5, [hl]
- set 6, [hl]
- ret
-
-SpecialGiveShuckle: ; 7305
-
-; Adding to the party.
- xor a
- ld [MonType], a
-
-; Level 15 Shuckle.
- ld a, SHUCKLE
- ld [CurPartySpecies], a
- ld a, 15
- ld [CurPartyLevel], a
-
- predef TryAddMonToParty
- jr nc, .NotGiven
-
-; Caught data.
- ld b, 0
- callba SetGiftPartyMonCaughtData
-
-; Holding a Berry.
- ld bc, PARTYMON_STRUCT_LENGTH
- ld a, [PartyCount]
- dec a
- push af
- push bc
- ld hl, PartyMon1Item
- call AddNTimes
- ld [hl], BERRY
- pop bc
- pop af
-
-; OT ID.
- ld hl, PartyMon1ID
- call AddNTimes
- ld a, $2
- ld [hli], a
- ld [hl], $6
-
-; Nickname.
- ld a, [PartyCount]
- dec a
- ld hl, PartyMonNicknames
- call SkipNames
- ld de, SpecialShuckleNick
- call CopyName2
-
-; OT.
- ld a, [PartyCount]
- dec a
- ld hl, PartyMonOT
- call SkipNames
- ld de, SpecialShuckleOT
- call CopyName2
-
-; Engine flag for this event.
- ld hl, DailyFlags
- set 5, [hl]
-; setflag ENGINE_SHUCKLE_GIVEN
- ld a, 1
- ld [ScriptVar], a
- ret
-
-.NotGiven
- xor a
- ld [ScriptVar], a
- ret
-
-SpecialShuckleOT:
- db "MANIA@"
-SpecialShuckleNick:
- db "SHUCKIE@"
-
-SpecialReturnShuckle: ; 737e
- callba SelectMonFromParty
- jr c, .refused
-
- ld a, [CurPartySpecies]
- cp SHUCKLE
- jr nz, .DontReturn
-
- ld a, [CurPartyMon]
- ld hl, PartyMon1ID
- ld bc, PARTYMON_STRUCT_LENGTH
- call AddNTimes
-
-; OT ID
- ld a, [hli]
- cp 00518 / $100
- jr nz, .DontReturn
- ld a, [hl]
- cp 00518 % $100
- jr nz, .DontReturn
-
-; OT
- ld a, [CurPartyMon]
- ld hl, PartyMonOT
- call SkipNames
- ld de, SpecialShuckleOT
-.CheckOT
- ld a, [de]
- cp [hl]
- jr nz, .DontReturn
- cp "@"
- jr z, .done
- inc de
- inc hl
- jr .CheckOT
-
-.done
- callba CheckCurPartyMonFainted
- jr c, .fainted
- ld a, [CurPartyMon]
- ld hl, PartyMon1Happiness
- ld bc, PARTYMON_STRUCT_LENGTH
- call AddNTimes
- ld a, [hl]
- cp 150
- ld a, $3
- jr nc, .HappyToStayWithYou
- xor a ; take from pc
- ld [wPokemonWithdrawDepositParameter], a
- callab RemoveMonFromPartyOrBox
- ld a, $2
-.HappyToStayWithYou
- ld [ScriptVar], a
- ret
-
-.refused
- ld a, $1
- ld [ScriptVar], a
- ret
-
-.DontReturn
- xor a
- ld [ScriptVar], a
- ret
-
-.fainted
- ld a, $4
- ld [ScriptVar], a
- ret
-
-Special_BillsGrandfather: ; 73f7
- callba SelectMonFromParty
- jr c, .cancel
- ld a, [CurPartySpecies]
- ld [ScriptVar], a
- ld [wNamedObjectIndexBuffer], a
- call GetPokemonName
- jp CopyPokemonName_Buffer1_Buffer3
-
-.cancel
- xor a
- ld [ScriptVar], a
- ret
-
-Special_YoungerHaircutBrother: ; 7413
- ld hl, Data_YoungerHaircutBrother
- jr MassageOrHaircut
-
-Special_OlderHaircutBrother: ; 7418
- ld hl, Data_OlderHaircutBrother
- jr MassageOrHaircut
-
-Special_DaisyMassage: ; 741d
- ld hl, Data_DaisyMassage
-
-MassageOrHaircut: ; 7420
- push hl
- callba SelectMonFromParty
- pop hl
- jr c, .nope
- ld a, [CurPartySpecies]
- cp EGG
- jr z, .egg
- push hl
- call GetCurNick
- call CopyPokemonName_Buffer1_Buffer3
- pop hl
- call Random
-; Bug: Subtracting $ff from $ff fails to set c.
-; This can result in overflow into the next data array.
-; In the case of getting a massage from Daisy, we bleed
-; into CopyPokemonName_Buffer1_Buffer3, which passes
-; $d0 to ChangeHappiness and returns $73 to the script.
-; The end result is that there is a 0.4% chance your
-; Pokemon's happiness will not change at all.
-.loop
- sub [hl]
- jr c, .ok
-rept 3
- inc hl
-endr
- jr .loop
-
-.ok
- inc hl
- ld a, [hli]
- ld [ScriptVar], a
- ld c, [hl]
- call ChangeHappiness
- ret
-
-.nope
- xor a
- ld [ScriptVar], a
- ret
-
-.egg
- ld a, 1
- ld [ScriptVar], a
- ret
-
-Data_YoungerHaircutBrother: ; 7459
- db $4c, 2, HAPPINESS_YOUNGCUT1 ; 30% chance
- db $80, 3, HAPPINESS_YOUNGCUT2 ; 20% chance
- db $ff, 4, HAPPINESS_YOUNGCUT3 ; 50% chance
-
-Data_OlderHaircutBrother: ; 7462
- db $9a, 2, HAPPINESS_OLDERCUT1 ; 60% chance
- db $4c, 3, HAPPINESS_OLDERCUT2 ; 10% chance
- db $ff, 4, HAPPINESS_OLDERCUT3 ; 30% chance
-
-Data_DaisyMassage: ; 746b
- db $ff, 2, HAPPINESS_MASSAGE ; 99.6% chance
-
-CopyPokemonName_Buffer1_Buffer3: ; 746e
- ld hl, StringBuffer1
- ld de, StringBuffer3
- ld bc, PKMN_NAME_LENGTH
- jp CopyBytes
-
Predef1: ; 747a
; not used
ret
@@ -716,916 +247,9 @@
SECTION "bank2", ROMX, BANK[$2]
-BlankScreen: ; 8000
- call DisableSpriteUpdates
- xor a
- ld [hBGMapMode], a
- call ClearBGPalettes
- call ClearSprites
- hlcoord 0, 0
- ld bc, TileMapEnd - TileMap
- ld a, " "
- call ByteFill
- hlcoord 0, 0, AttrMap
- ld bc, AttrMapEnd - AttrMap
- ld a, $7
- call ByteFill
- call WaitBGMap2
- call SetPalettes
- ret
-
-SpawnPlayer: ; 8029
- ld a, -1
- ld [wObjectFollow_Leader], a
- ld [wObjectFollow_Follower], a
- ld a, $0
- ld hl, PlayerObjectTemplate
- call CopyPlayerObjectTemplate
- ld b, $0
- call PlayerSpawn_ConvertCoords
- ld a, $0
- call GetMapObject
- ld hl, MAPOBJECT_COLOR
- add hl, bc
- ln e, (1 << 3) | PAL_OW_RED, PERSONTYPE_SCRIPT
- ld a, [wPlayerSpriteSetupFlags]
- bit 2, a
- jr nz, .ok
- ld a, [PlayerGender]
- bit 0, a
- jr z, .ok
- ln e, (1 << 3) | PAL_OW_BLUE, PERSONTYPE_SCRIPT
-
-.ok
- ld [hl], e
- ld a, $0
- ld [hMapObjectIndexBuffer], a
- ld bc, MapObjects
- ld a, $0
- ld [hObjectStructIndexBuffer], a
- ld de, ObjectStructs
- call CopyMapObjectToObjectStruct
- ld a, PLAYER
- ld [wCenteredObject], a
- ret
-
-PlayerObjectTemplate: ; 8071
-; A dummy map object used to initialize the player object.
-; Shorter than the actual amount copied by two bytes.
-; Said bytes seem to be unused.
- person_event SPRITE_CHRIS, -4, -4, SPRITEMOVEDATA_PLAYER, 15, 15, -1, -1, 0, PERSONTYPE_SCRIPT, 0, 0, -1
-
-CopyDECoordsToMapObject:: ; 807e
- push de
- ld a, b
- call GetMapObject
- pop de
- ld hl, MAPOBJECT_X_COORD
- add hl, bc
- ld [hl], d
- ld hl, MAPOBJECT_Y_COORD
- add hl, bc
- ld [hl], e
- ret
-
-PlayerSpawn_ConvertCoords: ; 808f
- push bc
- ld a, [XCoord]
- add 4
- ld d, a
- ld a, [YCoord]
- add 4
- ld e, a
- pop bc
- call CopyDECoordsToMapObject
- ret
-
-WritePersonXY:: ; 80a1
- ld a, b
- call CheckObjectVisibility
- ret c
-
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld d, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld e, [hl]
- ld a, [hMapObjectIndexBuffer]
- ld b, a
- call CopyDECoordsToMapObject
- and a
- ret
-
-RefreshPlayerCoords: ; 80b8
- ld a, [XCoord]
- add 4
- ld d, a
- ld hl, PlayerStandingMapX
- sub [hl]
- ld [hl], d
- ld hl, MapObjects + MAPOBJECT_X_COORD
- ld [hl], d
- ld hl, PlayerLastMapX
- ld [hl], d
- ld d, a
- ld a, [YCoord]
- add 4
- ld e, a
- ld hl, PlayerStandingMapY
- sub [hl]
- ld [hl], e
- ld hl, MapObjects + MAPOBJECT_Y_COORD
- ld [hl], e
- ld hl, PlayerLastMapY
- ld [hl], e
- ld e, a
- ld a, [wObjectFollow_Leader]
- cp $0
- ret nz ; wtf
- ret
-
-CopyObjectStruct:: ; 80e7
- call CheckObjectMask
- and a
- ret nz ; masked
-
- ld hl, ObjectStructs + OBJECT_STRUCT_LENGTH * 1
- ld a, 1
- ld de, OBJECT_STRUCT_LENGTH
-.loop
- ld [hObjectStructIndexBuffer], a
- ld a, [hl]
- and a
- jr z, .done
- add hl, de
- ld a, [hObjectStructIndexBuffer]
- inc a
- cp NUM_OBJECT_STRUCTS
- jr nz, .loop
- scf
- ret ; overflow
-
-.done
- ld d, h
- ld e, l
- call CopyMapObjectToObjectStruct
- ld hl, VramState
- bit 7, [hl]
- ret z
-
- ld hl, OBJECT_FLAGS2
- add hl, de
- set 5, [hl]
- ret
-
-CopyMapObjectToObjectStruct: ; 8116
- call .CopyMapObjectToTempObject
- call CopyTempObjectToObjectStruct
- ret
-
-.CopyMapObjectToTempObject: ; 811d
- ld a, [hObjectStructIndexBuffer]
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld [hl], a
-
- ld a, [hMapObjectIndexBuffer]
- ld [wTempObjectCopyMapObjectIndex], a
-
- ld hl, MAPOBJECT_SPRITE
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopySprite], a
-
- call GetSpriteVTile
- ld [wTempObjectCopySpriteVTile], a
-
- ld a, [hl]
- call GetSpritePalette
- ld [wTempObjectCopyPalette], a
-
- ld hl, MAPOBJECT_COLOR
- add hl, bc
- ld a, [hl]
- and $f0
- jr z, .skip_color_override
- swap a
- and $7 ; OAM_PALETTE
- ld [wTempObjectCopyPalette], a
-
-.skip_color_override
- ld hl, MAPOBJECT_MOVEMENT
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopyMovement], a
-
- ld hl, MAPOBJECT_RANGE
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopyRange], a
-
- ld hl, MAPOBJECT_X_COORD
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopyX], a
-
- ld hl, MAPOBJECT_Y_COORD
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopyY], a
-
- ld hl, MAPOBJECT_RADIUS
- add hl, bc
- ld a, [hl]
- ld [wTempObjectCopyRadius], a
- ret
-
-InitializeVisibleSprites: ; 8177
- ld bc, MapObjects + OBJECT_LENGTH
- ld a, 1
-.loop
- ld [hMapObjectIndexBuffer], a
- ld hl, MAPOBJECT_SPRITE
- add hl, bc
- ld a, [hl]
- and a
- jr z, .next
-
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- cp -1
- jr nz, .next
-
- ld a, [XCoord]
- ld d, a
- ld a, [YCoord]
- ld e, a
-
- ld hl, MAPOBJECT_X_COORD
- add hl, bc
- ld a, [hl]
- add 1
- sub d
- jr c, .next
-
- cp MAPOBJECT_SCREEN_WIDTH
- jr nc, .next
-
- ld hl, MAPOBJECT_Y_COORD
- add hl, bc
- ld a, [hl]
- add 1
- sub e
- jr c, .next
-
- cp MAPOBJECT_SCREEN_HEIGHT
- jr nc, .next
-
- push bc
- call CopyObjectStruct
- pop bc
- jp c, .ret
-
-.next
- ld hl, OBJECT_LENGTH
- add hl, bc
- ld b, h
- ld c, l
- ld a, [hMapObjectIndexBuffer]
- inc a
- cp NUM_OBJECTS
- jr nz, .loop
- ret
-
-.ret: ; 81c9
- ret
-
-CheckObjectEnteringVisibleRange:: ; 81ca
- nop
- ld a, [wPlayerStepDirection]
- cp STANDING
- ret z
- ld hl, .dw
- rst JumpTable
- ret
-
-.dw: ; 81d6
- dw .Down
- dw .Up
- dw .Left
- dw .Right
-
-.Up: ; 81de
- ld a, [YCoord]
- sub 1
- jr .Vertical
-
-.Down: ; 81e5
- ld a, [YCoord]
- add 9
-.Vertical: ; 81ea
- ld d, a
- ld a, [XCoord]
- ld e, a
- ld bc, MapObjects + OBJECT_LENGTH
- ld a, 1
-.loop_v
- ld [hMapObjectIndexBuffer], a
- ld hl, MAPOBJECT_SPRITE
- add hl, bc
- ld a, [hl]
- and a
- jr z, .next_v
- ld hl, MAPOBJECT_Y_COORD
- add hl, bc
- ld a, d
- cp [hl]
- jr nz, .next_v
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- cp -1
- jr nz, .next_v
- ld hl, MAPOBJECT_X_COORD
- add hl, bc
- ld a, [hl]
- add 1
- sub e
- jr c, .next_v
- cp MAPOBJECT_SCREEN_WIDTH
- jr nc, .next_v
- push de
- push bc
- call CopyObjectStruct
- pop bc
- pop de
-
-.next_v
- ld hl, OBJECT_LENGTH
- add hl, bc
- ld b, h
- ld c, l
- ld a, [hMapObjectIndexBuffer]
- inc a
- cp NUM_OBJECTS
- jr nz, .loop_v
- ret
-
-.Left: ; 8232
- ld a, [XCoord]
- sub 1
- jr .Horizontal
-
-.Right: ; 8239
- ld a, [XCoord]
- add 10
-.Horizontal: ; 823e
- ld e, a
- ld a, [YCoord]
- ld d, a
- ld bc, MapObjects + OBJECT_LENGTH
- ld a, 1
-.loop_h
- ld [hMapObjectIndexBuffer], a
- ld hl, MAPOBJECT_SPRITE
- add hl, bc
- ld a, [hl]
- and a
- jr z, .next_h
- ld hl, MAPOBJECT_X_COORD
- add hl, bc
- ld a, e
- cp [hl]
- jr nz, .next_h
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- cp -1
- jr nz, .next_h
- ld hl, MAPOBJECT_Y_COORD
- add hl, bc
- ld a, [hl]
- add 1
- sub d
- jr c, .next_h
- cp MAPOBJECT_SCREEN_HEIGHT
- jr nc, .next_h
- push de
- push bc
- call CopyObjectStruct
- pop bc
- pop de
-
-.next_h
- ld hl, OBJECT_LENGTH
- add hl, bc
- ld b, h
- ld c, l
- ld a, [hMapObjectIndexBuffer]
- inc a
- cp NUM_OBJECTS
- jr nz, .loop_h
- ret
-
-CopyTempObjectToObjectStruct: ; 8286
- ld a, [wTempObjectCopyMapObjectIndex]
- ld hl, OBJECT_MAP_OBJECT_INDEX
- add hl, de
- ld [hl], a
-
- ld a, [wTempObjectCopyMovement]
- call CopySpriteMovementData
-
- ld a, [wTempObjectCopyPalette]
- ld hl, OBJECT_PALETTE
- add hl, de
- or [hl]
- ld [hl], a
-
- ld a, [wTempObjectCopyY]
- call .InitYCoord
-
- ld a, [wTempObjectCopyX]
- call .InitXCoord
-
- ld a, [wTempObjectCopySprite]
- ld hl, OBJECT_SPRITE
- add hl, de
- ld [hl], a
-
- ld a, [wTempObjectCopySpriteVTile]
- ld hl, OBJECT_SPRITE_TILE
- add hl, de
- ld [hl], a
-
- ld hl, OBJECT_STEP_TYPE
- add hl, de
- ld [hl], STEP_TYPE_00
-
- ld hl, OBJECT_FACING_STEP
- add hl, de
- ld [hl], STANDING
-
- ld a, [wTempObjectCopyRadius]
- call .InitRadius
-
- ld a, [wTempObjectCopyRange]
- ld hl, OBJECT_RANGE
- add hl, de
- ld [hl], a
-
- and a
- ret
-
-.InitYCoord: ; 82d5
- ld hl, OBJECT_INIT_Y
- add hl, de
- ld [hl], a
-
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, de
- ld [hl], a
-
- ld hl, YCoord
- sub [hl]
- and $f
- swap a
- ld hl, wFollowNotExactPersonY
- sub [hl]
- ld hl, OBJECT_SPRITE_Y
- add hl, de
- ld [hl], a
- ret
-
-.InitXCoord: ; 82f1
- ld hl, OBJECT_INIT_X
- add hl, de
- ld [hl], a
- ld hl, OBJECT_NEXT_MAP_X
- add hl, de
- ld [hl], a
- ld hl, XCoord
- sub [hl]
- and $f
- swap a
- ld hl, wFollowNotExactPersonX
- sub [hl]
- ld hl, OBJECT_SPRITE_X
- add hl, de
- ld [hl], a
- ret
-
-.InitRadius: ; 830d
- ld h, a
- inc a
- and $f
- ld l, a
- ld a, h
- add $10
- and $f0
- or l
- ld hl, OBJECT_RADIUS
- add hl, de
- ld [hl], a
- ret
-
-TrainerWalkToPlayer: ; 831e
- ld a, [hLastTalked]
- call InitMovementBuffer
- ld a, movement_step_sleep_1
- call AppendToMovementBuffer
- ld a, [wd03f]
- dec a
- jr z, .TerminateStep
- ld a, [hLastTalked]
- ld b, a
- ld c, PLAYER
- ld d, 1
- call .GetPathToPlayer
- call DecrementMovementBufferCount
-
-.TerminateStep
- ld a, movement_step_end
- call AppendToMovementBuffer
- ret
-
-.GetPathToPlayer: ; 8341
- push de
- push bc
-; get player object struct, load to de
- ld a, c
- call GetMapObject
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- call GetObjectStruct
- ld d, b
- ld e, c
-
-; get last talked object struct, load to bc
- pop bc
- ld a, b
- call GetMapObject
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- call GetObjectStruct
-
-; get last talked coords, load to bc
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld a, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld c, [hl]
- ld b, a
-
-; get player coords, load to de
- ld hl, OBJECT_NEXT_MAP_X
- add hl, de
- ld a, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, de
- ld e, [hl]
- ld d, a
-
- pop af
- call ComputePathToWalkToPlayer
- ret
-
-Special_SurfStartStep: ; 8379
- call InitMovementBuffer
- call .GetMovementData
- call AppendToMovementBuffer
- ld a, movement_step_end
- call AppendToMovementBuffer
- ret
-
-.GetMovementData: ; 8388
- ld a, [PlayerDirection]
- srl a
- srl a
- and 3
- ld e, a
- ld d, 0
- ld hl, .movement_data
- add hl, de
- ld a, [hl]
- ret
-
-.movement_data
- slow_step_down
- slow_step_up
- slow_step_left
- slow_step_right
-
-FollowNotExact:: ; 839e
- push bc
- ld a, c
- call CheckObjectVisibility
- ld d, b
- ld e, c
- pop bc
- ret c
-
- ld a, b
- call CheckObjectVisibility
- ret c
-
-; Person 2 is now in bc, person 1 is now in de
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld a, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld c, [hl]
- ld b, a
-
- ld hl, OBJECT_NEXT_MAP_X
- add hl, de
- ld a, [hl]
- cp b
- jr z, .same_x
- jr c, .to_the_left
- inc b
- jr .continue
-
-.to_the_left
- dec b
- jr .continue
-
-.same_x
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, de
- ld a, [hl]
- cp c
- jr z, .continue
- jr c, .below
- inc c
- jr .continue
-
-.below
- dec c
-
-.continue
- ld hl, OBJECT_NEXT_MAP_X
- add hl, de
- ld [hl], b
- ld a, b
- ld hl, XCoord
- sub [hl]
- and $f
- swap a
- ld hl, wFollowNotExactPersonX
- sub [hl]
- ld hl, OBJECT_SPRITE_X
- add hl, de
- ld [hl], a
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, de
- ld [hl], c
- ld a, c
- ld hl, YCoord
- sub [hl]
- and $f
- swap a
- ld hl, wFollowNotExactPersonY
- sub [hl]
- ld hl, OBJECT_SPRITE_Y
- add hl, de
- ld [hl], a
- ld a, [hObjectStructIndexBuffer]
- ld hl, OBJECT_RANGE
- add hl, de
- ld [hl], a
- ld hl, OBJECT_MOVEMENTTYPE
- add hl, de
- ld [hl], SPRITEMOVEDATA_FOLLOWNOTEXACT
- ld hl, OBJECT_STEP_TYPE
- add hl, de
- ld [hl], STEP_TYPE_00
- ret
-
-GetRelativeFacing:: ; 8417
-; Determines which way map object e would have to turn to face map object d. Returns carry if it's impossible for whatever reason.
- ld a, d
- call GetMapObject
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- cp NUM_OBJECT_STRUCTS
- jr nc, .carry
- ld d, a
- ld a, e
- call GetMapObject
- ld hl, MAPOBJECT_OBJECT_STRUCT_ID
- add hl, bc
- ld a, [hl]
- cp NUM_OBJECT_STRUCTS
- jr nc, .carry
- ld e, a
- call .GetFacing_e_relativeto_d
- ret
-
-.carry
- scf
- ret
-
-.GetFacing_e_relativeto_d: ; 8439
-; Determines which way object e would have to turn to face object d. Returns carry if it's impossible.
-; load the coordinates of object d into bc
- ld a, d
- call GetObjectStruct
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld a, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld c, [hl]
- ld b, a
- push bc
-; load the coordinates of object e into de
- ld a, e
- call GetObjectStruct
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld d, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld e, [hl]
- pop bc
-; |x1 - x2|
- ld a, b
- sub d
- jr z, .same_x_1
- jr nc, .b_right_of_d_1
- cpl
- inc a
-
-.b_right_of_d_1
-; |y1 - y2|
- ld h, a
- ld a, c
- sub e
- jr z, .same_y_1
- jr nc, .c_below_e_1
- cpl
- inc a
-
-.c_below_e_1
-; |y1 - y2| - |x1 - x2|
- sub h
- jr c, .same_y_1
-
-.same_x_1
-; compare the y coordinates
- ld a, c
- cp e
- jr z, .same_x_and_y
- jr c, .c_directly_below_e
-; c directly above e
- ld d, DOWN
- and a
- ret
-
-.c_directly_below_e
- ld d, UP
- and a
- ret
-
-.same_y_1
- ld a, b
- cp d
- jr z, .same_x_and_y
- jr c, .b_directly_right_of_d
-; b directly left of d
- ld d, RIGHT
- and a
- ret
-
-.b_directly_right_of_d
- ld d, LEFT
- and a
- ret
-
-.same_x_and_y
- scf
- ret
-
-QueueFollowerFirstStep: ; 848a
- call .QueueFirstStep
- jr c, .same
- ld [wFollowMovementQueue], a
- xor a
- ld [wFollowerMovementQueueLength], a
- ret
-
-.same
- ld a, -1
- ld [wFollowerMovementQueueLength], a
- ret
-
-.QueueFirstStep
- ld a, [wObjectFollow_Leader]
- call GetObjectStruct
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld d, [hl]
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld e, [hl]
- ld a, [wObjectFollow_Follower]
- call GetObjectStruct
- ld hl, OBJECT_NEXT_MAP_X
- add hl, bc
- ld a, d
- cp [hl]
- jr z, .check_y
- jr c, .left
- and a
- ld a, movement_step_right
- ret
-
-.left
- and a
- ld a, movement_step_left
- ret
-
-.check_y
- ld hl, OBJECT_NEXT_MAP_Y
- add hl, bc
- ld a, e
- cp [hl]
- jr z, .same_xy
- jr c, .up
- and a
- ld a, movement_step_down
- ret
-
-.up
- and a
- ld a, movement_step_up
- ret
-
-.same_xy
- scf
- ret
-
-_Sine:: ; 84d9
-; A simple sine function.
-; Return d * sin(e) in hl.
-
-; e is a signed 6-bit value.
- ld a, e
- and %111111
- cp %100000
- jr nc, .negative
-
- call .ApplySineWave
- ld a, h
- ret
-
-.negative
- and %011111
- call .ApplySineWave
- ld a, h
- xor -1
- inc a
- ret
-
-.ApplySineWave: ; 84ef
- ld e, a
- ld a, d
- ld d, 0
- ld hl, .sinewave
- add hl, de
- add hl, de
- ld e, [hl]
- inc hl
- ld d, [hl]
- ld hl, 0
-
-; Factor amplitude
-.multiply
- srl a
- jr nc, .even
- add hl, de
-.even
- sla e
- rl d
- and a
- jr nz, .multiply
- ret
-
-.sinewave: ; 850b
-; A $20-word table representing a sine wave.
-; 90 degrees is index $10 at a base amplitude of $100.
- sine_wave $100
-
+INCLUDE "engine/player_object.asm"
+INCLUDE "engine/sine.asm"
INCLUDE "engine/predef.asm"
-
INCLUDE "engine/color.asm"
SECTION "bank3", ROMX, BANK[$3]
@@ -1651,3288 +275,15 @@
db -1
INCLUDE "engine/specials.asm"
-
-_PrintNum:: ; c4c7
-; Print c digits of the b-byte value from de to hl.
-; Allows 2 to 7 digits. For 1-digit numbers, add
-; the value to char "0" instead of calling PrintNum.
-; Some extra flags can be given in bits 5-7 of b.
-; Bit 5: money if set (unless left-aligned without leading zeros)
-; Bit 6: right-aligned if set
-; Bit 7: print leading zeros if set
-
- push bc
-
- bit 5, b
- jr z, .main
- bit 7, b
- jr nz, .moneyflag
- bit 6, b
- jr z, .main
-
-.moneyflag ; 101xxxxx or 011xxxxx
- ld a, "¥"
- ld [hli], a
- res 5, b ; 100xxxxx or 010xxxxx
-
-.main
- xor a
- ld [hPrintNum1], a
- ld [hPrintNum2], a
- ld [hPrintNum3], a
- ld a, b
- and $f
- cp 1
- jr z, .byte
- cp 2
- jr z, .word
-; maximum 3 bytes
-.long
- ld a, [de]
- ld [hPrintNum2], a
- inc de
- ld a, [de]
- ld [hPrintNum3], a
- inc de
- ld a, [de]
- ld [hPrintNum4], a
- jr .start
-
-.word
- ld a, [de]
- ld [hPrintNum3], a
- inc de
- ld a, [de]
- ld [hPrintNum4], a
- jr .start
-
-.byte
- ld a, [de]
- ld [hPrintNum4], a
-
-.start
- push de
-
- ld d, b
- ld a, c
- swap a
- and $f
- ld e, a
- ld a, c
- and $f
- ld b, a
- ld c, 0
- cp 2
- jr z, .two
- cp 3
- jr z, .three
- cp 4
- jr z, .four
- cp 5
- jr z, .five
- cp 6
- jr z, .six
-
-.seven
- ld a, 1000000 / $10000 % $100
- ld [hPrintNum5], a
- ld a, 1000000 / $100 % $100
- ld [hPrintNum6], a
- ld a, 1000000 % $100
- ld [hPrintNum7], a
- call .PrintDigit
- call .AdvancePointer
-
-.six
- ld a, 100000 / $10000 % $100
- ld [hPrintNum5], a
- ld a, 100000 / $100 % $100
- ld [hPrintNum6], a
- ld a, 100000 % $100
- ld [hPrintNum7], a
- call .PrintDigit
- call .AdvancePointer
-
-.five
- xor a
- ld [hPrintNum5], a
- ld a, 10000 / $100
- ld [hPrintNum6], a
- ld a, 10000 % $100
- ld [hPrintNum7], a
- call .PrintDigit
- call .AdvancePointer
-
-.four
- xor a
- ld [hPrintNum5], a
- ld a, 1000 / $100
- ld [hPrintNum6], a
- ld a, 1000 % $100
- ld [hPrintNum7], a
- call .PrintDigit
- call .AdvancePointer
-
-.three
- xor a
- ld [hPrintNum5], a
- xor a
- ld [hPrintNum6], a
- ld a, 100
- ld [hPrintNum7], a
- call .PrintDigit
- call .AdvancePointer
-
-.two
- dec e
- jr nz, .two_skip
- ld a, "0"
- ld [hPrintNum1], a
-.two_skip
-
- ld c, 0
- ld a, [hPrintNum4]
-.mod_10
- cp 10
- jr c, .modded_10
- sub 10
- inc c
- jr .mod_10
-.modded_10
-
- ld b, a
- ld a, [hPrintNum1]
- or c
- jr nz, .money
- call .PrintLeadingZero
- jr .money_leading_zero
-
-.money
- call .PrintYen
- push af
- ld a, "0"
- add c
- ld [hl], a
- pop af
- ld [hPrintNum1], a
- inc e
- dec e
- jr nz, .money_leading_zero
- inc hl
- ld [hl], $f2 ; XXX
-
-.money_leading_zero
- call .AdvancePointer
- call .PrintYen
- ld a, "0"
- add b
- ld [hli], a
-
- pop de
- pop bc
- ret
-
-.PrintYen: ; c5ba
- push af
- ld a, [hPrintNum1]
- and a
- jr nz, .stop
- bit 5, d
- jr z, .stop
- ld a, "¥"
- ld [hli], a
- res 5, d
-
-.stop
- pop af
- ret
-
-.PrintDigit: ; c5cb (3:45cb)
- dec e
- jr nz, .ok
- ld a, "0"
- ld [hPrintNum1], a
-.ok
- ld c, 0
-.loop
- ld a, [hPrintNum5]
- ld b, a
- ld a, [hPrintNum2]
- ld [hPrintNum8], a
- cp b
- jr c, .skip1
- sub b
- ld [hPrintNum2], a
- ld a, [hPrintNum6]
- ld b, a
- ld a, [hPrintNum3]
- ld [hPrintNum9], a
- cp b
- jr nc, .skip2
- ld a, [hPrintNum2]
- or 0
- jr z, .skip3
- dec a
- ld [hPrintNum2], a
- ld a, [hPrintNum3]
-.skip2
- sub b
- ld [hPrintNum3], a
- ld a, [hPrintNum7]
- ld b, a
- ld a, [hPrintNum4]
- ld [hPrintNum10], a
- cp b
- jr nc, .skip4
- ld a, [hPrintNum3]
- and a
- jr nz, .skip5
- ld a, [hPrintNum2]
- and a
- jr z, .skip6
- dec a
- ld [hPrintNum2], a
- xor a
-.skip5
- dec a
- ld [hPrintNum3], a
- ld a, [hPrintNum4]
-.skip4
- sub b
- ld [hPrintNum4], a
- inc c
- jr .loop
-.skip6
- ld a, [hPrintNum9]
- ld [hPrintNum3], a
-.skip3
- ld a, [hPrintNum8]
- ld [hPrintNum2], a
-.skip1
- ld a, [hPrintNum1]
- or c
- jr z, .PrintLeadingZero
- ld a, [hPrintNum1]
- and a
- jr nz, .done
- bit 5, d
- jr z, .done
- ld a, "¥"
- ld [hli], a
- res 5, d
-.done
- ld a, "0"
- add c
- ld [hl], a
- ld [hPrintNum1], a
- inc e
- dec e
- ret nz
- inc hl
- ld [hl], "·"
- ret
-
-.PrintLeadingZero: ; c644
-; prints a leading zero unless they are turned off in the flags
- bit 7, d ; print leading zeroes?
- ret z
- ld [hl], "0"
- ret
-
-.AdvancePointer: ; c64a
-; increments the pointer unless leading zeroes are not being printed,
-; the number is left-aligned, and no nonzero digits have been printed yet
- bit 7, d ; print leading zeroes?
- jr nz, .inc
- bit 6, d ; left alignment or right alignment?
- jr z, .inc
- ld a, [hPrintNum1]
- and a
- ret z
-.inc
- inc hl
- ret
-
-HealParty: ; c658
- xor a
- ld [CurPartyMon], a
- ld hl, PartySpecies
-.loop
- ld a, [hli]
- cp -1
- jr z, .done
- cp EGG
- jr z, .next
-
- push hl
- call HealPartyMon
- pop hl
-
-.next
- ld a, [CurPartyMon]
- inc a
- ld [CurPartyMon], a
- jr .loop
-
-.done
- ret
-
-HealPartyMon: ; c677
- ld a, MON_SPECIES
- call GetPartyParamLocation
- ld d, h
- ld e, l
-
- ld hl, MON_STATUS
- add hl, de
- xor a
- ld [hli], a
- ld [hl], a
-
- ld hl, MON_MAXHP
- add hl, de
-
- ; bc = MON_HP
- ld b, h
- ld c, l
- dec bc
- dec bc
-
- ld a, [hli]
- ld [bc], a
- inc bc
- ld a, [hl]
- ld [bc], a
-
- callba RestoreAllPP
- ret
-
-ComputeHPBarPixels: ; c699
-; e = bc * (6 * 8) / de
- ld a, b
- or c
- jr z, .zero
- push hl
- xor a
- ld [hMultiplicand + 0], a
- ld a, b
- ld [hMultiplicand + 1], a
- ld a, c
- ld [hMultiplicand + 2], a
- ld a, 6 * 8
- ld [hMultiplier], a
- call Multiply
- ; We need de to be under 256 because hDivisor is only 1 byte.
- ld a, d
- and a
- jr z, .divide
- ; divide de and hProduct by 4
- srl d
- rr e
- srl d
- rr e
- ld a, [hProduct + 2]
- ld b, a
- ld a, [hProduct + 3]
- srl b
- rr a
- srl b
- rr a
- ld [hDividend + 3], a
- ld a, b
- ld [hDividend + 2], a
-.divide
- ld a, e
- ld [hDivisor], a
- ld b, 4
- call Divide
- ld a, [hQuotient + 2]
- ld e, a
- pop hl
- and a
- ret nz
- ld e, 1
- ret
-
-.zero
- ld e, 0
- ret
-
-AnimateHPBar: ; c6e0
- call WaitBGMap
- call _AnimateHPBar
- call WaitBGMap
- ret
-
-ClearBuffer1: ; c6ea
- xor a
- ld hl, Buffer1
- ld bc, 7
- call ByteFill
- ret
-
-FieldMoveJumptable: ; c6f5
- ld a, [Buffer1]
- rst JumpTable
- ld [Buffer1], a
- bit 7, a
- jr nz, .okay
- and a
- ret
-
-.okay
- and $7f
- scf
- ret
-
-GetPartyNick: ; c706
-; write CurPartyMon nickname to StringBuffer1-3
- ld hl, PartyMonNicknames
- ld a, BOXMON
- ld [MonType], a
- ld a, [CurPartyMon]
- call GetNick
- call CopyName1
-; copy text from StringBuffer2 to StringBuffer3
- ld de, StringBuffer2
- ld hl, StringBuffer3
- call CopyName2
- ret
-
-CheckEngineFlag: ; c721
-; Check engine flag de
-; Return carry if flag is not set
- ld b, CHECK_FLAG
- callba EngineFlagAction
- ld a, c
- and a
- jr nz, .isset
- scf
- ret
-.isset
- xor a
- ret
-
-CheckBadge: ; c731
-; Check engine flag a (ENGINE_ZEPHYRBADGE thru ENGINE_EARTHBADGE)
-; Display "Badge required" text and return carry if the badge is not owned
- call CheckEngineFlag
- ret nc
- ld hl, .BadgeRequiredText
- call MenuTextBoxBackup ; push text to queue
- scf
- ret
-
-.BadgeRequiredText: ; c73d
- ; Sorry! A new BADGE
- ; is required.
- text_jump _BadgeRequiredText
- db "@"
-
-CheckPartyMove: ; c742
-; Check if a monster in your party has move d.
-
- ld e, 0
- xor a
- ld [CurPartyMon], a
-.loop
- ld c, e
- ld b, 0
- ld hl, PartySpecies
- add hl, bc
- ld a, [hl]
- and a
- jr z, .no
- cp a, -1
- jr z, .no
- cp a, EGG
- jr z, .next
-
- ld bc, PARTYMON_STRUCT_LENGTH
- ld hl, PartyMon1Moves
- ld a, e
- call AddNTimes
- ld b, NUM_MOVES
-.check
- ld a, [hli]
- cp d
- jr z, .yes
- dec b
- jr nz, .check
-
-.next
- inc e
- jr .loop
-
-.yes
- ld a, e
- ld [CurPartyMon], a ; which mon has the move
- xor a
- ret
-.no
- scf
- ret
-
-FieldMoveFailed: ; c779
- ld hl, .CantUseHere
- call MenuTextBoxBackup
- ret
-
-.CantUseHere: ; 0xc780
- ; Can't use that here.
- text_jump UnknownText_0x1c05c8
- db "@"
-
-CutFunction: ; c785
- call ClearBuffer1
-.loop
- ld hl, .Jumptable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.Jumptable: ; c796 (3:4796)
-
- dw .CheckAble
- dw .DoCut
- dw .FailCut
-
-.CheckAble: ; c79c (3:479c)
- ld de, ENGINE_HIVEBADGE
- call CheckBadge
- jr c, .nohivebadge
- call CheckMapForSomethingToCut
- jr c, .nothingtocut
- ld a, $1
- ret
-
-.nohivebadge
- ld a, $80
- ret
-
-.nothingtocut
- ld a, $2
- ret
-
-.DoCut: ; c7b2 (3:47b2)
- ld hl, Script_CutFromMenu
- call QueueScript
- ld a, $81
- ret
-
-.FailCut: ; c7bb (3:47bb)
- ld hl, Text_NothingToCut
- call MenuTextBoxBackup
- ld a, $80
- ret
-
-Text_UsedCut: ; 0xc7c4
- ; used CUT!
- text_jump UnknownText_0x1c05dd
- db "@"
-
-Text_NothingToCut: ; 0xc7c9
- ; There's nothing to CUT here.
- text_jump UnknownText_0x1c05ec
- db "@"
-
-CheckMapForSomethingToCut: ; c7ce
- ; Does the collision data of the facing tile permit cutting?
- call GetFacingTileCoord
- ld c, a
- push de
- callba CheckCutCollision
- pop de
- jr nc, .fail
- ; Get the location of the current block in OverworldMap.
- call GetBlockLocation
- ld c, [hl]
- ; See if that block contains something that can be cut.
- push hl
- ld hl, CutTreeBlockPointers
- call CheckOverworldTileArrays
- pop hl
- jr nc, .fail
- ; Back up the OverworldMap address to Buffer3
- ld a, l
- ld [Buffer3], a
- ld a, h
- ld [Buffer4], a
- ; Back up the replacement tile to Buffer5
- ld a, b
- ld [Buffer5], a
- ; Back up the animation index to Buffer6
- ld a, c
- ld [Buffer6], a
- xor a
- ret
-
-.fail
- scf
- ret
-
-Script_CutFromMenu: ; c7fe
- reloadmappart
- special UpdateTimePals
-
-Script_Cut: ; 0xc802
- callasm GetPartyNick
- writetext Text_UsedCut
- reloadmappart
- callasm CutDownTreeOrGrass
- closetext
- end
-
-CutDownTreeOrGrass: ; c810
- ld hl, Buffer3 ; OverworldMapTile
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [Buffer5] ; ReplacementTile
- ld [hl], a
- xor a
- ld [hBGMapMode], a
- call OverworldTextModeSwitch
- call UpdateSprites
- call DelayFrame
- ld a, [Buffer6] ; Animation type
- ld e, a
- callba OWCutAnimation
- call BufferScreen
- call GetMovementPermissions
- call UpdateSprites
- call DelayFrame
- call LoadStandardFont
- ret
-
-CheckOverworldTileArrays: ; c840
- ; Input: c contains the tile you're facing
- ; Output: Replacement tile in b and effect on wild encounters in c, plus carry set.
- ; Carry is not set if the facing tile cannot be replaced, or if the tileset
- ; does not contain a tile you can replace.
-
- ; Dictionary lookup for pointer to tile replacement table
- push bc
- ld a, [wTileset]
- ld de, 3
- call IsInArray
- pop bc
- jr nc, .nope
- ; Load the pointer
- inc hl
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ; Look up the tile you're facing
- ld de, 3
- ld a, c
- call IsInArray
- jr nc, .nope
- ; Load the replacement to b
- inc hl
- ld b, [hl]
- ; Load the animation type parameter to c
- inc hl
- ld c, [hl]
- scf
- ret
-
-.nope
- xor a
- ret
-
-CutTreeBlockPointers: ; c862
-; Which tileset are we in?
- dbw TILESET_JOHTO_1, .johto1
- dbw TILESET_JOHTO_2, .johto2
- dbw TILESET_KANTO, .kanto
- dbw TILESET_PARK, .park
- dbw TILESET_ILEX_FOREST, .ilex
- db -1
-
-.johto1: ; Johto OW
-; Which meta tile are we facing, which should we replace it with, and which animation?
- db $03, $02, $01 ; grass
- db $5b, $3c, $00 ; tree
- db $5f, $3d, $00 ; tree
- db $63, $3f, $00 ; tree
- db $67, $3e, $00 ; tree
- db -1
-
-.johto2: ; Goldenrod area
- db $03, $02, $01 ; grass
- db -1
-
-.kanto: ; Kanto OW
- db $0b, $0a, $01 ; grass
- db $32, $6d, $00 ; tree
- db $33, $6c, $00 ; tree
- db $34, $6f, $00 ; tree
- db $35, $4c, $00 ; tree
- db $60, $6e, $00 ; tree
- db -1
-
-.park: ; National Park
- db $13, $03, $01 ; grass
- db $03, $04, $01 ; grass
- db -1
-
-.ilex: ; Ilex Forest
- db $0f, $17, $00
- db -1
-
-WhirlpoolBlockPointers: ; c8a4
- dbw TILESET_JOHTO_1, .johto
- db -1
-
-.johto: ; c8a8
- db $07, $36, $00
- db -1
-
-OWFlash: ; c8ac
- call .CheckUseFlash
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.CheckUseFlash: ; c8b5
-; Flash
- ld de, ENGINE_ZEPHYRBADGE
- callba CheckBadge
- jr c, .nozephyrbadge
- push hl
- callba SpecialAerodactylChamber
- pop hl
- jr c, .useflash
- ld a, [wTimeOfDayPalset]
- cp %11111111 ; 3, 3, 3, 3
- jr nz, .notadarkcave
-.useflash
- call UseFlash
- ld a, $81
- ret
-
-.notadarkcave
- call FieldMoveFailed
- ld a, $80
- ret
-
-.nozephyrbadge
- ld a, $80
- ret
-
-UseFlash: ; c8e0
- ld hl, Script_UseFlash
- jp QueueScript
-
-Script_UseFlash: ; 0xc8e6
- reloadmappart
- special UpdateTimePals
- writetext UnknownText_0xc8f3
- callasm BlindingFlash
- closetext
- end
-
-UnknownText_0xc8f3: ; 0xc8f3
- text_jump UnknownText_0x1c0609
- start_asm
- call WaitSFX
- ld de, SFX_FLASH
- call PlaySFX
- call WaitSFX
- ld hl, .BlankText
- ret
-
-.BlankText: ; 0xc908
- db "@"
-
-SurfFunction: ; c909
- call ClearBuffer1
-.loop
- ld hl, .Jumptable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.Jumptable: ; c91a (3:491a)
- dw .TrySurf
- dw .DoSurf
- dw .FailSurf
- dw .AlreadySurfing
-
-.TrySurf: ; c922 (3:4922)
- ld de, ENGINE_FOGBADGE
- call CheckBadge
- jr c, .asm_c956
- ld hl, BikeFlags
- bit 1, [hl] ; always on bike
- jr nz, .cannotsurf
- ld a, [PlayerState]
- cp PLAYER_SURF
- jr z, .alreadyfail
- cp PLAYER_SURF_PIKA
- jr z, .alreadyfail
- call GetFacingTileCoord
- call GetTileCollision
- cp $1
- jr nz, .cannotsurf
- call CheckDirection
- jr c, .cannotsurf
- callba CheckFacingObject
- jr c, .cannotsurf
- ld a, $1
- ret
-.asm_c956
- ld a, $80
- ret
-.alreadyfail
- ld a, $3
- ret
-.cannotsurf
- ld a, $2
- ret
-
-.DoSurf: ; c95f (3:495f)
- call GetSurfType
- ld [Buffer2], a ; wd1eb (aliases: MovementType)
- call GetPartyNick
- ld hl, SurfFromMenuScript
- call QueueScript
- ld a, $81
- ret
-
-.FailSurf: ; c971 (3:4971)
- ld hl, CantSurfText
- call MenuTextBoxBackup
- ld a, $80
- ret
-
-.AlreadySurfing: ; c97a (3:497a)
- ld hl, AlreadySurfingText
- call MenuTextBoxBackup
- ld a, $80
- ret
-
-SurfFromMenuScript: ; c983
- special UpdateTimePals
-
-UsedSurfScript: ; c986
- writetext UsedSurfText ; "used SURF!"
- waitbutton
- closetext
-
- callasm .empty_fn ; empty function
-
- copybytetovar Buffer2
- writevarcode VAR_MOVEMENT
-
- special ReplaceKrisSprite
- special PlayMapMusic
-; step into the water
- special Special_SurfStartStep ; (slow_step_x, step_end)
- applymovement PLAYER, MovementBuffer ; PLAYER, MovementBuffer
- end
-
-.empty_fn: ; c9a2
- callba MobileFn_1060bb ; empty
- ret
-
-UsedSurfText: ; c9a9
- text_jump _UsedSurfText
- db "@"
-
-CantSurfText: ; c9ae
- text_jump _CantSurfText
- db "@"
-
-AlreadySurfingText: ; c9b3
- text_jump _AlreadySurfingText
- db "@"
-
-GetSurfType: ; c9b8
-; Surfing on Pikachu uses an alternate sprite.
-; This is done by using a separate movement type.
-
- ld a, [CurPartyMon]
- ld e, a
- ld d, 0
- ld hl, PartySpecies
- add hl, de
-
- ld a, [hl]
- cp PIKACHU
- ld a, PLAYER_SURF_PIKA
- ret z
- ld a, PLAYER_SURF
- ret
-
-CheckDirection: ; c9cb
-; Return carry if a tile permission prevents you
-; from moving in the direction you're facing.
-
-; Get player direction
- ld a, [PlayerDirection]
- and a, %00001100 ; bits 2 and 3 contain direction
- rrca
- rrca
- ld e, a
- ld d, 0
- ld hl, .Directions
- add hl, de
-
-; Can you walk in this direction?
- ld a, [TilePermissions]
- and [hl]
- jr nz, .quit
- xor a
- ret
-
-.quit
- scf
- ret
-
-.Directions
- db FACE_DOWN
- db FACE_UP
- db FACE_LEFT
- db FACE_RIGHT
-
-TrySurfOW:: ; c9e7
-; Checking a tile in the overworld.
-; Return carry if fail is allowed.
-
-; Don't ask to surf if already fail.
- ld a, [PlayerState]
- cp PLAYER_SURF_PIKA
- jr z, .quit
- cp PLAYER_SURF
- jr z, .quit
-
-; Must be facing water.
- ld a, [EngineBuffer1]
- call GetTileCollision
- cp 1 ; surfable
- jr nz, .quit
-
-; Check tile permissions.
- call CheckDirection
- jr c, .quit
-
- ld de, ENGINE_FOGBADGE
- call CheckEngineFlag
- jr c, .quit
-
- ld d, SURF
- call CheckPartyMove
- jr c, .quit
-
- ld hl, BikeFlags
- bit 1, [hl] ; always on bike (can't surf)
- jr nz, .quit
-
- call GetSurfType
- ld [MovementType], a
- call GetPartyNick
-
- ld a, BANK(AskSurfScript)
- ld hl, AskSurfScript
- call CallScript
-
- scf
- ret
-
-.quit
- xor a
- ret
-
-AskSurfScript: ; ca2c
- opentext
- writetext AskSurfText
- yesorno
- iftrue UsedSurfScript
- closetext
- end
-
-AskSurfText: ; ca36
- text_jump _AskSurfText ; The water is calm.
- db "@" ; Want to SURF?
-
-FlyFunction: ; ca3b
- call ClearBuffer1
-.loop
- ld hl, .Jumptable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.Jumptable
- dw .TryFly
- dw .DoFly
- dw .FailFly
-
-.TryFly: ; ca52
-; Fly
- ld de, ENGINE_STORMBADGE
- call CheckBadge
- jr c, .nostormbadge
- call GetMapPermission
- call CheckOutdoorMap
- jr z, .outdoors
- jr .indoors
-
-.outdoors
- xor a
- ld [hMapAnims], a
- call LoadStandardMenuDataHeader
- call ClearSprites
- callba _FlyMap
- ld a, e
- cp -1
- jr z, .illegal
- cp NUM_SPAWNS
- jr nc, .illegal
-
- ld [wd001], a
- call CloseWindow
- ld a, $1
- ret
-
-.nostormbadge
- ld a, $82
- ret
-
-.indoors
- ld a, $2
- ret
-
-.illegal
- call CloseWindow
- call WaitBGMap
- ld a, $80
- ret
-
-.DoFly: ; ca94
- ld hl, .FlyScript
- call QueueScript
- ld a, $81
- ret
-
-.FailFly: ; ca9d
- call FieldMoveFailed
- ld a, $82
- ret
-
-.FlyScript: ; 0xcaa3
- reloadmappart
- callasm HideSprites
- special UpdateTimePals
- callasm FlyFromAnim
- farscall Script_AbortBugContest
- special WarpToSpawnPoint
- callasm DelayLoadingNewSprites
- writecode VAR_MOVEMENT, PLAYER_NORMAL
- newloadmap MAPSETUP_FLY
- callasm FlyToAnim
- special WaitSFX
- callasm .ReturnFromFly
- end
-
-.ReturnFromFly: ; cacb
- callba Function561d
- call DelayFrame
- call ReplaceKrisSprite
- callba LoadOverworldFont
- ret
-
-WaterfallFunction: ; cade
- call .TryWaterfall
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.TryWaterfall: ; cae7
-; Waterfall
- ld de, ENGINE_RISINGBADGE
- callba CheckBadge
- ld a, $80
- ret c
- call CheckMapCanWaterfall
- jr c, .failed
- ld hl, Script_WaterfallFromMenu
- call QueueScript
- ld a, $81
- ret
-
-.failed
- call FieldMoveFailed
- ld a, $80
- ret
-
-CheckMapCanWaterfall: ; cb07
- ld a, [PlayerDirection]
- and $c
- cp FACE_UP
- jr nz, .failed
- ld a, [TileUp]
- call CheckWaterfallTile
- jr nz, .failed
- xor a
- ret
-
-.failed
- scf
- ret
-
-Script_WaterfallFromMenu: ; 0xcb1c
- reloadmappart
- special UpdateTimePals
-
-Script_UsedWaterfall: ; 0xcb20
- callasm GetPartyNick
- writetext .Text_UsedWaterfall
- waitbutton
- closetext
- playsound SFX_BUBBLEBEAM
-.loop
- applymovement PLAYER, .WaterfallStep
- callasm .CheckContinueWaterfall
- iffalse .loop
- end
-
-.CheckContinueWaterfall: ; cb38
- xor a
- ld [ScriptVar], a
- ld a, [PlayerStandingTile]
- call CheckWaterfallTile
- ret z
- callba MobileFn_1060c1
- ld a, $1
- ld [ScriptVar], a
- ret
-
-.WaterfallStep: ; cb4f
- turn_waterfall_up
- step_end
-
-.Text_UsedWaterfall: ; 0xcb51
- ; used WATERFALL!
- text_jump UnknownText_0x1c068e
- db "@"
-
-TryWaterfallOW:: ; cb56
- ld d, WATERFALL
- call CheckPartyMove
- jr c, .failed
- ld de, ENGINE_RISINGBADGE
- call CheckEngineFlag
- jr c, .failed
- call CheckMapCanWaterfall
- jr c, .failed
- ld a, BANK(Script_AskWaterfall)
- ld hl, Script_AskWaterfall
- call CallScript
- scf
- ret
-
-.failed
- ld a, BANK(Script_CantDoWaterfall)
- ld hl, Script_CantDoWaterfall
- call CallScript
- scf
- ret
-
-Script_CantDoWaterfall: ; 0xcb7e
- jumptext .Text_CantDoWaterfall
-
-.Text_CantDoWaterfall: ; 0xcb81
- ; Wow, it's a huge waterfall.
- text_jump UnknownText_0x1c06a3
- db "@"
-
-Script_AskWaterfall: ; 0xcb86
- opentext
- writetext .AskUseWaterfall
- yesorno
- iftrue Script_UsedWaterfall
- closetext
- end
-
-.AskUseWaterfall: ; 0xcb90
- ; Do you want to use WATERFALL?
- text_jump UnknownText_0x1c06bf
- db "@"
-
-EscapeRopeFunction: ; cb95
- call ClearBuffer1
- ld a, $1
- jr dig_incave
-
-DigFunction: ; cb9c
- call ClearBuffer1
- ld a, $2
-
-dig_incave
- ld [Buffer2], a
-.loop
- ld hl, .DigTable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.DigTable: ; cbb2
- dw .CheckCanDig
- dw .DoDig
- dw .FailDig
-
-.CheckCanDig: ; cbb8
- call GetMapPermission
- cp CAVE
- jr z, .incave
- cp DUNGEON
- jr z, .incave
-.fail
- ld a, $2
- ret
-
-.incave
- ld hl, wDigWarp
- ld a, [hli]
- and a
- jr z, .fail
- ld a, [hli]
- and a
- jr z, .fail
- ld a, [hl]
- and a
- jr z, .fail
- ld a, $1
- ret
-
-.DoDig: ; cbd8
- ld hl, wDigWarp
- ld de, wNextWarp
- ld bc, 3
- call CopyBytes
- call GetPartyNick
- ld a, [Buffer2]
- cp $2
- jr nz, .escaperope
- ld hl, .UsedDigScript
- call QueueScript
- ld a, $81
- ret
-
-.escaperope
- callba SpecialKabutoChamber
- ld hl, .UsedEscapeRopeScript
- call QueueScript
- ld a, $81
- ret
-
-.FailDig: ; cc06
- ld a, [Buffer2]
- cp $2
- jr nz, .failescaperope
- ld hl, .Text_CantUseHere
- call MenuTextBox
- call WaitPressAorB_BlinkCursor
- call CloseWindow
-
-.failescaperope
- ld a, $80
- ret
-
-.Text_UsedDig: ; 0xcc1c
- ; used DIG!
- text_jump UnknownText_0x1c06de
- db "@"
-
-.Text_UsedEscapeRope: ; 0xcc21
- ; used an ESCAPE ROPE.
- text_jump UnknownText_0x1c06ed
- db "@"
-
-.Text_CantUseHere: ; 0xcc26
- ; Can't use that here.
- text_jump UnknownText_0x1c0705
- db "@"
-
-.UsedEscapeRopeScript: ; 0xcc2b
- reloadmappart
- special UpdateTimePals
- writetext .Text_UsedEscapeRope
- jump .UsedDigOrEscapeRopeScript
-
-.UsedDigScript: ; 0xcc35
- reloadmappart
- special UpdateTimePals
- writetext .Text_UsedDig
-
-.UsedDigOrEscapeRopeScript: ; 0xcc3c
- waitbutton
- closetext
- playsound SFX_WARP_TO
- applymovement PLAYER, .DigOut
- farscall Script_AbortBugContest
- special WarpToSpawnPoint
- writecode VAR_MOVEMENT, PLAYER_NORMAL
- newloadmap MAPSETUP_DOOR
- playsound SFX_WARP_FROM
- applymovement PLAYER, .DigReturn
- end
-
-.DigOut: ; 0xcc59
- step_dig 32
- hide_person
- step_end
-
-.DigReturn: ; 0xcc5d
- show_person
- return_dig 32
- step_end
-
-TeleportFunction: ; cc61
- call ClearBuffer1
-.loop
- ld hl, .Jumptable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.Jumptable: ; cc72
- dw .TryTeleport
- dw .DoTeleport
- dw .FailTeleport
-
-.TryTeleport: ; cc78
- call GetMapPermission
- call CheckOutdoorMap
- jr z, .CheckIfSpawnPoint
- jr .nope
-
-.CheckIfSpawnPoint
- ld a, [wLastSpawnMapGroup]
- ld d, a
- ld a, [wLastSpawnMapNumber]
- ld e, a
- callba IsSpawnPoint
- jr nc, .nope
- ld a, c
- ld [wd001], a
- ld a, $1
- ret
-
-.nope
- ld a, $2
- ret
-
-.DoTeleport: ; cc9c
- call GetPartyNick
- ld hl, .TeleportScript
- call QueueScript
- ld a, $81
- ret
-
-.FailTeleport: ; cca8
- ld hl, .Text_CantUseHere
- call MenuTextBoxBackup
- ld a, $80
- ret
-
-.Text_ReturnToLastMonCenter: ; 0xccb1
- ; Return to the last #MON CENTER.
- text_jump UnknownText_0x1c071a
- db "@"
-
-.Text_CantUseHere: ; 0xccb6
- ; Can't use that here.
- text_jump UnknownText_0x1c073b
- db "@"
-
-.TeleportScript: ; 0xccbb
- reloadmappart
- special UpdateTimePals
- writetext .Text_ReturnToLastMonCenter
- pause 60
- reloadmappart
- closetext
- playsound SFX_WARP_TO
- applymovement PLAYER, .TeleportFrom
- farscall Script_AbortBugContest
- special WarpToSpawnPoint
- writecode VAR_MOVEMENT, PLAYER_NORMAL
- newloadmap MAPSETUP_TELEPORT
- playsound SFX_WARP_FROM
- applymovement PLAYER, .TeleportTo
- end
-
-.TeleportFrom: ; cce1
- teleport_from
- step_end
-
-.TeleportTo: ; cce3
- teleport_to
- step_end
-
-StrengthFunction: ; cce5
- call .TryStrength
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.TryStrength: ; ccee
-; Strength
- ld de, ENGINE_PLAINBADGE
- call CheckBadge
- jr c, .Failed
- jr .UseStrength
-
-.AlreadyUsing: ; unreferenced
- ld hl, .JumpText
- call MenuTextBoxBackup
- ld a, $80
- ret
-
-.JumpText: ; 0xcd01
- text_jump UnknownText_0x1c0751
- db "@"
-
-.Failed: ; cd06
- ld a, $80
- ret
-
-.UseStrength: ; cd09
- ld hl, Script_StrengthFromMenu
- call QueueScript
- ld a, $81
- ret
-
-SetStrengthFlag: ; cd12
- ld hl, BikeFlags
- set 0, [hl]
- ld a, [CurPartyMon]
- ld e, a
- ld d, 0
- ld hl, PartySpecies
- add hl, de
- ld a, [hl]
- ld [Buffer6], a
- call GetPartyNick
- ret
-
-Script_StrengthFromMenu: ; 0xcd29
- reloadmappart
- special UpdateTimePals
-
-Script_UsedStrength: ; 0xcd2d
- callasm SetStrengthFlag
- writetext .UsedStrength
- copybytetovar Buffer6
- cry 0
- pause 3
- writetext .StrengthAllowedItToMoveBoulders
- closetext
- end
-
-.UsedStrength: ; 0xcd41
- text_jump UnknownText_0x1c0774
- db "@"
-
-.StrengthAllowedItToMoveBoulders: ; 0xcd46
- text_jump UnknownText_0x1c0788
- db "@"
-
-AskStrengthScript:
- callasm TryStrengthOW
- iffalse .AskStrength
- if_equal $1, .DontMeetRequirements
- jump .AlreadyUsedStrength
-
-.DontMeetRequirements: ; 0xcd59
- jumptext UnknownText_0xcd73
-
-.AlreadyUsedStrength: ; 0xcd5c
- jumptext UnknownText_0xcd6e
-
-.AskStrength: ; 0xcd5f
- opentext
- writetext UnknownText_0xcd69
- yesorno
- iftrue Script_UsedStrength
- closetext
- end
-
-UnknownText_0xcd69: ; 0xcd69
- ; A #MON may be able to move this. Want to use STRENGTH?
- text_jump UnknownText_0x1c07a0
- db "@"
-
-UnknownText_0xcd6e: ; 0xcd6e
- ; Boulders may now be moved!
- text_jump UnknownText_0x1c07d8
- db "@"
-
-UnknownText_0xcd73: ; 0xcd73
- ; A #MON may be able to move this.
- text_jump UnknownText_0x1c07f4
- db "@"
-
-TryStrengthOW: ; cd78
- ld d, STRENGTH
- call CheckPartyMove
- jr c, .nope
-
- ld de, ENGINE_PLAINBADGE
- call CheckEngineFlag
- jr c, .nope
-
- ld hl, BikeFlags
- bit 0, [hl]
- jr z, .already_using
-
- ld a, 2
- jr .done
-
-.nope
- ld a, 1
- jr .done
-
-.already_using
- xor a
- jr .done
-
-.done
- ld [ScriptVar], a
- ret
-
-WhirlpoolFunction: ; cd9d
- call ClearBuffer1
-.loop
- ld hl, Jumptable_cdae
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-Jumptable_cdae: ; cdae
- dw .TryWhirlpool
- dw .DoWhirlpool
- dw .FailWhirlpool
-
-.TryWhirlpool: ; cdb4
- ld de, ENGINE_GLACIERBADGE
- call CheckBadge
- jr c, .noglacierbadge
- call TryWhirlpoolMenu
- jr c, .failed
- ld a, $1
- ret
-
-.failed
- ld a, $2
- ret
-
-.noglacierbadge
- ld a, $80
- ret
-
-.DoWhirlpool: ; cdca
- ld hl, Script_WhirlpoolFromMenu
- call QueueScript
- ld a, $81
- ret
-
-.FailWhirlpool: ; cdd3
- call FieldMoveFailed
- ld a, $80
- ret
-
-Text_UsedWhirlpool: ; 0xcdd9
- ; used WHIRLPOOL!
- text_jump UnknownText_0x1c0816
- db "@"
-
-TryWhirlpoolMenu: ; cdde
- call GetFacingTileCoord
- ld c, a
- push de
- call CheckWhirlpoolTile
- pop de
- jr c, .failed
- call GetBlockLocation
- ld c, [hl]
- push hl
- ld hl, WhirlpoolBlockPointers
- call CheckOverworldTileArrays
- pop hl
- jr nc, .failed
- ld a, l
- ld [Buffer3], a
- ld a, h
- ld [Buffer4], a
- ld a, b
- ld [Buffer5], a
- ld a, c
- ld [Buffer6], a
- xor a
- ret
-
-.failed
- scf
- ret
-
-Script_WhirlpoolFromMenu: ; 0xce0b
- reloadmappart
- special UpdateTimePals
-
-Script_UsedWhirlpool: ; 0xce0f
- callasm GetPartyNick
- writetext Text_UsedWhirlpool
- reloadmappart
- callasm DisappearWhirlpool
- closetext
- end
-
-DisappearWhirlpool: ; ce1d
- ld hl, Buffer3
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [Buffer5]
- ld [hl], a
- xor a
- ld [hBGMapMode], a
- call OverworldTextModeSwitch
- ld a, [Buffer6]
- ld e, a
- callba PlayWhirlpoolSound
- call BufferScreen
- call GetMovementPermissions
- ret
-
-TryWhirlpoolOW:: ; ce3e
- ld d, WHIRLPOOL
- call CheckPartyMove
- jr c, .failed
- ld de, ENGINE_GLACIERBADGE
- call CheckEngineFlag
- jr c, .failed
- call TryWhirlpoolMenu
- jr c, .failed
- ld a, BANK(Script_AskWhirlpoolOW)
- ld hl, Script_AskWhirlpoolOW
- call CallScript
- scf
- ret
-
-.failed
- ld a, BANK(Script_MightyWhirlpool)
- ld hl, Script_MightyWhirlpool
- call CallScript
- scf
- ret
-
-Script_MightyWhirlpool: ; 0xce66
- jumptext .MightyWhirlpoolText
-
-.MightyWhirlpoolText: ; 0xce69
- text_jump UnknownText_0x1c082b
- db "@"
-
-Script_AskWhirlpoolOW: ; 0xce6e
- opentext
- writetext UnknownText_0xce78
- yesorno
- iftrue Script_UsedWhirlpool
- closetext
- end
-
-UnknownText_0xce78: ; 0xce78
- text_jump UnknownText_0x1c0864
- db "@"
-
-HeadbuttFunction: ; ce7d
- call TryHeadbuttFromMenu
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-TryHeadbuttFromMenu: ; ce86
- call GetFacingTileCoord
- call CheckHeadbuttTreeTile
- jr nz, .no_tree
-
- ld hl, HeadbuttFromMenuScript
- call QueueScript
- ld a, $81
- ret
-
-.no_tree
- call FieldMoveFailed
- ld a, $80
- ret
-
-UnknownText_0xce9d: ; 0xce9d
- ; did a HEADBUTT!
- text_jump UnknownText_0x1c0897
- db "@"
-
-UnknownText_0xcea2: ; 0xcea2
- ; Nope. Nothing…
- text_jump UnknownText_0x1c08ac
- db "@"
-
-HeadbuttFromMenuScript: ; 0xcea7
- reloadmappart
- special UpdateTimePals
-
-HeadbuttScript: ; 0xceab
- callasm GetPartyNick
- writetext UnknownText_0xce9d
-
- reloadmappart
- callasm ShakeHeadbuttTree
-
- callasm TreeMonEncounter
- iffalse .no_battle
- closetext
- randomwildmon
- startbattle
- reloadmapafterbattle
- end
-
-.no_battle
- writetext UnknownText_0xcea2
- waitbutton
- closetext
- end
-
-TryHeadbuttOW:: ; cec9
- ld d, HEADBUTT
- call CheckPartyMove
- jr c, .no
-
- ld a, BANK(AskHeadbuttScript)
- ld hl, AskHeadbuttScript
- call CallScript
- scf
- ret
-
-.no
- xor a
- ret
-
-AskHeadbuttScript: ; 0xcedc
- opentext
- writetext UnknownText_0xcee6
- yesorno
- iftrue HeadbuttScript
- closetext
- end
-
-UnknownText_0xcee6: ; 0xcee6
- ; A #MON could be in this tree. Want to HEADBUTT it?
- text_jump UnknownText_0x1c08bc
- db "@"
-
-RockSmashFunction: ; ceeb
- call TryRockSmashFromMenu
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-TryRockSmashFromMenu: ; cef4
- call GetFacingObject
- jr c, .no_rock
- ld a, d
- cp $18
- jr nz, .no_rock
-
- ld hl, RockSmashFromMenuScript
- call QueueScript
- ld a, $81
- ret
-
-.no_rock
- call FieldMoveFailed
- ld a, $80
- ret
-
-GetFacingObject: ; cf0d
- callba CheckFacingObject
- jr nc, .fail
-
- ld a, [hObjectStructIndexBuffer]
- call GetObjectStruct
- ld hl, OBJECT_MAP_OBJECT_INDEX
- add hl, bc
- ld a, [hl]
- ld [hLastTalked], a
- call GetMapObject
- ld hl, MAPOBJECT_MOVEMENT
- add hl, bc
- ld a, [hl]
- ld d, a
- and a
- ret
-
-.fail
- scf
- ret
-
-RockSmashFromMenuScript: ; 0xcf2e
- reloadmappart
- special UpdateTimePals
-
-RockSmashScript: ; cf32
- callasm GetPartyNick
- writetext UnknownText_0xcf58
- closetext
- special WaitSFX
- playsound SFX_STRENGTH
- earthquake 84
- applymovement2 MovementData_0xcf55
- disappear -2
-
- callasm RockMonEncounter
- copybytetovar TempWildMonSpecies
- iffalse .done
- randomwildmon
- startbattle
- reloadmapafterbattle
-.done
- end
-
-MovementData_0xcf55: ; 0xcf55
- rock_smash 10
- step_end
-
-UnknownText_0xcf58: ; 0xcf58
- text_jump UnknownText_0x1c08f0
- db "@"
-
-AskRockSmashScript: ; 0xcf5d
- callasm HasRockSmash
- if_equal 1, .no
-
- opentext
- writetext UnknownText_0xcf77
- yesorno
- iftrue RockSmashScript
- closetext
- end
-.no
- jumptext UnknownText_0xcf72
-
-UnknownText_0xcf72: ; 0xcf72
- ; Maybe a #MON can break this.
- text_jump UnknownText_0x1c0906
- db "@"
-
-UnknownText_0xcf77: ; 0xcf77
- ; This rock looks breakable. Want to use ROCK SMASH?
- text_jump UnknownText_0x1c0924
- db "@"
-
-HasRockSmash: ; cf7c
- ld d, ROCK_SMASH
- call CheckPartyMove
- jr nc, .yes
-.no
- ld a, 1
- jr .done
-.yes
- xor a
- jr .done
-.done
- ld [ScriptVar], a
- ret
-
-FishFunction: ; cf8e
- ld a, e
- push af
- call ClearBuffer1
- pop af
- ld [Buffer2], a
-.loop
- ld hl, .FishTable
- call FieldMoveJumptable
- jr nc, .loop
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.FishTable: ; cfa5
- dw .TryFish
- dw .FishNoBite
- dw .FishGotSomething
- dw .FailFish
- dw .FishNoFish
-
-.TryFish: ; cfaf
- ld a, [PlayerState]
- cp PLAYER_SURF
- jr z, .fail
- cp PLAYER_SURF_PIKA
- jr z, .fail
- call GetFacingTileCoord
- call GetTileCollision
- cp $1
- jr z, .facingwater
-.fail
- ld a, $3
- ret
-
-.facingwater
- call GetFishingGroup
- and a
- jr nz, .goodtofish
- ld a, $4
- ret
-
-.goodtofish
- ld d, a
- ld a, [Buffer2]
- ld e, a
- callba Fish
- ld a, d
- and a
- jr z, .nonibble
- ld [TempWildMonSpecies], a
- ld a, e
- ld [CurPartyLevel], a
- ld a, BATTLETYPE_FISH
- ld [BattleType], a
- ld a, $2
- ret
-
-.nonibble
- ld a, $1
- ret
-
-.FailFish: ; cff1
- ld a, $80
- ret
-
-.FishGotSomething: ; cff4
- ld a, $1
- ld [Buffer6], a
- ld hl, Script_GotABite
- call QueueScript
- ld a, $81
- ret
-
-.FishNoBite: ; d002
- ld a, $2
- ld [Buffer6], a
- ld hl, Script_NotEvenANibble
- call QueueScript
- ld a, $81
- ret
-
-.FishNoFish: ; d010
- ld a, $0
- ld [Buffer6], a
- ld hl, Script_NotEvenANibble2
- call QueueScript
- ld a, $81
- ret
-
-Script_NotEvenANibble: ; 0xd01e
- scall Script_FishCastRod
- writetext UnknownText_0xd0a9
- jump Script_NotEvenANibble_FallThrough
-
-Script_NotEvenANibble2: ; 0xd027
- scall Script_FishCastRod
- writetext UnknownText_0xd0a9
-
-Script_NotEvenANibble_FallThrough: ; 0xd02d
- loademote EMOTE_SHADOW
- callasm PutTheRodAway
- closetext
- end
-
-Script_GotABite: ; 0xd035
- scall Script_FishCastRod
- callasm Fishing_CheckFacingUp
- iffalse .NotFacingUp
- applymovement PLAYER, .Movement_FacingUp
- jump .FightTheHookedPokemon
-
-.NotFacingUp: ; 0xd046
- applymovement PLAYER, .Movement_NotFacingUp
-
-.FightTheHookedPokemon: ; 0xd04a
- pause 40
- applymovement PLAYER, .Movement_RestoreRod
- writetext UnknownText_0xd0a4
- callasm PutTheRodAway
- closetext
- randomwildmon
- startbattle
- reloadmapafterbattle
- end
-
-.Movement_NotFacingUp: ; d05c
- fish_got_bite
- fish_got_bite
- fish_got_bite
- fish_got_bite
- show_emote
- step_end
-
-.Movement_FacingUp: ; d062
- fish_got_bite
- fish_got_bite
- fish_got_bite
- fish_got_bite
- step_sleep_1
- show_emote
- step_end
-
-.Movement_RestoreRod: ; d069
- hide_emote
- fish_cast_rod
- step_end
-
-Fishing_CheckFacingUp: ; d06c
- ld a, [PlayerDirection]
- and $c
- cp OW_UP
- ld a, $1
- jr z, .up
- xor a
-
-.up
- ld [ScriptVar], a
- ret
-
-Script_FishCastRod: ; 0xd07c
- reloadmappart
- loadvar hBGMapMode, $0
- special UpdateTimePals
- loademote EMOTE_ROD
- callasm LoadFishingGFX
- loademote EMOTE_SHOCK
- applymovement PLAYER, MovementData_0xd093
- pause 40
- end
-
-MovementData_0xd093: ; d093
- fish_cast_rod
- step_end
-
-PutTheRodAway: ; d095
- xor a
- ld [hBGMapMode], a
- ld a, $1
- ld [PlayerAction], a
- call UpdateSprites
- call ReplaceKrisSprite
- ret
-
-UnknownText_0xd0a4: ; 0xd0a4
- ; Oh! A bite!
- text_jump UnknownText_0x1c0958
- db "@"
-
-UnknownText_0xd0a9: ; 0xd0a9
- ; Not even a nibble!
- text_jump UnknownText_0x1c0965
- db "@"
-
-UnknownText_0xd0ae: ; unused
- ; Looks like there's nothing here.
- text_jump UnknownText_0x1c0979
- db "@"
-
-BikeFunction: ; d0b3
- call .TryBike
- and $7f
- ld [wFieldMoveSucceeded], a
- ret
-
-.TryBike: ; d0bc
- call .CheckEnvironment
- jr c, .CannotUseBike
- ld a, [PlayerState]
- cp PLAYER_NORMAL
- jr z, .GetOnBike
- cp PLAYER_BIKE
- jr z, .GetOffBike
- jr .CannotUseBike
-
-.GetOnBike
- ld hl, Script_GetOnBike
- ld de, Script_GetOnBike_Register
- call .CheckIfRegistered
- call QueueScript
- xor a
- ld [MusicFade], a
- ld de, MUSIC_NONE
- call PlayMusic
- call DelayFrame
- call MaxVolume
- ld de, MUSIC_BICYCLE
- ld a, e
- ld [wMapMusic], a
- call PlayMusic
- ld a, $1
- ret
-
-.GetOffBike
- ld hl, BikeFlags
- bit 1, [hl]
- jr nz, .CantGetOffBike
- ld hl, Script_GetOffBike
- ld de, Script_GetOffBike_Register
- call .CheckIfRegistered
- ld a, BANK(Script_GetOffBike)
- jr .done
-
-.CantGetOffBike
- ld hl, Script_CantGetOffBike
- jr .done
-
-.CannotUseBike
- ld a, $0
- ret
-
-.done
- call QueueScript
- ld a, $1
- ret
-
-.CheckIfRegistered: ; d119
- ld a, [wUsingItemWithSelect]
- and a
- ret z
- ld h, d
- ld l, e
- ret
-
-.CheckEnvironment: ; d121
- call GetMapPermission
- call CheckOutdoorMap
- jr z, .ok
- cp CAVE
- jr z, .ok
- cp GATE
- jr z, .ok
- jr .nope
-
-.ok
- call GetPlayerStandingTile
- and $f ; can't use our bike in a wall or on water
- jr nz, .nope
- xor a
- ret
-
-.nope
- scf
- ret
-
-Script_GetOnBike: ; 0xd13e
- reloadmappart
- special UpdateTimePals
- writecode VAR_MOVEMENT, PLAYER_BIKE
- writetext GotOnTheBikeText
- waitbutton
- closetext
- special ReplaceKrisSprite
- end
-
-Script_GetOnBike_Register: ; 0xd14e
- writecode VAR_MOVEMENT, PLAYER_BIKE
- closetext
- special ReplaceKrisSprite
- end
-
-; XXX
- nop
- ret
-
-Script_GetOffBike: ; 0xd158
- reloadmappart
- special UpdateTimePals
- writecode VAR_MOVEMENT, PLAYER_NORMAL
- writetext GotOffTheBikeText
- waitbutton
-
-FinishGettingOffBike:
- closetext
- special ReplaceKrisSprite
- special PlayMapMusic
- end
-
-Script_GetOffBike_Register: ; 0xd16b
- writecode VAR_MOVEMENT, PLAYER_NORMAL
- jump FinishGettingOffBike
-
-Script_CantGetOffBike: ; 0xd171
- writetext .CantGetOffBikeText
- waitbutton
- closetext
- end
-
-.CantGetOffBikeText: ; 0xd177
- ; You can't get off here!
- text_jump UnknownText_0x1c099a
- db "@"
-
-GotOnTheBikeText: ; 0xd17c
- ; got on the @ .
- text_jump UnknownText_0x1c09b2
- db "@"
-
-GotOffTheBikeText: ; 0xd181
- ; got off the @ .
- text_jump UnknownText_0x1c09c7
- db "@"
-
-TryCutOW:: ; d186
- ld d, CUT
- call CheckPartyMove
- jr c, .cant_cut
-
- ld de, ENGINE_HIVEBADGE
- call CheckEngineFlag
- jr c, .cant_cut
-
- ld a, BANK(AskCutScript)
- ld hl, AskCutScript
- call CallScript
- scf
- ret
-
-.cant_cut
- ld a, BANK(CantCutScript)
- ld hl, CantCutScript
- call CallScript
- scf
- ret
-
-AskCutScript: ; 0xd1a9
- opentext
- writetext UnknownText_0xd1c8
- yesorno
- iffalse .script_d1b8
- callasm .CheckMap
- iftrue Script_Cut
-.script_d1b8
- closetext
- end
-
-.CheckMap: ; d1ba
- xor a
- ld [ScriptVar], a
- call CheckMapForSomethingToCut
- ret c
- ld a, TRUE
- ld [ScriptVar], a
- ret
-
-UnknownText_0xd1c8: ; 0xd1c8
- text_jump UnknownText_0x1c09dd
- db "@"
-
-CantCutScript: ; 0xd1cd
- jumptext UnknownText_0xd1d0
-
-UnknownText_0xd1d0: ; 0xd1d0
- text_jump UnknownText_0x1c0a05
- db "@"
-
-_ReceiveItem:: ; d1d5
- call DoesHLEqualNumItems
- jp nz, PutItemInPocket
- push hl
- call CheckItemPocket
- pop de
- ld a, [wItemAttributeParamBuffer]
- dec a
- ld hl, .Pockets
- rst JumpTable
- ret
-
-.Pockets: ; d1e9
- dw .Item
- dw .KeyItem
- dw .Ball
- dw .TMHM
-
-.Item: ; d1f1
- ld h, d
- ld l, e
- jp PutItemInPocket
-
-.KeyItem: ; d1f6
- ld h, d
- ld l, e
- jp ReceiveKeyItem
-
-.Ball: ; d1fb
- ld hl, NumBalls
- jp PutItemInPocket
-
-.TMHM: ; d201
- ld h, d
- ld l, e
- ld a, [CurItem]
- ld c, a
- call GetTMHMNumber
- jp ReceiveTMHM
-
-_TossItem:: ; d20d
- call DoesHLEqualNumItems
- jr nz, .remove
- push hl
- call CheckItemPocket
- pop de
- ld a, [wItemAttributeParamBuffer]
- dec a
- ld hl, .Pockets
- rst JumpTable
- ret
-
-.Pockets
- dw .Item
- dw .KeyItem
- dw .Ball
- dw .TMHM
-
-.Ball ; d228
- ld hl, NumBalls
- jp RemoveItemFromPocket
-
-.TMHM ; d22e
- ld h, d
- ld l, e
- ld a, [CurItem]
- ld c, a
- call GetTMHMNumber
- jp TossTMHM
-
-.KeyItem ; d23a
- ld h, d
- ld l, e
- jp TossKeyItem
-
-.Item ; d23f
- ld h, d
- ld l, e
-
-.remove
- jp RemoveItemFromPocket
-
-_CheckItem:: ; d244
- call DoesHLEqualNumItems
- jr nz, .nope
- push hl
- call CheckItemPocket
- pop de
- ld a, [wItemAttributeParamBuffer]
- dec a
- ld hl, .Pockets
- rst JumpTable
- ret
-
-.Pockets
- dw .Item
- dw .KeyItem
- dw .Ball
- dw .TMHM
-
-.Ball ; d25f
- ld hl, NumBalls
- jp CheckTheItem
-
-.TMHM ; d265
- ld h, d
- ld l, e
- ld a, [CurItem]
- ld c, a
- call GetTMHMNumber
- jp CheckTMHM
-
-.KeyItem ; d271
- ld h, d
- ld l, e
- jp CheckKeyItems
-
-.Item ; d276
- ld h, d
- ld l, e
-
-.nope
- jp CheckTheItem
-
-DoesHLEqualNumItems: ; d27b
- ld a, l
- cp NumItems % $100
- ret nz
- ld a, h
- cp NumItems / $100
- ret
-
-GetPocketCapacity: ; d283
- ld c, MAX_ITEMS
- ld a, e
- cp NumItems % $100
- jr nz, .not_bag
- ld a, d
- cp NumItems / $100
- ret z
-
-.not_bag
- ld c, MAX_PC_ITEMS
- ld a, e
- cp PCItems % $100
- jr nz, .not_pc
- ld a, d
- cp PCItems / $100
- ret z
-
-.not_pc
- ld c, MAX_BALLS
- ret
-
-PutItemInPocket: ; d29c
- ld d, h
- ld e, l
- inc hl
- ld a, [CurItem]
- ld c, a
- ld b, 0
-.loop
- ld a, [hli]
- cp -1
- jr z, .terminator
- cp c
- jr nz, .next
- ld a, 99
- sub [hl]
- add b
- ld b, a
- ld a, [wItemQuantityChangeBuffer]
- cp b
- jr z, .ok
- jr c, .ok
-
-.next
- inc hl
- jr .loop
-
-.terminator
- call GetPocketCapacity
- ld a, [de]
- cp c
- jr c, .ok
- and a
- ret
-
-.ok
- ld h, d
- ld l, e
- ld a, [CurItem]
- ld c, a
- ld a, [wItemQuantityChangeBuffer]
- ld [wItemQuantityBuffer], a
-.loop2
- inc hl
- ld a, [hli]
- cp -1
- jr z, .terminator2
- cp c
- jr nz, .loop2
- ld a, [wItemQuantityBuffer]
- add [hl]
- cp 100
- jr nc, .newstack
- ld [hl], a
- jr .done
-
-.newstack
- ld [hl], 99
- sub 99
- ld [wItemQuantityBuffer], a
- jr .loop2
-
-.terminator2
- dec hl
- ld a, [CurItem]
- ld [hli], a
- ld a, [wItemQuantityBuffer]
- ld [hli], a
- ld [hl], -1
- ld h, d
- ld l, e
- inc [hl]
-
-.done
- scf
- ret
-
-RemoveItemFromPocket: ; d2ff
- ld d, h
- ld e, l
- ld a, [hli]
- ld c, a
- ld a, [CurItemQuantity]
- cp c
- jr nc, .ok ; memory
- ld c, a
- ld b, $0
- add hl, bc
- add hl, bc
- ld a, [CurItem]
- cp [hl]
- inc hl
- jr z, .skip
- ld h, d
- ld l, e
- inc hl
-
-.ok
- ld a, [CurItem]
- ld b, a
-.loop
- ld a, [hli]
- cp b
- jr z, .skip
- cp -1
- jr z, .nope
- inc hl
- jr .loop
-
-.skip
- ld a, [wItemQuantityChangeBuffer]
- ld b, a
- ld a, [hl]
- sub b
- jr c, .nope
- ld [hl], a
- ld [wItemQuantityBuffer], a
- and a
- jr nz, .yup
- dec hl
- ld b, h
- ld c, l
- inc hl
- inc hl
-.loop2
- ld a, [hli]
- ld [bc], a
- inc bc
- cp -1
- jr nz, .loop2
- ld h, d
- ld l, e
- dec [hl]
-
-.yup
- scf
- ret
-
-.nope
- and a
- ret
-
-CheckTheItem: ; d349
- ld a, [CurItem]
- ld c, a
-.loop
- inc hl
- ld a, [hli]
- cp -1
- jr z, .done
- cp c
- jr nz, .loop
- scf
- ret
-
-.done
- and a
- ret
-
-ReceiveKeyItem: ; d35a
- ld hl, NumKeyItems
- ld a, [hli]
- cp MAX_KEY_ITEMS
- jr nc, .nope
- ld c, a
- ld b, 0
- add hl, bc
- ld a, [CurItem]
- ld [hli], a
- ld [hl], -1
- ld hl, NumKeyItems
- inc [hl]
- scf
- ret
-
-.nope
- and a
- ret
-
-TossKeyItem: ; d374
- ld a, [wd107]
- ld e, a
- ld d, 0
- ld hl, NumKeyItems
- ld a, [hl]
- cp e
- jr nc, .ok
- call .Toss
- ret nc
- jr .ok2
-
-.ok
- dec [hl]
- inc hl
- add hl, de
-
-.ok2
- ld d, h
- ld e, l
- inc hl
-.loop
- ld a, [hli]
- ld [de], a
- inc de
- cp -1
- jr nz, .loop
- scf
- ret
-
-.Toss: ; d396
- ld hl, NumKeyItems
- ld a, [CurItem]
- ld c, a
-.loop3
- inc hl
- ld a, [hl]
- cp c
- jr z, .ok3
- cp -1
- jr nz, .loop3
- xor a
- ret
-
-.ok3
- ld a, [NumKeyItems]
- dec a
- ld [NumKeyItems], a
- scf
- ret
-
-CheckKeyItems: ; d3b1
- ld a, [CurItem]
- ld c, a
- ld hl, KeyItems
-.loop
- ld a, [hli]
- cp c
- jr z, .done
- cp -1
- jr nz, .loop
- and a
- ret
-
-.done
- scf
- ret
-
-ReceiveTMHM: ; d3c4
- dec c
- ld b, 0
- ld hl, TMsHMs
- add hl, bc
- ld a, [wItemQuantityChangeBuffer]
- add [hl]
- cp 100
- jr nc, .toomany
- ld [hl], a
- scf
- ret
-
-.toomany
- and a
- ret
-
-TossTMHM: ; d3d8
- dec c
- ld b, 0
- ld hl, TMsHMs
- add hl, bc
- ld a, [wItemQuantityChangeBuffer]
- ld b, a
- ld a, [hl]
- sub b
- jr c, .nope
- ld [hl], a
- ld [wItemQuantityBuffer], a
- jr nz, .yup
- ld a, [wTMHMPocketScrollPosition]
- and a
- jr z, .yup
- dec a
- ld [wTMHMPocketScrollPosition], a
-
-.yup
- scf
- ret
-
-.nope
- and a
- ret
-
-CheckTMHM: ; d3fb
- dec c
- ld b, $0
- ld hl, TMsHMs
- add hl, bc
- ld a, [hl]
- and a
- ret z
- scf
- ret
-
-GetTMHMNumber:: ; d407
-; Return the number of a TM/HM by item id c.
-
- ld a, c
-
-; Skip any dummy items.
- cp ITEM_C3 ; TM04-05
- jr c, .done
- cp ITEM_DC ; TM28-29
- jr c, .skip
-
- dec a
-.skip
- dec a
-.done
- sub TM01
- inc a
- ld c, a
- ret
-
-GetNumberedTMHM: ; d417
-; Return the item id of a TM/HM by number c.
-
- ld a, c
-
-; Skip any gaps.
- cp ITEM_C3 - (TM01 - 1)
- jr c, .done
- cp ITEM_DC - (TM01 - 1) - 1
- jr c, .skip_one
-
-.skip_two
- inc a
-.skip_one
- inc a
-.done
- add TM01
- dec a
- ld c, a
- ret
-
-_CheckTossableItem:: ; d427
-; Return 1 in wItemAttributeParamBuffer and carry if CurItem can't be removed from the bag.
- ld a, ITEMATTR_PERMISSIONS
- call GetItemAttr
- bit 7, a
- jr nz, ItemAttr_ReturnCarry
- and a
- ret
-
-CheckSelectableItem: ; d432
-; Return 1 in wItemAttributeParamBuffer and carry if CurItem can't be selected.
- ld a, ITEMATTR_PERMISSIONS
- call GetItemAttr
- bit 6, a
- jr nz, ItemAttr_ReturnCarry
- and a
- ret
-
-CheckItemPocket:: ; d43d
-; Return the pocket for CurItem in wItemAttributeParamBuffer.
- ld a, ITEMATTR_POCKET
- call GetItemAttr
- and $f
- ld [wItemAttributeParamBuffer], a
- ret
-
-CheckItemContext: ; d448
-; Return the context for CurItem in wItemAttributeParamBuffer.
- ld a, ITEMATTR_HELP
- call GetItemAttr
- and $f
- ld [wItemAttributeParamBuffer], a
- ret
-
-CheckItemMenu: ; d453
-; Return the menu for CurItem in wItemAttributeParamBuffer.
- ld a, ITEMATTR_HELP
- call GetItemAttr
- swap a
- and $f
- ld [wItemAttributeParamBuffer], a
- ret
-
-GetItemAttr: ; d460
-; Get attribute a of CurItem.
-
- push hl
- push bc
-
- ld hl, ItemAttributes
- ld c, a
- ld b, 0
- add hl, bc
-
- xor a
- ld [wItemAttributeParamBuffer], a
-
- ld a, [CurItem]
- dec a
- ld c, a
- ld a, NUM_ITEMATTRS
- call AddNTimes
- ld a, BANK(ItemAttributes)
- call GetFarByte
-
- pop bc
- pop hl
- ret
-
-ItemAttr_ReturnCarry: ; d47f
- ld a, 1
- ld [wItemAttributeParamBuffer], a
- scf
- ret
-
-GetItemPrice: ; d486
-; Return the price of CurItem in de.
- push hl
- push bc
- ld a, ITEMATTR_PRICE
- call GetItemAttr
- ld e, a
- ld a, ITEMATTR_PRICE_HI
- call GetItemAttr
- ld d, a
- pop bc
- pop hl
- ret
-
+INCLUDE "engine/printnum.asm"
+INCLUDE "engine/health.asm"
+INCLUDE "event/overworld.asm"
+INCLUDE "engine/items.asm"
INCLUDE "engine/player_step.asm"
INCLUDE "engine/anim_hp_bar.asm"
INCLUDE "engine/move_mon.asm"
+INCLUDE "engine/billspctop.asm"
-_BillsPC: ; e3fd
- call .CheckCanUsePC
- ret c
- call .LogIn
- call .UseBillsPC
- jp .LogOut
-
-.CheckCanUsePC: ; e40a (3:640a)
- ld a, [PartyCount]
- and a
- ret nz
- ld hl, .Text_GottaHavePokemon
- call MenuTextBoxBackup
- scf
- ret
-
-.Text_GottaHavePokemon: ; 0xe417
- ; You gotta have #MON to call!
- text_jump UnknownText_0x1c1006
- db "@"
-
-.LogIn: ; e41c (3:641c)
- xor a
- ld [hBGMapMode], a
- call LoadStandardMenuDataHeader
- call ClearPCItemScreen
- ld hl, Options
- ld a, [hl]
- push af
- set NO_TEXT_SCROLL, [hl]
- ld hl, .Text_What
- call PrintText
- pop af
- ld [Options], a
- call LoadFontsBattleExtra
- ret
-
-.Text_What: ; 0xe43a
- ; What?
- text_jump UnknownText_0x1c1024
- db "@"
-
-.LogOut: ; e43f (3:643f)
- call CloseSubmenu
- ret
-
-.UseBillsPC: ; e443 (3:6443)
- ld hl, .MenuDataHeader
- call LoadMenuDataHeader
- ld a, $1
-.loop
- ld [wMenuCursorBuffer], a
- call SetPalettes
- xor a
- ld [wWhichIndexSet], a
- ld [hBGMapMode], a
- call DoNthMenu
- jr c, .cancel
- ld a, [wMenuCursorBuffer]
- push af
- ld a, [MenuSelection]
- ld hl, .Jumptable
- rst JumpTable
- pop bc
- ld a, b
- jr nc, .loop
-.cancel
- call CloseWindow
- ret
-
-.MenuDataHeader: ; 0xe46f
- db $40 ; flags
- db 00, 00 ; start coords
- db 17, 19 ; end coords
- dw .MenuData2
- db 1 ; default option
-
-.MenuData2: ; 0xe477
- db $80 ; flags
- db 0 ; items
- dw .items
- dw PlaceMenuStrings
- dw .strings
-
-.strings: ; e47f
- db "WITHDRAW <PK><MN>@"
- db "DEPOSIT <PK><MN>@"
- db "CHANGE BOX@"
- db "MOVE <PK><MN> W/O MAIL@"
- db "SEE YA!@"
-
-.Jumptable: ; e4ba (3:64ba)
- dw BillsPC_WithdrawMenu
- dw BillsPC_DepositMenu
- dw BillsPC_ChangeBoxMenu
- dw BillsPC_MovePKMNMenu
- dw BillsPC_SeeYa
-
-.items: ; e4c4
- db 5
- db 0 ; WITHDRAW
- db 1; DEPOSIT
- db 2 ; CHANGE BOX
- db 3 ; MOVE PKMN
- db 4 ; SEE YA!
- db -1
-
-BillsPC_SeeYa: ; e4cb
- scf
- ret
-
-BillsPC_MovePKMNMenu: ; e4cd
- call LoadStandardMenuDataHeader
- callba IsAnyMonHoldingMail
- jr nc, .no_mail
- ld hl, .Text_MonHoldingMail
- call PrintText
- jr .quit
-
-.no_mail
- callba StartMovePkmnWOMail_SaveGame
- jr c, .quit
- callba _MovePKMNWithoutMail
- call ReturnToMapFromSubmenu
- call ClearPCItemScreen
-
-.quit
- call CloseWindow
- and a
- ret
-
-.Text_MonHoldingMail: ; 0xe4f9
- ; There is a #MON holding MAIL. Please remove the MAIL.
- text_jump UnknownText_0x1c102b
- db "@"
-
-BillsPC_DepositMenu: ; e4fe (3:64fe)
- call LoadStandardMenuDataHeader
- callba _DepositPKMN
- call ReturnToMapFromSubmenu
- call ClearPCItemScreen
- call CloseWindow
- and a
- ret
-
-Functione512: ; unused
- ld a, [PartyCount]
- and a
- jr z, .no_pkmn
- cp 2
- jr c, .only_one_pkmn
- and a
- ret
-
-.no_pkmn
- ld hl, .Text_NoPKMN
- call MenuTextBoxBackup
- scf
- ret
-
-.only_one_pkmn
- ld hl, .Text_ItsYourLastPKMN
- call MenuTextBoxBackup
- scf
- ret
-
-.Text_NoPKMN: ; 0xe52e
- ; You don't have a single #MON!
- text_jump UnknownText_0x1c1062
- db "@"
-
-.Text_ItsYourLastPKMN: ; 0xe533
- ; You can't deposit your last #MON!
- text_jump UnknownText_0x1c1080
- db "@"
-
-CheckCurPartyMonFainted: ; e538
- ld hl, PartyMon1HP
- ld de, PARTYMON_STRUCT_LENGTH
- ld b, $0
-.loop
- ld a, [CurPartyMon]
- cp b
- jr z, .skip
- ld a, [hli]
- or [hl]
- jr nz, .notfainted
- dec hl
-
-.skip
- inc b
- ld a, [PartyCount]
- cp b
- jr z, .done
- add hl, de
- jr .loop
-
-.done
- scf
- ret
-
-.notfainted
- and a
- ret
-
-BillsPC_WithdrawMenu: ; e559 (3:6559)
- call LoadStandardMenuDataHeader
- callba _WithdrawPKMN
- call ReturnToMapFromSubmenu
- call ClearPCItemScreen
- call CloseWindow
- and a
- ret
-
-Functione56d: ; unused
- ld a, [PartyCount]
- cp PARTY_LENGTH
- jr nc, .asm_e576
- and a
- ret
-
-.asm_e576
- ld hl, UnknownText_0xe57e
- call MenuTextBoxBackup
- scf
- ret
-
-UnknownText_0xe57e: ; 0xe57e
- ; You can't take any more #MON.
- text_jump UnknownText_0x1c10a2
- db "@"
-
-BillsPC_ChangeBoxMenu: ; e583 (3:6583)
- callba _ChangeBox
- and a
- ret
-
-ClearPCItemScreen: ; e58b
- call DisableSpriteUpdates
- xor a
- ld [hBGMapMode], a
- call ClearBGPalettes
- call ClearSprites
- hlcoord 0, 0
- ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
- ld a, " "
- call ByteFill
- hlcoord 0,0
- lb bc, 10, 18
- call TextBox
- hlcoord 0,12
- lb bc, 4, 18
- call TextBox
- call WaitBGMap2
- call SetPalettes ; load regular palettes?
- ret
-
-CopyBoxmonToTempMon: ; e5bb
- ld a, [CurPartyMon]
- ld hl, sBoxMon1Species
- ld bc, BOXMON_STRUCT_LENGTH
- call AddNTimes
- ld de, TempMonSpecies
- ld bc, BOXMON_STRUCT_LENGTH
- ld a, BANK(sBoxMon1Species)
- call GetSRAMBank
- call CopyBytes
- call CloseSRAM
- ret
-
-Functione5d9: ; unreferenced
- ld a, [wCurBox]
- cp b
- jr z, .same_box
- ld a, b
- ld hl, .BoxAddrs
- ld bc, 3
- call AddNTimes
- ld a, [hli]
- push af
- ld a, [hli]
- ld h, [hl]
- ld l, a
- pop af
- jr .okay
-
-.same_box
- ld a, BANK(sBoxCount)
- ld hl, sBoxCount
-
-.okay
- call GetSRAMBank
- ld a, [hl]
- ld bc, 1 + MONS_PER_BOX + 1
- add hl, bc
- ld b, a
- ld c, $0
- ld de, wc608
- ld a, b
- and a
- jr z, .empty_box
-.loop
- push hl
- push bc
- ld a, c
- ld bc, 0
- add hl, bc
- ld bc, BOXMON_STRUCT_LENGTH
- call AddNTimes
- ld a, [hl]
- ld [de], a
- inc de
- ld [CurSpecies], a
- call GetBaseData
- pop bc
- pop hl
-
- push hl
- push bc
- ld a, c
- ld bc, MONS_PER_BOX * (BOXMON_STRUCT_LENGTH + NAME_LENGTH)
- add hl, bc
- call SkipNames
- call CopyBytes
- pop bc
- pop hl
-
- push hl
- push bc
- ld a, c
- ld bc, MON_LEVEL
- add hl, bc
- ld bc, BOXMON_STRUCT_LENGTH
- call AddNTimes
- ld a, [hl]
- ld [de], a
- inc de
- pop bc
- pop hl
-
- push hl
- push bc
- ld a, c
- ld bc, MON_DVS
- add hl, bc
- ld bc, BOXMON_STRUCT_LENGTH
- call AddNTimes
- ld a, [hli]
- and $f0
- ld b, a
- ld a, [hl]
- and $f0
- swap a
- or b
- ld b, a
- ld a, [BaseGender]
- cp b
- ld a, $1
- jr c, .okay2
- xor a
-.okay2
- ld [de], a
- inc de
- pop bc
- pop hl
-
- inc c
- dec b
- jr nz, .loop
-.empty_box
- call CloseSRAM
- ret
-
-.BoxAddrs: ; e66e
- dba sBox1
- dba sBox2
- dba sBox3
- dba sBox4
- dba sBox5
- dba sBox6
- dba sBox7
- dba sBox8
- dba sBox9
- dba sBox10
- dba sBox11
- dba sBox12
- dba sBox13
- dba sBox14
-
GetBreedMon1LevelGrowth: ; e698
ld hl, wBreedMon1Stats
ld de, TempMon
@@ -5001,95 +352,6 @@
db "@"
INCLUDE "items/item_effects.asm"
-
-GetPokeBallWobble: ; f971 (3:7971)
-; Returns whether a Poke Ball will wobble in the catch animation.
-; Whether a Pokemon is caught is determined beforehand.
-
- push de
-
- ld a, [rSVBK]
- ld d, a
- push de
-
- ld a, 1 ; BANK(Buffer2)
- ld [rSVBK], a
-
- ld a, [Buffer2]
- inc a
- ld [Buffer2], a
-
-; Wobble up to 3 times.
- cp 3 + 1
- jr z, .finished
-
- ld a, [wWildMon]
- and a
- ld c, 0 ; next
- jr nz, .done
-
- ld hl, .WobbleProbabilities
- ld a, [Buffer1]
- ld b, a
-.loop
- ld a, [hli]
- cp b
- jr nc, .checkwobble
- inc hl
- jr .loop
-
-.checkwobble
- ld b, [hl]
- call Random
- cp b
- ld c, 0 ; next
- jr c, .done
- ld c, 2 ; escaped
- jr .done
-
-.finished
- ld a, [wWildMon]
- and a
- ld c, 1 ; caught
- jr nz, .done
- ld c, 2 ; escaped
-
-.done
- pop de
- ld e, a
- ld a, d
- ld [rSVBK], a
- ld a, e
- pop de
- ret
-
-.WobbleProbabilities: ; f9ba
-; catch rate, chance of wobbling / 255
-; nLeft/255 = (nRight/255) ** 4
- db 1, 63
- db 2, 75
- db 3, 84
- db 4, 90
- db 5, 95
- db 7, 103
- db 10, 113
- db 15, 126
- db 20, 134
- db 30, 149
- db 40, 160
- db 50, 169
- db 60, 177
- db 80, 191
- db 100, 201
- db 120, 211
- db 140, 220
- db 160, 227
- db 180, 234
- db 200, 240
- db 220, 246
- db 240, 251
- db 254, 253
- db 255, 255
KnowsMove: ; f9ea
ld a, MON_MOVES
--- a/maps/BattleTower1F.asm
+++ b/maps/BattleTower1F.asm
@@ -62,7 +62,7 @@
opentext
writetext Text_BattleTowerWelcomesYou
buttonsound
- writebyte BATTLETOWERACTION_00 ; if new save file: bit 1, [sbe4f]
+ writebyte BATTLETOWERACTION_00 ; if new save file: bit 1, [s1_be4f]
special BattleTowerAction
if_not_equal $0, Script_Menu_ChallengeExplanationCancel
jump Script_BattleTowerIntroductionYesNo
@@ -87,7 +87,7 @@
special Special_TryQuickSave
iffalse Script_Menu_ChallengeExplanationCancel
dotrigger $1
- writebyte BATTLETOWERACTION_01 ; set 1, [sbe4f]
+ writebyte BATTLETOWERACTION_01 ; set 1, [s1_be4f]
special BattleTowerAction
special Function1700b0
if_equal $a, Script_Menu_ChallengeExplanationCancel
--- a/misc/battle_tower_5c.asm
+++ b/misc/battle_tower_5c.asm
@@ -1085,9 +1085,9 @@
and a
ret z
- ld a, BANK(sbe4f)
+ ld a, BANK(s1_be4f)
call GetSRAMBank
- ld a, [sbe4f]
+ ld a, [s1_be4f]
and $2
ld [ScriptVar], a
call CloseSRAM
@@ -1103,11 +1103,11 @@
ret
Function170788: ; 170788 (5c:4788) BattleTowerAction $01
- ld a, BANK(sbe4f)
+ ld a, BANK(s1_be4f)
call GetSRAMBank
- ld a, [sbe4f]
+ ld a, [s1_be4f]
or $2
- ld [sbe4f], a
+ ld [s1_be4f], a
call CloseSRAM
ret
@@ -1591,9 +1591,9 @@
and a
ret z
- ld a, BANK(sbe4f)
+ ld a, BANK(s1_be4f)
call GetSRAMBank
- ld a, [sbe4f]
+ ld a, [s1_be4f]
and $1
ld [ScriptVar], a
call CloseSRAM
@@ -1600,11 +1600,11 @@
ret
Function170ad7: ; 170ad7 (5c:4ad7) BattleTowerAction $15
- ld a, BANK(sbe4f)
+ ld a, BANK(s1_be4f)
call GetSRAMBank
- ld a, [sbe4f]
+ ld a, [s1_be4f]
or $1
- ld [sbe4f], a
+ ld [s1_be4f], a
call CloseSRAM
ret
--- a/sram.asm
+++ b/sram.asm
@@ -81,7 +81,7 @@
SECTION "Backup Save", SRAM [$b200], BANK [0]
sBackupOptions:: ds OptionsEnd - Options
-s0_b208:: ds 1
+s0_b208:: ds 1 ; loaded with 99, used to check save corruption
sBackupGameData::
sBackupPlayerData:: ds wPlayerDataEnd - wPlayerData
@@ -94,11 +94,11 @@
; bf0d
sBackupChecksum:: ds 2
-s0_bf0f:: ds 1
+s0_bf0f:: ds 1 ; loaded with 0x7f, used to check save corruption
sStackTop:: ds 2
-SECTION "SRAM Bank 1", SRAM, BANK [1]
+SECTION "Save", SRAM, BANK [1]
sOptions:: ds OptionsEnd - Options
@@ -117,11 +117,13 @@
sChecksum:: ds 2
s1_ad0f:: ds 1 ; loaded with 0x7f, used to check save corruption
+SECTION "Active Box", SRAM, BANK [1]
; ad10
box sBox
; b160
ds $f4
+SECTION "Link Battle Data", SRAM, BANK [1]
sLinkBattleResults:: ds $c
sLinkBattleStats:: ; b260
@@ -143,6 +145,7 @@
sLinkBattleRecord5:: link_battle_record sLinkBattleRecord5
sLinkBattleStatsEnd::
+SECTION "SRAM Hall of Fame", SRAM, BANK [1]
sHallOfFame:: ; b2c0
; temporary until I can find a way to macrofy it
hall_of_fame sHallOfFame01
@@ -190,6 +193,7 @@
; endr
sHallOfFameEnd::
+SECTION "SRAM Crystal Data", SRAM, BANK [1]
sMobileEventIndex:: ds 1 ; be3c
sCrystalData::
@@ -208,7 +212,7 @@
; The 7 trainers of the BattleTower are saved here, so nobody appears more than once
sBTTrainers:: ; sbe48
ds 7
-sbe4f:: ds 1
+s1_be4f:: ds 1
sBattleTowerReward:: ds 1
; Pkmn of previous trainer
sBTPkmnOfTrainers:: ; 0xbe51