123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839 |
- ; 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:
- ld a, $a
- ld hl, wBuffer ; 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, [wEnemyDisabledMove] ; forbid disabled move (if any)
- swap a
- and $f
- jr z, .noMoveDisabled
- ld hl, wBuffer
- 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
- ld a, [wTrainerClass]
- 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
- 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, wBuffer ; temp move selection array
- ld de, wEnemyMonMoves ; enemy moves
- ld c, NUM_MOVES
- .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 NUM_MOVES + 1
- jr nz, .loopUndoPartialIteration
- ld hl, wBuffer ; temp move selection array
- ld de, wEnemyMonMoves ; enemy moves
- ld c, NUM_MOVES
- .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
- 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, wBuffer ; use created temporary array as move set
- ret
- .useOriginalMoveSet
- ld hl, wEnemyMonMoves ; use original move set
- ret
- AIMoveChoiceModificationFunctionPointers:
- 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:
- 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 offset)
- ld de, wEnemyMonMoves ; enemy moves
- ld b, NUM_MOVES + 1
- .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, [wEnemyMovePower]
- and a
- jr nz, .nextMove
- ld a, [wEnemyMoveEffect]
- 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 ; heavily discourage move
- ld [hl], a
- jr .nextMove
- StatusAilmentMoveEffects:
- db $01 ; unused sleep effect
- db SLEEP_EFFECT
- db POISON_EFFECT
- db PARALYZE_EFFECT
- db $FF
- ; slightly encourage moves with specific effects.
- ; in particular, stat-modifying moves and other move effects
- ; that fall in-between
- AIMoveChoiceModification2:
- ld a, [wAILayer2Encouragement]
- cp $1
- ret nz
- ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
- ld de, wEnemyMonMoves ; enemy moves
- ld b, NUM_MOVES + 1
- .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, [wEnemyMoveEffect]
- 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] ; slightly encourage this move
- jr .nextMove
- ; encourages moves that are effective against the player's mon (even if non-damaging).
- ; discourage damaging moves that are ineffective or not very effective against the player's mon,
- ; unless there's no damaging move that deals at least neutral damage
- AIMoveChoiceModification3:
- ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
- ld de, wEnemyMonMoves ; enemy moves
- ld b, NUM_MOVES + 1
- .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, [wTypeEffectiveness]
- cp $10
- jr z, .nextMove
- jr c, .notEffectiveMove
- dec [hl] ; slightly encourage this move
- jr .nextMove
- .notEffectiveMove ; discourages non-effective moves if better moves are available
- push hl
- push de
- push bc
- ld a, [wEnemyMoveType]
- ld d, a
- ld hl, wEnemyMonMoves ; enemy moves
- ld b, NUM_MOVES + 1
- ld c, $0
- .loopMoves
- dec b
- jr z, .done
- ld a, [hli]
- and a
- jr z, .done
- call ReadMove
- ld a, [wEnemyMoveEffect]
- 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, [wEnemyMoveType]
- cp d
- jr z, .loopMoves
- ld a, [wEnemyMovePower]
- 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] ; slightly discourage this move
- jr .nextMove
- AIMoveChoiceModification4:
- ret
- ReadMove:
- push hl
- push de
- push bc
- dec a
- ld hl, Moves
- ld bc, MoveEnd - Moves
- call AddNTimes
- ld de, wEnemyMoveNum
- 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:
- 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
- INCLUDE "engine/battle/trainer_pic_money_pointers.asm"
- INCLUDE "text/trainer_names.asm"
- INCLUDE "engine/battle/bank_e_misc.asm"
- INCLUDE "engine/battle/read_trainer_party.asm"
- INCLUDE "data/trainer_moves.asm"
- INCLUDE "data/trainer_parties.asm"
- TrainerAI:
- and a
- ld a, [wIsInBattle]
- dec a
- ret z ; if not a trainer, we're done here
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- ret z
- ld a, [wTrainerClass] ; 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:
- ; 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:
- cp $40
- ret nc
- jp AISwitchIfEnoughMons
- BlackbeltAI:
- cp $20
- ret nc
- jp AIUseXAttack
- GiovanniAI:
- cp $40
- ret nc
- jp AIUseGuardSpec
- CooltrainerMAI:
- cp $40
- ret nc
- jp AIUseXAttack
- CooltrainerFAI:
- cp $40
- ld a, $A
- call AICheckIfHPBelowFraction
- jp c, AIUseHyperPotion
- ld a, 5
- call AICheckIfHPBelowFraction
- ret nc
- jp AISwitchIfEnoughMons
- BrockAI:
- ; if his active monster has a status condition, use a full heal
- ld a, [wEnemyMonStatus]
- and a
- ret z
- jp AIUseFullHeal
- MistyAI:
- cp $40
- ret nc
- jp AIUseXDefend
- LtSurgeAI:
- cp $40
- ret nc
- jp AIUseXSpeed
- ErikaAI:
- cp $80
- ret nc
- ld a, $A
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseSuperPotion
- KogaAI:
- cp $40
- ret nc
- jp AIUseXAttack
- BlaineAI:
- cp $40
- ret nc
- jp AIUseSuperPotion
- SabrinaAI:
- cp $40
- ret nc
- ld a, $A
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseHyperPotion
- Sony2AI:
- cp $20
- ret nc
- ld a, 5
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUsePotion
- Sony3AI:
- cp $20
- ret nc
- ld a, 5
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseFullRestore
- LoreleiAI:
- cp $80
- ret nc
- ld a, 5
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseSuperPotion
- BrunoAI:
- cp $40
- ret nc
- jp AIUseXDefend
- AgathaAI:
- cp $14
- jp c, AISwitchIfEnoughMons
- cp $80
- ret nc
- ld a, 4
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseSuperPotion
- LanceAI:
- cp $80
- ret nc
- ld a, 5
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseHyperPotion
- GenericAI:
- and a ; clear carry
- ret
- ; end of individual trainer AI routines
- DecrementAICount:
- ld hl, wAICount
- dec [hl]
- scf
- ret
- AIPlayRestoringSFX:
- ld a, SFX_HEAL_AILMENT
- jp PlaySoundWaitForCurrent
- AIUseFullRestore:
- call AICureStatus
- ld a, FULL_RESTORE
- ld [wAIItem], 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:
- ; enemy trainer heals his monster with a potion
- ld a, POTION
- ld b, 20
- jr AIRecoverHP
- AIUseSuperPotion:
- ; enemy trainer heals his monster with a super potion
- ld a, SUPER_POTION
- ld b, 50
- jr AIRecoverHP
- AIUseHyperPotion:
- ; enemy trainer heals his monster with a hyper potion
- ld a, HYPER_POTION
- ld b, 200
- ; fallthrough
- AIRecoverHP:
- ; heal b HP and print "trainer used $(a) on pokemon!"
- ld [wAIItem], 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:
- call AIPrintItemUse_
- coord hl, 2, 2
- xor a
- ld [wHPBarType], a
- predef UpdateHPBar2
- jp DecrementAICount
- AISwitchIfEnoughMons:
- ; 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, wEnemyMon2 - wEnemyMon1
- 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:
- ; 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
- ; This wFirstMonsNotOutYet variable is abused to prevent the player from
- ; switching in a new mon in response to this switch.
- ld a, 1
- ld [wFirstMonsNotOutYet], a
- callab EnemySendOut
- xor a
- ld [wFirstMonsNotOutYet], a
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- ret z
- scf
- ret
- AIBattleWithdrawText:
- TX_FAR _AIBattleWithdrawText
- db "@"
- AIUseFullHeal:
- call AIPlayRestoringSFX
- call AICureStatus
- ld a, FULL_HEAL
- jp AIPrintItemUse
- AICureStatus:
- ; 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, wEnemyBattleStatus3
- res 0, [hl]
- ret
- AIUseXAccuracy: ; unused
- call AIPlayRestoringSFX
- ld hl, wEnemyBattleStatus2
- set 0, [hl]
- ld a, X_ACCURACY
- jp AIPrintItemUse
- AIUseGuardSpec:
- call AIPlayRestoringSFX
- ld hl, wEnemyBattleStatus2
- set 1, [hl]
- ld a, GUARD_SPEC
- jp AIPrintItemUse
- AIUseDireHit: ; unused
- call AIPlayRestoringSFX
- ld hl, wEnemyBattleStatus2
- set 2, [hl]
- ld a, DIRE_HIT
- jp AIPrintItemUse
- AICheckIfHPBelowFraction:
- ; 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:
- ld b, $A
- ld a, X_ATTACK
- jr AIIncreaseStat
- AIUseXDefend:
- ld b, $B
- ld a, X_DEFEND
- jr AIIncreaseStat
- AIUseXSpeed:
- ld b, $C
- ld a, X_SPEED
- jr AIIncreaseStat
- AIUseXSpecial:
- ld b, $D
- ld a, X_SPECIAL
- ; fallthrough
- AIIncreaseStat:
- ld [wAIItem], a
- push bc
- call AIPrintItemUse_
- pop bc
- ld hl, wEnemyMoveEffect
- ld a, [hld]
- push af
- ld a, [hl]
- push af
- push hl
- ld a, ANIM_AF
- ld [hli], a
- ld [hl], b
- callab StatModifierUpEffect
- pop hl
- pop af
- ld [hli], a
- pop af
- ld [hl], a
- jp DecrementAICount
- AIPrintItemUse:
- ld [wAIItem], a
- call AIPrintItemUse_
- jp DecrementAICount
- AIPrintItemUse_:
- ; print "x used [wAIItem] on z!"
- ld a, [wAIItem]
- ld [wd11e], a
- call GetItemName
- ld hl, AIBattleUseItemText
- jp PrintText
- AIBattleUseItemText:
- TX_FAR _AIBattleUseItemText
- db "@"
|