mirror of
https://github.com/pret/poketcg.git
synced 2026-04-25 15:42:58 -05:00
Split bank 8
This commit is contained in:
parent
36ef80903a
commit
09239933ed
|
|
@ -134,7 +134,7 @@ Each deck AI lists some Pokémon card IDs that have an associated score for retr
|
|||
|
||||
However, the game never actually stores the pointer to these lists (a notable expection being the Legendary Moltres deck), so the AI cannot access these score modifiers.
|
||||
|
||||
**Fix:** Edit all applicable decks in `src/engine/deck_ai/decks/`, uncommenting the following line:
|
||||
**Fix:** Edit all applicable decks in `src/engine/ai/decks/`, uncommenting the following line:
|
||||
```diff
|
||||
.store_list_pointers
|
||||
store_list_pointer wAICardListAvoidPrize, .list_prize
|
||||
|
|
@ -283,7 +283,7 @@ AIDecide_PokemonTrader_PowerGenerator: ; 2200b (8:600b)
|
|||
|
||||
## AI never uses Energy Trans in order to retreat Arena card
|
||||
|
||||
There is a mistake in the AI retreat logic, in [src/engine/deck_ai/decks/general.asm](https://github.com/pret/poketcg/blob/master/src/engine/deck_ai/decks/general.asm):
|
||||
There is a mistake in the AI retreat logic, in [src/engine/ai/decks/general.asm](https://github.com/pret/poketcg/blob/master/src/engine/ai/decks/general.asm):
|
||||
```
|
||||
.used_switch
|
||||
; if AI used switch, unset its AI flag
|
||||
|
|
@ -308,7 +308,7 @@ There is a mistake in the AI retreat logic, in [src/engine/deck_ai/decks/general
|
|||
|
||||
## Sam's practice deck does wrong card ID check
|
||||
|
||||
There is a mistake in the AI logic for deciding which Pokémon for Sam to switch to, in [src/engine/deck_ai/decks/sams_practice.asm](https://github.com/pret/poketcg/blob/master/src/engine/deck_ai/decks/sams_practice.asm):
|
||||
There is a mistake in the AI logic for deciding which Pokémon for Sam to switch to, in [src/engine/ai/decks/sams_practice.asm](https://github.com/pret/poketcg/blob/master/src/engine/ai/decks/sams_practice.asm):
|
||||
```
|
||||
; this is a bug, it's attempting to compare a card ID with a deck index.
|
||||
; the intention was to change the card to switch to depending on whether
|
||||
|
|
|
|||
47
src/data/ai_trainer_card_logic.asm
Normal file
47
src/data/ai_trainer_card_logic.asm
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
ai_trainer_card_logic: MACRO
|
||||
db \1 ; AI_TRAINER_CARD_PHASE_* constant
|
||||
db \2 ; ID of trainer card
|
||||
dw \3 ; function for AI decision to play card
|
||||
dw \4 ; function for AI playing the card
|
||||
ENDM
|
||||
|
||||
AITrainerCardLogic: ; 20000 (8:4000)
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_07, POTION, AIDecide_Potion1, AIPlay_Potion
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_10, POTION, AIDecide_Potion2, AIPlay_Potion
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_08, SUPER_POTION, AIDecide_SuperPotion1, AIPlay_SuperPotion
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_11, SUPER_POTION, AIDecide_SuperPotion2, AIPlay_SuperPotion
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_13, DEFENDER, AIDecide_Defender1, AIPlay_Defender
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_14, DEFENDER, AIDecide_Defender2, AIPlay_Defender
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_13, PLUSPOWER, AIDecide_Pluspower1, AIPlay_Pluspower
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_14, PLUSPOWER, AIDecide_Pluspower2, AIPlay_Pluspower
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_09, SWITCH, AIDecide_Switch, AIPlay_Switch
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_07, GUST_OF_WIND, AIDecide_GustOfWind, AIPlay_GustOfWind
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_10, GUST_OF_WIND, AIDecide_GustOfWind, AIPlay_GustOfWind
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_04, BILL, AIDecide_Bill, AIPlay_Bill
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_05, ENERGY_REMOVAL, AIDecide_EnergyRemoval, AIPlay_EnergyRemoval
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_05, SUPER_ENERGY_REMOVAL, AIDecide_SuperEnergyRemoval, AIPlay_SuperEnergyRemoval
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_07, POKEMON_BREEDER, AIDecide_PokemonBreeder, AIPlay_PokemonBreeder
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_15, PROFESSOR_OAK, AIDecide_ProfessorOak, AIPlay_ProfessorOak
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_10, ENERGY_RETRIEVAL, AIDecide_EnergyRetrieval, AIPlay_EnergyRetrieval
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_11, SUPER_ENERGY_RETRIEVAL, AIDecide_SuperEnergyRetrieval, AIPlay_SuperEnergyRetrieval
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_06, POKEMON_CENTER, AIDecide_PokemonCenter, AIPlay_PokemonCenter
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_07, IMPOSTER_PROFESSOR_OAK, AIDecide_ImposterProfessorOak, AIPlay_ImposterProfessorOak
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_12, ENERGY_SEARCH, AIDecide_EnergySearch, AIPlay_EnergySearch
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_03, POKEDEX, AIDecide_Pokedex, AIPlay_Pokedex
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_07, FULL_HEAL, AIDecide_FullHeal, AIPlay_FullHeal
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_10, MR_FUJI, AIDecide_MrFuji, AIPlay_MrFuji
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_10, SCOOP_UP, AIDecide_ScoopUp, AIPlay_ScoopUp
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_02, MAINTENANCE, AIDecide_Maintenance, AIPlay_Maintenance
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_03, RECYCLE, AIDecide_Recycle, AIPlay_Recycle
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_13, LASS, AIDecide_Lass, AIPlay_Lass
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_04, ITEM_FINDER, AIDecide_ItemFinder, AIPlay_ItemFinder
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_01, IMAKUNI_CARD, AIDecide_Imakuni, AIPlay_Imakuni
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_01, GAMBLER, AIDecide_Gambler, AIPlay_Gambler
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_05, REVIVE, AIDecide_Revive, AIPlay_Revive
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_13, POKEMON_FLUTE, AIDecide_PokemonFlute, AIPlay_PokemonFlute
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_05, CLEFAIRY_DOLL, AIDecide_ClefairyDollOrMysteriousFossil, AIPlay_ClefairyDollOrMysteriousFossil
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_05, MYSTERIOUS_FOSSIL, AIDecide_ClefairyDollOrMysteriousFossil, AIPlay_ClefairyDollOrMysteriousFossil
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_02, POKE_BALL, AIDecide_Pokeball, AIPlay_Pokeball
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_02, COMPUTER_SEARCH, AIDecide_ComputerSearch, AIPlay_ComputerSearch
|
||||
ai_trainer_card_logic AI_TRAINER_CARD_PHASE_02, POKEMON_TRADER, AIDecide_PokemonTrader, AIPlay_PokemonTrader
|
||||
db $ff
|
||||
970
src/engine/ai/common.asm
Normal file
970
src/engine/ai/common.asm
Normal file
|
|
@ -0,0 +1,970 @@
|
|||
; runs through Player's whole deck and
|
||||
; sets carry if there's any Pokemon other
|
||||
; than Mewtwo1.
|
||||
CheckIfPlayerHasPokemonOtherThanMewtwo1: ; 227a9 (8:67a9)
|
||||
call SwapTurn
|
||||
ld e, 0
|
||||
.loop_deck
|
||||
ld a, e
|
||||
push de
|
||||
call LoadCardDataToBuffer2_FromDeckIndex
|
||||
pop de
|
||||
ld a, [wLoadedCard2Type]
|
||||
cp TYPE_ENERGY
|
||||
jp nc, .next ; can be a jr
|
||||
ld a, [wLoadedCard2ID]
|
||||
cp MEWTWO1
|
||||
jr nz, .not_mewtwo1
|
||||
.next
|
||||
inc e
|
||||
ld a, DECK_SIZE
|
||||
cp e
|
||||
jr nz, .loop_deck
|
||||
|
||||
; no carry
|
||||
call SwapTurn
|
||||
or a
|
||||
ret
|
||||
|
||||
.not_mewtwo1
|
||||
call SwapTurn
|
||||
scf
|
||||
ret
|
||||
|
||||
; returns no carry if, given the Player is using a Mewtwo1 mill deck,
|
||||
; the AI already has a Bench fully set up, in which case it
|
||||
; will process some Trainer cards in hand (namely Energy Removals).
|
||||
; this is used to check whether to skip some normal AI routines
|
||||
; this turn and jump right to the attacking phase.
|
||||
HandleAIAntiMewtwoDeckStrategy: ; 227d3 (8:67d3)
|
||||
; return carry if Player is not playing Mewtwo1 mill deck
|
||||
ld a, [wAIBarrierFlagCounter]
|
||||
bit AI_MEWTWO_MILL_F, a
|
||||
jr z, .set_carry
|
||||
|
||||
; else, check if there's been less than 2 turns
|
||||
; without the Player using Barrier.
|
||||
cp AI_MEWTWO_MILL + 2
|
||||
jr c, .count_bench
|
||||
|
||||
; if there has been, reset wAIBarrierFlagCounter
|
||||
; and return carry.
|
||||
xor a
|
||||
ld [wAIBarrierFlagCounter], a
|
||||
jr .set_carry
|
||||
|
||||
; else, check number of Pokemon that are set up in Bench
|
||||
; if less than 4, return carry.
|
||||
.count_bench
|
||||
farcall CountNumberOfSetUpBenchPokemon
|
||||
cp 4
|
||||
jr c, .set_carry
|
||||
|
||||
; if there's at least 4 Pokemon in the Bench set up,
|
||||
; process Trainer hand cards of AI_TRAINER_CARD_PHASE_05
|
||||
ld a, AI_TRAINER_CARD_PHASE_05
|
||||
farcall AIProcessHandTrainerCards
|
||||
or a
|
||||
ret
|
||||
|
||||
.set_carry
|
||||
scf
|
||||
ret
|
||||
|
||||
; lists in wDuelTempList all the basic energy cards
|
||||
; in card location of a.
|
||||
; outputs in a number of cards found.
|
||||
; returns carry if none were found.
|
||||
; input:
|
||||
; a = CARD_LOCATION_* to look
|
||||
; output:
|
||||
; a = number of cards found
|
||||
FindBasicEnergyCardsInLocation: ; 227f6 (8:67f6)
|
||||
ld [wTempAI], a
|
||||
lb de, 0, 0
|
||||
ld hl, wDuelTempList
|
||||
|
||||
; d = number of basic energy cards found
|
||||
; e = current card in deck
|
||||
; loop entire deck
|
||||
.loop
|
||||
ld a, DUELVARS_CARD_LOCATIONS
|
||||
add e
|
||||
push hl
|
||||
call GetTurnDuelistVariable
|
||||
ld hl, wTempAI
|
||||
cp [hl]
|
||||
pop hl
|
||||
jr nz, .next_card
|
||||
|
||||
; is in the card location we're looking for
|
||||
ld a, e
|
||||
push de
|
||||
push hl
|
||||
call GetCardIDFromDeckIndex
|
||||
pop hl
|
||||
ld a, e
|
||||
pop de
|
||||
cp DOUBLE_COLORLESS_ENERGY
|
||||
; only basic energy cards
|
||||
; will set carry here
|
||||
jr nc, .next_card
|
||||
|
||||
; is a basic energy card
|
||||
; add this card to the TempList
|
||||
ld a, e
|
||||
ld [hli], a
|
||||
inc d
|
||||
.next_card
|
||||
inc e
|
||||
ld a, DECK_SIZE
|
||||
cp e
|
||||
jr nz, .loop
|
||||
|
||||
; check if any were found
|
||||
ld a, d
|
||||
or a
|
||||
jr z, .set_carry
|
||||
|
||||
; some were found, add the termination byte on TempList
|
||||
ld a, $ff
|
||||
ld [hl], a
|
||||
ld a, d
|
||||
ret
|
||||
|
||||
.set_carry
|
||||
scf
|
||||
ret
|
||||
|
||||
; returns in a the card index of energy card
|
||||
; attached to Pokémon in Play Area location a,
|
||||
; that is to be discarded by the AI for an effect.
|
||||
; outputs $ff is none was found.
|
||||
; input:
|
||||
; a = PLAY_AREA_* constant of card
|
||||
; output:
|
||||
; a = deck index of attached energy card chosen
|
||||
AIPickEnergyCardToDiscard: ; 2282e (8:682e)
|
||||
; load Pokémon's attached energy cards.
|
||||
ldh [hTempPlayAreaLocation_ff9d], a
|
||||
call CreateArenaOrBenchEnergyCardList
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld e, a
|
||||
call GetPlayAreaCardAttachedEnergies
|
||||
ld a, [wTotalAttachedEnergies]
|
||||
or a
|
||||
jr z, .no_energy
|
||||
|
||||
; load card's ID and type.
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld b, a
|
||||
ld a, DUELVARS_ARENA_CARD
|
||||
add b
|
||||
call GetTurnDuelistVariable
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
ld [wTempCardID], a
|
||||
call LoadCardDataToBuffer1_FromCardID
|
||||
ld a, [wLoadedCard1Type]
|
||||
or TYPE_ENERGY
|
||||
ld [wTempCardType], a
|
||||
|
||||
; find a card that is not useful.
|
||||
; if none is found, just return the first energy card attached.
|
||||
ld hl, wDuelTempList
|
||||
.loop
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
jr z, .not_found
|
||||
farcall CheckIfEnergyIsUseful
|
||||
jr nc, .found
|
||||
inc hl
|
||||
jr .loop
|
||||
|
||||
.found
|
||||
ld a, [hl]
|
||||
ret
|
||||
.not_found
|
||||
ld hl, wDuelTempList
|
||||
ld a, [hl]
|
||||
ret
|
||||
.no_energy
|
||||
ld a, $ff
|
||||
ret
|
||||
|
||||
; returns in a the deck index of an energy card attached to card
|
||||
; in player's Play Area location a to remove.
|
||||
; prioritizes double colorless energy, then any useful energy,
|
||||
; then defaults to the first energy card attached if neither
|
||||
; of those are found.
|
||||
; returns $ff in a if there are no energy cards attached.
|
||||
; input:
|
||||
; a = Play Area location to check
|
||||
; output:
|
||||
; a = deck index of attached energy card
|
||||
PickAttachedEnergyCardToRemove: ; 22875 (8:6875)
|
||||
; construct energy list and check if there are any energy cards attached
|
||||
ldh [hTempPlayAreaLocation_ff9d], a
|
||||
call CreateArenaOrBenchEnergyCardList
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld e, a
|
||||
call GetPlayAreaCardAttachedEnergies
|
||||
ld a, [wTotalAttachedEnergies]
|
||||
or a
|
||||
jr z, .no_energy
|
||||
|
||||
; load card data and store its type
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld b, a
|
||||
ld a, DUELVARS_ARENA_CARD
|
||||
add b
|
||||
call GetTurnDuelistVariable
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
ld [wTempCardID], a
|
||||
call LoadCardDataToBuffer1_FromCardID
|
||||
ld a, [wLoadedCard1Type]
|
||||
or TYPE_ENERGY
|
||||
ld [wTempCardType], a
|
||||
|
||||
; first look for any double colorless energy
|
||||
ld hl, wDuelTempList
|
||||
.loop_1
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
jr z, .check_useful
|
||||
push hl
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
cp DOUBLE_COLORLESS_ENERGY
|
||||
pop hl
|
||||
jr z, .found
|
||||
inc hl
|
||||
jr .loop_1
|
||||
|
||||
; then look for any energy cards that are useful
|
||||
.check_useful
|
||||
ld hl, wDuelTempList
|
||||
.loop_2
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
jr z, .default
|
||||
farcall CheckIfEnergyIsUseful
|
||||
jr c, .found
|
||||
inc hl
|
||||
jr .loop_2
|
||||
|
||||
; return the energy card that was found
|
||||
.found
|
||||
ld a, [hl]
|
||||
ret
|
||||
|
||||
; if none were found with the above criteria,
|
||||
; just return the first option
|
||||
.default
|
||||
ld hl, wDuelTempList
|
||||
ld a, [hl]
|
||||
ret
|
||||
|
||||
; return $ff if no energy cards attached
|
||||
.no_energy
|
||||
ld a, $ff
|
||||
ret
|
||||
|
||||
; stores in wTempAI and wCurCardCanAttack the deck indices
|
||||
; of energy cards attached to card in Play Area location a.
|
||||
; prioritizes double colorless energy, then any useful energy,
|
||||
; then defaults to the first two energy cards attached if neither
|
||||
; of those are found.
|
||||
; returns $ff in a if there are no energy cards attached.
|
||||
; input:
|
||||
; a = Play Area location to check
|
||||
; output:
|
||||
; [wTempAI] = deck index of attached energy card
|
||||
; [wCurCardCanAttack] = deck index of attached energy card
|
||||
PickTwoAttachedEnergyCards: ; 228d1 (8:68d1)
|
||||
ldh [hTempPlayAreaLocation_ff9d], a
|
||||
call CreateArenaOrBenchEnergyCardList
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld e, a
|
||||
farcall CountNumberOfEnergyCardsAttached
|
||||
cp 2
|
||||
jp c, .not_enough
|
||||
|
||||
; load card data and store its type
|
||||
ldh a, [hTempPlayAreaLocation_ff9d]
|
||||
ld b, a
|
||||
ld a, DUELVARS_ARENA_CARD
|
||||
add b
|
||||
call GetTurnDuelistVariable
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
ld [wTempCardID], a
|
||||
call LoadCardDataToBuffer1_FromCardID
|
||||
ld a, [wLoadedCard1Type]
|
||||
or TYPE_ENERGY
|
||||
ld [wTempCardType], a
|
||||
ld a, $ff
|
||||
ld [wTempAI], a
|
||||
ld [wCurCardCanAttack], a
|
||||
|
||||
; first look for any double colorless energy
|
||||
ld hl, wDuelTempList
|
||||
.loop_1
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
jr z, .check_useful
|
||||
push hl
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
cp DOUBLE_COLORLESS_ENERGY
|
||||
pop hl
|
||||
jr z, .found_double_colorless
|
||||
inc hl
|
||||
jr .loop_1
|
||||
.found_double_colorless
|
||||
ld a, [wTempAI]
|
||||
cp $ff
|
||||
jr nz, .already_chosen_1
|
||||
ld a, [hli]
|
||||
ld [wTempAI], a
|
||||
jr .loop_1
|
||||
.already_chosen_1
|
||||
ld a, [hl]
|
||||
ld [wCurCardCanAttack], a
|
||||
jr .done
|
||||
|
||||
; then look for any energy cards that are useful
|
||||
.check_useful
|
||||
ld hl, wDuelTempList
|
||||
.loop_2
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
jr z, .default
|
||||
farcall CheckIfEnergyIsUseful
|
||||
jr c, .found_useful
|
||||
inc hl
|
||||
jr .loop_2
|
||||
.found_useful
|
||||
ld a, [wTempAI]
|
||||
cp $ff
|
||||
jr nz, .already_chosen_2
|
||||
ld a, [hli]
|
||||
ld [wTempAI], a
|
||||
jr .loop_2
|
||||
.already_chosen_2
|
||||
ld a, [hl]
|
||||
ld [wCurCardCanAttack], a
|
||||
jr .done
|
||||
|
||||
; if none were found with the above criteria,
|
||||
; just return the first 2 options
|
||||
.default
|
||||
ld hl, wDuelTempList
|
||||
ld a, [wTempAI]
|
||||
cp $ff
|
||||
jr nz, .pick_one_card
|
||||
|
||||
; pick 2 cards
|
||||
ld a, [hli]
|
||||
ld [wTempAI], a
|
||||
ld a, [hl]
|
||||
ld [wCurCardCanAttack], a
|
||||
jr .done
|
||||
.pick_one_card
|
||||
ld a, [wTempAI]
|
||||
ld b, a
|
||||
.loop_3
|
||||
ld a, [hli]
|
||||
cp b
|
||||
jr z, .loop_3 ; already picked
|
||||
ld [wCurCardCanAttack], a
|
||||
|
||||
.done
|
||||
ld a, [wCurCardCanAttack]
|
||||
ld b, a
|
||||
ld a, [wTempAI]
|
||||
ret
|
||||
|
||||
; return $ff if no energy cards attached
|
||||
.not_enough
|
||||
ld a, $ff
|
||||
ret
|
||||
|
||||
; copies $ff terminated buffer from hl to de
|
||||
CopyBuffer: ; 2297b (8:697b)
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
cp $ff
|
||||
ret z
|
||||
inc de
|
||||
jr CopyBuffer
|
||||
|
||||
; zeroes a bytes starting at hl
|
||||
ClearMemory_Bank8: ; 22983 (8:6983)
|
||||
push af
|
||||
push bc
|
||||
push hl
|
||||
ld b, a
|
||||
xor a
|
||||
.loop
|
||||
ld [hli], a
|
||||
dec b
|
||||
jr nz, .loop
|
||||
pop hl
|
||||
pop bc
|
||||
pop af
|
||||
ret
|
||||
|
||||
; counts number of energy cards found in hand
|
||||
; and outputs result in a
|
||||
; sets carry if none are found
|
||||
; output:
|
||||
; a = number of energy cards found
|
||||
CountOppEnergyCardsInHand: ; 22990 (8:6990)
|
||||
farcall CreateEnergyCardListFromHand
|
||||
ret c
|
||||
ld b, -1
|
||||
ld hl, wDuelTempList
|
||||
.loop
|
||||
inc b
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr nz, .loop
|
||||
ld a, b
|
||||
or a
|
||||
ret
|
||||
|
||||
; converts HP in a to number of equivalent damage counters
|
||||
; input:
|
||||
; a = HP
|
||||
; output:
|
||||
; a = number of damage counters
|
||||
ConvertHPToCounters: ; 229a3 (8:69a3)
|
||||
push bc
|
||||
ld c, 0
|
||||
.loop
|
||||
sub 10
|
||||
jr c, .carry
|
||||
inc c
|
||||
jr .loop
|
||||
.carry
|
||||
ld a, c
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; calculates floor(hl / 10)
|
||||
CalculateWordTensDigit: ; 229b0 (8:69b0)
|
||||
push bc
|
||||
push de
|
||||
lb bc, $ff, -10
|
||||
lb de, $ff, -1
|
||||
.asm_229b8
|
||||
inc de
|
||||
add hl, bc
|
||||
jr c, .asm_229b8
|
||||
ld h, d
|
||||
ld l, e
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; returns in a division of b by a
|
||||
CalculateBDividedByA_Bank8: ; 229c1 (8:69c1)
|
||||
push bc
|
||||
ld c, a
|
||||
ld a, b
|
||||
ld b, c
|
||||
ld c, 0
|
||||
.loop
|
||||
sub b
|
||||
jr c, .done
|
||||
inc c
|
||||
jr .loop
|
||||
.done
|
||||
ld a, c
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; returns in a the deck index of the first
|
||||
; instance of card with ID equal to the ID in e
|
||||
; in card location a.
|
||||
; returns carry if found.
|
||||
; input:
|
||||
; a = CARD_LOCATION_*
|
||||
; e = card ID to look for
|
||||
LookForCardIDInLocation: ; 229d0 (8:69d0)
|
||||
ld b, a
|
||||
ld c, e
|
||||
lb de, $00, 0 ; d is never used
|
||||
.loop
|
||||
ld a, DUELVARS_CARD_LOCATIONS
|
||||
add e
|
||||
call GetTurnDuelistVariable
|
||||
cp b
|
||||
jr nz, .next
|
||||
ld a, e
|
||||
push de
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
pop de
|
||||
cp c
|
||||
jr z, .found
|
||||
.next
|
||||
inc e
|
||||
ld a, DECK_SIZE
|
||||
cp e
|
||||
jr nz, .loop
|
||||
|
||||
; not found
|
||||
or a
|
||||
ret
|
||||
.found
|
||||
ld a, e
|
||||
scf
|
||||
ret
|
||||
|
||||
; return carry if card ID loaded in a is found in hand
|
||||
; and outputs in a the deck index of that card
|
||||
; input:
|
||||
; a = card ID
|
||||
; output:
|
||||
; a = card deck index, if found
|
||||
; carry set if found
|
||||
LookForCardIDInHandList_Bank8: ; 229f3 (8:69f3)
|
||||
ld [wTempCardIDToLook], a
|
||||
call CreateHandCardList
|
||||
ld hl, wDuelTempList
|
||||
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
ret z
|
||||
|
||||
ldh [hTempCardIndex_ff98], a
|
||||
call LoadCardDataToBuffer1_FromDeckIndex
|
||||
ld b, a
|
||||
ld a, [wTempCardIDToLook]
|
||||
cp b
|
||||
jr nz, .loop
|
||||
|
||||
ldh a, [hTempCardIndex_ff98]
|
||||
scf
|
||||
ret
|
||||
|
||||
; searches in deck for card ID 1 in a, and
|
||||
; if found, searches in Hand/Play Area for card ID 2 in b, and
|
||||
; if found, searches for card ID 1 in Hand/Play Area, and
|
||||
; if none found, return carry and output deck index
|
||||
; of the card ID 1 in deck.
|
||||
; input:
|
||||
; a = card ID 1
|
||||
; b = card ID 2
|
||||
; output:
|
||||
; a = index of card ID 1 in deck
|
||||
LookForCardIDInDeck_GivenCardIDInHandAndPlayArea: ; 22a10 (8:6a10)
|
||||
; store a in wCurCardCanAttack
|
||||
; and b in wTempAI
|
||||
ld c, a
|
||||
ld a, b
|
||||
ld [wTempAI], a
|
||||
ld a, c
|
||||
ld [wCurCardCanAttack], a
|
||||
|
||||
; look for the card ID 1 in deck
|
||||
ld e, a
|
||||
ld a, CARD_LOCATION_DECK
|
||||
call LookForCardIDInLocation
|
||||
ret nc
|
||||
|
||||
; was found, store its deck index in memory
|
||||
ld [wTempAIPokemonCard], a
|
||||
|
||||
; look for the card ID 2
|
||||
; in Hand and Play Area, return if not found.
|
||||
ld a, [wTempAI]
|
||||
call LookForCardIDInHandAndPlayArea
|
||||
ret nc
|
||||
|
||||
; look for the card ID 1 in the Hand and Play Area
|
||||
; if any card is found, return no carry.
|
||||
ld a, [wCurCardCanAttack]
|
||||
call LookForCardIDInHandAndPlayArea
|
||||
jr c, .no_carry
|
||||
; none found
|
||||
|
||||
ld a, [wTempAIPokemonCard]
|
||||
scf
|
||||
ret
|
||||
|
||||
.no_carry
|
||||
or a
|
||||
ret
|
||||
|
||||
; returns carry if card ID in a
|
||||
; is found in Play Area or in hand
|
||||
; input:
|
||||
; a = card ID
|
||||
LookForCardIDInHandAndPlayArea: ; 22a39 (8:6a39)
|
||||
ld b, a
|
||||
push bc
|
||||
call LookForCardIDInHandList_Bank8
|
||||
pop bc
|
||||
ret c
|
||||
|
||||
ld a, b
|
||||
ld b, PLAY_AREA_ARENA
|
||||
call LookForCardIDInPlayArea_Bank8
|
||||
ret c
|
||||
or a
|
||||
ret
|
||||
|
||||
; searches in deck for card ID 1 in a, and
|
||||
; if found, searches in Hand Area for card ID 2 in b, and
|
||||
; if found, searches for card ID 1 in Hand/Play Area, and
|
||||
; if none found, return carry and output deck index
|
||||
; of the card ID 1 in deck.
|
||||
; input:
|
||||
; a = card ID 1
|
||||
; b = card ID 2
|
||||
; output:
|
||||
; a = index of card ID 1 in deck
|
||||
LookForCardIDInDeck_GivenCardIDInHand: ; 22a49 (8:6a49)
|
||||
; store a in wCurCardCanAttack
|
||||
; and b in wTempAI
|
||||
ld c, a
|
||||
ld a, b
|
||||
ld [wTempAI], a
|
||||
ld a, c
|
||||
ld [wCurCardCanAttack], a
|
||||
|
||||
; look for the card ID 1 in deck
|
||||
ld e, a
|
||||
ld a, CARD_LOCATION_DECK
|
||||
call LookForCardIDInLocation
|
||||
ret nc
|
||||
|
||||
; was found, store its deck index in memory
|
||||
ld [wTempAIPokemonCard], a
|
||||
|
||||
; look for the card ID 2 in hand, return if not found.
|
||||
ld a, [wTempAI]
|
||||
call LookForCardIDInHandList_Bank8
|
||||
ret nc
|
||||
|
||||
; look for the card ID 1 in the Hand and Play Area
|
||||
; if any card is found, return no carry.
|
||||
ld a, [wCurCardCanAttack]
|
||||
call LookForCardIDInHandAndPlayArea
|
||||
jr c, .no_carry
|
||||
; none found
|
||||
|
||||
ld a, [wTempAIPokemonCard]
|
||||
scf
|
||||
ret
|
||||
|
||||
.no_carry
|
||||
or a
|
||||
ret
|
||||
|
||||
; returns carry if card ID in a
|
||||
; is found in Play Area, starting with
|
||||
; location in b
|
||||
; input:
|
||||
; a = card ID
|
||||
; b = PLAY_AREA_* to start with
|
||||
; output:
|
||||
; a = PLAY_AREA_* of found card
|
||||
; carry set if found
|
||||
LookForCardIDInPlayArea_Bank8: ; 22a72 (8:6a72)
|
||||
ld [wTempCardIDToLook], a
|
||||
.loop
|
||||
ld a, DUELVARS_ARENA_CARD
|
||||
add b
|
||||
call GetTurnDuelistVariable
|
||||
cp $ff
|
||||
ret z
|
||||
|
||||
call LoadCardDataToBuffer1_FromDeckIndex
|
||||
ld c, a
|
||||
ld a, [wTempCardIDToLook]
|
||||
cp c
|
||||
jr z, .is_same
|
||||
|
||||
inc b
|
||||
ld a, MAX_PLAY_AREA_POKEMON
|
||||
cp b
|
||||
jr nz, .loop
|
||||
ld b, $ff
|
||||
or a
|
||||
ret
|
||||
|
||||
.is_same
|
||||
ld a, b
|
||||
scf
|
||||
ret
|
||||
|
||||
; runs through list avoiding card in e.
|
||||
; removes first card in list not equal to e
|
||||
; and that has a type allowed to be removed, in d.
|
||||
; returns carry if successful in finding a card.
|
||||
; input:
|
||||
; d = type of card allowed to be removed
|
||||
; ($00 = Trainer, $01 = Pokemon, $02 = Energy)
|
||||
; e = card deck index to avoid removing
|
||||
; output:
|
||||
; a = card index of removed card
|
||||
RemoveFromListDifferentCardOfGivenType: ; 22a95 (8:6a95)
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
call CountCardsInDuelTempList
|
||||
call ShuffleCards
|
||||
|
||||
; loop list until a card with
|
||||
; deck index different from e is found.
|
||||
.loop_list
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .no_carry
|
||||
cp e
|
||||
jr z, .loop_list
|
||||
|
||||
; get this card's type
|
||||
ldh [hTempCardIndex_ff98], a
|
||||
push de
|
||||
call GetCardIDFromDeckIndex
|
||||
call GetCardType
|
||||
pop de
|
||||
cp TYPE_ENERGY
|
||||
jr c, .pkmn_card
|
||||
cp TYPE_TRAINER
|
||||
jr nz, .energy
|
||||
|
||||
; only remove from list specific type.
|
||||
|
||||
; trainer
|
||||
ld a, d
|
||||
or a
|
||||
jr nz, .loop_list
|
||||
jr .remove_card
|
||||
.energy
|
||||
ld a, d
|
||||
cp $02
|
||||
jr nz, .loop_list
|
||||
jr .remove_card
|
||||
.pkmn_card
|
||||
ld a, d
|
||||
cp $01
|
||||
jr nz, .loop_list
|
||||
; fallthrough
|
||||
|
||||
.remove_card
|
||||
ld d, h
|
||||
ld e, l
|
||||
dec hl
|
||||
.loop_remove
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [hli], a
|
||||
cp $ff
|
||||
jr nz, .loop_remove
|
||||
|
||||
; success
|
||||
ldh a, [hTempCardIndex_ff98]
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
scf
|
||||
ret
|
||||
.no_carry
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
or a
|
||||
ret
|
||||
|
||||
; used in Pokemon Trader checks to look for a specific
|
||||
; card in the deck to trade with a card in hand that
|
||||
; has a card ID different from e.
|
||||
; returns carry if successful.
|
||||
; input:
|
||||
; a = card ID 1
|
||||
; e = card ID 2
|
||||
; output:
|
||||
; a = deck index of card ID 1 found in deck
|
||||
; e = deck index of Pokemon card in hand different than card ID 2
|
||||
LookForCardIDToTradeWithDifferentHandCard: ; 22ae0 (8:6ae0)
|
||||
ld hl, wCurCardCanAttack
|
||||
ld [hl], e
|
||||
ld [wTempAI], a
|
||||
|
||||
; if card ID 1 is in hand, return no carry.
|
||||
call LookForCardIDInHandList_Bank8
|
||||
jr c, .no_carry
|
||||
|
||||
; if card ID 1 is not in deck, return no carry.
|
||||
ld a, [wTempAI]
|
||||
ld e, a
|
||||
ld a, CARD_LOCATION_DECK
|
||||
call LookForCardIDInLocation
|
||||
jr nc, .no_carry
|
||||
|
||||
; store its deck index
|
||||
ld [wTempAI], a
|
||||
|
||||
; look in hand for Pokemon card ID that
|
||||
; is different from card ID 2.
|
||||
ld a, [wCurCardCanAttack]
|
||||
ld c, a
|
||||
call CreateHandCardList
|
||||
ld hl, wDuelTempList
|
||||
|
||||
.loop_hand
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .no_carry
|
||||
ld b, a
|
||||
call LoadCardDataToBuffer1_FromDeckIndex
|
||||
cp c
|
||||
jr z, .loop_hand
|
||||
ld a, [wLoadedCard1Type]
|
||||
cp TYPE_ENERGY
|
||||
jr nc, .loop_hand
|
||||
|
||||
; found, output deck index of card ID 1 in deck
|
||||
; and deck index of card found in hand, and set carry
|
||||
ld e, b
|
||||
ld a, [wTempAI]
|
||||
scf
|
||||
ret
|
||||
|
||||
.no_carry
|
||||
or a
|
||||
ret
|
||||
|
||||
; returns carry if at least one card in the hand
|
||||
; has the card ID of input. Outputs its index.
|
||||
; input:
|
||||
; a = card ID to look for
|
||||
; output:
|
||||
; a = deck index of card in hand found
|
||||
CheckIfHasCardIDInHand: ; 22b1f (8:6b1f)
|
||||
ld [wTempCardIDToLook], a
|
||||
call CreateHandCardList
|
||||
ld hl, wDuelTempList
|
||||
ld c, 0
|
||||
|
||||
.loop_hand
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
ret z
|
||||
ldh [hTempCardIndex_ff98], a
|
||||
call LoadCardDataToBuffer1_FromDeckIndex
|
||||
ld b, a
|
||||
ld a, [wTempCardIDToLook]
|
||||
cp b
|
||||
jr nz, .loop_hand
|
||||
ld a, c
|
||||
or a
|
||||
jr nz, .set_carry
|
||||
inc c
|
||||
jr nz, .loop_hand
|
||||
|
||||
.set_carry
|
||||
ldh a, [hTempCardIndex_ff98]
|
||||
scf
|
||||
ret
|
||||
|
||||
; outputs in a total number of Pokemon cards in hand
|
||||
; plus Pokemon in Turn Duelist's Play Area.
|
||||
CountPokemonCardsInHandAndInPlayArea: ; 22b45 (8:6b45)
|
||||
ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
|
||||
call GetTurnDuelistVariable
|
||||
ld [wTempAI], a
|
||||
call CreateHandCardList
|
||||
ld hl, wDuelTempList
|
||||
.loop_hand
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .done
|
||||
call GetCardIDFromDeckIndex
|
||||
call GetCardType
|
||||
cp TYPE_ENERGY
|
||||
jr nc, .loop_hand
|
||||
ld a, [wTempAI]
|
||||
inc a
|
||||
ld [wTempAI], a
|
||||
jr .loop_hand
|
||||
.done
|
||||
ld a, [wTempAI]
|
||||
ret
|
||||
|
||||
; returns carry if a duplicate Pokemon card is found in hand.
|
||||
; outputs in a the deck index of one of them.
|
||||
FindDuplicatePokemonCards: ; 22b6f (8:6b6f)
|
||||
ld a, $ff
|
||||
ld [wTempAI], a
|
||||
call CreateHandCardList
|
||||
ld hl, wDuelTempList
|
||||
push hl
|
||||
|
||||
.loop_hand_outer
|
||||
pop hl
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .done
|
||||
call GetCardIDFromDeckIndex
|
||||
ld b, e
|
||||
push hl
|
||||
|
||||
.loop_hand_inner
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
jr z, .loop_hand_outer
|
||||
ld c, a
|
||||
call GetCardIDFromDeckIndex
|
||||
ld a, e
|
||||
cp b
|
||||
jr nz, .loop_hand_inner
|
||||
|
||||
; found two cards with same ID,
|
||||
; if they are Pokemon cards, store its deck index.
|
||||
push bc
|
||||
call GetCardType
|
||||
pop bc
|
||||
cp TYPE_ENERGY
|
||||
jr nc, .loop_hand_outer
|
||||
ld a, c
|
||||
ld [wTempAI], a
|
||||
; for some reason loop still continues
|
||||
; even though if some other duplicate
|
||||
; cards are found, it overwrites the result.
|
||||
jr .loop_hand_outer
|
||||
|
||||
.done
|
||||
ld a, [wTempAI]
|
||||
cp $ff
|
||||
jr z, .no_carry
|
||||
|
||||
; found
|
||||
scf
|
||||
ret
|
||||
.no_carry
|
||||
or a
|
||||
ret
|
||||
|
||||
; return carry flag if attack is not high recoil.
|
||||
AICheckIfAttackIsHighRecoil: ; 22bad (8:6bad)
|
||||
farcall AIProcessButDontUseAttack
|
||||
ret nc
|
||||
ld a, [wSelectedAttack]
|
||||
ld e, a
|
||||
ld a, DUELVARS_ARENA_CARD
|
||||
call GetTurnDuelistVariable
|
||||
ld d, a
|
||||
call CopyAttackDataAndDamage_FromDeckIndex
|
||||
ld a, ATTACK_FLAG1_ADDRESS | HIGH_RECOIL_F
|
||||
call CheckLoadedAttackFlag
|
||||
ccf
|
||||
ret
|
||||
|
|
@ -61,22 +61,22 @@ ENDM
|
|||
; wAICardListRetreatBonus : scores given to certain cards for retreat;
|
||||
; wAICardListEnergyBonus : max number of energy cards and card scores.
|
||||
|
||||
INCLUDE "engine/deck_ai/decks/general.asm"
|
||||
INCLUDE "engine/deck_ai/decks/sams_practice.asm"
|
||||
INCLUDE "engine/deck_ai/decks/general_no_retreat.asm"
|
||||
INCLUDE "engine/deck_ai/decks/legendary_moltres.asm"
|
||||
INCLUDE "engine/deck_ai/decks/legendary_zapdos.asm"
|
||||
INCLUDE "engine/deck_ai/decks/legendary_articuno.asm"
|
||||
INCLUDE "engine/deck_ai/decks/legendary_dragonite.asm"
|
||||
INCLUDE "engine/deck_ai/decks/first_strike.asm"
|
||||
INCLUDE "engine/deck_ai/decks/rock_crusher.asm"
|
||||
INCLUDE "engine/deck_ai/decks/go_go_rain_dance.asm"
|
||||
INCLUDE "engine/deck_ai/decks/zapping_selfdestruct.asm"
|
||||
INCLUDE "engine/deck_ai/decks/flower_power.asm"
|
||||
INCLUDE "engine/deck_ai/decks/strange_psyshock.asm"
|
||||
INCLUDE "engine/deck_ai/decks/wonders_of_science.asm"
|
||||
INCLUDE "engine/deck_ai/decks/fire_charge.asm"
|
||||
INCLUDE "engine/deck_ai/decks/im_ronald.asm"
|
||||
INCLUDE "engine/deck_ai/decks/powerful_ronald.asm"
|
||||
INCLUDE "engine/deck_ai/decks/invincible_ronald.asm"
|
||||
INCLUDE "engine/deck_ai/decks/legendary_ronald.asm"
|
||||
INCLUDE "engine/ai/decks/general.asm"
|
||||
INCLUDE "engine/ai/decks/sams_practice.asm"
|
||||
INCLUDE "engine/ai/decks/general_no_retreat.asm"
|
||||
INCLUDE "engine/ai/decks/legendary_moltres.asm"
|
||||
INCLUDE "engine/ai/decks/legendary_zapdos.asm"
|
||||
INCLUDE "engine/ai/decks/legendary_articuno.asm"
|
||||
INCLUDE "engine/ai/decks/legendary_dragonite.asm"
|
||||
INCLUDE "engine/ai/decks/first_strike.asm"
|
||||
INCLUDE "engine/ai/decks/rock_crusher.asm"
|
||||
INCLUDE "engine/ai/decks/go_go_rain_dance.asm"
|
||||
INCLUDE "engine/ai/decks/zapping_selfdestruct.asm"
|
||||
INCLUDE "engine/ai/decks/flower_power.asm"
|
||||
INCLUDE "engine/ai/decks/strange_psyshock.asm"
|
||||
INCLUDE "engine/ai/decks/wonders_of_science.asm"
|
||||
INCLUDE "engine/ai/decks/fire_charge.asm"
|
||||
INCLUDE "engine/ai/decks/im_ronald.asm"
|
||||
INCLUDE "engine/ai/decks/powerful_ronald.asm"
|
||||
INCLUDE "engine/ai/decks/invincible_ronald.asm"
|
||||
INCLUDE "engine/ai/decks/legendary_ronald.asm"
|
||||
1228
src/engine/ai/pkmn_powers.asm
Normal file
1228
src/engine/ai/pkmn_powers.asm
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1205,7 +1205,7 @@ AIProcessHandTrainerCards: ; 14663 (5:4663)
|
|||
farcall _AIProcessHandTrainerCards
|
||||
ret
|
||||
|
||||
INCLUDE "engine/deck_ai/deck_ai.asm"
|
||||
INCLUDE "engine/ai/deck_ai.asm"
|
||||
|
||||
; return carry if card ID loaded in a is found in hand
|
||||
; and outputs in a the deck index of that card
|
||||
|
|
|
|||
|
|
@ -8258,7 +8258,7 @@ AIDoAction_TakePrize: ; 2bd7 (0:2bd7)
|
|||
jr AIDoAction ; this line is not needed
|
||||
|
||||
; calls the appropriate AI routine to handle action,
|
||||
; depending on the deck ID (see engine/deck_ai/deck_ai.asm)
|
||||
; depending on the deck ID (see engine/ai/deck_ai.asm)
|
||||
; input:
|
||||
; - a = AIACTION_* constant
|
||||
AIDoAction: ; 2bdb (0:2bdb)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ ROMX $07
|
|||
"Credits Sequence"
|
||||
"Booster Packs"
|
||||
ROMX $08
|
||||
"Bank 8"
|
||||
"AI Logic"
|
||||
ROMX $0b
|
||||
"Effect Functions"
|
||||
ROMX $0c
|
||||
|
|
|
|||
|
|
@ -31,8 +31,10 @@ INCLUDE "data/sequences/credits_sequence.asm"
|
|||
SECTION "Booster Packs", ROMX
|
||||
INCLUDE "engine/booster_packs.asm"
|
||||
|
||||
SECTION "Bank 8", ROMX
|
||||
INCLUDE "engine/bank08.asm"
|
||||
SECTION "AI Logic", ROMX
|
||||
INCLUDE "engine/ai/trainer_cards.asm"
|
||||
INCLUDE "engine/ai/pkmn_powers.asm"
|
||||
INCLUDE "engine/ai/common.asm"
|
||||
|
||||
SECTION "Effect Functions", ROMX
|
||||
INCLUDE "engine/effect_functions.asm"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user