Split up banks 1-3 of main.asm

This commit is contained in:
pikalaxalt 2016-03-27 12:47:28 -04:00
parent 2650bcffad
commit 93e12d2003
20 changed files with 4786 additions and 4784 deletions

View File

@ -980,7 +980,7 @@ BattleAnimCmd_RaiseSub: ; cc640 (33:4640)
GetSubstitutePic: ; cc64c
ld hl, sScratch
ld bc, $310
ld bc, (7 * 7) tiles
.loop
xor a
ld [hli], a
@ -994,16 +994,16 @@ GetSubstitutePic: ; cc64c
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 @@ GetSubstitutePic: ; cc64c
.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

View File

@ -7873,7 +7873,7 @@ BattleCommand_Substitute: ; 36e7c
ld [hl], a
ld [de], a
call _CheckBattleScene
jr c, .mobile
jr c, .no_anim
xor a
ld [wNumHits], a
@ -7883,7 +7883,7 @@ BattleCommand_Substitute: ; 36e7c
call LoadAnim
jr .finish
.mobile
.no_anim
call BattleCommand_RaiseSubNoAnim
.finish
ld hl, MadeSubstituteText

View File

@ -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

388
engine/billspctop.asm Executable file
View File

@ -0,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

110
engine/health.asm Executable file
View File

@ -0,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

584
engine/items.asm Executable file
View File

@ -0,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

View File

@ -451,22 +451,20 @@ Script_ReceivePhoneCall: ; 0x90241
; 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
@ -494,7 +492,6 @@ Phone_CallerTextboxWithName: ; 90292 (24:4292)
call Function90363
ret
PhoneCall:: ; 9029a
ld a, b
ld [PhoneScriptBank], a

856
engine/player_object.asm Executable file
View File

@ -0,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

300
engine/printnum.asm Executable file
View File

@ -0,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

50
engine/sine.asm Executable file
View File

@ -0,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

238
event/happiness_egg.asm Executable file
View File

@ -0,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

1890
event/overworld.asm Executable file

File diff suppressed because it is too large Load Diff

231
event/special.asm Executable file
View File

@ -0,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

View File

@ -1812,7 +1812,7 @@ GetBlockLocation:: ; 2a66
add 6
ld c, a
ld b, 0
ld hl, wc801
ld hl, OverworldMap + 1
add hl, bc
ld a, e
srl a

View File

@ -338,11 +338,13 @@ endr
; 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 @@ GetMthMoveOfCurrentMon: ; f969
add hl, bc
ret
; f971
INCLUDE "items/pokeball_wobble.asm"

88
items/pokeball_wobble.asm Executable file
View File

@ -0,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

4756
main.asm

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,7 @@ ReceptionistScript_0x9e3e2:
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 @@ Script_ChoseChallenge: ; 0x9e40f
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

View File

@ -1085,9 +1085,9 @@ Function17075f: ; 17075f (5c:475f) BattleTowerAction $00
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 @@ Function170778: ; 170778 (5c:4778) BattleTowerAction $02
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,20 +1591,20 @@ Function170abe: ; 170abe (5c:4abe) BattleTowerAction $14
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
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

View File

@ -81,7 +81,7 @@ sLuckyIDNumber:: ds 2
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 @@ sBackupGameDataEnd::
; 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 @@ sGameDataEnd::
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 @@ sLinkBattleRecord4:: link_battle_record sLinkBattleRecord4
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 @@ sHallOfFame:: ; b2c0
; endr
sHallOfFameEnd::
SECTION "SRAM Crystal Data", SRAM, BANK [1]
sMobileEventIndex:: ds 1 ; be3c
sCrystalData::
@ -208,7 +212,7 @@ sBTChoiceOfLevelGroup:: ds 1
; 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