mirror of
https://github.com/pret/pokered.git
synced 2024-10-23 15:08:23 +00:00
1565 lines
28 KiB
NASM
Executable file
1565 lines
28 KiB
NASM
Executable file
; does nothing since no stats are ever selected (barring glitches)
|
||
DoubleSelectedStats: ; 39680 (e:5680)
|
||
ld a, [H_WHOSETURN]
|
||
and a
|
||
ld a, [wPlayerStatsToDouble]
|
||
ld hl, wBattleMonAttack + 1
|
||
jr z, .notEnemyTurn
|
||
ld a, [wEnemyStatsToDouble]
|
||
ld hl, wEnemyMonAttack + 1
|
||
.notEnemyTurn
|
||
ld c, 4
|
||
ld b, a
|
||
.loop
|
||
srl b
|
||
call c, .doubleStat
|
||
inc hl
|
||
inc hl
|
||
dec c
|
||
ret z
|
||
jr .loop
|
||
|
||
.doubleStat
|
||
ld a, [hl]
|
||
add a
|
||
ld [hld], a
|
||
ld a, [hl]
|
||
rl a
|
||
ld [hli], a
|
||
ret
|
||
|
||
; does nothing since no stats are ever selected (barring glitches)
|
||
HalveSelectedStats: ; 396a7 (e:56a7)
|
||
ld a, [H_WHOSETURN]
|
||
and a
|
||
ld a, [wPlayerStatsToHalve]
|
||
ld hl, wBattleMonAttack
|
||
jr z, .notEnemyTurn
|
||
ld a, [wEnemyStatsToHalve]
|
||
ld hl, wEnemyMonAttack
|
||
.notEnemyTurn
|
||
ld c, 4
|
||
ld b, a
|
||
.loop
|
||
srl b
|
||
call c, .halveStat
|
||
inc hl
|
||
inc hl
|
||
dec c
|
||
ret z
|
||
jr .loop
|
||
|
||
.halveStat
|
||
ld a, [hl]
|
||
srl a
|
||
ld [hli], a
|
||
rr [hl]
|
||
or [hl]
|
||
jr nz, .nonzeroStat
|
||
ld [hl], 1
|
||
.nonzeroStat
|
||
dec hl
|
||
ret
|
||
|
||
_ScrollTrainerPicAfterBattle: ; 396d3 (e:56d3)
|
||
; Load the enemy trainer's pic and scrolls it into
|
||
; the screen from the right.
|
||
xor a
|
||
ld [wEnemyMonSpecies2], a
|
||
ld b, $1
|
||
call GoPAL_SET
|
||
callab _LoadTrainerPic
|
||
hlCoord 19, 0
|
||
ld c, $0
|
||
.scrollLoop
|
||
inc c
|
||
ld a, c
|
||
cp 7
|
||
ret z
|
||
ld d, $0
|
||
push bc
|
||
push hl
|
||
.drawTrainerPicLoop
|
||
call DrawTrainerPicColumn
|
||
inc hl
|
||
ld a, 7
|
||
add d
|
||
ld d, a
|
||
dec c
|
||
jr nz, .drawTrainerPicLoop
|
||
ld c, 4
|
||
call DelayFrames
|
||
pop hl
|
||
pop bc
|
||
dec hl
|
||
jr .scrollLoop
|
||
|
||
; write one 7-tile column of the trainer pic to the tilemap
|
||
DrawTrainerPicColumn: ; 39707 (e:5707)
|
||
push hl
|
||
push de
|
||
push bc
|
||
ld e, 7
|
||
.loop
|
||
ld [hl], d
|
||
ld bc, SCREEN_WIDTH
|
||
add hl, bc
|
||
inc d
|
||
dec e
|
||
jr nz, .loop
|
||
pop bc
|
||
pop de
|
||
pop hl
|
||
ret
|
||
|
||
; creates a set of moves that may be used and returns its address in hl
|
||
; unused slots are filled with 0, all used slots may be chosen with equal probability
|
||
AIEnemyTrainerChooseMoves: ; 39719 (e:5719)
|
||
ld a, $a
|
||
ld hl, wHPBarMaxHP ; init temporary move selection array. Only the moves with the lowest numbers are chosen in the end
|
||
ld [hli], a ; move 1
|
||
ld [hli], a ; move 2
|
||
ld [hli], a ; move 3
|
||
ld [hl], a ; move 4
|
||
ld a, [W_ENEMYDISABLEDMOVE] ; forbid disabled move (if any)
|
||
swap a
|
||
and $f
|
||
jr z, .noMoveDisabled
|
||
ld hl, wHPBarMaxHP
|
||
dec a
|
||
ld c, a
|
||
ld b, $0
|
||
add hl, bc ; advance pointer to forbidden move
|
||
ld [hl], $50 ; forbid (highly discourage) disabled move
|
||
.noMoveDisabled
|
||
ld hl, TrainerClassMoveChoiceModifications ; 589B
|
||
ld a, [W_TRAINERCLASS]
|
||
ld b, a
|
||
.loopTrainerClasses
|
||
dec b
|
||
jr z, .readTrainerClassData
|
||
.loopTrainerClassData
|
||
ld a, [hli]
|
||
and a
|
||
jr nz, .loopTrainerClassData
|
||
jr .loopTrainerClasses
|
||
.readTrainerClassData
|
||
ld a, [hl]
|
||
and a
|
||
jp z, .useOriginalMoveSet
|
||
push hl
|
||
.nextMoveChoiceModification
|
||
pop hl
|
||
ld a, [hli]
|
||
and a
|
||
jr z, .loopFindMinimumEntries
|
||
push hl
|
||
ld hl, AIMoveChoiceModificationFunctionPointers ; $57a3
|
||
dec a
|
||
add a
|
||
ld c, a
|
||
ld b, $0
|
||
add hl, bc ; skip to pointer
|
||
ld a, [hli] ; read pointer into hl
|
||
ld h, [hl]
|
||
ld l, a
|
||
ld de, .nextMoveChoiceModification ; set return address
|
||
push de
|
||
jp [hl] ; execute modification function
|
||
.loopFindMinimumEntries ; all entries will be decremented sequentially until one of them is zero
|
||
ld hl, wHPBarMaxHP ; temp move selection array
|
||
ld de, wEnemyMonMoves ; enemy moves
|
||
ld c, $4
|
||
.loopDecrementEntries
|
||
ld a, [de]
|
||
inc de
|
||
and a
|
||
jr z, .loopFindMinimumEntries
|
||
dec [hl]
|
||
jr z, .minimumEntriesFound
|
||
inc hl
|
||
dec c
|
||
jr z, .loopFindMinimumEntries
|
||
jr .loopDecrementEntries
|
||
.minimumEntriesFound
|
||
ld a, c
|
||
.loopUndoPartialIteration ; undo last (partial) loop iteration
|
||
inc [hl]
|
||
dec hl
|
||
inc a
|
||
cp $5
|
||
jr nz, .loopUndoPartialIteration
|
||
ld hl, wHPBarMaxHP ; temp move selection array
|
||
ld de, wEnemyMonMoves ; enemy moves
|
||
ld c, $4
|
||
.filterMinimalEntries ; all minimal entries now have value 1. All other slots will be disabled (move set to 0)
|
||
ld a, [de]
|
||
and a
|
||
jr nz, .moveExisting ; 0x3978a $1
|
||
ld [hl], a
|
||
.moveExisting
|
||
ld a, [hl]
|
||
dec a
|
||
jr z, .slotWithMinimalValue
|
||
xor a
|
||
ld [hli], a ; disable move slot
|
||
jr .next
|
||
.slotWithMinimalValue
|
||
ld a, [de]
|
||
ld [hli], a ; enable move slot
|
||
.next
|
||
inc de
|
||
dec c
|
||
jr nz, .filterMinimalEntries
|
||
ld hl, wHPBarMaxHP ; use created temporary array as move set
|
||
ret
|
||
.useOriginalMoveSet
|
||
ld hl, wEnemyMonMoves ; use original move set
|
||
ret
|
||
|
||
AIMoveChoiceModificationFunctionPointers: ; 397a3 (e:57a3)
|
||
dw AIMoveChoiceModification1
|
||
dw AIMoveChoiceModification2
|
||
dw AIMoveChoiceModification3
|
||
dw AIMoveChoiceModification4 ; unused, does nothing
|
||
|
||
; discourages moves that cause no damage but only a status ailment if player's mon already has one
|
||
AIMoveChoiceModification1: ; 397ab (e:57ab)
|
||
ld a, [wBattleMonStatus]
|
||
and a
|
||
ret z ; return if no status ailment on player's mon
|
||
ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest)
|
||
ld de, wEnemyMonMoves ; enemy moves
|
||
ld b, $5
|
||
.nextMove
|
||
dec b
|
||
ret z ; processed all 4 moves
|
||
inc hl
|
||
ld a, [de]
|
||
and a
|
||
ret z ; no more moves in move set
|
||
inc de
|
||
call ReadMove
|
||
ld a, [W_ENEMYMOVEPOWER]
|
||
and a
|
||
jr nz, .nextMove
|
||
ld a, [W_ENEMYMOVEEFFECT]
|
||
push hl
|
||
push de
|
||
push bc
|
||
ld hl, StatusAilmentMoveEffects
|
||
ld de, $0001
|
||
call IsInArray
|
||
pop bc
|
||
pop de
|
||
pop hl
|
||
jr nc, .nextMove
|
||
ld a, [hl]
|
||
add $5 ; discourage move
|
||
ld [hl], a
|
||
jr .nextMove
|
||
|
||
StatusAilmentMoveEffects ; 57e2
|
||
db $01 ; some sleep effect?
|
||
db SLEEP_EFFECT
|
||
db POISON_EFFECT
|
||
db PARALYZE_EFFECT
|
||
db $FF
|
||
|
||
; slightly encourage moves with specific effects
|
||
AIMoveChoiceModification2: ; 397e7 (e:57e7)
|
||
ld a, [wccd5]
|
||
cp $1
|
||
ret nz
|
||
ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest)
|
||
ld de, wEnemyMonMoves ; enemy moves
|
||
ld b, $5
|
||
.nextMove
|
||
dec b
|
||
ret z ; processed all 4 moves
|
||
inc hl
|
||
ld a, [de]
|
||
and a
|
||
ret z ; no more moves in move set
|
||
inc de
|
||
call ReadMove
|
||
ld a, [W_ENEMYMOVEEFFECT]
|
||
cp ATTACK_UP1_EFFECT
|
||
jr c, .nextMove
|
||
cp BIDE_EFFECT
|
||
jr c, .preferMove
|
||
cp ATTACK_UP2_EFFECT
|
||
jr c, .nextMove
|
||
cp POISON_EFFECT
|
||
jr c, .preferMove
|
||
jr .nextMove
|
||
.preferMove
|
||
dec [hl] ; slighly encourage this move
|
||
jr .nextMove
|
||
|
||
; encourages moves that are effective against the player's mon
|
||
AIMoveChoiceModification3: ; 39817 (e:5817)
|
||
ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest)
|
||
ld de, wEnemyMonMoves ; enemy moves
|
||
ld b, $5
|
||
.nextMove
|
||
dec b
|
||
ret z ; processed all 4 moves
|
||
inc hl
|
||
ld a, [de]
|
||
and a
|
||
ret z ; no more moves in move set
|
||
inc de
|
||
call ReadMove
|
||
push hl
|
||
push bc
|
||
push de
|
||
callab AIGetTypeEffectiveness
|
||
pop de
|
||
pop bc
|
||
pop hl
|
||
ld a, [wd11e]
|
||
cp $10
|
||
jr z, .nextMove
|
||
jr c, .notEffectiveMove
|
||
dec [hl] ; slighly encourage this move
|
||
jr .nextMove
|
||
.notEffectiveMove ; discourages non-effective moves if better moves are available
|
||
push hl
|
||
push de
|
||
push bc
|
||
ld a, [W_ENEMYMOVETYPE]
|
||
ld d, a
|
||
ld hl, wEnemyMonMoves ; enemy moves
|
||
ld b, $5
|
||
ld c, $0
|
||
.loopMoves
|
||
dec b
|
||
jr z, .done
|
||
ld a, [hli]
|
||
and a
|
||
jr z, .done
|
||
call ReadMove
|
||
ld a, [W_ENEMYMOVEEFFECT]
|
||
cp SUPER_FANG_EFFECT
|
||
jr z, .betterMoveFound ; Super Fang is considered to be a better move
|
||
cp SPECIAL_DAMAGE_EFFECT
|
||
jr z, .betterMoveFound ; any special damage moves are considered to be better moves
|
||
cp FLY_EFFECT
|
||
jr z, .betterMoveFound ; Fly is considered to be a better move
|
||
ld a, [W_ENEMYMOVETYPE]
|
||
cp d
|
||
jr z, .loopMoves
|
||
ld a, [W_ENEMYMOVEPOWER]
|
||
and a
|
||
jr nz, .betterMoveFound ; damaging moves of a different type are considered to be better moves
|
||
jr .loopMoves
|
||
.betterMoveFound
|
||
ld c, a
|
||
.done
|
||
ld a, c
|
||
pop bc
|
||
pop de
|
||
pop hl
|
||
and a
|
||
jr z, .nextMove
|
||
inc [hl] ; slighly discourage this move
|
||
jr .nextMove
|
||
AIMoveChoiceModification4: ; 39883 (e:5883)
|
||
ret
|
||
|
||
ReadMove: ; 39884 (e:5884)
|
||
push hl
|
||
push de
|
||
push bc
|
||
dec a
|
||
ld hl,Moves
|
||
ld bc,6
|
||
call AddNTimes
|
||
ld de,W_ENEMYMOVENUM
|
||
call CopyData
|
||
pop bc
|
||
pop de
|
||
pop hl
|
||
ret
|
||
|
||
; move choice modification methods that are applied for each trainer class
|
||
; 0 is sentinel value
|
||
TrainerClassMoveChoiceModifications: ; 3989b (e:589b)
|
||
db 0 ; YOUNGSTER
|
||
db 1,0 ; BUG CATCHER
|
||
db 1,0 ; LASS
|
||
db 1,3,0 ; SAILOR
|
||
db 1,0 ; JR__TRAINER_M
|
||
db 1,0 ; JR__TRAINER_F
|
||
db 1,2,3,0; POKEMANIAC
|
||
db 1,2,0 ; SUPER_NERD
|
||
db 1,0 ; HIKER
|
||
db 1,0 ; BIKER
|
||
db 1,3,0 ; BURGLAR
|
||
db 1,0 ; ENGINEER
|
||
db 1,2,0 ; JUGGLER_X
|
||
db 1,3,0 ; FISHER
|
||
db 1,3,0 ; SWIMMER
|
||
db 0 ; CUE_BALL
|
||
db 1,0 ; GAMBLER
|
||
db 1,3,0 ; BEAUTY
|
||
db 1,2,0 ; PSYCHIC_TR
|
||
db 1,3,0 ; ROCKER
|
||
db 1,0 ; JUGGLER
|
||
db 1,0 ; TAMER
|
||
db 1,0 ; BIRD_KEEPER
|
||
db 1,0 ; BLACKBELT
|
||
db 1,0 ; SONY1
|
||
db 1,3,0 ; PROF_OAK
|
||
db 1,2,0 ; CHIEF
|
||
db 1,2,0 ; SCIENTIST
|
||
db 1,3,0 ; GIOVANNI
|
||
db 1,0 ; ROCKET
|
||
db 1,3,0 ; COOLTRAINER_M
|
||
db 1,3,0 ; COOLTRAINER_F
|
||
db 1,0 ; BRUNO
|
||
db 1,0 ; BROCK
|
||
db 1,3,0 ; MISTY
|
||
db 1,3,0 ; LT__SURGE
|
||
db 1,3,0 ; ERIKA
|
||
db 1,3,0 ; KOGA
|
||
db 1,3,0 ; BLAINE
|
||
db 1,3,0 ; SABRINA
|
||
db 1,2,0 ; GENTLEMAN
|
||
db 1,3,0 ; SONY2
|
||
db 1,3,0 ; SONY3
|
||
db 1,2,3,0; LORELEI
|
||
db 1,0 ; CHANNELER
|
||
db 1,0 ; AGATHA
|
||
db 1,3,0 ; LANCE
|
||
|
||
TrainerPicAndMoneyPointers: ; 39914 (e:5914)
|
||
; trainer pic pointers and base money.
|
||
; money received after battle = base money × level of highest-level enemy mon
|
||
dw YoungsterPic
|
||
money 1500
|
||
|
||
dw BugCatcherPic
|
||
money 1000
|
||
|
||
dw LassPic
|
||
money 1500
|
||
|
||
dw SailorPic
|
||
money 3000
|
||
|
||
dw JrTrainerMPic
|
||
money 2000
|
||
|
||
dw JrTrainerFPic
|
||
money 2000
|
||
|
||
dw PokemaniacPic
|
||
money 5000
|
||
|
||
dw SuperNerdPic
|
||
money 2500
|
||
|
||
dw HikerPic
|
||
money 3500
|
||
|
||
dw BikerPic
|
||
money 2000
|
||
|
||
dw BurglarPic
|
||
money 9000
|
||
|
||
dw EngineerPic
|
||
money 5000
|
||
|
||
dw JugglerPic
|
||
money 3500
|
||
|
||
dw FisherPic
|
||
money 3500
|
||
|
||
dw SwimmerPic
|
||
money 500
|
||
|
||
dw CueBallPic
|
||
money 2500
|
||
|
||
dw GamblerPic
|
||
money 7000
|
||
|
||
dw BeautyPic
|
||
money 7000
|
||
|
||
dw PsychicPic
|
||
money 1000
|
||
|
||
dw RockerPic
|
||
money 2500
|
||
|
||
dw JugglerPic
|
||
money 3500
|
||
|
||
dw TamerPic
|
||
money 4000
|
||
|
||
dw BirdKeeperPic
|
||
money 2500
|
||
|
||
dw BlackbeltPic
|
||
money 2500
|
||
|
||
dw Rival1Pic
|
||
money 3500
|
||
|
||
dw ProfOakPic
|
||
money 9900
|
||
|
||
dw ChiefPic
|
||
money 3000
|
||
|
||
dw ScientistPic
|
||
money 5000
|
||
|
||
dw GiovanniPic
|
||
money 9900
|
||
|
||
dw RocketPic
|
||
money 3000
|
||
|
||
dw CooltrainerMPic
|
||
money 3500
|
||
|
||
dw CooltrainerFPic
|
||
money 3500
|
||
|
||
dw BrunoPic
|
||
money 9900
|
||
|
||
dw BrockPic
|
||
money 9900
|
||
|
||
dw MistyPic
|
||
money 9900
|
||
|
||
dw LtSurgePic
|
||
money 9900
|
||
|
||
dw ErikaPic
|
||
money 9900
|
||
|
||
dw KogaPic
|
||
money 9900
|
||
|
||
dw BlainePic
|
||
money 9900
|
||
|
||
dw SabrinaPic
|
||
money 9900
|
||
|
||
dw GentlemanPic
|
||
money 7000
|
||
|
||
dw Rival2Pic
|
||
money 6500
|
||
|
||
dw Rival3Pic
|
||
money 9900
|
||
|
||
dw LoreleiPic
|
||
money 9900
|
||
|
||
dw ChannelerPic
|
||
money 3000
|
||
|
||
dw AgathaPic
|
||
money 9900
|
||
|
||
dw LancePic
|
||
money 9900
|
||
|
||
INCLUDE "text/trainer_names.asm"
|
||
|
||
; formats a string at wMovesString that lists the moves at wMoves
|
||
FormatMovesString: ; 39b87 (e:5b87)
|
||
ld hl, wMoves
|
||
ld de, wMovesString
|
||
ld b, $0
|
||
.printMoveNameLoop
|
||
ld a, [hli]
|
||
and a ; end of move list?
|
||
jr z, .printDashLoop ; print dashes when no moves are left
|
||
push hl
|
||
ld [wd0b5], a
|
||
ld a, BANK(MoveNames)
|
||
ld [wPredefBank], a
|
||
ld a, MOVE_NAME
|
||
ld [wNameListType], a
|
||
call GetName
|
||
ld hl, wcd6d
|
||
.copyNameLoop
|
||
ld a, [hli]
|
||
cp $50
|
||
jr z, .doneCopyingName
|
||
ld [de], a
|
||
inc de
|
||
jr .copyNameLoop
|
||
.doneCopyingName
|
||
ld a, b
|
||
ld [wcd6c], a
|
||
inc b
|
||
ld a, $4e ; line break
|
||
ld [de], a
|
||
inc de
|
||
pop hl
|
||
ld a, b
|
||
cp NUM_MOVES
|
||
jr z, .done
|
||
jr .printMoveNameLoop
|
||
.printDashLoop
|
||
ld a, "-"
|
||
ld [de], a
|
||
inc de
|
||
inc b
|
||
ld a, b
|
||
cp NUM_MOVES
|
||
jr z, .done
|
||
ld a, $4e ; line break
|
||
ld [de], a
|
||
inc de
|
||
jr .printDashLoop
|
||
.done
|
||
ld a, "@"
|
||
ld [de], a
|
||
ret
|
||
|
||
; XXX this is called in a few places, but it doesn't appear to do anything useful
|
||
Func_39bd5: ; 39bd5 (e:5bd5)
|
||
ld a, [wd11b]
|
||
cp $1
|
||
jr nz, .asm_39be6
|
||
ld hl, wEnemyPartyCount
|
||
ld de, wEnemyMonOT
|
||
ld a, ENEMYOT_NAME
|
||
jr .asm_39c18
|
||
.asm_39be6
|
||
cp $4
|
||
jr nz, .calcAttackStat4
|
||
ld hl, wPartyCount
|
||
ld de, wPartyMonOT
|
||
ld a, PLAYEROT_NAME
|
||
jr .asm_39c18
|
||
.calcAttackStat4
|
||
cp $5
|
||
jr nz, .asm_39c02
|
||
ld hl, wStringBuffer2 + 11
|
||
ld de, MonsterNames
|
||
ld a, MONSTER_NAME
|
||
jr .asm_39c18
|
||
.asm_39c02
|
||
cp $2
|
||
jr nz, .asm_39c10
|
||
ld hl, wNumBagItems
|
||
ld de, ItemNames
|
||
ld a, ITEM_NAME
|
||
jr .asm_39c18
|
||
.asm_39c10
|
||
ld hl, wStringBuffer2 + 11
|
||
ld de, ItemNames
|
||
ld a, ITEM_NAME
|
||
.asm_39c18
|
||
ld [wNameListType], a
|
||
ld a, l
|
||
ld [wList], a
|
||
ld a, h
|
||
ld [wList + 1], a
|
||
ld a, e
|
||
ld [wcf8d], a
|
||
ld a, d
|
||
ld [wcf8e], a
|
||
ld bc, ItemPrices
|
||
ld a, c
|
||
ld [wItemPrices], a
|
||
ld a, b
|
||
ld [wItemPrices + 1], a
|
||
ret
|
||
|
||
; get species of mon e in list [wcc49] for LoadMonData
|
||
GetMonSpecies: ; 39c37 (e:5c37)
|
||
ld hl, wPartySpecies
|
||
ld a, [wcc49]
|
||
and a
|
||
jr z, .getSpecies
|
||
dec a
|
||
jr z, .enemyParty
|
||
ld hl, wBoxSpecies
|
||
jr .getSpecies
|
||
.enemyParty
|
||
ld hl, wEnemyPartyMons
|
||
.getSpecies
|
||
ld d, 0
|
||
add hl, de
|
||
ld a, [hl]
|
||
ld [wcf91], a
|
||
ret
|
||
|
||
ReadTrainer: ; 39c53 (e:5c53)
|
||
|
||
; don't change any moves in a link battle
|
||
ld a,[wLinkState]
|
||
and a
|
||
ret nz
|
||
|
||
; set [wEnemyPartyCount] to 0, [wEnemyPartyMons] to FF
|
||
; XXX first is total enemy pokemon?
|
||
; XXX second is species of first pokemon?
|
||
ld hl,wEnemyPartyCount
|
||
xor a
|
||
ld [hli],a
|
||
dec a
|
||
ld [hl],a
|
||
|
||
; get the pointer to trainer data for this class
|
||
ld a,[W_CUROPPONENT]
|
||
sub $C9 ; convert value from pokemon to trainer
|
||
add a,a
|
||
ld hl,TrainerDataPointers
|
||
ld c,a
|
||
ld b,0
|
||
add hl,bc ; hl points to trainer class
|
||
ld a,[hli]
|
||
ld h,[hl]
|
||
ld l,a
|
||
ld a,[W_TRAINERNO]
|
||
ld b,a
|
||
; At this point b contains the trainer number,
|
||
; and hl points to the trainer class.
|
||
; Our next task is to iterate through the trainers,
|
||
; decrementing b each time, until we get to the right one.
|
||
.outer
|
||
dec b
|
||
jr z,.IterateTrainer
|
||
.inner
|
||
ld a,[hli]
|
||
and a
|
||
jr nz,.inner
|
||
jr .outer
|
||
|
||
; if the first byte of trainer data is FF,
|
||
; - each pokemon has a specific level
|
||
; (as opposed to the whole team being of the same level)
|
||
; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
|
||
; else the first byte is the level of every pokemon on the team
|
||
.IterateTrainer
|
||
ld a,[hli]
|
||
cp $FF ; is the trainer special?
|
||
jr z,.SpecialTrainer ; if so, check for special moves
|
||
ld [W_CURENEMYLVL],a
|
||
.LoopTrainerData
|
||
ld a,[hli]
|
||
and a ; have we reached the end of the trainer data?
|
||
jr z,.FinishUp
|
||
ld [wcf91],a ; write species somewhere (XXX why?)
|
||
ld a,1
|
||
ld [wcc49],a
|
||
push hl
|
||
call AddPartyMon
|
||
pop hl
|
||
jr .LoopTrainerData
|
||
.SpecialTrainer
|
||
; if this code is being run:
|
||
; - each pokemon has a specific level
|
||
; (as opposed to the whole team being of the same level)
|
||
; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
|
||
ld a,[hli]
|
||
and a ; have we reached the end of the trainer data?
|
||
jr z,.AddLoneMove
|
||
ld [W_CURENEMYLVL],a
|
||
ld a,[hli]
|
||
ld [wcf91],a
|
||
ld a,1
|
||
ld [wcc49],a
|
||
push hl
|
||
call AddPartyMon
|
||
pop hl
|
||
jr .SpecialTrainer
|
||
.AddLoneMove
|
||
; does the trainer have a single monster with a different move
|
||
ld a,[W_LONEATTACKNO] ; Brock is 01, Misty is 02, Erika is 04, etc
|
||
and a
|
||
jr z,.AddTeamMove
|
||
dec a
|
||
add a,a
|
||
ld c,a
|
||
ld b,0
|
||
ld hl,LoneMoves
|
||
add hl,bc
|
||
ld a,[hli]
|
||
ld d,[hl]
|
||
ld hl,wEnemyMon1Moves + 2
|
||
ld bc,wEnemyMon2 - wEnemyMon1
|
||
call AddNTimes
|
||
ld [hl],d
|
||
jr .FinishUp
|
||
.AddTeamMove
|
||
; check if our trainer's team has special moves
|
||
|
||
; get trainer class number
|
||
ld a,[W_CUROPPONENT]
|
||
sub $C8
|
||
ld b,a
|
||
ld hl,TeamMoves
|
||
|
||
; iterate through entries in TeamMoves, checking each for our trainer class
|
||
.IterateTeamMoves
|
||
ld a,[hli]
|
||
cp b
|
||
jr z,.GiveTeamMoves ; is there a match?
|
||
inc hl ; if not, go to the next entry
|
||
inc a
|
||
jr nz,.IterateTeamMoves
|
||
|
||
; no matches found. is this trainer champion rival?
|
||
ld a,b
|
||
cp SONY3
|
||
jr z,.ChampionRival
|
||
jr .FinishUp ; nope
|
||
.GiveTeamMoves
|
||
ld a,[hl]
|
||
ld [wEnemyMon5Moves + 2],a
|
||
jr .FinishUp
|
||
.ChampionRival ; give moves to his team
|
||
|
||
; pidgeot
|
||
ld a,SKY_ATTACK
|
||
ld [wEnemyMon1Moves + 2],a
|
||
|
||
; starter
|
||
ld a,[W_RIVALSTARTER]
|
||
cp STARTER3
|
||
ld b,MEGA_DRAIN
|
||
jr z,.GiveStarterMove
|
||
cp STARTER1
|
||
ld b,FIRE_BLAST
|
||
jr z,.GiveStarterMove
|
||
ld b,BLIZZARD ; must be squirtle
|
||
.GiveStarterMove
|
||
ld a,b
|
||
ld [wEnemyMon6Moves + 2],a
|
||
.FinishUp ; XXX this needs documenting
|
||
xor a ; clear D079-D07B
|
||
ld de,wd079
|
||
ld [de],a
|
||
inc de
|
||
ld [de],a
|
||
inc de
|
||
ld [de],a
|
||
ld a,[W_CURENEMYLVL]
|
||
ld b,a
|
||
.LastLoop
|
||
ld hl,wd047
|
||
ld c,2
|
||
push bc
|
||
predef AddBCDPredef
|
||
pop bc
|
||
inc de
|
||
inc de
|
||
dec b
|
||
jr nz,.LastLoop
|
||
ret
|
||
|
||
INCLUDE "data/trainer_moves.asm"
|
||
|
||
INCLUDE "data/trainer_parties.asm"
|
||
|
||
TrainerAI: ; 3a52e (e:652e)
|
||
;XXX called at 34964, 3c342, 3c398
|
||
and a
|
||
ld a,[W_ISINBATTLE]
|
||
dec a
|
||
ret z ; if not a trainer, we're done here
|
||
ld a,[wLinkState]
|
||
cp LINK_STATE_BATTLING
|
||
ret z
|
||
ld a,[W_TRAINERCLASS] ; what trainer class is this?
|
||
dec a
|
||
ld c,a
|
||
ld b,0
|
||
ld hl,TrainerAIPointers
|
||
add hl,bc
|
||
add hl,bc
|
||
add hl,bc
|
||
ld a,[wAICount]
|
||
and a
|
||
ret z ; if no AI uses left, we're done here
|
||
inc hl
|
||
inc a
|
||
jr nz,.getpointer
|
||
dec hl
|
||
ld a,[hli]
|
||
ld [wAICount],a
|
||
.getpointer
|
||
ld a,[hli]
|
||
ld h,[hl]
|
||
ld l,a
|
||
call Random
|
||
jp [hl]
|
||
|
||
TrainerAIPointers: ; 3a55c (e:655c)
|
||
; one entry per trainer class
|
||
; first byte, number of times (per Pokémon) it can occur
|
||
; next two bytes, pointer to AI subroutine for trainer class
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,JugglerAI ; juggler_x
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 3,JugglerAI ; juggler
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 2,BlackbeltAI ; blackbelt
|
||
dbw 3,GenericAI
|
||
dbw 3,GenericAI
|
||
dbw 1,GenericAI ; chief
|
||
dbw 3,GenericAI
|
||
dbw 1,GiovanniAI ; giovanni
|
||
dbw 3,GenericAI
|
||
dbw 2,CooltrainerMAI ; cooltrainerm
|
||
dbw 1,CooltrainerFAI ; cooltrainerf
|
||
dbw 2,BrunoAI ; bruno
|
||
dbw 5,BrockAI ; brock
|
||
dbw 1,MistyAI ; misty
|
||
dbw 1,LtSurgeAI ; surge
|
||
dbw 1,ErikaAI ; erika
|
||
dbw 2,KogaAI ; koga
|
||
dbw 2,BlaineAI ; blaine
|
||
dbw 1,SabrinaAI ; sabrina
|
||
dbw 3,GenericAI
|
||
dbw 1,Sony2AI ; sony2
|
||
dbw 1,Sony3AI ; sony3
|
||
dbw 2,LoreleiAI ; lorelei
|
||
dbw 3,GenericAI
|
||
dbw 2,AgathaAI ; agatha
|
||
dbw 1,LanceAI ; lance
|
||
|
||
JugglerAI: ; 3a5e9 (e:65e9)
|
||
cp $40
|
||
ret nc
|
||
jp AISwitchIfEnoughMons
|
||
|
||
BlackbeltAI: ; 3a5ef (e:65ef)
|
||
cp $20
|
||
ret nc
|
||
jp AIUseXAttack
|
||
|
||
GiovanniAI: ; 3a5f5 (e:65f5)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseGuardSpec
|
||
|
||
CooltrainerMAI: ; 3a5fb (e:65fb)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseXAttack
|
||
|
||
CooltrainerFAI: ; 3a601 (e:6601)
|
||
cp $40
|
||
ld a,$A
|
||
call AICheckIfHPBelowFraction
|
||
jp c,AIUseHyperPotion
|
||
ld a,5
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AISwitchIfEnoughMons
|
||
|
||
BrockAI: ; 3a614 (e:6614)
|
||
; if his active monster has a status condition, use a full heal
|
||
ld a,[wEnemyMonStatus]
|
||
and a
|
||
ret z
|
||
jp AIUseFullHeal
|
||
|
||
MistyAI: ; 3a61c (e:661c)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseXDefend
|
||
|
||
LtSurgeAI: ; 3a622 (e:6622)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseXSpeed
|
||
|
||
ErikaAI: ; 3a628 (e:6628)
|
||
cp $80
|
||
ret nc
|
||
ld a,$A
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseSuperPotion
|
||
|
||
KogaAI: ; 3a634 (e:6634)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseXAttack
|
||
|
||
BlaineAI: ; 3a63a (e:663a)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseSuperPotion
|
||
|
||
SabrinaAI: ; 3a640 (e:6640)
|
||
cp $40
|
||
ret nc
|
||
ld a,$A
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseHyperPotion
|
||
|
||
Sony2AI: ; 3a64c (e:664c)
|
||
cp $20
|
||
ret nc
|
||
ld a,5
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUsePotion
|
||
|
||
Sony3AI: ; 3a658 (e:6658)
|
||
cp $20
|
||
ret nc
|
||
ld a,5
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseFullRestore
|
||
|
||
LoreleiAI: ; 3a664 (e:6664)
|
||
cp $80
|
||
ret nc
|
||
ld a,5
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseSuperPotion
|
||
|
||
BrunoAI: ; 3a670 (e:6670)
|
||
cp $40
|
||
ret nc
|
||
jp AIUseXDefend
|
||
|
||
AgathaAI: ; 3a676 (e:6676)
|
||
cp $14
|
||
jp c,AISwitchIfEnoughMons
|
||
cp $80
|
||
ret nc
|
||
ld a,4
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseSuperPotion
|
||
|
||
LanceAI: ; 3a687 (e:6687)
|
||
cp $80
|
||
ret nc
|
||
ld a,5
|
||
call AICheckIfHPBelowFraction
|
||
ret nc
|
||
jp AIUseHyperPotion
|
||
|
||
GenericAI: ; 3a693 (e:6693)
|
||
and a ; clear carry
|
||
ret
|
||
|
||
; end of individual trainer AI routines
|
||
|
||
DecrementAICount: ; 3a695 (e:6695)
|
||
ld hl,wAICount
|
||
dec [hl]
|
||
scf
|
||
ret
|
||
|
||
Func_3a69b: ; 3a69b (e:669b)
|
||
ld a,(SFX_08_3e - SFX_Headers_08) / 3
|
||
jp PlaySoundWaitForCurrent
|
||
|
||
AIUseFullRestore: ; 3a6a0 (e:66a0)
|
||
call AICureStatus
|
||
ld a,FULL_RESTORE
|
||
ld [wcf05],a
|
||
ld de,wHPBarOldHP
|
||
ld hl,wEnemyMonHP + 1
|
||
ld a,[hld]
|
||
ld [de],a
|
||
inc de
|
||
ld a,[hl]
|
||
ld [de],a
|
||
inc de
|
||
ld hl,wEnemyMonMaxHP + 1
|
||
ld a,[hld]
|
||
ld [de],a
|
||
inc de
|
||
ld [wHPBarMaxHP],a
|
||
ld [wEnemyMonHP + 1],a
|
||
ld a,[hl]
|
||
ld [de],a
|
||
ld [wHPBarMaxHP+1],a
|
||
ld [wEnemyMonHP],a
|
||
jr AIPrintItemUseAndUpdateHPBar
|
||
|
||
AIUsePotion: ; 3a6ca (e:66ca)
|
||
; enemy trainer heals his monster with a potion
|
||
ld a,POTION
|
||
ld b,20
|
||
jr AIRecoverHP
|
||
|
||
AIUseSuperPotion: ; 3a6d0 (e:66d0)
|
||
; enemy trainer heals his monster with a super potion
|
||
ld a,SUPER_POTION
|
||
ld b,50
|
||
jr AIRecoverHP
|
||
|
||
AIUseHyperPotion: ; 3a6d6 (e:66d6)
|
||
; enemy trainer heals his monster with a hyper potion
|
||
ld a,HYPER_POTION
|
||
ld b,200
|
||
; fallthrough
|
||
|
||
AIRecoverHP: ; 3a6da (e:66da)
|
||
; heal b HP and print "trainer used $(a) on pokemon!"
|
||
ld [wcf05],a
|
||
ld hl,wEnemyMonHP + 1
|
||
ld a,[hl]
|
||
ld [wHPBarOldHP],a
|
||
add b
|
||
ld [hld],a
|
||
ld [wHPBarNewHP],a
|
||
ld a,[hl]
|
||
ld [wHPBarOldHP+1],a
|
||
ld [wHPBarNewHP+1],a
|
||
jr nc,.next
|
||
inc a
|
||
ld [hl],a
|
||
ld [wHPBarNewHP+1],a
|
||
.next
|
||
inc hl
|
||
ld a,[hld]
|
||
ld b,a
|
||
ld de,wEnemyMonMaxHP + 1
|
||
ld a,[de]
|
||
dec de
|
||
ld [wHPBarMaxHP],a
|
||
sub b
|
||
ld a,[hli]
|
||
ld b,a
|
||
ld a,[de]
|
||
ld [wHPBarMaxHP+1],a
|
||
sbc b
|
||
jr nc,AIPrintItemUseAndUpdateHPBar
|
||
inc de
|
||
ld a,[de]
|
||
dec de
|
||
ld [hld],a
|
||
ld [wHPBarNewHP],a
|
||
ld a,[de]
|
||
ld [hl],a
|
||
ld [wHPBarNewHP+1],a
|
||
; fallthrough
|
||
|
||
AIPrintItemUseAndUpdateHPBar: ; 3a718 (e:6718)
|
||
call AIPrintItemUse_
|
||
hlCoord 2, 2
|
||
xor a
|
||
ld [wHPBarType],a
|
||
predef UpdateHPBar2
|
||
jp DecrementAICount
|
||
|
||
AISwitchIfEnoughMons: ; 3a72a (e:672a)
|
||
; enemy trainer switches if there are 3 or more unfainted mons in party
|
||
ld a,[wEnemyPartyCount]
|
||
ld c,a
|
||
ld hl,wEnemyMon1HP
|
||
|
||
ld d,0 ; keep count of unfainted monsters
|
||
|
||
; count how many monsters haven't fainted yet
|
||
.loop
|
||
ld a,[hli]
|
||
ld b,a
|
||
ld a,[hld]
|
||
or b
|
||
jr z,.Fainted ; has monster fainted?
|
||
inc d
|
||
.Fainted
|
||
push bc
|
||
ld bc,$2C
|
||
add hl,bc
|
||
pop bc
|
||
dec c
|
||
jr nz,.loop
|
||
|
||
ld a,d ; how many available monsters are there?
|
||
cp 2 ; don't bother if only 1 or 2
|
||
jp nc,SwitchEnemyMon
|
||
and a
|
||
ret
|
||
|
||
SwitchEnemyMon: ; 3a74b (e:674b)
|
||
|
||
; prepare to withdraw the active monster: copy hp, number, and status to roster
|
||
|
||
ld a,[wEnemyMonPartyPos]
|
||
ld hl,wEnemyMon1HP
|
||
ld bc,wEnemyMon2 - wEnemyMon1
|
||
call AddNTimes
|
||
ld d,h
|
||
ld e,l
|
||
ld hl,wEnemyMonHP
|
||
ld bc,4
|
||
call CopyData
|
||
|
||
ld hl, AIBattleWithdrawText
|
||
call PrintText
|
||
|
||
ld a,1
|
||
ld [wd11d],a
|
||
callab EnemySendOut
|
||
xor a
|
||
ld [wd11d],a
|
||
|
||
ld a,[wLinkState]
|
||
cp LINK_STATE_BATTLING
|
||
ret z
|
||
scf
|
||
ret
|
||
|
||
AIBattleWithdrawText: ; 3a781 (e:6781)
|
||
TX_FAR _AIBattleWithdrawText
|
||
db "@"
|
||
|
||
AIUseFullHeal: ; 3a786 (e:6786)
|
||
call Func_3a69b
|
||
call AICureStatus
|
||
ld a,FULL_HEAL
|
||
jp AIPrintItemUse
|
||
|
||
AICureStatus: ; 3a791 (e:6791)
|
||
; cures the status of enemy's active pokemon
|
||
ld a,[wEnemyMonPartyPos]
|
||
ld hl,wEnemyMon1Status
|
||
ld bc,wEnemyMon2 - wEnemyMon1
|
||
call AddNTimes
|
||
xor a
|
||
ld [hl],a ; clear status in enemy team roster
|
||
ld [wEnemyMonStatus],a ; clear status of active enemy
|
||
ld hl,W_ENEMYBATTSTATUS3
|
||
res 0,[hl]
|
||
ret
|
||
|
||
AIUseXAccuracy: ; 0x3a7a8 unused
|
||
call Func_3a69b
|
||
ld hl,W_ENEMYBATTSTATUS2
|
||
set 0,[hl]
|
||
ld a,X_ACCURACY
|
||
jp AIPrintItemUse
|
||
|
||
AIUseGuardSpec: ; 3a7b5 (e:67b5)
|
||
call Func_3a69b
|
||
ld hl,W_ENEMYBATTSTATUS2
|
||
set 1,[hl]
|
||
ld a,GUARD_SPEC_
|
||
jp AIPrintItemUse
|
||
|
||
AIUseDireHit: ; 0x3a7c2 unused
|
||
call Func_3a69b
|
||
ld hl,W_ENEMYBATTSTATUS2
|
||
set 2,[hl]
|
||
ld a,DIRE_HIT
|
||
jp AIPrintItemUse
|
||
|
||
AICheckIfHPBelowFraction: ; 3a7cf (e:67cf)
|
||
; return carry if enemy trainer's current HP is below 1 / a of the maximum
|
||
ld [H_DIVISOR],a
|
||
ld hl,wEnemyMonMaxHP
|
||
ld a,[hli]
|
||
ld [H_DIVIDEND],a
|
||
ld a,[hl]
|
||
ld [H_DIVIDEND + 1],a
|
||
ld b,2
|
||
call Divide
|
||
ld a,[H_QUOTIENT + 3]
|
||
ld c,a
|
||
ld a,[H_QUOTIENT + 2]
|
||
ld b,a
|
||
ld hl,wEnemyMonHP + 1
|
||
ld a,[hld]
|
||
ld e,a
|
||
ld a,[hl]
|
||
ld d,a
|
||
ld a,d
|
||
sub b
|
||
ret nz
|
||
ld a,e
|
||
sub c
|
||
ret
|
||
|
||
AIUseXAttack: ; 3a7f2 (e:67f2)
|
||
ld b,$A
|
||
ld a,X_ATTACK
|
||
jr AIIncreaseStat
|
||
|
||
AIUseXDefend: ; 3a7f8 (e:67f8)
|
||
ld b,$B
|
||
ld a,X_DEFEND
|
||
jr AIIncreaseStat
|
||
|
||
AIUseXSpeed: ; 3a7fe (e:67fe)
|
||
ld b,$C
|
||
ld a,X_SPEED
|
||
jr AIIncreaseStat
|
||
|
||
AIUseXSpecial: ; 3a804 (e:6804)
|
||
ld b,$D
|
||
ld a,X_SPECIAL
|
||
; fallthrough
|
||
|
||
AIIncreaseStat: ; 3a808 (e:6808)
|
||
ld [wcf05],a
|
||
push bc
|
||
call AIPrintItemUse_
|
||
pop bc
|
||
ld hl,W_ENEMYMOVEEFFECT
|
||
ld a,[hld]
|
||
push af
|
||
ld a,[hl]
|
||
push af
|
||
push hl
|
||
ld a,$AF
|
||
ld [hli],a
|
||
ld [hl],b
|
||
callab StatModifierUpEffect
|
||
pop hl
|
||
pop af
|
||
ld [hli],a
|
||
pop af
|
||
ld [hl],a
|
||
jp DecrementAICount
|
||
|
||
AIPrintItemUse: ; 3a82c (e:682c)
|
||
ld [wcf05],a
|
||
call AIPrintItemUse_
|
||
jp DecrementAICount
|
||
|
||
AIPrintItemUse_: ; 3a835 (e:6835)
|
||
; print "x used [wcf05] on z!"
|
||
ld a,[wcf05]
|
||
ld [wd11e],a
|
||
call GetItemName
|
||
ld hl, AIBattleUseItemText
|
||
jp PrintText
|
||
|
||
AIBattleUseItemText: ; 3a844 (e:6844)
|
||
TX_FAR _AIBattleUseItemText
|
||
db "@"
|
||
|
||
DrawAllPokeballs: ; 3a849 (e:6849)
|
||
call LoadPartyPokeballGfx
|
||
call SetupOwnPartyPokeballs
|
||
ld a, [W_ISINBATTLE] ; W_ISINBATTLE
|
||
dec a
|
||
ret z ; return if wild pokémon
|
||
jp SetupEnemyPartyPokeballs
|
||
|
||
DrawEnemyPokeballs: ; 0x3a857
|
||
call LoadPartyPokeballGfx
|
||
jp SetupEnemyPartyPokeballs
|
||
|
||
LoadPartyPokeballGfx: ; 3a85d (e:685d)
|
||
ld de, PokeballTileGraphics ; $697e
|
||
ld hl, vSprites + $310
|
||
ld bc, (BANK(PokeballTileGraphics) << 8) + $04
|
||
jp CopyVideoData
|
||
|
||
SetupOwnPartyPokeballs: ; 3a869 (e:6869)
|
||
call PlacePlayerHUDTiles
|
||
ld hl, wPartyMon1
|
||
ld de, wPartyCount ; wPartyCount
|
||
call SetupPokeballs
|
||
ld a, $60
|
||
ld hl, W_BASECOORDX ; wd081
|
||
ld [hli], a
|
||
ld [hl], a
|
||
ld a, $8
|
||
ld [wTrainerEngageDistance], a
|
||
ld hl, wOAMBuffer
|
||
jp WritePokeballOAMData
|
||
|
||
SetupEnemyPartyPokeballs: ; 3a887 (e:6887)
|
||
call PlaceEnemyHUDTiles
|
||
ld hl, wEnemyMons
|
||
ld de, wEnemyPartyCount ; wEnemyPartyCount
|
||
call SetupPokeballs
|
||
ld hl, W_BASECOORDX ; wd081
|
||
ld a, $48
|
||
ld [hli], a
|
||
ld [hl], $20
|
||
ld a, $f8
|
||
ld [wTrainerEngageDistance], a
|
||
ld hl, wOAMBuffer + PARTY_LENGTH * 4
|
||
jp WritePokeballOAMData
|
||
|
||
SetupPokeballs: ; 0x3a8a6
|
||
ld a, [de]
|
||
push af
|
||
ld de, wBuffer
|
||
ld c, PARTY_LENGTH
|
||
ld a, $34 ; empty pokeball
|
||
.emptyloop
|
||
ld [de], a
|
||
inc de
|
||
dec c
|
||
jr nz, .emptyloop
|
||
pop af
|
||
ld de, wBuffer
|
||
.monloop
|
||
push af
|
||
call PickPokeball
|
||
inc de
|
||
pop af
|
||
dec a
|
||
jr nz, .monloop
|
||
ret
|
||
|
||
PickPokeball: ; 3a8c2 (e:68c2)
|
||
inc hl
|
||
ld a, [hli]
|
||
and a
|
||
jr nz, .alive
|
||
ld a, [hl]
|
||
and a
|
||
ld b, $33 ; crossed ball (fainted)
|
||
jr z, .done_fainted
|
||
.alive
|
||
inc hl
|
||
inc hl
|
||
ld a, [hl] ; status
|
||
and a
|
||
ld b, $32 ; black ball (status)
|
||
jr nz, .done
|
||
dec b ; regular ball
|
||
jr .done
|
||
.done_fainted
|
||
inc hl
|
||
inc hl
|
||
.done
|
||
ld a, b
|
||
ld [de], a
|
||
ld bc, $0028 ; rest of mon struct
|
||
add hl, bc
|
||
ret
|
||
|
||
WritePokeballOAMData: ; 3a8e1 (e:68e1)
|
||
ld de, wBuffer
|
||
ld c, PARTY_LENGTH
|
||
.loop
|
||
ld a, [W_BASECOORDY] ; wd082
|
||
ld [hli], a
|
||
ld a, [W_BASECOORDX] ; wd081
|
||
ld [hli], a
|
||
ld a, [de]
|
||
ld [hli], a
|
||
xor a
|
||
ld [hli], a
|
||
ld a, [W_BASECOORDX] ; wd081
|
||
ld b, a
|
||
ld a, [wTrainerEngageDistance]
|
||
add b
|
||
ld [W_BASECOORDX], a ; wd081
|
||
inc de
|
||
dec c
|
||
jr nz, .loop
|
||
ret
|
||
|
||
PlacePlayerHUDTiles: ; 3a902 (e:6902)
|
||
ld hl, PlayerBattleHUDGraphicsTiles ; $6916
|
||
ld de, wTrainerFacingDirection
|
||
ld bc, $3
|
||
call CopyData
|
||
hlCoord 18, 10
|
||
ld de, rIE ; $ffff
|
||
jr PlaceHUDTiles
|
||
|
||
PlayerBattleHUDGraphicsTiles: ; 3a916 (e:6916)
|
||
; The tile numbers for specific parts of the battle display for the player's pokemon
|
||
db $73 ; unused ($73 is hardcoded into the routine that uses these bytes)
|
||
db $77 ; lower-right corner tile of the HUD
|
||
db $6F ; lower-left triangle tile of the HUD
|
||
|
||
PlaceEnemyHUDTiles: ; 3a919 (e:6919)
|
||
ld hl, EnemyBattleHUDGraphicsTiles ; $692d
|
||
ld de, wTrainerFacingDirection
|
||
ld bc, $3
|
||
call CopyData
|
||
hlCoord 1, 2
|
||
ld de, $1
|
||
jr PlaceHUDTiles
|
||
|
||
EnemyBattleHUDGraphicsTiles: ; 3a92d (e:692d)
|
||
; The tile numbers for specific parts of the battle display for the enemy
|
||
db $73 ; unused ($73 is hardcoded in the routine that uses these bytes)
|
||
db $74 ; lower-left corner tile of the HUD
|
||
db $78 ; lower-right triangle tile of the HUD
|
||
|
||
PlaceHUDTiles: ; 3a930 (e:6930)
|
||
ld [hl], $73
|
||
ld bc, $14
|
||
add hl, bc
|
||
ld a, [wTrainerScreenY]
|
||
ld [hl], a
|
||
ld a, $8
|
||
.asm_3a93c
|
||
add hl, de
|
||
ld [hl], $76
|
||
dec a
|
||
jr nz, .asm_3a93c
|
||
add hl, de
|
||
ld a, [wTrainerScreenX]
|
||
ld [hl], a
|
||
ret
|
||
|
||
SetupPlayerAndEnemyPokeballs: ; 3a948 (e:6948)
|
||
call LoadPartyPokeballGfx
|
||
ld hl, wPartyMon1Species ; wPartyMon1Species (aliases: wPartyMon1)
|
||
ld de, wPartyCount ; wPartyCount
|
||
call SetupPokeballs
|
||
ld hl, W_BASECOORDX ; wd081
|
||
ld a, $50
|
||
ld [hli], a
|
||
ld [hl], $40
|
||
ld a, $8
|
||
ld [wTrainerEngageDistance], a
|
||
ld hl, wOAMBuffer
|
||
call WritePokeballOAMData
|
||
ld hl, wEnemyMons ; wEnemyMon1Species
|
||
ld de, wEnemyPartyCount ; wEnemyPartyCount
|
||
call SetupPokeballs
|
||
ld hl, W_BASECOORDX ; wd081
|
||
ld a, $50
|
||
ld [hli], a
|
||
ld [hl], $68
|
||
ld hl, wOAMBuffer + $18
|
||
jp WritePokeballOAMData
|
||
|
||
; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (faited) and pokeball slot (no mon)
|
||
PokeballTileGraphics:: ; 3a97e (e:697e)
|
||
INCBIN "gfx/pokeball.2bpp"
|