diff options
Diffstat (limited to 'engine/overworld')
-rwxr-xr-x | engine/overworld/cable_club_npc.asm | 156 | ||||
-rwxr-xr-x | engine/overworld/card_key.asm | 108 | ||||
-rwxr-xr-x | engine/overworld/cinnabar_lab.asm | 125 | ||||
-rwxr-xr-x | engine/overworld/cut.asm | 258 | ||||
-rwxr-xr-x | engine/overworld/cut2.asm | 89 | ||||
-rwxr-xr-x | engine/overworld/doors.asm | 88 | ||||
-rwxr-xr-x | engine/overworld/elevator.asm | 69 | ||||
-rwxr-xr-x | engine/overworld/emotion_bubbles.asm | 68 | ||||
-rwxr-xr-x | engine/overworld/healing_machine.asm | 102 | ||||
-rwxr-xr-x | engine/overworld/hidden_items.asm | 168 | ||||
-rwxr-xr-x | engine/overworld/hidden_objects.asm | 129 | ||||
-rwxr-xr-x | engine/overworld/ledges.asm | 87 | ||||
-rwxr-xr-x | engine/overworld/map_sprites.asm | 440 | ||||
-rwxr-xr-x | engine/overworld/npc_movement.asm | 291 | ||||
-rwxr-xr-x | engine/overworld/oaks_aide.asm | 71 | ||||
-rwxr-xr-x | engine/overworld/pewter_guys.asm | 101 | ||||
-rwxr-xr-x | engine/overworld/player_animations.asm | 520 | ||||
-rwxr-xr-x | engine/overworld/pokecenter.asm | 68 | ||||
-rwxr-xr-x | engine/overworld/pokemart.asm | 256 | ||||
-rwxr-xr-x | engine/overworld/saffron_guards.asm | 18 | ||||
-rwxr-xr-x | engine/overworld/ssanne.asm | 88 | ||||
-rwxr-xr-x | engine/overworld/trainers.asm | 347 |
22 files changed, 3647 insertions, 0 deletions
diff --git a/engine/overworld/cable_club_npc.asm b/engine/overworld/cable_club_npc.asm new file mode 100755 index 00000000..88bf177f --- /dev/null +++ b/engine/overworld/cable_club_npc.asm @@ -0,0 +1,156 @@ +CableClubNPC: ; 71c5 (1:71c5) + ld hl, CableClubNPCText1 + call PrintText + ld a, [$d74b] + bit 5, a + jp nz, Func_71e1 + ld c, $3c + call DelayFrames + ld hl, CableClubNPCText6 + call PrintText + jp Func_7298 + +Func_71e1: ; 71e1 (1:71e1) + ld a, $1 + ld [$cc34], a + ld a, $5a + ld [$cc47], a +.asm_71eb + ld a, [$ffaa] + cp $2 + jr z, .asm_721a ; 0x71ef $29 + cp $1 + jr z, .asm_721a ; 0x71f3 $25 + ld a, $ff + ld [$ffaa], a + ld a, $2 + ld [$ff01], a + xor a + ld [$ffad], a + ld a, $80 + ld [$ff02], a + ld a, [$cc47] + dec a + ld [$cc47], a + jr z, .asm_7287 ; 0x720b $7a + ld a, $1 + ld [$ff01], a + ld a, $81 + ld [$ff02], a + call DelayFrame + jr .asm_71eb ; 0x7218 $d1 +.asm_721a + call Func_22ed + call DelayFrame + call Func_22ed + ld c, $32 + call DelayFrames + ld hl, CableClubNPCText2 + call PrintText + xor a + ld [$cc34], a + call YesNoChoice + ld a, $1 + ld [$cc34], a + ld a, [$cc26] + and a + jr nz, .asm_728f ; 0x723e $4f + callab SaveSAVtoSRAM + call WaitForSoundToFinish + ld a, (SFX_02_5d - SFX_Headers_02) / 3 + call PlaySoundWaitForCurrent + ld hl, CableClubNPCText3 + call PrintText + ld hl, $cc47 + ld a, $3 + ld [hli], a + xor a + ld [hl], a + ld [$ffa9], a + ld [$cc42], a + call Func_227f + ld hl, $cc47 + ld a, [hli] + inc a + jr nz, Func_72a8 ; 0x726b $3b + ld a, [hl] + inc a + jr nz, Func_72a8 ; 0x726f $37 + ld b, $a +.asm_7273 + call DelayFrame + call Func_22ed + dec b + jr nz, .asm_7273 ; 0x727a $f7 + call Func_72d7 + ld hl, CableClubNPCText4 + call PrintText + jr Func_7298 ; 0x7285 $11 +.asm_7287 + ld hl, CableClubNPCText7 + call PrintText + jr Func_7298 ; 0x728d $9 +.asm_728f + call Func_72d7 + ld hl, CableClubNPCText5 + call PrintText + ; fall through + +Func_7298: ; 7298 (1:7298) + xor a + ld hl, $cc47 + ld [hli], a + ld [hl], a + ld hl, $d72e + res 6, [hl] + xor a + ld [$cc34], a + ret + +Func_72a8: ; 72a8 (1:72a8) + xor a + ld [hld], a + ld [hl], a + ld hl, LinkMenu + ld b, BANK(LinkMenu) + jp Bankswitch + +CableClubNPCText7: ; 72b3 (1:72b3) + TX_FAR _CableClubNPCText7 + db "@" + +CableClubNPCText1: ; 72b8 (1:72b8) + TX_FAR _CableClubNPCText1 + db "@" + +CableClubNPCText2: ; 72bd (1:72bd) + TX_FAR _CableClubNPCText2 + db "@" + +CableClubNPCText3: ; 72c2 (1:72c2) + TX_FAR _CableClubNPCText3 + db $a, "@" + +CableClubNPCText4: ; 72c8 (1:72c8) + TX_FAR _CableClubNPCText4 + db "@" + +CableClubNPCText5: ; 72cd (1:72cd) + TX_FAR _CableClubNPCText5 + db "@" + +CableClubNPCText6: ; 72d2 (1:72d2) + TX_FAR _CableClubNPCText6 + db "@" + +Func_72d7: ; 72d7 (1:72d7) + call Delay3 + ld a, $ff + ld [$ffaa], a + ld a, $2 + ld [$ff01], a + xor a + ld [$ffad], a + ld a, $80 + ld [$ff02], a + ret diff --git a/engine/overworld/card_key.asm b/engine/overworld/card_key.asm new file mode 100755 index 00000000..658f4712 --- /dev/null +++ b/engine/overworld/card_key.asm @@ -0,0 +1,108 @@ +PrintCardKeyText: ; 52673 (14:6673) + ld hl, SilphCoMapList + ld a, [W_CURMAP] + ld b, a +.asm_5267a + ld a, [hli] + cp $ff + ret z + cp b + jr nz, .asm_5267a + ld a, $35 + call Predef ; indirect jump to Func_c586 (c586 (3:4586)) + ld a, [$cfc6] + cp $18 + jr z, .asm_5269c + cp $24 + jr z, .asm_5269c + ld b, a + ld a, [W_CURMAP] + cp SILPH_CO_11F + ret nz + ld a, b + cp $5e + ret nz +.asm_5269c + ld b, CARD_KEY + call IsItemInBag + jr z, .asm_526dc + call Func_526fd + push de + ld a, $1 + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + call PrintPredefTextID + pop de + srl d + ld a, d + ld b, a + ld [$d73f], a + srl e + ld a, e + ld c, a + ld [$d740], a + ld a, [W_CURMAP] ; $d35e + cp SILPH_CO_11F + jr nz, .asm_526c8 + ld a, $3 + jr .asm_526ca +.asm_526c8 + ld a, $e +.asm_526ca + ld [$d09f], a + ld a, $17 + call Predef ; indirect jump to Func_ee9e + ld hl, $d126 + set 5, [hl] + ld a, (SFX_1f_57 - SFX_Headers_1f) / 3 + jp PlaySound +.asm_526dc + ld a, $2 + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + jp PrintPredefTextID + +SilphCoMapList: ; 526e3 (14:66e3) + db SILPH_CO_2F + db SILPH_CO_3F + db SILPH_CO_4F + db SILPH_CO_5F + db SILPH_CO_6F + db SILPH_CO_7F + db SILPH_CO_8F + db SILPH_CO_9F + db SILPH_CO_10F + db SILPH_CO_11F + db $FF + +CardKeySuccessText: ; 526ee (14:66ee) + TX_FAR _CardKeySuccessText1 + db $0b + TX_FAR _CardKeySuccessText2 + db "@" + +CardKeyFailText: ; 526f8 (14:66f8) + TX_FAR _CardKeyFailText + db "@" + +Func_526fd: ; 526fd (14:66fd) + ld a, [W_YCOORD] ; $d361 + ld d, a + ld a, [W_XCOORD] ; $d362 + ld e, a + ld a, [$c109] + and a + jr nz, .asm_5270d + inc d + ret +.asm_5270d + cp $4 + jr nz, .asm_52713 + dec d + ret +.asm_52713 + cp $8 + jr nz, .asm_52719 + dec e + ret +.asm_52719 + inc e + ret diff --git a/engine/overworld/cinnabar_lab.asm b/engine/overworld/cinnabar_lab.asm new file mode 100755 index 00000000..4087b334 --- /dev/null +++ b/engine/overworld/cinnabar_lab.asm @@ -0,0 +1,125 @@ +GiveFossilToCinnabarLab: ; 61006 (18:5006) + ld hl, $d730 + set 6, [hl] + xor a + ld [wCurrentMenuItem], a ; $cc26 + ld a, $3 + ld [wMenuWatchedKeys], a ; $cc29 + ld a, [$cd37] + dec a + ld [wMaxMenuItem], a ; $cc28 + ld a, $2 + ld [wTopMenuItemY], a ; $cc24 + ld a, $1 + ld [wTopMenuItemX], a ; $cc25 + ld a, [$cd37] + dec a + ld bc, $2 + ld hl, $3 + call AddNTimes + dec l + ld b, l + ld c, $d + ld hl, wTileMap + call TextBoxBorder + call UpdateSprites + call Func_610c2 + ld hl, $d730 + res 6, [hl] + call HandleMenuInput + bit 1, a + jr nz, .asm_610a7 + ld hl, $cc5b + ld a, [wCurrentMenuItem] ; $cc26 + ld d, $0 + ld e, a + add hl, de + ld a, [hl] + ld [$ffdb], a + cp DOME_FOSSIL + jr z, .choseDomeFossil + cp HELIX_FOSSIL + jr z, .choseHelixFossil + ld b, AERODACTYL + jr .fossilSelected +.choseHelixFossil + ld b, OMANYTE + jr .fossilSelected +.choseDomeFossil + ld b, KABUTO +.fossilSelected + ld [W_FOSSILITEM], a + ld a, b + ld [W_FOSSILMON], a + call LoadFossilItemAndMonName + ld hl, LabFossil_610ae + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] ; $cc26 + and a + jr nz, .asm_610a7 + ld hl, LabFossil_610b3 + call PrintText + ld a, [W_FOSSILITEM] + ld [$ffdb], a + callba RemoveItemByID + ld hl, LabFossil_610b8 + call PrintText + ld hl, $d7a3 + set 0, [hl] + set 1, [hl] + ret +.asm_610a7 + ld hl, LabFossil_610bd + call PrintText + ret + +LabFossil_610ae: ; 610ae (18:50ae) + TX_FAR _Lab4Text_610ae + db "@" + +LabFossil_610b3: ; 610b3 (18:50b3) + TX_FAR _Lab4Text_610b3 + db "@" + +LabFossil_610b8: ; 610b8 (18:50b8) + TX_FAR _Lab4Text_610b8 + db "@" + +LabFossil_610bd: ; 610bd (18:50bd) + TX_FAR _Lab4Text_610bd + db "@" + +Func_610c2: ; 610c2 (18:50c2) + ld hl, $cc5b + xor a + ld [$ffdb], a +.asm_610c8 + ld a, [hli] + cp $ff + ret z + push hl + ld [$d11e], a + call GetItemName + FuncCoord 2, 2 ; $c3ca + ld hl, Coord + ld a, [$ffdb] + ld bc, $28 + call AddNTimes + ld de, $cd6d + call PlaceString + ld hl, $ffdb + inc [hl] + pop hl + jr .asm_610c8 + +; loads the names of the fossil item and the resulting mon +LoadFossilItemAndMonName: ; 610eb (18:50eb) + ld a, [W_FOSSILMON] + ld [$d11e], a + call GetMonName + call CopyStringToCF4B + ld a, [W_FOSSILITEM] + ld [$d11e], a + call GetItemName + ret diff --git a/engine/overworld/cut.asm b/engine/overworld/cut.asm new file mode 100755 index 00000000..6c888e7f --- /dev/null +++ b/engine/overworld/cut.asm @@ -0,0 +1,258 @@ +UsedCut: ; ef54 (3:6f54) + xor a + ld [$cd6a], a + ld a, [W_CURMAPTILESET] ; $d367 + and a ; OVERWORLD + jr z, .asm_ef6b + cp GYM + jr nz, .asm_ef77 + ld a, [$cfc6] + cp $50 ; gym cut tree + jr nz, .asm_ef77 + jr asm_ef82 +.asm_ef6b + dec a + ld a, [$cfc6] + cp $3d ; cut tree + jr z, asm_ef82 + cp $52 ; grass + jr z, asm_ef82 +.asm_ef77 + ld hl, NothingToCutText + jp PrintText + +NothingToCutText: ; ef7d (3:6f7d) + TX_FAR _NothingToCutText + db "@" + +asm_ef82: ; ef82 (3:6f82) + ld [$cd4d], a + ld a, $1 + ld [$cd6a], a + ld a, [wWhichPokemon] ; $cf92 + ld hl, W_PARTYMON1NAME ; $d2b5 + call GetPartyMonName + ld hl, $d730 + set 6, [hl] + call GBPalWhiteOutWithDelay3 + call CleanLCD_OAM + call Func_3dbe + ld a, $90 + ld [$ffb0], a + call Delay3 + call LoadGBPal + call LoadCurrentMapView + call SaveScreenTilesToBuffer2 + call Delay3 + xor a + ld [$ffb0], a + ld hl, UsedCutText + call PrintText + call LoadScreenTilesFromBuffer2 + ld hl, $d730 + res 6, [hl] + ld a, $ff + ld [$cfcb], a + call AnimateCutTree + ld de, CutTreeBlockSwaps ; $7100 + call Func_f09f + call Func_eedc + callba Func_79e96 + ld a, $1 + ld [$cfcb], a + ld a, (SFX_02_56 - SFX_Headers_02) / 3 + call PlaySound + ld a, $90 + ld [$ffb0], a + call UpdateSprites + jp Func_eedc + +UsedCutText: ; eff2 (3:6ff2) + TX_FAR _UsedCutText + db "@" + +AnimateCutTree: ; eff7 (3:6ff7) + xor a + ld [$cd50], a + ld a, $e4 + ld [rOBP1], a ; $ff49 + ld a, [$cd4d] + cp $52 + jr z, .asm_f020 + ld de, Overworld_GFX + $2d0 ; $42d0 ; cuttable tree sprite top row + ld hl, $8fc0 + ld bc, (BANK(Overworld_GFX) << 8) + $02 + call CopyVideoData + ld de, Overworld_GFX + $3d0 ; $43d0 ; cuttable tree sprite bottom row + ld hl, $8fe0 + ld bc, (BANK(Overworld_GFX) << 8) + $02 + call CopyVideoData + jr asm_f055 +.asm_f020 + ld hl, $8fc0 + call LoadCutTreeOAM + ld hl, $8fd0 + call LoadCutTreeOAM + ld hl, $8fe0 + call LoadCutTreeOAM + ld hl, $8ff0 + call LoadCutTreeOAM + call asm_f055 + ld hl, $c393 + ld de, $4 + ld a, $30 + ld c, e +.asm_f044 + ld [hl], a + add hl, de + xor $60 + dec c + jr nz, .asm_f044 + ret + +LoadCutTreeOAM: ; f04c (3:704c) + ld de, AnimationTileset2 + $60 ; $474e ; tile depicting a leaf + ld bc, (BANK(AnimationTileset2) << 8) + $01 + jp CopyVideoData +asm_f055: ; f055 (3:7055) + call Func_f068 + ld a, $9 + ld de, CutTreeOAM ; $7060 + jp WriteOAMBlock + +CutTreeOAM: ; f060 (3:7060) + db $FC,$10,$FD,$10 + db $FE,$10,$FF,$10 + +Func_f068: ; f068 (3:7068) + ld hl, $c104 + ld a, [hli] + ld b, a + inc hl + ld a, [hli] + ld c, a ; bc holds ypos/xpos of player's sprite + inc hl + inc hl + ld a, [hl] ; a holds direction of player (00: down, 04: up, 08: left, 0C: right) + srl a + ld e, a + ld d, $0 ; de holds direction (00: down, 02: up, 04: left, 06: right) + ld a, [$cd50] + and a + ld hl, CutTreeAnimationOffsets ; $708f + jr z, .asm_f084 + ld hl, CutTreeAnimationOffsets2 ; $7097 +.asm_f084 + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ld a, b + add d + ld b, a + ld a, c + add e + ld c, a + ret + +CutTreeAnimationOffsets: ; f08f (3:708f) +; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn + db 8, 36 ; player is facing down + db 8, 4 ; player is facing up + db -8, 20 ; player is facing left + db 24, 20 ; player is facing right + +CutTreeAnimationOffsets2: ; f097 (3:7097) +; Not sure if these ever get used. CutTreeAnimationOffsets only seems to be used. +; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn +; These offsets represent 2 blocks away from the player + db 8, 52 ; player is facing down + db 8, -12 ; player is facing up + db -24, 20 ; player is facing left + db 40, 20 ; player is facing right + +Func_f09f: ; f09f (3:709f) + push de + ld a, [W_CURMAPWIDTH] ; $d369 + add $6 + ld c, a + ld b, $0 + ld d, $0 + ld hl, $d35f + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + ld a, [$c109] + and a + jr z, .asm_f0c7 + cp $4 + jr z, .asm_f0cf + cp $8 + jr z, .asm_f0d7 + ld a, [W_XBLOCKCOORD] ; $d364 + and a + jr z, .asm_f0e0 + jr .asm_f0ec +.asm_f0c7 + ld a, [W_YBLOCKCOORD] ; $d363 + and a + jr z, .asm_f0e0 + jr .asm_f0df +.asm_f0cf + ld a, [W_YBLOCKCOORD] ; $d363 + and a + jr z, .asm_f0e1 + jr .asm_f0e0 +.asm_f0d7 + ld a, [W_XBLOCKCOORD] ; $d364 + and a + jr z, .asm_f0e6 + jr .asm_f0e0 +.asm_f0df + add hl, bc +.asm_f0e0 + add hl, bc +.asm_f0e1 + ld e, $2 + add hl, de + jr .asm_f0f0 +.asm_f0e6 + ld e, $1 + add hl, bc + add hl, de + jr .asm_f0f0 +.asm_f0ec + ld e, $3 + add hl, bc + add hl, de +.asm_f0f0 + pop de + ld a, [hl] + ld c, a +.asm_f0f3 + ld a, [de] + inc de + inc de + cp $ff + ret z + cp c + jr nz, .asm_f0f3 + dec de + ld a, [de] + ld [hl], a + ret + +CutTreeBlockSwaps: ; f100 (3:7100) +; first byte = tileset block containing the cut tree +; second byte = corresponding tileset block after the cut animation happens + db $32, $6D + db $33, $6C + db $34, $6F + db $35, $4C + db $60, $6E + db $0B, $0A + db $3C, $35 + db $3F, $35 + db $3D, $36 + db $FF ; list terminator diff --git a/engine/overworld/cut2.asm b/engine/overworld/cut2.asm new file mode 100755 index 00000000..c83e571b --- /dev/null +++ b/engine/overworld/cut2.asm @@ -0,0 +1,89 @@ +Func_79e96: ; 79e96 (1e:5e96) + ld a, [$cd4d] + cp $52 + jr z, .asm_79ec8 + ld c, $8 +.asm_79e9f + push bc + ld hl, $c391 + ld a, $1 + ld [$d08a], a + ld c, $2 + call Func_79339 + ld hl, $c399 + ld a, $ff + ld [$d08a], a + ld c, $2 + call Func_79339 + ld a, [rOBP1] ; $ff49 + xor $64 + ld [rOBP1], a ; $ff49 + call DelayFrame + pop bc + dec c + jr nz, .asm_79e9f + ret +.asm_79ec8 + ld c, $2 +.asm_79eca + push bc + ld c, $8 + call Func_79eed + call Func_79f30 + ld c, $8 + call Func_79eed + call Func_79f30 + ld hl, $c390 + ld a, $2 + ld [$d08a], a + ld c, $4 + call Func_79352 + pop bc + dec c + jr nz, .asm_79eca + ret + +Func_79eed: ; 79eed (1e:5eed) + push bc + ld hl, $c391 + ld a, $1 + ld [$d08a], a + ld c, $1 + call Func_79339 + ld hl, $c395 + ld a, $2 + ld [$d08a], a + ld c, $1 + call Func_79339 + ld hl, $c399 + ld a, $fe + ld [$d08a], a + ld c, $1 + call Func_79339 + ld hl, $c39d + ld a, $ff + ld [$d08a], a + ld c, $1 + call Func_79339 + ld a, [rOBP1] ; $ff49 + xor $64 + ld [rOBP1], a ; $ff49 + call DelayFrame + pop bc + dec c + jr nz, Func_79eed + ret + +Func_79f30: ; 79f30 (1e:5f30) + ld hl, $c390 + ld de, $cee9 + ld bc, $8 + call CopyData + ld hl, $c398 + ld de, $c390 + ld bc, $8 + call CopyData + ld hl, $cee9 + ld de, $c398 + ld bc, $8 + jp CopyData diff --git a/engine/overworld/doors.asm b/engine/overworld/doors.asm new file mode 100755 index 00000000..ff58b752 --- /dev/null +++ b/engine/overworld/doors.asm @@ -0,0 +1,88 @@ +HandleDoors: ; 1a609 (6:6609) + push de + ld hl, DoorTileIDPointers ; $662c + ld a, [W_CURMAPTILESET] ; $d367 + ld de, $3 + call IsInArray + pop de + jr nc, .asm_1a62a + inc hl + ld a, [hli] + ld h, [hl] + ld l, a + FuncCoord 8, 9 ; $c45c + ld a, [Coord] + ld b, a +.asm_1a621 + ld a, [hli] + and a + jr z, .asm_1a62a + cp b + jr nz, .asm_1a621 + scf + ret +.asm_1a62a + and a + ret + +DoorTileIDPointers: ; 1a62c (6:662c) + db OVERWORLD + dw OverworldDoorTileIDs + db FOREST + dw ForestDoorTileIDs + db MART + dw MartDoorTileIDs + db HOUSE + dw HouseDoorTileIDs + db FOREST_GATE + dw TilesetMuseumDoorTileIDs + db MUSEUM + dw TilesetMuseumDoorTileIDs + db GATE + dw TilesetMuseumDoorTileIDs + db SHIP + dw ShipDoorTileIDs + db LOBBY + dw LobbyDoorTileIDs + db MANSION + dw MansionDoorTileIDs + db LAB + dw LabDoorTileIDs + db FACILITY + dw FacilityDoorTileIDs + db PLATEAU + dw PlateauDoorTileIDs + db $ff + +OverworldDoorTileIDs: ; 1a654 (6:6654) + db $1B,$58,$00 + +ForestDoorTileIDs: ; 1a657 (6:6657) + db $3a,$00 + +MartDoorTileIDs: ; 1a659 (6:6659) + db $5e,$00 + +HouseDoorTileIDs: ; 1a65b (6:665b) + db $54,$00 + +TilesetMuseumDoorTileIDs: ; 1a65d (6:665d) + db $3b,$00 + +ShipDoorTileIDs: ; 1a65f (6:665f) + db $1e,$00 + +LobbyDoorTileIDs: ; 1a661 (6:6661) + db $1c,$38,$1a,$00 + +MansionDoorTileIDs: ; 1a665 (6:6665) + db $1a,$1c,$53,$00 + +LabDoorTileIDs: ; 1a669 (6:6669) + db $34,$00 + +FacilityDoorTileIDs: ; 1a66b (6:666b) + db $43,$58,$1b,$00 + +PlateauDoorTileIDs: ; 1a66f (6:666f) + db $3b,$1b,$00 diff --git a/engine/overworld/elevator.asm b/engine/overworld/elevator.asm new file mode 100755 index 00000000..e483e0c3 --- /dev/null +++ b/engine/overworld/elevator.asm @@ -0,0 +1,69 @@ +ShakeElevator: ; 7bf15 (1e:7f15) + ld de, $ffe0 + call Func_7bf64 + ld de, $240 + call Func_7bf64 + call Delay3 + ld a, $ff + call PlaySound + ld a, [$ffaf] + ld d, a + ld e, $1 + ; number of times to play collision sfx + ld b, $64 +.asm_7bf30 + ld a, e + xor $fe + ld e, a + add d + ld [$ffaf], a + push bc + ld c, BANK(SFX_02_5b) + ld a, (SFX_02_5b - SFX_Headers_02) / 3 + call PlayMusic + pop bc + ld c, $2 + call DelayFrames + dec b + jr nz, .asm_7bf30 + ld a, d + ld [$ffaf], a + ld a, $ff + call PlaySound + ld c, BANK(SFX_02_5f) + ld a, (SFX_02_5f - SFX_Headers_02) / 3 + call PlayMusic +.asm_7bf57 + ld a, [$c02a] + cp $b9 + jr z, .asm_7bf57 + call UpdateSprites + jp Func_2307 + +Func_7bf64: ; 7bf64 (1e:7f64) + ld hl, $d527 + ld a, [hld] + push af + ld a, [hl] + push af + push hl + push hl + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + ld a, h + and $3 + or $98 + ld d, a + ld a, l + pop hl + ld [hli], a + ld [hl], d + call ScheduleNorthRowRedraw + pop hl + pop af + ld [hli], a + pop af + ld [hl], a + jp Delay3 diff --git a/engine/overworld/emotion_bubbles.asm b/engine/overworld/emotion_bubbles.asm new file mode 100755 index 00000000..b480c06d --- /dev/null +++ b/engine/overworld/emotion_bubbles.asm @@ -0,0 +1,68 @@ +PrintEmotionBubble: ; 17c47 (5:7c47) + ld a, [$cd50] + ld c, a + ld b, $0 + ld hl, EmotionBubblesPointerTable ; $7caf + add hl, bc + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + ld hl, $8f80 + ld bc, (BANK(EmotionBubblesPointerTable) << 8) + $04 + call CopyVideoData + ld a, [$cfcb] + push af + ld a, $ff + ld [$cfcb], a + ld a, [$d736] + bit 6, a + ld hl, $c38f + ld de, $c39f + jr z, .asm_17c7a + ld hl, $c37f + ld de, $c38f +.asm_17c7a + ld bc, $90 +.asm_17c7d + ld a, [hl] + ld [de], a + dec hl + dec de + dec bc + ld a, c + or b + jr nz, .asm_17c7d + ld hl, $c104 + ld a, [$cd4f] + swap a + ld c, a + ld b, $0 + add hl, bc + ld a, [hli] + ld b, a + inc hl + ld a, [hl] + add $8 + ld c, a + ld de, EmotionBubblesOAM ; $7cb5 + xor a + call WriteOAMBlock + ld c, $3c + call DelayFrames + pop af + ld [$cfcb], a + call DelayFrame + jp UpdateSprites + +EmotionBubblesPointerTable: ; 17caf (5:7caf) + dw EmotionBubbles + dw EmotionBubbles + $40 + dw EmotionBubbles + $80 + +EmotionBubblesOAM: ; 17cb5 (5:7cb5) + db $F8,$00,$F9,$00 + db $FA,$00,$FB,$00 + +EmotionBubbles: ; 17cbd (5:7cbd) + INCBIN "gfx/emotion_bubbles.w16.2bpp" diff --git a/engine/overworld/healing_machine.asm b/engine/overworld/healing_machine.asm new file mode 100755 index 00000000..77ff4ccc --- /dev/null +++ b/engine/overworld/healing_machine.asm @@ -0,0 +1,102 @@ +AnimateHealingMachine: ; 70433 (1c:4433) + ld de, PokeCenterFlashingMonitorAndHealBall ; $44b7 + ld hl, $87c0 + ld bc, (BANK(PokeCenterFlashingMonitorAndHealBall) << 8) + $03 + call CopyVideoData + ld hl, $cfcb + ld a, [hl] + push af + ld [hl], $ff + push hl + ld a, [rOBP1] ; $ff49 + push af + ld a, $e0 + ld [rOBP1], a ; $ff49 + ld hl, $c384 + ld de, PokeCenterOAMData ; $44d7 + call Func_70503 + ld a, $4 + ld [wMusicHeaderPointer], a + ld a, $ff + ld [$c0ee], a + call PlaySound +.asm_70464 + ld a, [wMusicHeaderPointer] + and a + jr nz, .asm_70464 + ld a, [W_NUMINPARTY] ; $d163 + ld b, a +.asm_7046e + call Func_70503 + ld a, (SFX_02_4a - SFX_Headers_02) / 3 + call PlaySound + ld c, $1e + call DelayFrames + dec b + jr nz, .asm_7046e + ld a, [$c0ef] + cp $1f + ld [$c0f0], a + jr nz, .asm_70495 + ld a, $ff + ld [$c0ee], a + call PlaySound + ld a, Bank(Func_9876) + ld [$c0ef], a +.asm_70495 + ld a, MUSIC_PKMN_HEALED + ld [$c0ee], a + call PlaySound + ld d, $28 + call Func_704f3 +.asm_704a2 + ld a, [$c026] + cp MUSIC_PKMN_HEALED + jr z, .asm_704a2 + ld c, $20 + call DelayFrames + pop af + ld [rOBP1], a ; $ff49 + pop hl + pop af + ld [hl], a + jp UpdateSprites + +PokeCenterFlashingMonitorAndHealBall: ; 704b7 (1c:44b7) + INCBIN "gfx/pokecenter_ball.2bpp" + +PokeCenterOAMData: ; 704d7 (1c:44d7) + db $24,$34,$7C,$10 ; heal machine monitor + db $2B,$30,$7D,$10 ; pokeballs 1-6 + db $2B,$38,$7D,$30 + db $30,$30,$7D,$10 + db $30,$38,$7D,$30 + db $35,$30,$7D,$10 + db $35,$38,$7D,$30 + +Func_704f3: ; 704f3 (1c:44f3) + ld b, $8 +.asm_704f5 + ld a, [rOBP1] ; $ff49 + xor d + ld [rOBP1], a ; $ff49 + ld c, $a + call DelayFrames + dec b + jr nz, .asm_704f5 + ret + +Func_70503: ; 70503 (1c:4503) + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ret diff --git a/engine/overworld/hidden_items.asm b/engine/overworld/hidden_items.asm new file mode 100755 index 00000000..db6bf1cd --- /dev/null +++ b/engine/overworld/hidden_items.asm @@ -0,0 +1,168 @@ +HiddenItems: ; 76688 (1d:6688) + ld hl, HiddenItemCoords + call Func_76857 + ld [$cd41], a + ld hl, $d6f0 + ld a, [$cd41] + ld c, a + ld b, $2 + ld a, $10 + call Predef + ld a, c + and a + ret nz + call EnableAutoTextBoxDrawing + ld a, $1 + ld [$cc3c], a + ld a, [$cd3d] ; item ID + ld [$d11e], a + call GetItemName + ld a, $24 + jp PrintPredefTextID + +INCLUDE "data/hidden_item_coords.asm" + +FoundHiddenItemText: ; 7675b (1d:675b) +; XXX where is the pointer to this? + TX_FAR _FoundHiddenItemText + db $8 + ld a, [$cd3d] ; item ID + ld b, a + ld c, 1 + call GiveItem + jr nc, .BagFull + ld hl, $d6f0 + ld a, [$cd41] + ld c, a + ld b, $1 + ld a, $10 + call Predef + ld a, (SFX_02_3b - SFX_Headers_02) / 3 + call PlaySoundWaitForCurrent ; play sound + call WaitForSoundToFinish ; wait for sound to finish playing + jp TextScriptEnd +.BagFull + call WaitForTextScrollButtonPress ; wait for button press + xor a + ld [$cc3c], a + ld hl, HiddenItemBagFullText + call PrintText + jp TextScriptEnd + +HiddenItemBagFullText: ; 76794 (1d:6794) + TX_FAR _HiddenItemBagFullText + db "@" + +HiddenCoins: ; 76799 (1d:6799) + ld b, COIN_CASE + ld a, $1c + call Predef + ld a, b + and a + ret z + ld hl, HiddenCoinCoords + call Func_76857 + ld [$cd41], a + ld hl, $d6fe + ld a, [$cd41] + ld c, a + ld b, $2 + ld a, $10 + call Predef + ld a, c + and a + ret nz + xor a + ld [$ff9f], a + ld [$ffa0], a + ld [$ffa1], a + ld a, [$cd3d] + sub COIN + cp 10 + jr z, .bcd10 + cp 20 + jr z, .bcd20 + cp 40 + jr z, .bcd20 + jr .bcd100 +.bcd10 + ld a, $10 + ld [$ffa1], a + jr .bcddone +.bcd20 + ld a, $20 + ld [$ffa1], a + jr .bcddone +.bcd40 ; due to a typo, this is never used + ld a, $40 + ld [$ffa1], a + jr .bcddone +.bcd100 + ld a, $1 + ld [$ffa0], a +.bcddone + ld de, $d5a5 + ld hl, $ffa1 + ld c, $2 + ld a, $b + call Predef + ld hl, $d6fe + ld a, [$cd41] + ld c, a + ld b, $1 + ld a, $10 + call Predef + call EnableAutoTextBoxDrawing + ld a, [wPlayerCoins] + cp $99 + jr nz, .RoomInCoinCase + ld a, [wPlayerCoins + 1] + cp $99 + jr nz, .RoomInCoinCase + ld a, $2c + jr .done +.RoomInCoinCase + ld a, $2b +.done + jp PrintPredefTextID + +INCLUDE "data/hidden_coins.asm" + +FoundHiddenCoinsText: ; 76847 (1d:6847) + TX_FAR _FoundHiddenCoinsText + db $10,"@" + +DroppedHiddenCoinsText: ; 7684d (1d:684d) + TX_FAR _FoundHiddenCoins2Text + db $10 + TX_FAR _DroppedHiddenCoinsText + db "@" + +Func_76857: ; 76857 (1d:6857) + ld a, [$cd40] + ld d, a + ld a, [$cd41] + ld e, a + ld a, [W_CURMAP] + ld b, a + ld c, $ff +.loop + inc c + ld a, [hli] + cp $ff ; end of the list? + ret z ; if so, we're done here + cp b + jr nz, .asm_76877 ; 0x7686b $a + ld a, [hli] + cp d + jr nz, .asm_76878 ; 0x7686f $7 + ld a, [hli] + cp e + jr nz, .loop + ld a, c + ret +.asm_76877 + inc hl +.asm_76878 + inc hl + jr .loop diff --git a/engine/overworld/hidden_objects.asm b/engine/overworld/hidden_objects.asm new file mode 100755 index 00000000..e4777a84 --- /dev/null +++ b/engine/overworld/hidden_objects.asm @@ -0,0 +1,129 @@ +Func_46981: ; 46981 (11:6981) + xor a + ld [$d71e], a + ld a, [$d72d] + bit 4, a + ret nz + call ArePlayerCoordsInArray + ret nc + ld a, [wWhichTrade] ; $cd3d + ld [$d71e], a + ld hl, $d72d + set 4, [hl] + ld hl, $d732 + set 4, [hl] + ret + +Func_469a0: ; 469a0 (11:69a0) + ld hl, $ffeb + xor a + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld de, $0 + ld hl, HiddenObjectMaps ; $6a40 +.asm_469ae + ld a, [hli] + ld b, a + cp $ff + jr z, .asm_469fc + ld a, [W_CURMAP] ; $d35e + cp b + jr z, .asm_469be + inc de + inc de + jr .asm_469ae +.asm_469be + ld hl, HiddenObjectPointers ; $6a96 + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + push hl + ld hl, wWhichTrade ; $cd3d + xor a + ld [hli], a + ld [hli], a + ld [hl], a + pop hl +.asm_469ce + ld a, [hli] + cp $ff + jr z, .asm_469fc + ld [$cd40], a + ld b, a + ld a, [hli] + ld [$cd41], a + ld c, a + call Func_46a01 + ld a, [$ffea] + and a + jr z, .asm_469f0 + inc hl + inc hl + inc hl + inc hl + push hl + ld hl, $cd3f + inc [hl] + pop hl + jr .asm_469ce +.asm_469f0 + ld a, [hli] + ld [wWhichTrade], a ; $cd3d + ld a, [hli] + ld [$cd3e], a + ld a, [hli] + ld h, [hl] + ld l, a + ret +.asm_469fc + ld a, $ff + ld [$ffee], a + ret + +Func_46a01: ; 46a01 (11:6a01) + ld a, [$c109] + cp $4 + jr z, .asm_46a16 + cp $8 + jr z, .asm_46a25 + cp $c + jr z, .asm_46a2b + ld a, [W_YCOORD] ; $d361 + inc a + jr .asm_46a1a +.asm_46a16 + ld a, [W_YCOORD] ; $d361 + dec a +.asm_46a1a + cp b + jr nz, .asm_46a3b + ld a, [W_XCOORD] ; $d362 + cp c + jr nz, .asm_46a3b + jr .asm_46a38 +.asm_46a25 + ld a, [W_XCOORD] ; $d362 + dec a + jr .asm_46a2f +.asm_46a2b + ld a, [W_XCOORD] ; $d362 + inc a +.asm_46a2f + cp c + jr nz, .asm_46a3b + ld a, [W_YCOORD] ; $d361 + cp b + jr nz, .asm_46a3b +.asm_46a38 + xor a + jr .asm_46a3d +.asm_46a3b + ld a, $ff +.asm_46a3d + ld [$ffea], a + ret + +INCLUDE "data/hidden_objects.asm" diff --git a/engine/overworld/ledges.asm b/engine/overworld/ledges.asm new file mode 100755 index 00000000..d2f248cd --- /dev/null +++ b/engine/overworld/ledges.asm @@ -0,0 +1,87 @@ +HandleLedges: ; 1a672 (6:6672) + ld a, [$d736] + bit 6, a + ret nz + ld a, [W_CURMAPTILESET] ; $d367 + and a ; OVERWORLD + ret nz + ld a, $35 + call Predef ; indirect jump to Func_c586 (c586 (3:4586)) + ld a, [$c109] + ld b, a + FuncCoord 8, 9 ; $c45c + ld a, [Coord] + ld c, a + ld a, [$cfc6] + ld d, a + ld hl, LedgeTiles ; $66cf +.asm_1a691 + ld a, [hli] + cp $ff + ret z + cp b + jr nz, .asm_1a6a4 + ld a, [hli] + cp c + jr nz, .asm_1a6a5 + ld a, [hli] + cp d + jr nz, .asm_1a6a6 + ld a, [hl] + ld e, a + jr .asm_1a6a9 +.asm_1a6a4 + inc hl +.asm_1a6a5 + inc hl +.asm_1a6a6 + inc hl + jr .asm_1a691 +.asm_1a6a9 + ld a, [H_CURRENTPRESSEDBUTTONS] + and e + ret z + ld a, $ff + ld [wJoypadForbiddenButtonsMask], a + ld hl, $d736 + set 6, [hl] + call Func_3486 + ld a, e + ld [$ccd3], a + ld [$ccd4], a + ld a, $2 + ld [$cd38], a + call LoadHoppingShadowOAM + ld a, (SFX_02_4e - SFX_Headers_02) / 3 + call PlaySound + ret + + ; (player direction) (tile player standing on) (ledge tile) (input required) +LedgeTiles: ; 1a6cf (6:66cf) + db $00,$2C,$37,$80 + db $00,$39,$36,$80 + db $00,$39,$37,$80 + db $08,$2C,$27,$20 + db $08,$39,$27,$20 + db $0C,$2C,$0D,$10 + db $0C,$2C,$1D,$10 + db $0C,$39,$0D,$10 + db $FF + +LoadHoppingShadowOAM: ; 1a6f0 (6:66f0) + ld hl, $8ff0 + ld de, LedgeHoppingShadow ; $6708 + ld bc, (BANK(LedgeHoppingShadow) << 8) + $01 + call CopyVideoDataDouble + ld a, $9 + ld bc, $5448 ; b, c = y, x coordinates of shadow + ld de, LedgeHoppingShadowOAM ; $6710 + call WriteOAMBlock + ret + +LedgeHoppingShadow: ; 1a708 (6:6708) + INCBIN "gfx/ledge_hopping_shadow.1bpp" + +LedgeHoppingShadowOAM: ; 1a710 (6:6710) + db $FF,$10,$FF,$20 + db $FF,$40,$FF,$60 diff --git a/engine/overworld/map_sprites.asm b/engine/overworld/map_sprites.asm new file mode 100755 index 00000000..a734319d --- /dev/null +++ b/engine/overworld/map_sprites.asm @@ -0,0 +1,440 @@ +; Loads tile patterns for map's sprites. +; For outside maps, it loads one of several fixed sets of sprites. +; For inside maps, it loads each sprite picture ID used in the map header. +; This is also called after displaying text because loading +; text tile patterns overwrites half of the sprite tile pattern data. +; Note on notation: +; $C1X* and $C2X* are used to denote $C100-$C1FF and $C200-$C2FF sprite slot +; fields, respectively, within loops. The X is the loop index. +; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y* +; denote fields of the sprite slots interated over in the inner loop. +InitMapSprites: ; 1785b (5:785b) + call InitOutsideMapSprites + ret c ; return if the map is an outside map (already handled by above call) +; if the map is an inside map (i.e. mapID >= $25) + ld hl,wSpriteStateData1 + ld de,$c20d +; Loop to copy picture ID's from $C1X0 to $C2XD for LoadMapSpriteTilePatterns. +.copyPictureIDLoop + ld a,[hl] ; $C1X0 (picture ID) + ld [de],a ; $C2XD + ld a,$10 + add e + ld e,a + ld a,$10 + add l + ld l,a + jr nz,.copyPictureIDLoop + +; This is used for both inside and outside maps, since it is called by +; InitOutsideMapSprites. +; Loads tile pattern data for sprites into VRAM. +LoadMapSpriteTilePatterns: ; 17871 (5:7871) + ld a,[W_NUMSPRITES] + and a ; are there any sprites? + jr nz,.spritesExist + ret +.spritesExist + ld c,a ; c = [W_NUMSPRITES] + ld b,$10 ; number of sprite slots + ld hl,$c20d + xor a + ld [$ff8e],a ; 4-tile sprite counter +.copyPictureIDLoop ; loop to copy picture ID from $C2XD to $C2XE + ld a,[hli] ; $C2XD (sprite picture ID) + ld [hld],a ; $C2XE + ld a,l + add a,$10 + ld l,a + dec b + jr nz,.copyPictureIDLoop + ld hl,$c21e +.loadTilePatternLoop + ld de,$c21d +; Check if the current picture ID has already had its tile patterns loaded. +; This done by looping through the previous sprite slots and seeing if any of +; their picture ID's match that of the current sprite slot. +.checkIfAlreadyLoadedLoop + ld a,e + and a,$f0 + ld b,a ; b = offset of the wSpriteStateData2 sprite slot being checked against + ld a,l + and a,$f0 ; a = offset of current wSpriteStateData2 sprite slot + cp b ; done checking all previous sprite slots? + jr z,.notAlreadyLoaded + ld a,[de] ; picture ID of the wSpriteStateData2 sprite slot being checked against + cp [hl] ; do the picture ID's match? + jp z,.alreadyLoaded + ld a,e + add a,$10 + ld e,a + jr .checkIfAlreadyLoadedLoop +.notAlreadyLoaded + ld de,$c20e + ld b,$01 +; loop to find the highest tile pattern VRAM slot (among the first 10 slots) used by a previous sprite slot +; this is done in order to find the first free VRAM slot available +.findNextVRAMSlotLoop + ld a,e + add a,$10 + ld e,a + ld a,l + cp e ; reached current slot? + jr z,.foundNextVRAMSlot + ld a,[de] ; $C2YE (VRAM slot) + cp a,11 ; is it one of the first 10 slots? + jr nc,.findNextVRAMSlotLoop + cp b ; compare the slot being checked to the current max + jr c,.findNextVRAMSlotLoop ; if the slot being checked is less than the current max +; if the slot being checked is greater than or equal to the current max + ld b,a ; store new max VRAM slot + jr .findNextVRAMSlotLoop +.foundNextVRAMSlot + inc b ; increment previous max value to get next VRAM tile pattern slot + ld a,b ; a = next VRAM tile pattern slot + push af + ld a,[hl] ; $C2XE (sprite picture ID) + ld b,a ; b = current sprite picture ID + cp a,SPRITE_BALL ; is it a 4-tile sprite? + jr c,.notFourTileSprite + pop af + ld a,[$ff8e] ; 4-tile sprite counter + add a,11 + jr .storeVRAMSlot +.notFourTileSprite + pop af +.storeVRAMSlot + ld [hl],a ; store VRAM slot at $C2XE + ld [$ff8d],a ; used to determine if it's 4-tile sprite later + ld a,b ; a = current sprite picture ID + dec a + add a + add a + push bc + push hl + ld hl,SpriteSheetPointerTable + jr nc,.noCarry + inc h +.noCarry + add l + ld l,a + jr nc,.noCarry2 + inc h +.noCarry2 + push hl + call ReadSpriteSheetData + push af + push de + push bc + ld hl,$8000 ; VRAM base address + ld bc,$c0 ; number of bytes per VRAM slot + ld a,[$ff8d] + cp a,11 ; is it a 4-tile sprite? + jr nc,.fourTileSpriteVRAMAddr + ld d,a + dec d +; Equivalent to multiplying $C0 (number of bytes in 12 tiles) times the VRAM +; slot and adding the result to $8000 (the VRAM base address). +.calculateVRAMAddrLoop + add hl,bc + dec d + jr nz,.calculateVRAMAddrLoop + jr .loadStillTilePattern +.fourTileSpriteVRAMAddr + ld hl,$87c0 ; address for second 4-tile sprite + ld a,[$ff8e] ; 4-tile sprite counter + and a ; is it the first 4-tile sprite? + jr nz,.loadStillTilePattern +; if it's the first 4-tile sprite + ld hl,$8780 ; address for first 4-tile sprite + inc a + ld [$ff8e],a ; 4-tile sprite counter +.loadStillTilePattern + pop bc + pop de + pop af + push hl + push hl + ld h,d + ld l,e + pop de + ld b,a + ld a,[$cfc4] + bit 0,a ; reloading upper half of tile patterns after displaying text? + jr nz,.skipFirstLoad ; if so, skip loading data into the lower half + ld a,b + ld b,0 + call FarCopyData2 ; load tile pattern data for sprite when standing still +.skipFirstLoad + pop de + pop hl + ld a,[$ff8d] + cp a,11 ; is it a 4-tile sprite? + jr nc,.skipSecondLoad ; if so, there is no second block + push de + call ReadSpriteSheetData + push af + ld a,$c0 + add e + ld e,a + jr nc,.noCarry3 + inc d +.noCarry3 + ld a,[$cfc4] + bit 0,a ; reloading upper half of tile patterns after displaying text? + jr nz,.loadWhileLCDOn + pop af + pop hl + set 3,h ; add $800 to hl + push hl + ld h,d + ld l,e + pop de + call FarCopyData2 ; load tile pattern data for sprite when walking + jr .skipSecondLoad +; When reloading the upper half of tile patterns after diplaying text, the LCD +; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must +; be used instead of FarCopyData2. +.loadWhileLCDOn + pop af + pop hl + set 3,h ; add $800 to hl + ld b,a + swap c + call CopyVideoData ; load tile pattern data for sprite when walking +.skipSecondLoad + pop hl + pop bc + jr .nextSpriteSlot +.alreadyLoaded ; if the current picture ID has already had its tile patterns loaded + inc de + ld a,[de] ; a = VRAM slot for the current picture ID (from $C2YE) + ld [hl],a ; store VRAM slot in current wSpriteStateData2 sprite slot (at $C2XE) +.nextSpriteSlot + ld a,l + add a,$10 + ld l,a + dec c + jp nz,.loadTilePatternLoop + ld hl,$c20d + ld b,$10 +; the pictures ID's stored at $C2XD are no longer needed, so zero them +.zeroStoredPictureIDLoop + xor a + ld [hl],a ; $C2XD + ld a,$10 + add l + ld l,a + dec b + jr nz,.zeroStoredPictureIDLoop + ret + +; reads data from SpriteSheetPointerTable +; INPUT: +; hl = address of sprite sheet entry +; OUTPUT: +; de = pointer to sprite sheet +; bc = length in bytes +; a = ROM bank +ReadSpriteSheetData: ; 17971 (5:7971) + ld a,[hli] + ld e,a + ld a,[hli] + ld d,a + ld a,[hli] + ld c,a + xor a + ld b,a + ld a,[hli] + ret + +; Loads sprite set for outside maps (cities and routes) and sets VRAM slots. +; sets carry if the map is a city or route, unsets carry if not +InitOutsideMapSprites: ; 1797b (5:797b) + ld a,[W_CURMAP] + cp a,REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)? + ret nc ; if not, return + ld hl,MapSpriteSets + add l + ld l,a + jr nc,.noCarry + inc h +.noCarry + ld a,[hl] ; a = spriteSetID + cp a,$f0 ; does the map have 2 sprite sets? + call nc,GetSplitMapSpriteSetID ; if so, choose the appropriate one + ld b,a ; b = spriteSetID + ld a,[$cfc4] + bit 0,a ; reloading upper half of tile patterns after displaying text? + jr nz,.loadSpriteSet ; if so, forcibly reload the sprite set + ld a,[W_SPRITESETID] + cp b ; has the sprite set ID changed? + jr z,.skipLoadingSpriteSet ; if not, don't load it again +.loadSpriteSet + ld a,b + ld [W_SPRITESETID],a + dec a + ld b,a + sla a + ld c,a + sla a + sla a + add c + add b ; a = (spriteSetID - 1) * 11 + ld de,SpriteSets +; add a to de to get offset of sprite set + add e + ld e,a + jr nc,.noCarry2 + inc d +.noCarry2 + ld hl,$c20d + ld a,SPRITE_RED + ld [hl],a + ld bc,W_SPRITESET +; Load the sprite set into RAM. +; This loop also fills $C2XD (sprite picture ID) where X is from $0 to $A +; with picture ID's. This is done so that LoadMapSpriteTilePatterns will +; load tile patterns for all sprite pictures in the sprite set. +.loadSpriteSetLoop + ld a,$10 + add l + ld l,a + ld a,[de] ; sprite picture ID from sprite set + ld [hl],a ; $C2XD (sprite picture ID) + ld [bc],a + inc de + inc bc + ld a,l + cp a,$bd ; reached 11th sprite slot? + jr nz,.loadSpriteSetLoop + ld b,4 ; 4 remaining sprite slots +.zeroRemainingSlotsLoop ; loop to zero the picture ID's of the remaining sprite slots + ld a,$10 + add l + ld l,a + xor a + ld [hl],a ; $C2XD (sprite picture ID) + dec b + jr nz,.zeroRemainingSlotsLoop + ld a,[W_NUMSPRITES] + push af ; save number of sprites + ld a,11 ; 11 sprites in sprite set + ld [W_NUMSPRITES],a + call LoadMapSpriteTilePatterns + pop af + ld [W_NUMSPRITES],a ; restore number of sprites + ld hl,$c21e + ld b,$0f +; The VRAM tile pattern slots that LoadMapSpriteTilePatterns set are in the +; order of the map's sprite set, not the order of the actual sprites loaded +; for the current map. So, they are not needed and are zeroed by this loop. +.zeroVRAMSlotsLoop + xor a + ld [hl],a ; $C2XE (VRAM slot) + ld a,$10 + add l + ld l,a + dec b + jr nz,.zeroVRAMSlotsLoop +.skipLoadingSpriteSet + ld hl,$c110 +; This loop stores the correct VRAM tile pattern slots according the sprite +; data from the map's header. Since the VRAM tile pattern slots are filled in +; the order of the sprite set, in order to find the VRAM tile pattern slot +; for a sprite slot, the picture ID for the sprite is looked up within the +; sprite set. The index of the picture ID within the sprite set plus one +; (since the Red sprite always has the first VRAM tile pattern slot) is the +; VRAM tile pattern slot. +.storeVRAMSlotsLoop + ld c,0 + ld a,[hl] ; $C1X0 (picture ID) (zero if sprite slot is not used) + and a ; is the sprite slot used? + jr z,.skipGettingPictureIndex ; if the sprite slot is not used + ld b,a ; b = picture ID + ld de,W_SPRITESET +; Loop to find the index of the sprite's picture ID within the sprite set. +.getPictureIndexLoop + inc c + ld a,[de] + inc de + cp b ; does the picture ID match? + jr nz,.getPictureIndexLoop + inc c +.skipGettingPictureIndex + push hl + inc h + ld a,$0e + add l + ld l,a + ld a,c ; a = VRAM slot (zero if sprite slot is not used) + ld [hl],a ; $C2XE (VRAM slot) + pop hl + ld a,$10 + add l + ld l,a + and a + jr nz,.storeVRAMSlotsLoop + scf + ret + +; Chooses the correct sprite set ID depending on the player's position within +; the map for maps with two sprite sets. +GetSplitMapSpriteSetID: ; 17a1a (5:7a1a) + cp a,$f8 + jr z,.route20 + ld hl,SplitMapSpriteSets + and a,$0f + dec a + sla a + sla a + add l + ld l,a + jr nc,.noCarry + inc h +.noCarry + ld a,[hli] ; determines whether the map is split East/West or North/South + cp a,$01 + ld a,[hli] ; position of dividing line + ld b,a + jr z,.eastWestDivide +.northSouthDivide + ld a,[W_YCOORD] + jr .compareCoord +.eastWestDivide + ld a,[W_XCOORD] +.compareCoord + cp b + jr c,.loadSpriteSetID +; if in the East side or South side + inc hl +.loadSpriteSetID + ld a,[hl] + ret +; Uses sprite set $01 for West side and $0A for East side. +; Route 20 is a special case because the two map sections have a more complex +; shape instead of the map simply being split horizontally or vertically. +.route20 + ld hl,W_XCOORD + ld a,[hl] + cp a,$2b + ld a,$01 + ret c + ld a,[hl] + cp a,$3e + ld a,$0a + ret nc + ld a,[hl] + cp a,$37 + ld b,$08 + jr nc,.next + ld b,$0d +.next + ld a,[W_YCOORD] + cp b + ld a,$0a + ret c + ld a,$01 + ret + +INCLUDE "data/sprite_sets.asm" diff --git a/engine/overworld/npc_movement.asm b/engine/overworld/npc_movement.asm new file mode 100755 index 00000000..54d7321b --- /dev/null +++ b/engine/overworld/npc_movement.asm @@ -0,0 +1,291 @@ +Func_1a3e0: ; 1a3e0 (6:63e0) + ld hl, $d730 + res 1, [hl] + call HandleDoors + jr nc, .asm_1a406 + ld a, $fc + ld [wJoypadForbiddenButtonsMask], a + ld hl, $d736 + set 1, [hl] + ld a, $1 + ld [$cd38], a + ld a, $80 + ld [$ccd3], a + xor a + ld [$c102], a + call Func_3486 + ret +.asm_1a406 + xor a + ld [$cd3a], a + ld [$cd38], a + ld [$ccd3], a + ld hl, $d736 + res 0, [hl] + res 1, [hl] + ld hl, $d730 + res 7, [hl] + ret + +Func_1a41d: ; 1a41d (6:641d) + ld hl, $d730 + res 7, [hl] + ld hl, $d72e + res 7, [hl] + ld hl, $d736 + res 0, [hl] + res 1, [hl] + xor a + ld [$cf17], a + ld [$cc57], a + ld [$cf10], a + ld [$cd3a], a + ld [$cd38], a + ld [$ccd3], a + ret + +PointerTable_1a442: ; 1a442 (6:6442) + dw Func_1a44c + dw Func_1a485 + dw Func_1a4a1 + dw Func_1a4a6 + dw Func_1a4f4 + +Func_1a44c: ; 1a44c (6:644c) + ld a, [W_XCOORD] ; $d362 + sub $a + ld [$cca1], a + jr z, .asm_1a475 + ld b, $0 + ld c, a + ld hl, $cc97 + ld a, $80 + call FillMemory + ld [hl], $ff + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + ld de, $cc97 + call MoveSprite + ld a, $1 + ld [$cf10], a + jr .asm_1a47a +.asm_1a475 + ld a, $3 + ld [$cf10], a +.asm_1a47a + ld hl, W_FLAGS_D733 + set 1, [hl] + ld a, $fc + ld [wJoypadForbiddenButtonsMask], a + ret + +Func_1a485: ; 1a485 (6:6485) + ld a, [$d730] + bit 0, a + ret nz + ld a, [$cca1] + ld [$cd38], a + ld [$ff95], a + ld a, $23 + call Predef + call Func_3486 + ld a, $2 + ld [$cf10], a + ret + +Func_1a4a1: ; 1a4a1 (6:64a1) + ld a, [$cd38] + and a + ret nz + +Func_1a4a6: ; 1a4a6 (6:64a6) + xor a + ld [$cd3b], a + ld a, [$cf13] + swap a + ld [$cf17], a + xor a + ld [$c206], a + ld hl, $ccd3 + ld de, RLEList_1a4e9 + call DecodeRLEList + dec a + ld [$cd38], a + ld hl, $cc97 + ld de, RLEList_1a4dc + call DecodeRLEList + ld hl, $d72e + res 7, [hl] + ld hl, $d730 + set 7, [hl] + ld a, $4 + ld [$cf10], a + ret + +RLEList_1a4dc: ; 1a4dc (6:64dc) + db $00, $05 + db $80, $01 + db $00, $05 + db $C0, $03 + db $40, $01 + db $E0, $01 + db $FF + +RLEList_1a4e9: ; 1a4e9 (6:64e9) + db $40, $02 + db $10, $03 + db $80, $05 + db $20, $01 + db $80, $06 + db $FF + +Func_1a4f4: ; 1a4f4 (6:64f4) + ld a, [$cd38] + and a + ret nz + ld a, $0 + ld [$cc4d], a + ld a, $11 + call Predef ; indirect jump to RemoveMissableObject (f1d7 (3:71d7)) + ld hl, $d730 + res 7, [hl] + ld hl, $d72e + res 7, [hl] + jp Func_314e + +PointerTable_1a510: ; 1a510 (6:6510) + dw Func_1a514 + dw Func_1a56b + +Func_1a514: ; 1a514 (6:6514) + ld a, Bank(Func_9876) + ld [$c0ef], a + ld [$c0f0], a + ld a, MUSIC_MUSEUM_GUY + ld [$c0ee], a + call PlaySound + ld a, [$cf13] + swap a + ld [$cf17], a + call Func_3486 + ld hl, $ccd3 + ld de, RLEList_PewterMuseumPlayer + call DecodeRLEList + dec a + ld [$cd38], a + xor a + ld [$d12f], a + ld a, $4f + call Predef + ld hl, $cc97 + ld de, RLEList_PewterMuseumGuy + call DecodeRLEList + ld hl, $d72e + res 7, [hl] + ld a, $1 + ld [$cf10], a + ret + +RLEList_PewterMuseumPlayer: ; 1a559 (6:6559) + db $00, $01 + db $40, $03 + db $20, $0D + db $40, $06 + db $FF + +RLEList_PewterMuseumGuy: ; 1a562 (6:6562) + db $40, $06 + db $80, $0D + db $40, $03 + db $80, $01 + db $FF + +Func_1a56b: ; 1a56b (6:656b) + ld a, [$cd38] + and a + ret nz + ld hl, $d730 + res 7, [hl] + ld hl, $d72e + res 7, [hl] + jp Func_314e + +PointerTable_1a57d: ; 1a57d (6:657d) + dw Func_1a581 + dw Func_1a56b + +Func_1a581: ; 1a581 (6:6581) + ld a, Bank(Func_9876) + ld [$c0ef], a + ld [$c0f0], a + ld a, MUSIC_MUSEUM_GUY + ld [$c0ee], a + call PlaySound + ld a, [$cf13] + swap a + ld [$cf17], a + xor a + ld [$c206], a + ld hl, $ccd3 + ld de, RLEList_PewterGymPlayer + call DecodeRLEList + dec a + ld [$cd38], a + ld a, $1 + ld [$d12f], a + ld a, $4f + call Predef + ld hl, $cc97 + ld de, RLEList_PewterGymGuy + call DecodeRLEList + ld hl, $d72e + res 7, [hl] + ld hl, $d730 + set 7, [hl] + ld a, $1 + ld [$cf10], a + ret + +RLEList_PewterGymPlayer: ; 1a5cd (6:65cd) + db $00, $01 + db $10, $02 + db $80, $05 + db $20, $0B + db $40, $05 + db $20, $0F + db $FF + +RLEList_PewterGymGuy: ; 1a5da (6:65da) + db $00, $02 + db $80, $0F + db $40, $05 + db $80, $0B + db $00, $05 + db $C0, $03 + db $FF + +; XXX why would this function want to return on POKEMONTOWER_7? +Func_1a5e7: ; 1a5e7 (6:65e7) + ld a, [W_CURMAP] ; $d35e + cp POKEMONTOWER_7 + ret z + ld hl, RivalIDs ; $6605 + ld a, [wEngagedTrainerClass] + ld b, a +.loop + ld a, [hli] + cp $ff + jr z, .notRival + cp b + ret z + jr .loop +.notRival + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + jp SetSpriteMovementBytesToFF + +RivalIDs: ; 1a605 (6:6605) + db SONY1 + $c8 + db SONY2 + $c8 + db SONY3 + $c8 + db $ff diff --git a/engine/overworld/oaks_aide.asm b/engine/overworld/oaks_aide.asm new file mode 100755 index 00000000..ca2c6726 --- /dev/null +++ b/engine/overworld/oaks_aide.asm @@ -0,0 +1,71 @@ +OaksAideScript ; 0x59035 + ld hl, OaksAideHiText + call PrintText + call YesNoChoice + ld a, [$cc26] + and a + jr nz, .asm_59086 ; 0x59042 $42 + ld hl, wPokedexOwned + ld b, wPokedexOwnedEnd - wPokedexOwned + call CountSetBits + ld a, [$d11e] + ld [$ffdd], a + ld b, a + ld a, [$ffdb] + cp b + jr z, .asm_59059 ; 0x59055 $2 + jr nc, .asm_5907c ; 0x59057 $23 +.asm_59059 + ld hl, OaksAideHereYouGoText + call PrintText + ld a, [$ffdc] + ld b, a + ld c, 1 + call GiveItem + jr nc, .BagFull + ld hl, OaksAideGotItemText + call PrintText + ld a, $1 + jr .asm_5908e ; 0x59071 $1b +.BagFull + ld hl, OaksAideNoRoomText + call PrintText + xor a + jr .asm_5908e ; 0x5907a $12 +.asm_5907c + ld hl, OaksAideUhOhText + call PrintText + ld a, $80 + jr .asm_5908e ; 0x59084 $8 +.asm_59086 + ld hl, OaksAideComeBackText + call PrintText + ld a, $ff +.asm_5908e + ld [$ffdb], a + ret + +OaksAideHiText: ; 59091 (16:5091) + TX_FAR _OaksAideHiText + db "@" + +OaksAideUhOhText: ; 59096 (16:5096) + TX_FAR _OaksAideUhOhText + db "@" + +OaksAideComeBackText: ; 5909b (16:509b) + TX_FAR _OaksAideComeBackText + db "@" + +OaksAideHereYouGoText: ; 590a0 (16:50a0) + TX_FAR _OaksAideHereYouGoText + db "@" + +OaksAideGotItemText: ; 590a5 (16:50a5) + TX_FAR _OaksAideGotItemText + db $0b + db "@" + +OaksAideNoRoomText: ; 590ab (16:50ab) + TX_FAR _OaksAideNoRoomText + db "@" diff --git a/engine/overworld/pewter_guys.asm b/engine/overworld/pewter_guys.asm new file mode 100755 index 00000000..7c5779a2 --- /dev/null +++ b/engine/overworld/pewter_guys.asm @@ -0,0 +1,101 @@ +PewterGuys: ; 37ca1 (d:7ca1) + ld hl, $ccd3 + ld a, [$cd38] + dec a + ld [$cd38], a + ld d, 0 + ld e, a + add hl, de + ld d, h + ld e, l + ld hl, PointerTable_37ce6 + ld a, [$d12f] + add a + ld b, 0 + ld c, a + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [W_YCOORD] + ld b, a + ld a, [W_XCOORD] + ld c, a +.asm_37cc7 + ld a, [hli] + cp b + jr nz, .asm_37ce1 + ld a, [hli] + cp c + jr nz, .asm_37ce2 + ld a, [hli] + ld h, [hl] + ld l, a +.asm_37cd2 + ld a, [hli] + cp $ff + ret z + ld [de], a + inc de + ld a, [$cd38] + inc a + ld [$cd38], a + jr .asm_37cd2 +.asm_37ce1 + inc hl +.asm_37ce2 + inc hl + inc hl + jr .asm_37cc7 + +PointerTable_37ce6: ; 37ce6 (d:7ce6) + dw PewterMuseumGuyCoords + dw PewterGymGuyCoords + +; these are the four coordinates of the spaces below, above, to the left and +; to the right of the museum guy, and pointers to different movements for +; the player to make to get positioned before the main movement. +PewterMuseumGuyCoords: ; 37cea (d:7cea) + db 18, 27 + dw .down + db 16, 27 + dw .up + db 17, 26 + dw .left + db 17, 28 + dw .right + +.down + db $40, $40, $ff +.up + db $10, $20, $ff +.left + db $40, $10, $ff +.right + db $40, $20, $ff + +; these are the five coordinates which trigger the gym guy and pointers to +; different movements for the player to make to get positioned before the +; main movement +PewterGymGuyCoords: ; 37d06 (d:7d06) + db 16, 34 + dw .one + db 17, 35 + dw .two + db 18, 37 + dw .three + db 19, 37 + dw .four + db 17, 36 + dw .five + +.one + db $20, $80, $80, $10, $ff +.two + db $20, $80, $10, $20, $ff +.three + db $20, $20, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff +.four + db $20, $20, $40, $20, $ff +.five + db $20, $80, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff diff --git a/engine/overworld/player_animations.asm b/engine/overworld/player_animations.asm new file mode 100755 index 00000000..1af178c7 --- /dev/null +++ b/engine/overworld/player_animations.asm @@ -0,0 +1,520 @@ +Func_70510: ; 70510 (1c:4510) + call Func_706ef + ld a, $ec + ld [$c104], a + call Delay3 + push hl + call GBFadeIn2 + ld hl, W_FLAGS_D733 + bit 7, [hl] + res 7, [hl] + jr nz, .asm_70568 + ld a, (SFX_02_4c - SFX_Headers_02) / 3 + call PlaySound + ld hl, $d732 + bit 4, [hl] + res 4, [hl] + pop hl + jr nz, .asm_7055e + call Func_705aa + ld a, (SFX_02_4f - SFX_Headers_02) / 3 + call PlaySound + call Func_70787 + ld a, b + and a + jr nz, .asm_7055b + ld hl, wWhichTrade ; $cd3d + xor a + ld [hli], a + inc a + ld [hli], a + ld a, $8 + ld [hli], a + ld [hl], $ff + ld hl, $cd48 + call Func_70730 +.asm_70558 + call Func_2307 +.asm_7055b + jp Func_70772 +.asm_7055e + ld c, $32 + call DelayFrames + call Func_705aa + jr .asm_7055b +.asm_70568 + pop hl + ld de, BirdSprite ; $4d80 + ld hl, $8000 + ld bc, (BANK(BirdSprite) << 8) + $0c + call CopyVideoData + call Func_706d7 + ld a, (SFX_02_50 - SFX_Headers_02) / 3 + call PlaySound + ld hl, wWhichTrade ; $cd3d + xor a + ld [hli], a + ld a, $c + ld [hli], a + ld [hl], $8 + ld de, FlyAnimationEnterScreenCoords ; $4592 + call Func_706ae + call LoadPlayerSpriteGraphics + jr .asm_70558 + +FlyAnimationEnterScreenCoords: ; 70592 (1c:4592) +; y, x pairs +; This is the sequence of screen coordinates used by the overworld +; Fly animation when the player is entering a map. + db $05, $98 + db $0F, $90 + db $18, $88 + db $20, $80 + db $27, $78 + db $2D, $70 + db $32, $68 + db $36, $60 + db $39, $58 + db $3B, $50 + db $3C, $48 + db $3C, $40 + +Func_705aa: ; 705aa (1c:45aa) + ld hl, wWhichTrade ; $cd3d + ld a, $10 + ld [hli], a + ld a, $3c + ld [hli], a + call Func_7077f + ld [hl], a + jp Func_70755 + +_DoFlyOrTeleportAwayGraphics: ; 705ba (1c:45ba) + call Func_706ef + call Func_70787 + ld a, b + and a + jr z, .asm_705ef + dec a + jp nz, Func_7067d +.asm_705c8 + ld a, (SFX_02_4b - SFX_Headers_02) / 3 + call PlaySound + ld hl, wWhichTrade ; $cd3d + ld a, $f0 + ld [hli], a + ld a, $ec + ld [hli], a + call Func_7077f + ld [hl], a + call Func_70755 + call Func_70787 + ld a, b + dec a + jr z, .asm_705e9 + ld c, $a + call DelayFrames +.asm_705e9 + call GBFadeOut2 + jp Func_70772 +.asm_705ef + ld a, $4 + call StopMusic + ld a, [$d732] + bit 6, a + jr z, .asm_70610 + ld hl, wWhichTrade ; $cd3d + ld a, $10 + ld [hli], a + ld a, $ff + ld [hli], a + xor a + ld [hli], a + ld [hl], $a1 + ld hl, $cd48 + call Func_70730 + jr .asm_705c8 +.asm_70610 + call Func_706d7 + ld hl, wWhichTrade ; $cd3d + ld a, $ff + ld [hli], a + ld a, $8 + ld [hli], a + ld [hl], $c + call Func_706ae + ld a, (SFX_02_50 - SFX_Headers_02) / 3 + call PlaySound + ld hl, wWhichTrade ; $cd3d + xor a + ld [hli], a + ld a, $c + ld [hli], a + ld [hl], $c + ld de, FlyAnimationScreenCoords1 ; $464f + call Func_706ae + ld c, $28 + call DelayFrames + ld hl, $cd3e + ld a, $b + ld [hli], a + ld [hl], $8 + ld de, FlyAnimationScreenCoords2 ; $4667 + call Func_706ae + call GBFadeOut2 + jp Func_70772 + +FlyAnimationScreenCoords1: ; 7064f (1c:464f) +; y, x pairs +; This is the sequence of screen coordinates used by the first part +; of the Fly overworld animation. + db $3C, $48 + db $3C, $50 + db $3B, $58 + db $3A, $60 + db $39, $68 + db $37, $70 + db $37, $78 + db $33, $80 + db $30, $88 + db $2D, $90 + db $2A, $98 + db $27, $A0 + +FlyAnimationScreenCoords2: ; 70667 (1c:4667) +; y, x pairs +; This is the sequence of screen coordinates used by the second part +; of the Fly overworld animation. + db $1A, $90 + db $19, $80 + db $17, $70 + db $15, $60 + db $12, $50 + db $0F, $40 + db $0C, $30 + db $09, $20 + db $05, $10 + db $00, $00 + + db $F0, $00 + +Func_7067d: ; 7067d (1c:467d) + ld a, $ff + ld [$cfcb], a + ld a, [$c302] + ld [$c30a], a + ld a, [$c306] + ld [$c30e], a + ld a, $a0 + ld [wOAMBuffer], a + ld [$c304], a + ld c, $2 + call DelayFrames + ld a, $a0 + ld [$c308], a + ld [$c30c], a + call GBFadeOut2 + ld a, $1 + ld [$cfcb], a + jp Func_70772 + +Func_706ae: ; 706ae (1c:46ae) + ld a, [$cd3f] + xor $1 + ld [$cd3f], a + ld [$c102], a + call Delay3 + ld a, [wWhichTrade] ; $cd3d + cp $ff + jr z, .asm_706cd + ld hl, $c104 + ld a, [de] + inc de + ld [hli], a + inc hl + ld a, [de] + inc de + ld [hl], a +.asm_706cd + ld a, [$cd3e] + dec a + ld [$cd3e], a + jr nz, Func_706ae + ret + +Func_706d7: ; 706d7 (1c:46d7) + ld de, BirdSprite ; $4d80 + ld hl, $8000 + ld bc, (BANK(BirdSprite) << 8) + $0c + call CopyVideoData + ld de, BirdSprite + $c0 ; $4e40 ; moving amination sprite + ld hl, $8800 + ld bc, (BANK(BirdSprite) << 8) + $0c + jp CopyVideoData + +Func_706ef: ; 706ef (1c:46ef) + ld a, [$c102] + ld [$cd50], a + ld a, [$c104] + ld [$cd4f], a + ld hl, PlayerSpinningFacingOrder ; $4713 + ld de, $cd48 + ld bc, $4 + call CopyData + ld a, [$c102] + ld hl, $cd48 +.asm_7070d + cp [hl] + inc hl + jr nz, .asm_7070d + dec hl + ret + +PlayerSpinningFacingOrder: ; 70713 (1c:4713) +; The order of the direction the player's sprite is facing when teleporting +; away. Creates a spinning effect. + db $00, $08, $04, $0C ; down, left, up, right + +Func_70717: ; 70717 (1c:4717) + ld a, [hl] + ld [$c102], a + push hl + ld hl, $cd48 + ld de, $cd47 + ld bc, $4 + call CopyData + ld a, [$cd47] + ld [$cd4b], a + pop hl + ret + +Func_70730: ; 70730 (1c:4730) + call Func_70717 + ld a, [wWhichTrade] ; $cd3d + ld c, a + and $3 + jr nz, .asm_70743 + ld a, [$cd40] + cp $ff + call nz, PlaySound +.asm_70743 + ld a, [$cd3e] + add c + ld [wWhichTrade], a ; $cd3d + ld c, a + ld a, [$cd3f] + cp c + ret z + call DelayFrames + jr Func_70730 + +Func_70755: ; 70755 (1c:4755) + call Func_70717 + ld a, [wWhichTrade] ; $cd3d + ld c, a + ld a, [$c104] + add c + ld [$c104], a + ld c, a + ld a, [$cd3e] + cp c + ret z + ld a, [$cd3f] + ld c, a + call DelayFrames + jr Func_70755 + +Func_70772: ; 70772 (1c:4772) + ld a, [$cd4f] + ld [$c104], a + ld a, [$cd50] + ld [$c102], a + ret + +Func_7077f: ; 7077f (1c:477f) + ld a, [$cf1b] + xor $1 + inc a + inc a + ret + +Func_70787: ; 70787 (1c:4787) + ld b, 0 + ld hl, DataTable_707a9 ; $47a9 + ld a, [W_CURMAPTILESET] ; $d367 + ld c, a +.asm_70790 + ld a, [hli] + cp $ff + jr z, .asm_707a4 + cp c + jr nz, .asm_7079e + FuncCoord 8, 9 ; $c45c + ld a, [Coord] + cp [hl] + jr z, .asm_707a2 +.asm_7079e + inc hl + inc hl + jr .asm_70790 +.asm_707a2 + inc hl + ld b, [hl] +.asm_707a4 + ld a, b + ld [$cd5b], a + ret + +; format: db tileset id, tile id, value to be put in $cd5b +DataTable_707a9: ; 707a9 (1c:47a9) + db FACILITY, $20, 1 ; warp pad + db FACILITY, $11, 2 ; hole + db CAVERN, $22, 2 ; hole + db INTERIOR, $55, 1 ; warp pad + db $FF + +Func_707b6: ; 707b6 (1c:47b6) + ld c, $a + call DelayFrames + ld hl, $d736 + set 6, [hl] + ld de, RedSprite ; $4180 + ld hl, $8000 + ld bc, (BANK(RedSprite) << 8) + $0c + call CopyVideoData + ld a, $4 + ld hl, RedFishingTiles ; $4866 + call Func_71771 + ld a, [$c102] + ld c, a + ld b, $0 + ld hl, FishingRodGfxProperties ; $4856 + add hl, bc + ld de, $c39c + ld bc, $4 + call CopyData + ld c, $64 + call DelayFrames + ld a, [wWhichTrade] ; $cd3d + and a + ld hl, NoNibbleText + jr z, .asm_70836 + cp $2 + ld hl, NothingHereText + jr z, .asm_70836 + ld b, $a +.asm_707fe + ld hl, $c104 + call Func_70842 + ld hl, $c39c + call Func_70842 + call Delay3 + dec b + jr nz, .asm_707fe + ld a, [$c102] + cp $4 + jr nz, .asm_7081c + ld a, $a0 + ld [$c39c], a +.asm_7081c + ld hl, $cd4f + xor a + ld [hli], a + ld [hl], a + ld a, $4c + call Predef ; indirect jump to PrintEmotionBubble (17c47 (5:7c47)) + ld a, [$c102] + cp $4 + jr nz, .asm_70833 + ld a, $44 + ld [$c39c], a +.asm_70833 + ld hl, ItsABiteText +.asm_70836 + call PrintText + ld hl, $d736 + res 6, [hl] + call LoadFontTilePatterns + ret + +Func_70842: ; 70842 (1c:4842) + ld a, [hl] + xor $1 + ld [hl], a + ret + +NoNibbleText: ; 70847 (1c:4847) + TX_FAR _NoNibbleText + db "@" + +NothingHereText: ; 7084c (1c:484c) + TX_FAR _NothingHereText + db "@" + +ItsABiteText: ; 70851 (1c:4851) + TX_FAR _ItsABiteText + db "@" + +FishingRodGfxProperties: ; 70856 (1c:4856) +; specicies how the fishing rod should be drawn on the screen +; first byte = screen y coordinate +; second byte = screen x coordinate +; third byte = tile number +; fourth byte = sprite properties + db $5B, $4C, $FD, $00 ; player facing down + db $44, $4C, $FD, $00 ; player facing up + db $50, $40, $FE, $00 ; player facing left + db $50, $58, $FE, $20 ; player facing right ($20 means "horizontally flip the tile") + +RedFishingTiles: ; 70866 (1c:4866) + dw RedFishingTilesFront + db $02, $1E + dw $8020 + + dw RedFishingTilesBack + db $02, $1E + dw $8060 + + dw RedFishingTilesSide + db $02, $1E + dw $80A0 + + dw RedFishingRodTiles + db $03, $1E + dw $8FD0 + +_HandleMidJump: ; 7087e (1c:487e) + ld a, [$d714] + ld c, a + inc a + cp $10 + jr nc, .asm_70895 + ld [$d714], a + ld b, $0 + ld hl, PlayerJumpingYScreenCoords ; $48ba + add hl, bc + ld a, [hl] + ld [$c104], a ; player's sprite y coordinate + ret +.asm_70895 + ld a, [wWalkCounter] ; $cfc5 + cp $0 + ret nz + call UpdateSprites + call Delay3 + xor a + ld [H_CURRENTPRESSEDBUTTONS], a + ld [H_NEWLYPRESSEDBUTTONS], a + ld [H_NEWLYRELEASEDBUTTONS], a + ld [$d714], a + ld hl, $d736 + res 6, [hl] + ld hl, $d730 + res 7, [hl] + xor a + ld [wJoypadForbiddenButtonsMask], a + ret + +PlayerJumpingYScreenCoords: ; 708ba (1c:48ba) +; Sequence of y screen coordinates for player's sprite when jumping over a ledge. + db $38, $36, $34, $32, $31, $30, $30, $30, $31, $32, $33, $34, $36, $38, $3C, $3C diff --git a/engine/overworld/pokecenter.asm b/engine/overworld/pokecenter.asm new file mode 100755 index 00000000..45599498 --- /dev/null +++ b/engine/overworld/pokecenter.asm @@ -0,0 +1,68 @@ +DisplayPokemonCenterDialogue_: ; 6fe6 (1:6fe6) + call SaveScreenTilesToBuffer1 ; save screen + ld hl, PokemonCenterWelcomeText + call PrintText + ld hl, $d72e + bit 2, [hl] + set 1, [hl] + set 2, [hl] + jr nz, .skipShallWeHealYourPokemon + ld hl, ShallWeHealYourPokemonText + call PrintText +.skipShallWeHealYourPokemon + call YesNoChoicePokeCenter ; yes/no menu + ld a, [wCurrentMenuItem] + and a + jr nz, .declinedHealing ; if the player chose No + call SetLastBlackoutMap + call LoadScreenTilesFromBuffer1 ; restore screen + ld hl, NeedYourPokemonText + call PrintText + ld a, $18 + ld [$c112], a ; make the nurse turn to face the machine + call Delay3 + PREDEF HealPartyPredef + callba AnimateHealingMachine ; do the healing machine animation + xor a + ld [wMusicHeaderPointer], a + ld a, [$c0f0] + ld [$c0ef], a + ld a, [$d35b] + ld [$cfca], a + ld [$c0ee], a + call PlaySound + ld hl, PokemonFightingFitText + call PrintText + ld a, $14 + ld [$c112], a ; make the nurse bow + ld c, a + call DelayFrames + jr .done +.declinedHealing + call LoadScreenTilesFromBuffer1 ; restore screen +.done + ld hl, PokemonCenterFarewellText + call PrintText + jp UpdateSprites ; move sprites + +PokemonCenterWelcomeText: ; 705d (1:705d) + TX_FAR _PokemonCenterWelcomeText + db "@" + +ShallWeHealYourPokemonText: ; 7062 (1:7062) + db $a + TX_FAR _ShallWeHealYourPokemonText + db "@" + +NeedYourPokemonText: ; 7068 (1:7068) + TX_FAR _NeedYourPokemonText + db "@" + +PokemonFightingFitText: ; 706d (1:706d) + TX_FAR _PokemonFightingFitText + db "@" + +PokemonCenterFarewellText: ; 7072 (1:7072) + db $a + TX_FAR _PokemonCenterFarewellText + db "@" diff --git a/engine/overworld/pokemart.asm b/engine/overworld/pokemart.asm new file mode 100755 index 00000000..6e6f5ee2 --- /dev/null +++ b/engine/overworld/pokemart.asm @@ -0,0 +1,256 @@ +DisplayPokemartDialogue_: ; 6c20 (1:6c20) + ld a,[wListScrollOffset] + ld [$d07e],a + call UpdateSprites ; move sprites + xor a + ld [$cf0a],a ; flag that is set if something is sold or bought +.loop + xor a + ld [wListScrollOffset],a + ld [wCurrentMenuItem],a + ld [$cc2f],a + inc a + ld [$cf93],a + ld a,$13 + ld [$d125],a + call DisplayTextBoxID ; draw money text box + ld a,$15 + ld [$d125],a + call DisplayTextBoxID ; do buy/sell/quit menu + ld hl,$d128 ; pointer to this pokemart's inventory + ld a,[hli] + ld l,[hl] + ld h,a ; hl = address of inventory + ld a,[$d12e] + cp a,$02 + jp z,.done + ld a,[$d12d] ; ID of the chosen menu item + and a ; buying? + jp z,.buyMenu + dec a ; selling? + jp z,.sellMenu + dec a ; quitting? + jp z,.done +.sellMenu + xor a + ld [$cf93],a + ld a,$02 + ld [$d11b],a + callab Func_39bd5 + ld a,[wNumBagItems] + and a + jp z,.bagEmpty + ld hl,PokemonSellingGreetingText + call PrintText + call SaveScreenTilesToBuffer1 ; save screen +.sellMenuLoop + call LoadScreenTilesFromBuffer1 ; restore saved screen + ld a,$13 + ld [$d125],a + call DisplayTextBoxID ; draw money text box + ld hl,wNumBagItems + ld a,l + ld [$cf8b],a + ld a,h + ld [$cf8c],a + xor a + ld [$cf93],a + ld [wCurrentMenuItem],a + ld a,ITEMLISTMENU + ld [wListMenuID],a + call DisplayListMenuID + jp c,.returnToMainPokemartMenu ; if the player closed the menu +.confirmItemSale ; if the player is trying to sell a specific item + call IsKeyItem ; check if item is unsellable + ld a,[$d124] + and a + jr nz,.unsellableItem + ld a,[$cf91] + call IsItemHM + jr c,.unsellableItem + ld a,PRICEDITEMLISTMENU + ld [wListMenuID],a + ld [$ff8e],a ; halve prices when selling + call DisplayChooseQuantityMenu + inc a + jr z,.sellMenuLoop ; if the player closed the choose quantity menu with the B button + ld hl,PokemartTellSellPriceText + ld bc,$0e01 + call PrintText + FuncCoord 14,7 + ld hl,Coord + ld bc,$080f + ld a,$14 + ld [$d125],a + call DisplayTextBoxID ; yes/no menu + ld a,[$d12e] + cp a,$02 + jr z,.sellMenuLoop ; if the player pressed the B button + ld a,[$d12d] ; ID of the chosen menu item + dec a + jr z,.sellMenuLoop ; if the player chose No +.sellItem + ld a,[$cf0a] ; flag that is set if something is sold or bought + and a + jr nz,.skipSettingFlag1 + inc a + ld [$cf0a],a +.skipSettingFlag1 + call AddAmountSoldToMoney + ld hl,wNumBagItems + call RemoveItemFromInventory + jp .sellMenuLoop +.unsellableItem + ld hl,PokemartUnsellableItemText + call PrintText + jp .returnToMainPokemartMenu +.bagEmpty + ld hl,PokemartItemBagEmptyText + call PrintText + call SaveScreenTilesToBuffer1 ; save screen + jp .returnToMainPokemartMenu +.buyMenu + ld a,$01 + ld [$cf93],a + ld a,$03 + ld [$d11b],a + callab Func_39bd5 + ld hl,PokemartBuyingGreetingText + call PrintText + call SaveScreenTilesToBuffer1 ; save screen +.buyMenuLoop + call LoadScreenTilesFromBuffer1 ; restore saved screen + ld a,$13 + ld [$d125],a + call DisplayTextBoxID ; draw money text box + ld hl,$cf7b + ld a,l + ld [$cf8b],a + ld a,h + ld [$cf8c],a + xor a + ld [wCurrentMenuItem],a + inc a + ld [$cf93],a + inc a ; a = 2 (PRICEDITEMLISTMENU) + ld [wListMenuID],a + call DisplayListMenuID + jr c,.returnToMainPokemartMenu ; if the player closed the menu + ld a,$63 + ld [$cf97],a + xor a + ld [$ff8e],a + call DisplayChooseQuantityMenu + inc a + jr z,.buyMenuLoop ; if the player closed the choose quantity menu with the B button + ld a,[$cf91] ; item ID + ld [$d11e],a ; store item ID for GetItemName + call GetItemName + call CopyStringToCF4B ; copy name to $cf4b + ld hl,PokemartTellBuyPriceText + call PrintText + FuncCoord 14,7 + ld hl,Coord + ld bc,$080f + ld a,$14 + ld [$d125],a + call DisplayTextBoxID ; yes/no menu + ld a,[$d12e] + cp a,$02 + jp z,.buyMenuLoop ; if the player pressed the B button + ld a,[$d12d] ; ID of the chosen menu item + dec a + jr z,.buyMenuLoop ; if the player chose No +.buyItem + call .isThereEnoughMoney + jr c,.notEnoughMoney + ld hl,wNumBagItems + call AddItemToInventory + jr nc,.bagFull + call SubtractAmountPaidFromMoney + ld a,[$cf0a] ; flag that is set if something is sold or bought + and a + jr nz,.skipSettingFlag2 + ld a,$01 + ld [$cf0a],a +.skipSettingFlag2 + ld a,(SFX_02_5a - SFX_Headers_02) / 3 + call PlaySoundWaitForCurrent ; play sound + call WaitForSoundToFinish ; wait until sound is done playing + ld hl,PokemartBoughtItemText + call PrintText + jp .buyMenuLoop +.returnToMainPokemartMenu + call LoadScreenTilesFromBuffer1 ; restore save screen + ld a,$13 + ld [$d125],a + call DisplayTextBoxID ; draw money text box + ld hl,PokemartAnythingElseText + call PrintText + jp .loop +.isThereEnoughMoney + ld de,wPlayerMoney + ld hl,$ff9f ; item price + ld c,3 ; length of money in bytes + jp StringCmp +.notEnoughMoney + ld hl,PokemartNotEnoughMoneyText + call PrintText + jr .returnToMainPokemartMenu +.bagFull + ld hl,PokemartItemBagFullText + call PrintText + jr .returnToMainPokemartMenu +.done + ld hl,PokemartThankYouText + call PrintText + ld a,$01 + ld [$cfcb],a + call UpdateSprites ; move sprites + ld a,[$d07e] + ld [wListScrollOffset],a + ret + +PokemartBuyingGreetingText: ; 6e0c (1:6e0c) + TX_FAR _PokemartBuyingGreetingText + db "@" + +PokemartTellBuyPriceText: ; 6e11 (1:6e11) + TX_FAR _PokemartTellBuyPriceText + db "@" + +PokemartBoughtItemText: ; 6e16 (1:6e16) + TX_FAR _PokemartBoughtItemText + db "@" + +PokemartNotEnoughMoneyText: ; 6e1b (1:6e1b) + TX_FAR _PokemartNotEnoughMoneyText + db "@" + +PokemartItemBagFullText: ; 6e20 (1:6e20) + TX_FAR _PokemartItemBagFullText + db "@" + +PokemonSellingGreetingText: ; 6e25 (1:6e25) + TX_FAR _PokemonSellingGreetingText + db "@" + +PokemartTellSellPriceText: ; 6e2a (1:6e2a) + TX_FAR _PokemartTellSellPriceText + db "@" + +PokemartItemBagEmptyText: ; 6e2f (1:6e2f) + TX_FAR _PokemartItemBagEmptyText + db "@" + +PokemartUnsellableItemText: ; 6e34 (1:6e34) + TX_FAR _PokemartUnsellableItemText + db "@" + +PokemartThankYouText: ; 6e39 (1:6e39) + TX_FAR _PokemartThankYouText + db "@" + +PokemartAnythingElseText: ; 6e3e (1:6e3e) + TX_FAR _PokemartAnythingElseText + db "@" diff --git a/engine/overworld/saffron_guards.asm b/engine/overworld/saffron_guards.asm new file mode 100755 index 00000000..8e584a2d --- /dev/null +++ b/engine/overworld/saffron_guards.asm @@ -0,0 +1,18 @@ +RemoveGuardDrink: ; 5a59f (16:659f) + ld hl, GuardDrinksList +.drinkLoop + ld a, [hli] + ld [$ffdb], a + and a + ret z + push hl + ld b, a + call IsItemInBag + pop hl + jr z, .drinkLoop + ld b, BANK(RemoveItemByID) + ld hl, RemoveItemByID + jp Bankswitch + +GuardDrinksList: ; 5a5b7 (16:65b7) + db FRESH_WATER, SODA_POP, LEMONADE, $00 diff --git a/engine/overworld/ssanne.asm b/engine/overworld/ssanne.asm new file mode 100755 index 00000000..e8060810 --- /dev/null +++ b/engine/overworld/ssanne.asm @@ -0,0 +1,88 @@ +Func_79f54: ; 79f54 (1e:5f54) + ld a, $1 + ld [$cd50], a + ld a, [$cfcb] + push af + ld a, $ff + ld [$cfcb], a + ld a, $e4 + ld [rOBP1], a ; $ff49 + call LoadSmokeTileFourTimes + callba asm_f055 + ld c, $8 +.asm_79f73 + push bc + call Func_79f92 + ld bc, .asm_79f7e + push bc + ld c, $4 + jp [hl] +.asm_79f7e + ld a, [rOBP1] ; $ff49 + xor $64 + ld [rOBP1], a ; $ff49 + call Delay3 + pop bc + dec c + jr nz, .asm_79f73 + pop af + ld [$cfcb], a + jp LoadPlayerSpriteGraphics + +Func_79f92: ; 79f92 (1e:5f92) + ld a, [$c109] + ld hl, PointerTable_79fb0 ; $5fb0 + ld c, a + ld b, $0 + add hl, bc + ld a, [hli] + ld [$d08a], a + ld a, [hli] + ld e, a + ld a, [hli] + ld h, [hl] + ld l, a + push hl + ld hl, $c390 + ld d, $0 + add hl, de + ld e, l + ld d, h + pop hl + ret + +PointerTable_79fb0: ; 79fb0 (1e:5fb0) + db $FF,$00 + dw Func_79350 + + db $01,$00 + dw Func_79350 + + db $01,$01 + dw Func_79337 + + db $FF,$01 + dw Func_79337 + +LoadSmokeTileFourTimes: ; 79fc0 (1e:5fc0) + ld hl, $8fc0 + ld c, $4 +.loop + push bc + push hl + call LoadSmokeTile + pop hl + ld bc, $10 + add hl, bc + pop bc + dec c + jr nz, .loop + ret + +LoadSmokeTile: ; 79fd4 (1e:5fd4) + ld de, SSAnneSmokePuffTile ; $5fdd + ld bc, (BANK(SSAnneSmokePuffTile) << 8) + $01 + jp CopyVideoData + +SSAnneSmokePuffTile: ; 79fdd (1e:5fdd) + INCBIN "gfx/ss_anne_smoke_puff.2bpp" diff --git a/engine/overworld/trainers.asm b/engine/overworld/trainers.asm new file mode 100755 index 00000000..8968332a --- /dev/null +++ b/engine/overworld/trainers.asm @@ -0,0 +1,347 @@ +Func_567f9: ; 567f9 (15:67f9) + ld hl, wSpriteStateData1 + ld de, $4 + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + call Func_56903 + ld a, [hli] + ld [$ffeb], a + inc hl + ld a, [hl] + ld [$ffec], a + ld de, $fe + add hl, de + ld a, [hli] + ld [$ffed], a + ld a, [hl] + ld [$ffee], a + ret + +Func_56819: ; 56819 (15:6819) + ld hl, wSpriteStateData1 + ld de, $0004 + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + call Func_56903 + ld a, [hli] + ld [$d130], a + inc hl + ld a, [hl] + ld [$d131], a + ld de, $00fe + add hl, de + ld a, [hli] + ld [$d132], a + ld a, [hl] + ld [$d133], a + ret + +Func_5683d: ; 5683d (15:683d) + ld hl, wSpriteStateData1 + ld de, $4 + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + call Func_56903 + ld a, [$ffeb] + ld [hli], a + inc hl + ld a, [$ffec] + ld [hl], a + ld de, $fe + add hl, de + ld a, [$ffed] + ld [hli], a + ld a, [$ffee] + ld [hl], a + ret + +Func_5685d: ; 5685d (15:685d) + ld hl, wSpriteStateData1 + ld de, $0004 + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + call Func_56903 + ld a, [$d130] + ld [hli], a + inc hl + ld a, [$d131] + ld [hl], a + ld de, $00fe + add hl, de + ld a, [$d132] + ld [hli], a + ld a, [$d133] + ld [hl], a + ret + +TrainerWalkUpToPlayer: ; 56881 (15:6881) + ld a, [$cf13] + swap a + ld [wTrainerSpriteOffset], a ; $cd3d + call ReadTrainerScreenPosition + ld a, [wTrainerFacingDirection] + and a + jr z, .facingDown + cp $4 + jr z, .facingUp + cp $8 + jr z, .facingLeft + jr .facingRight +.facingDown + ld a, [wTrainerScreenY] + ld b, a + ld a, $3c ; (fixed) player screen Y pos + call CalcDifference + cp $10 ; trainer is right above player + ret z + swap a + dec a + ld c, a ; bc = steps yet to go to reach player + xor a + ld b, a ; a = direction to go to + jr .writeWalkScript +.facingUp + ld a, [wTrainerScreenY] + ld b, a + ld a, $3c ; (fixed) player screen Y pos + call CalcDifference + cp $10 ; trainer is right below player + ret z + swap a + dec a + ld c, a ; bc = steps yet to go to reach player + ld b, $0 + ld a, $40 ; a = direction to go to + jr .writeWalkScript +.facingRight + ld a, [wTrainerScreenX] + ld b, a + ld a, $40 ; (fixed) player screen X pos + call CalcDifference + cp $10 ; trainer is directly left of player + ret z + swap a + dec a + ld c, a ; bc = steps yet to go to reach player + ld b, $0 + ld a, $c0 ; a = direction to go to + jr .writeWalkScript +.facingLeft + ld a, [$cd41] + ld b, a + ld a, $40 ; (fixed) player screen X pos + call CalcDifference + cp $10 ; trainer is directly right of player + ret z + swap a + dec a + ld c, a ; bc = steps yet to go to reach player + ld b, $0 + ld a, $80 ; a = direction to go to +.writeWalkScript + ld hl, $cc97 + ld de, $cc97 + call FillMemory ; write the necessary steps to reach player + ld [hl], $ff ; write end of list sentinel + ld a, [$cf13] + ld [H_DOWNARROWBLINKCNT2], a ; $ff8c + jp MoveSprite_ + +Func_56903: ; 56903 (15:6903) + push de + add hl, de + ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c + swap a + ld d, $0 + ld e, a + add hl, de + pop de + ret + +; tests if this trainer is in the right position to engage the player and do so if she is. +CheckEngagePlayer: ; 5690f (15:690f) + push hl + push de + ld a, [wTrainerSpriteOffset] ; $cd3d + add $2 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] ; c1x2: sprite image index + sub $ff + jr nz, .spriteOnScreen ; test if sprite is on screen + jp .noEngage +.spriteOnScreen + ld a, [wTrainerSpriteOffset] ; $cd3d + add $9 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] ; c1x9: facing direction + ld [$cd3f], a + call ReadTrainerScreenPosition + ld a, [$cd40] ; sprite screen Y pos + ld b, a + ld a, $3c + cp b + jr z, .linedUpY + ld a, [$cd41] ; sprite screen X pos + ld b, a + ld a, $40 + cp b + jr z, .linedUpX + xor a + jp .noEngage +.linedUpY + ld a, [$cd41] ; sprite screen X pos + ld b, a + ld a, $40 ; (fixed) player X position + call CalcDifference ; calc distance + jr z, .noEngage ; exact same position as player + call CheckSpriteCanSeePlayer + jr c, .engage + xor a + jr .noEngage +.linedUpX + ld a, [$cd40] ; sprite screen Y pos + ld b, a + ld a, $3c ; (fixed) player Y position + call CalcDifference ; calc distance + jr z, .noEngage ; exact same position as player + call CheckSpriteCanSeePlayer + jr c, .engage + xor a + jp .noEngage +.engage + call CheckPlayerIsInFrontOfSprite + ld a, [wTrainerSpriteOffset] ; $cd3d + and a + jr z, .noEngage + ld hl, wFlags_0xcd60 + set 0, [hl] + call EngageMapTrainer + ld a, $ff +.noEngage: ; 56988 (15:6988) + ld [wTrainerSpriteOffset], a ; $cd3d + pop de + pop hl + ret + +; reads trainer's Y position to $cd40 and X position to $cd41 +ReadTrainerScreenPosition: ; 5698e (15:698e) + ld a, [wTrainerSpriteOffset] ; $cd3d + add $4 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] + ld [$cd40], a + ld a, [wTrainerSpriteOffset] ; $cd3d + add $6 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] + ld [$cd41], a + ret + +; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite +; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back +; a: distance player to sprite +CheckSpriteCanSeePlayer: ; 569af (15:69af) + ld b, a + ld a, [wTrainerEngageDistance] ; sprite line of sight (engage distance) + cp b + jr nc, .checkIfLinedUp + jr .notInLine ; player too far away +.checkIfLinedUp + ld a, [$cd3f] ; sprite facing direction + cp $0 ; down + jr z, .checkXCoord + cp $4 ; up + jr z, .checkXCoord + cp $8 ; left + jr z, .checkYCoord + cp $c ; right + jr z, .checkYCoord + jr .notInLine +.checkXCoord + ld a, [$cd41] ; sprite screen X position + ld b, a + cp $40 + jr z, .inLine + jr .notInLine +.checkYCoord + ld a, [$cd40] ; sprite screen Y position + ld b, a + cp $3c + jr nz, .notInLine +.inLine + scf + ret +.notInLine + and a + ret + +; tests if the player is in front of the sprite (rather than behind it) +CheckPlayerIsInFrontOfSprite: ; 569e3 (15:69e3) + ld a, [W_CURMAP] ; $d35e + cp POWER_PLANT + jp z, .engage ; XXX not sure why bypass this for power plant (maybe to get voltorb fake items to work?) + ld a, [wTrainerSpriteOffset] ; $cd3d + add $4 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] ; c1x4 (sprite screen Y pos) + cp $fc + jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block + ld a, $c +.notOnTopmostTile + ld [$cd40], a + ld a, [wTrainerSpriteOffset] ; $cd3d + add $6 + ld d, $0 + ld e, a + ld hl, wSpriteStateData1 + add hl, de + ld a, [hl] ; c1x6 (sprite screen X pos) + ld [$cd41], a + ld a, [$cd3f] ; facing direction + cp $0 + jr nz, .notFacingDown + ld a, [$cd40] ; sprite screen Y pos + cp $3c + jr c, .engage ; sprite above player + jr .noEngage ; sprite below player +.notFacingDown + cp $4 + jr nz, .notFacingUp + ld a, [$cd40] ; sprite screen Y pos + cp $3c + jr nc, .engage ; sprite below player + jr .noEngage ; sprite above player +.notFacingUp + cp $8 + jr nz, .notFacingLeft + ld a, [$cd41] ; sprite screen X pos + cp $40 + jr nc, .engage ; sprite right of player + jr .noEngage ; sprite left of player +.notFacingLeft + ld a, [$cd41] ; sprite screen X pos + cp $40 + jr nc, .noEngage ; sprite right of player +.engage + ld a, $ff + jr .done +.noEngage + xor a +.done + ld [wTrainerSpriteOffset], a ; $cd3d + ret |