diff options
Diffstat (limited to 'battle/ai')
-rw-r--r-- | battle/ai/items.asm | 882 | ||||
-rwxr-xr-x | battle/ai/move.asm | 221 | ||||
-rwxr-xr-x | battle/ai/redundant.asm | 198 | ||||
-rw-r--r-- | battle/ai/scoring.asm | 3598 | ||||
-rwxr-xr-x | battle/ai/switch.asm | 672 |
5 files changed, 0 insertions, 5571 deletions
diff --git a/battle/ai/items.asm b/battle/ai/items.asm deleted file mode 100644 index 09595077a..000000000 --- a/battle/ai/items.asm +++ /dev/null @@ -1,882 +0,0 @@ -AI_SwitchOrTryItem: ; 38000 - and a - - ld a, [wBattleMode] - dec a - ret z - - ld a, [wLinkMode] - and a - ret nz - - farcall CheckEnemyLockedIn - ret nz - - ld a, [PlayerSubStatus5] - bit SUBSTATUS_CANT_RUN, a - jr nz, DontSwitch - - ld a, [wEnemyWrapCount] - and a - jr nz, DontSwitch - - ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH - ld a, [InBattleTowerBattle] ; Load always the first TrainerClass for BattleTower-Trainers - and a - jr nz, .ok - - ld a, [TrainerClass] - dec a - ld bc, NUM_TRAINER_ATTRIBUTES - call AddNTimes -.ok - bit SWITCH_OFTEN_F, [hl] - jp nz, SwitchOften - bit SWITCH_RARELY_F, [hl] - jp nz, SwitchRarely - bit SWITCH_SOMETIMES_F, [hl] - jp nz, SwitchSometimes - ; fallthrough - -DontSwitch: ; 38041 - call AI_TryItem - ret -; 38045 - -SwitchOften: ; 38045 - callfar CheckAbleToSwitch - ld a, [wEnemySwitchMonParam] - and $f0 - jp z, DontSwitch - - cp $10 - jr nz, .not_10 - call Random - cp 1 + 50 percent - jr c, .switch - jp DontSwitch -.not_10 - - cp $20 - jr nz, .not_20 - call Random - cp -1 + 79 percent - jr c, .switch - jp DontSwitch -.not_20 - - ; $30 - call Random - cp 4 percent - jp c, DontSwitch - -.switch - ld a, [wEnemySwitchMonParam] - and $f - inc a - ; In register 'a' is the number (1-6) of the Pkmn to switch to - ld [wEnemySwitchMonIndex], a - jp AI_TrySwitch -; 38083 - -SwitchRarely: ; 38083 - callfar CheckAbleToSwitch - ld a, [wEnemySwitchMonParam] - and $f0 - jp z, DontSwitch - - cp $10 - jr nz, .not_10 - call Random - cp 8 percent - jr c, .switch - jp DontSwitch -.not_10 - - cp $20 - jr nz, .not_20 - call Random - cp 12 percent - jr c, .switch - jp DontSwitch -.not_20 - - ; $30 - call Random - cp -1 + 79 percent - jp c, DontSwitch - -.switch - ld a, [wEnemySwitchMonParam] - and $f - inc a - ld [wEnemySwitchMonIndex], a - jp AI_TrySwitch -; 380c1 - -SwitchSometimes: ; 380c1 - callfar CheckAbleToSwitch - ld a, [wEnemySwitchMonParam] - and $f0 - jp z, DontSwitch - - cp $10 - jr nz, .not_10 - call Random - cp -1 + 20 percent - jr c, .switch - jp DontSwitch -.not_10 - - cp $20 - jr nz, .not_20 - call Random - cp 1 + 50 percent - jr c, .switch - jp DontSwitch -.not_20 - - ; $30 - call Random - cp -1 + 20 percent - jp c, DontSwitch - -.switch - ld a, [wEnemySwitchMonParam] - and $f - inc a - ld [wEnemySwitchMonIndex], a - jp AI_TrySwitch -; 380ff - - -CheckSubstatusCantRun: ; 380ff - ld a, [EnemySubStatus5] - bit SUBSTATUS_CANT_RUN, a - ret -; 38105 - - -AI_TryItem: ; 38105 - ; items are not allowed in the BattleTower - ld a, [InBattleTowerBattle] - and a - ret nz - - ld a, [wEnemyTrainerItem1] - ld b, a - ld a, [wEnemyTrainerItem2] - or b - ret z - - call .IsHighestLevel - ret nc - - ld a, [TrainerClass] - dec a - ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH - ld bc, NUM_TRAINER_ATTRIBUTES - call AddNTimes - ld b, h - ld c, l - ld hl, AI_Items - ld de, wEnemyTrainerItem1 -.loop - ld a, [hl] - and a - inc a - ret z - - ld a, [de] - cp [hl] - jr z, .has_item - inc de - ld a, [de] - cp [hl] - jr z, .has_item - - dec de - inc hl - inc hl - inc hl - jr .loop - -.has_item - inc hl - - push hl - push de - ld de, .callback - push de - ld a, [hli] - ld h, [hl] - ld l, a - jp hl -.callback - pop de - pop hl - - inc hl - inc hl - jr c, .loop - -.used_item - xor a - ld [de], a - inc a - ld [wEnemyGoesFirst], a - - ld hl, EnemySubStatus3 - res SUBSTATUS_BIDE, [hl] - - xor a - ld [EnemyFuryCutterCount], a - ld [EnemyProtectCount], a - ld [wEnemyRageCounter], a - - ld hl, EnemySubStatus4 - res SUBSTATUS_RAGE, [hl] - - xor a - ld [LastEnemyCounterMove], a - - scf - ret - - -.IsHighestLevel: ; 38170 - ld a, [OTPartyCount] - ld d, a - ld e, 0 - ld hl, OTPartyMon1Level - ld bc, PARTYMON_STRUCT_LENGTH -.next - ld a, [hl] - cp e - jr c, .ok - ld e, a -.ok - add hl, bc - dec d - jr nz, .next - - ld a, [CurOTMon] - ld hl, OTPartyMon1Level - call AddNTimes - ld a, [hl] - cp e - jr nc, .yes - -.no - and a - ret - -.yes - scf - ret -; 38196 - - -AI_Items: ; 39196 - dbw FULL_RESTORE, .FullRestore - dbw MAX_POTION, .MaxPotion - dbw HYPER_POTION, .HyperPotion - dbw SUPER_POTION, .SuperPotion - dbw POTION, .Potion - dbw X_ACCURACY, .XAccuracy - dbw FULL_HEAL, .FullHeal - dbw GUARD_SPEC, .GuardSpec - dbw DIRE_HIT, .DireHit - dbw X_ATTACK, .XAttack - dbw X_DEFEND, .XDefend - dbw X_SPEED, .XSpeed - dbw X_SPECIAL, .XSpecial - db $ff -; 381be - -.FullHeal: ; 381be - call .Status - jp c, .DontUse - call EnemyUsedFullHeal - jp .Use -; 381ca - -.Status: ; 381ca (e:41ca) - ld a, [EnemyMonStatus] - and a - jp z, .DontUse - - ld a, [bc] - bit CONTEXT_USE_F, a - jr nz, .StatusCheckContext - ld a, [bc] - bit ALWAYS_USE_F, a - jp nz, .Use - call Random - cp -1 + 20 percent - jp c, .Use - jp .DontUse - -.StatusCheckContext: - ld a, [EnemySubStatus5] - bit SUBSTATUS_TOXIC, a - jr z, .FailToxicCheck - ld a, [EnemyToxicCount] - cp 4 - jr c, .FailToxicCheck - call Random - cp 1 + 50 percent - jp c, .Use -.FailToxicCheck: - ld a, [EnemyMonStatus] - and 1 << FRZ | SLP - jp z, .DontUse - jp .Use -; 38208 - -.FullRestore: ; 38208 - call .HealItem - jp nc, .UseFullRestore - ld a, [bc] - bit CONTEXT_USE_F, a - jp z, .DontUse - call .Status - jp c, .DontUse - -.UseFullRestore: - call EnemyUsedFullRestore - jp .Use -; 38220 - -.MaxPotion: ; 38220 - call .HealItem - jp c, .DontUse - call EnemyUsedMaxPotion - jp .Use - -.HealItem: ; 3822c (e:422c) - ld a, [bc] - bit CONTEXT_USE_F, a - jr nz, .CheckHalfOrQuarterHP - callfar AICheckEnemyHalfHP - jp c, .DontUse - ld a, [bc] - bit UNKNOWN_USE_F, a - jp nz, .CheckQuarterHP - callfar AICheckEnemyQuarterHP - jp nc, .UseHealItem - call Random - cp 1 + 50 percent - jp c, .UseHealItem - jp .DontUse - -.CheckQuarterHP: ; 38254 (e:4254) - callfar AICheckEnemyQuarterHP - jp c, .DontUse - call Random - cp -1 + 20 percent - jp c, .DontUse - jr .UseHealItem - -.CheckHalfOrQuarterHP: ; 38267 (e:4267) - callfar AICheckEnemyHalfHP - jp c, .DontUse - callfar AICheckEnemyQuarterHP - jp nc, .UseHealItem - call Random - cp -1 + 20 percent - jp nc, .DontUse - -.UseHealItem: ; 38281 (e:4281) - jp .Use -; 38284 - -.HyperPotion: ; 38284 - call .HealItem - jp c, .DontUse - ld b, 200 - call EnemyUsedHyperPotion - jp .Use -; 38292 (e:4292) - -.SuperPotion: ; 38292 - call .HealItem - jp c, .DontUse - ld b, 50 - call EnemyUsedSuperPotion - jp .Use -; 382a0 - -.Potion: ; 382a0 - call .HealItem - jp c, .DontUse - ld b, 20 - call EnemyUsedPotion - jp .Use -; 382ae - -.asm_382ae ; This appears to be unused - callfar AICheckEnemyMaxHP - jr c, .dont_use - push bc - ld de, EnemyMonMaxHP + 1 - ld hl, EnemyMonHP + 1 - ld a, [de] - sub [hl] - jr z, .check_40_percent - dec hl - dec de - ld c, a - sbc [hl] - and a - jr nz, .check_40_percent - ld a, c - cp b - jp c, .check_50_percent - callfar AICheckEnemyQuarterHP - jr c, .check_40_percent - -.check_50_percent - pop bc - ld a, [bc] - bit UNKNOWN_USE_F, a - jp z, .Use - call Random - cp 1 + 50 percent - jp c, .Use - -.dont_use - jp .DontUse - -.check_40_percent - pop bc - ld a, [bc] - bit UNKNOWN_USE_F, a - jp z, .DontUse - call Random - cp 1 + 39 percent - jp c, .Use - jp .DontUse -; 382f9 - -.XAccuracy: ; 382f9 - call .XItem - jp c, .DontUse - call EnemyUsedXAccuracy - jp .Use -; 38305 - -.GuardSpec: ; 38305 - call .XItem - jp c, .DontUse - call EnemyUsedGuardSpec - jp .Use -; 38311 - -.DireHit: ; 38311 - call .XItem - jp c, .DontUse - call EnemyUsedDireHit - jp .Use -; 3831d (e:431d) - -.XAttack: ; 3831d - call .XItem - jp c, .DontUse - call EnemyUsedXAttack - jp .Use -; 38329 - -.XDefend: ; 38329 - call .XItem - jp c, .DontUse - call EnemyUsedXDefend - jp .Use -; 38335 - -.XSpeed: ; 38335 - call .XItem - jp c, .DontUse - call EnemyUsedXSpeed - jp .Use -; 38341 - -.XSpecial: ; 38341 - call .XItem - jp c, .DontUse - call EnemyUsedXSpecial - jp .Use -; 3834d - -.XItem: ; 3834d (e:434d) - ld a, [EnemyTurnsTaken] - and a - jr nz, .notfirstturnout - ld a, [bc] - bit ALWAYS_USE_F, a - jp nz, .Use - call Random - cp 1 + 50 percent - jp c, .DontUse - ld a, [bc] - bit CONTEXT_USE_F, a - jp nz, .Use - call Random - cp 1 + 50 percent - jp c, .DontUse - jp .Use -.notfirstturnout - ld a, [bc] - bit ALWAYS_USE_F, a - jp z, .DontUse - call Random - cp -1 + 20 percent - jp nc, .DontUse - jp .Use - -.DontUse: - scf - ret - -.Use: - and a - ret - - -AIUpdateHUD: ; 38387 - call UpdateEnemyMonInParty - farcall UpdateEnemyHUD - ld a, $1 - ld [hBGMapMode], a - ld hl, wEnemyItemState - dec [hl] - scf - ret -; 3839a - -AIUsedItemSound: ; 3839a - push de - ld de, SFX_FULL_HEAL - call PlaySFX - pop de - ret -; 383a3 - - -EnemyUsedFullHeal: ; 383a3 (e:43a3) - call AIUsedItemSound - call AI_HealStatus - ld a, FULL_HEAL - jp PrintText_UsedItemOn_AND_AIUpdateHUD - -EnemyUsedMaxPotion: ; 383ae (e:43ae) - ld a, MAX_POTION - ld [CurEnemyItem], a - jr FullRestoreContinue - -EnemyUsedFullRestore: ; 383b5 (e:43b5) - call AI_HealStatus - ld a, FULL_RESTORE - ld [CurEnemyItem], a - ld hl, EnemySubStatus3 - res SUBSTATUS_CONFUSED, [hl] - xor a - ld [EnemyConfuseCount], a - -FullRestoreContinue: ; 383c6 - ld de, wCurHPAnimOldHP - ld hl, EnemyMonHP + 1 - ld a, [hld] - ld [de], a - inc de - ld a, [hl] - ld [de], a - inc de - ld hl, EnemyMonMaxHP + 1 - ld a, [hld] - ld [de], a - inc de - ld [wCurHPAnimMaxHP], a - ld [EnemyMonHP + 1], a - ld a, [hl] - ld [de], a - ld [wCurHPAnimMaxHP + 1], a - ld [EnemyMonHP], a - jr EnemyPotionFinish -; 383e8 (e:43e8) - -EnemyUsedPotion: ; 383e8 - ld a, POTION - ld b, 20 - jr EnemyPotionContinue - -EnemyUsedSuperPotion: ; 383ee - ld a, SUPER_POTION - ld b, 50 - jr EnemyPotionContinue - -EnemyUsedHyperPotion: ; 383f4 (e:43f4) - ld a, HYPER_POTION - ld b, 200 - -EnemyPotionContinue: ; 383f8 - ld [CurEnemyItem], a - ld hl, EnemyMonHP + 1 - ld a, [hl] - ld [wCurHPAnimOldHP], a - add b - ld [hld], a - ld [wCurHPAnimNewHP], a - ld a, [hl] - ld [wCurHPAnimOldHP + 1], a - ld [wCurHPAnimNewHP + 1], a - jr nc, .ok - inc a - ld [hl], a - ld [wCurHPAnimNewHP + 1], a -.ok - inc hl - ld a, [hld] - ld b, a - ld de, EnemyMonMaxHP + 1 - ld a, [de] - dec de - ld [wCurHPAnimMaxHP], a - sub b - ld a, [hli] - ld b, a - ld a, [de] - ld [wCurHPAnimMaxHP + 1], a - sbc b - jr nc, EnemyPotionFinish - inc de - ld a, [de] - dec de - ld [hld], a - ld [wCurHPAnimNewHP], a - ld a, [de] - ld [hl], a - ld [wCurHPAnimNewHP + 1], a - -EnemyPotionFinish: ; 38436 - call PrintText_UsedItemOn - hlcoord 2, 2 - xor a - ld [wWhichHPBar], a - call AIUsedItemSound - predef AnimateHPBar - jp AIUpdateHUD - - -AI_TrySwitch: ; 3844b -; Determine whether the AI can switch based on how many Pokemon are still alive. -; If it can switch, it will. - ld a, [OTPartyCount] - ld c, a - ld hl, OTPartyMon1HP - ld d, 0 -.SwitchLoop: - ld a, [hli] - ld b, a - ld a, [hld] - or b - jr z, .fainted - inc d -.fainted - push bc - ld bc, PARTYMON_STRUCT_LENGTH - add hl, bc - pop bc - dec c - jr nz, .SwitchLoop - - ld a, d - cp 2 - jp nc, AI_Switch - and a - ret -; 3846c - -AI_Switch: ; 3846c - ld a, $1 - ld [wEnemyIsSwitching], a - ld [wEnemyGoesFirst], a - ld hl, EnemySubStatus4 - res SUBSTATUS_RAGE, [hl] - xor a - ld [hBattleTurn], a - callfar PursuitSwitch - - push af - ld a, [CurOTMon] - ld hl, OTPartyMon1Status - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld d, h - ld e, l - ld hl, EnemyMonStatus - ld bc, MON_MAXHP - MON_STATUS - call CopyBytes - pop af - - jr c, .skiptext - ld hl, TextJump_EnemyWithdrew - call PrintText - -.skiptext - ld a, 1 - ld [wBattleHasJustStarted], a - callfar NewEnemyMonStatus - callfar ResetEnemyStatLevels - ld hl, PlayerSubStatus1 - res SUBSTATUS_IN_LOVE, [hl] - farcall EnemySwitch - farcall ResetBattleParticipants - xor a - ld [wBattleHasJustStarted], a - ld a, [wLinkMode] - and a - ret nz - scf - ret -; 384d0 - -TextJump_EnemyWithdrew: ; 384d0 - text_jump Text_EnemyWithdrew - db "@" -; 384d5 - -Function384d5: ; This appears to be unused - call AIUsedItemSound - call AI_HealStatus - ld a, FULL_HEAL_RED ; X_SPEED - jp PrintText_UsedItemOn_AND_AIUpdateHUD -; 384e0 - -AI_HealStatus: ; 384e0 - ld a, [CurOTMon] - ld hl, OTPartyMon1Status - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - xor a - ld [hl], a - ld [EnemyMonStatus], a - ; Bug: this should reset SUBSTATUS_NIGHTMARE too - ; Uncomment the lines below to fix - ; ld hl, EnemySubStatus1 - ; res SUBSTATUS_NIGHTMARE, [hl] - ld hl, EnemySubStatus5 - res SUBSTATUS_TOXIC, [hl] - ret -; 384f7 - -EnemyUsedXAccuracy: ; 384f7 - call AIUsedItemSound - ld hl, EnemySubStatus4 - set SUBSTATUS_X_ACCURACY, [hl] - ld a, X_ACCURACY - jp PrintText_UsedItemOn_AND_AIUpdateHUD -; 38504 - -EnemyUsedGuardSpec: ; 38504 - call AIUsedItemSound - ld hl, EnemySubStatus4 - set SUBSTATUS_MIST, [hl] - ld a, GUARD_SPEC - jp PrintText_UsedItemOn_AND_AIUpdateHUD -; 38511 - -EnemyUsedDireHit: ; 38511 - call AIUsedItemSound - ld hl, EnemySubStatus4 - set SUBSTATUS_FOCUS_ENERGY, [hl] - ld a, DIRE_HIT - jp PrintText_UsedItemOn_AND_AIUpdateHUD -; 3851e - -Function3851e: ; This appears to be unused - ld [hDivisor], a - ld hl, EnemyMonMaxHP - ld a, [hli] - ld [hDividend], a - ld a, [hl] - ld [hDividend + 1], a - ld b, 2 - call Divide - ld a, [hQuotient + 2] - ld c, a - ld a, [hQuotient + 1] - ld b, a - ld hl, EnemyMonHP + 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 -; 38541 - -EnemyUsedXAttack: ; 38541 - ld b, ATTACK - ld a, X_ATTACK - jr EnemyUsedXItem -; 38547 - -EnemyUsedXDefend: ; 38547 - ld b, DEFENSE - ld a, X_DEFEND - jr EnemyUsedXItem -; 3854d - -EnemyUsedXSpeed: ; 3854d - ld b, SPEED - ld a, X_SPEED - jr EnemyUsedXItem -; 38553 - -EnemyUsedXSpecial: ; 38553 - ld b, SP_ATTACK - ld a, X_SPECIAL - - -; Parameter -; a = ITEM_CONSTANT -; b = BATTLE_CONSTANT (ATTACK, DEFENSE, SPEED, SP_ATTACK, SP_DEFENSE, ACCURACY, EVASION) -EnemyUsedXItem: - ld [CurEnemyItem], a - push bc - call PrintText_UsedItemOn - pop bc - farcall CheckIfStatCanBeRaised - jp AIUpdateHUD -; 38568 - - -; Parameter -; a = ITEM_CONSTANT -PrintText_UsedItemOn_AND_AIUpdateHUD: ; 38568 - ld [CurEnemyItem], a - call PrintText_UsedItemOn - jp AIUpdateHUD -; 38571 - -PrintText_UsedItemOn: ; 38571 - ld a, [CurEnemyItem] - ld [wd265], a - call GetItemName - ld hl, StringBuffer1 - ld de, wMonOrItemNameBuffer - ld bc, ITEM_NAME_LENGTH - call CopyBytes - ld hl, TextJump_EnemyUsedOn - jp PrintText -; 3858c - -TextJump_EnemyUsedOn: ; 3858c - text_jump Text_EnemyUsedOn - db "@" -; 38591 diff --git a/battle/ai/move.asm b/battle/ai/move.asm deleted file mode 100755 index 11586c0da..000000000 --- a/battle/ai/move.asm +++ /dev/null @@ -1,221 +0,0 @@ -AIChooseMove: ; 440ce -; Score each move in EnemyMonMoves starting from Buffer1. Lower is better. -; Pick the move with the lowest score. - -; Wildmons attack at random. - ld a, [wBattleMode] - dec a - ret z - - ld a, [wLinkMode] - and a - ret nz - -; No use picking a move if there's no choice. - farcall CheckEnemyLockedIn - ret nz - - -; The default score is 20. Unusable moves are given a score of 80. - ld a, 20 - ld hl, Buffer1 - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - -; Don't pick disabled moves. - ld a, [EnemyDisabledMove] - and a - jr z, .CheckPP - - ld hl, EnemyMonMoves - ld c, 0 -.CheckDisabledMove: - cp [hl] - jr z, .ScoreDisabledMove - inc c - inc hl - jr .CheckDisabledMove -.ScoreDisabledMove: - ld hl, Buffer1 - ld b, 0 - add hl, bc - ld [hl], 80 - -; Don't pick moves with 0 PP. -.CheckPP: - ld hl, Buffer1 - 1 - ld de, EnemyMonPP - ld b, 0 -.CheckMovePP: - inc b - ld a, b - cp EnemyMonMovesEnd - EnemyMonMoves + 1 - jr z, .ApplyLayers - inc hl - ld a, [de] - inc de - and $3f - jr nz, .CheckMovePP - ld [hl], 80 - jr .CheckMovePP - - -; Apply AI scoring layers depending on the trainer class. -.ApplyLayers: - ld hl, TrainerClassAttributes + TRNATTR_AI_MOVE_WEIGHTS - - ; If we have a battle in BattleTower just load the Attributes of the first TrainerClass (Falkner) - ; so we have always the same AI, regardless of the loaded class of trainer - ld a, [InBattleTowerBattle] - bit 0, a - jr nz, .battle_tower_skip - - ld a, [TrainerClass] - dec a - ld bc, 7 ; Trainer2AI - Trainer1AI - call AddNTimes - -.battle_tower_skip - lb bc, CHECK_FLAG, 0 - push bc - push hl - -.CheckLayer: - pop hl - pop bc - - ld a, c - cp 16 ; up to 16 scoring layers - jr z, .DecrementScores - - push bc - ld d, BANK(TrainerClassAttributes) - predef FlagPredef - ld d, c - pop bc - - inc c - push bc - push hl - - ld a, d - and a - jr z, .CheckLayer - - ld hl, AIScoringPointers - dec c - ld b, 0 - add hl, bc - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld a, BANK(AIScoring) - call FarCall_hl - - jr .CheckLayer - -; Decrement the scores of all moves one by one until one reaches 0. -.DecrementScores: - ld hl, Buffer1 - ld de, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves - -.DecrementNextScore: - ; If the enemy has no moves, this will infinite. - ld a, [de] - inc de - and a - jr z, .DecrementScores - - ; We are done whenever a score reaches 0 - dec [hl] - jr z, .PickLowestScoreMoves - - ; If we just decremented the fourth move's score, go back to the first move - inc hl - dec c - jr z, .DecrementScores - - jr .DecrementNextScore - -; In order to avoid bias towards the moves located first in memory, increment the scores -; that were decremented one more time than the rest (in case there was a tie). -; This means that the minimum score will be 1. -.PickLowestScoreMoves: - ld a, c - -.move_loop - inc [hl] - dec hl - inc a - cp NUM_MOVES + 1 - jr nz, .move_loop - - ld hl, Buffer1 - ld de, EnemyMonMoves - ld c, NUM_MOVES - -; Give a score of 0 to a blank move -.loop2 - ld a, [de] - and a - jr nz, .skip_load - ld [hl], a - -; Disregard the move if its score is not 1 -.skip_load - ld a, [hl] - dec a - jr z, .keep - xor a - ld [hli], a - jr .after_toss - -.keep - ld a, [de] - ld [hli], a -.after_toss - inc de - dec c - jr nz, .loop2 - -; Randomly choose one of the moves with a score of 1 -.ChooseMove: - ld hl, Buffer1 - call Random - and 3 - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - and a - jr z, .ChooseMove - - ld [CurEnemyMove], a - ld a, c - ld [CurEnemyMoveNum], a - ret -; 441af - - -AIScoringPointers: ; 441af - dw AI_Basic - dw AI_Setup - dw AI_Types - dw AI_Offensive - dw AI_Smart - dw AI_Opportunist - dw AI_Aggressive - dw AI_Cautious - dw AI_Status - dw AI_Risky - dw AI_None - dw AI_None - dw AI_None - dw AI_None - dw AI_None - dw AI_None -; 441cf diff --git a/battle/ai/redundant.asm b/battle/ai/redundant.asm deleted file mode 100755 index 2e8f7c6df..000000000 --- a/battle/ai/redundant.asm +++ /dev/null @@ -1,198 +0,0 @@ -AI_Redundant: ; 2c41a -; Check if move effect c will fail because it's already been used. -; Return z if the move is a good choice. -; Return nz if the move is a bad choice. - ld a, c - ld de, 3 - ld hl, .Moves - call IsInArray - jp nc, .NotRedundant - inc hl - ld a, [hli] - ld h, [hl] - ld l, a - jp hl - -.Moves: ; 2c42c - dbw EFFECT_DREAM_EATER, .DreamEater - dbw EFFECT_HEAL, .Heal - dbw EFFECT_LIGHT_SCREEN, .LightScreen - dbw EFFECT_MIST, .Mist - dbw EFFECT_FOCUS_ENERGY, .FocusEnergy - dbw EFFECT_CONFUSE, .Confuse - dbw EFFECT_TRANSFORM, .Transform - dbw EFFECT_REFLECT, .Reflect - dbw EFFECT_SUBSTITUTE, .Substitute - dbw EFFECT_LEECH_SEED, .LeechSeed - dbw EFFECT_DISABLE, .Disable - dbw EFFECT_ENCORE, .Encore - dbw EFFECT_SNORE, .Snore - dbw EFFECT_SLEEP_TALK, .SleepTalk - dbw EFFECT_MEAN_LOOK, .MeanLook - dbw EFFECT_NIGHTMARE, .Nightmare - dbw EFFECT_SPIKES, .Spikes - dbw EFFECT_FORESIGHT, .Foresight - dbw EFFECT_PERISH_SONG, .PerishSong - dbw EFFECT_SANDSTORM, .Sandstorm - dbw EFFECT_ATTRACT, .Attract - dbw EFFECT_SAFEGUARD, .Safeguard - dbw EFFECT_RAIN_DANCE, .RainDance - dbw EFFECT_SUNNY_DAY, .SunnyDay - dbw EFFECT_TELEPORT, .Teleport - dbw EFFECT_MORNING_SUN, .MorningSun - dbw EFFECT_SYNTHESIS, .Synthesis - dbw EFFECT_MOONLIGHT, .Moonlight - dbw EFFECT_SWAGGER, .Swagger - dbw EFFECT_FUTURE_SIGHT, .FutureSight - db -1 - -.LightScreen: ; 2c487 - ld a, [EnemyScreens] - bit SCREENS_LIGHT_SCREEN, a - ret - -.Mist: ; 2c48d - ld a, [EnemySubStatus4] - bit SUBSTATUS_MIST, a - ret - -.FocusEnergy: ; 2c493 - ld a, [EnemySubStatus4] - bit SUBSTATUS_FOCUS_ENERGY, a - ret - -.Confuse: ; 2c499 - ld a, [PlayerSubStatus3] - bit SUBSTATUS_CONFUSED, a - ret nz - ld a, [PlayerScreens] - bit SCREENS_SAFEGUARD, a - ret - -.Transform: ; 2c4a5 - ld a, [EnemySubStatus5] - bit SUBSTATUS_TRANSFORMED, a - ret - -.Reflect: ; 2c4ab - ld a, [EnemyScreens] - bit SCREENS_REFLECT, a - ret - -.Substitute: ; 2c4b1 - ld a, [EnemySubStatus4] - bit SUBSTATUS_SUBSTITUTE, a - ret - -.LeechSeed: ; 2c4b7 - ld a, [PlayerSubStatus4] - bit SUBSTATUS_LEECH_SEED, a - ret - -.Disable: ; 2c4bd - ld a, [PlayerDisableCount] - and a - ret - -.Encore: ; 2c4c2 - ld a, [PlayerSubStatus5] - bit SUBSTATUS_ENCORED, a - ret - -.Snore: -.SleepTalk: ; 2c4c8 - ld a, [EnemyMonStatus] - and SLP - jr z, .Redundant - jr .NotRedundant - -.MeanLook: ; 2c4d1 - ld a, [EnemySubStatus5] - bit SUBSTATUS_CANT_RUN, a - ret - -.Nightmare: ; 2c4d7 - ld a, [BattleMonStatus] - and a - jr z, .Redundant - ld a, [PlayerSubStatus1] - bit SUBSTATUS_NIGHTMARE, a - ret - -.Spikes: ; 2c4e3 - ld a, [PlayerScreens] - bit SCREENS_SPIKES, a - ret - -.Foresight: ; 2c4e9 - ld a, [PlayerSubStatus1] - bit SUBSTATUS_IDENTIFIED, a - ret - -.PerishSong: ; 2c4ef - ld a, [PlayerSubStatus1] - bit SUBSTATUS_PERISH, a - ret - -.Sandstorm: ; 2c4f5 - ld a, [Weather] - cp WEATHER_SANDSTORM - jr z, .Redundant - jr .NotRedundant - -.Attract: ; 2c4fe - farcall CheckOppositeGender - jr c, .Redundant - ld a, [PlayerSubStatus1] - bit SUBSTATUS_IN_LOVE, a - ret - -.Safeguard: ; 2c50c - ld a, [EnemyScreens] - bit SCREENS_SAFEGUARD, a - ret - -.RainDance: ; 2c512 - ld a, [Weather] - cp WEATHER_RAIN - jr z, .Redundant - jr .NotRedundant - -.SunnyDay: ; 2c51b - ld a, [Weather] - cp WEATHER_SUN - jr z, .Redundant - jr .NotRedundant - -.DreamEater: ; 2c524 - ld a, [BattleMonStatus] - and SLP - jr z, .Redundant - jr .NotRedundant - -.Swagger: ; 2c52d - ld a, [PlayerSubStatus3] - bit SUBSTATUS_CONFUSED, a - ret - -.FutureSight: ; 2c533 - ld a, [EnemyScreens] - bit 5, a - ret - -.Heal: -.MorningSun: -.Synthesis: -.Moonlight: ; 2c539 - farcall AICheckEnemyMaxHP - jr nc, .NotRedundant - -.Teleport: -.Redundant: ; 2c541 - ld a, 1 - and a - ret - -.NotRedundant: ; 2c545 - xor a - ret diff --git a/battle/ai/scoring.asm b/battle/ai/scoring.asm deleted file mode 100644 index 44194d6f7..000000000 --- a/battle/ai/scoring.asm +++ /dev/null @@ -1,3598 +0,0 @@ -AIScoring: ; 38591 - -AI_Basic: ; 38591 -; Don't do anything redundant: -; -Using status-only moves if the player can't be statused -; -Using moves that fail if they've already been used - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - inc hl - ld a, [de] - and a - ret z - - inc de - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - ld c, a - -; Dismiss moves with special effects if they are -; useless or not a good choice right now. -; For example, healing moves, weather moves, Dream Eater... - push hl - push de - push bc - farcall AI_Redundant - pop bc - pop de - pop hl - jr nz, .discourage - -; Dismiss status-only moves if the player can't be statused. - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - push hl - push de - push bc - ld hl, .statusonlyeffects - ld de, 1 - call IsInArray - - pop bc - pop de - pop hl - jr nc, .checkmove - - ld a, [BattleMonStatus] - and a - jr nz, .discourage - -; Dismiss Safeguard if it's already active. - ld a, [PlayerScreens] - bit SCREENS_SAFEGUARD, a - jr z, .checkmove - -.discourage - call AIDiscourageMove - jr .checkmove -; 385db - -.statusonlyeffects - db EFFECT_SLEEP - db EFFECT_TOXIC - db EFFECT_POISON - db EFFECT_PARALYZE - db $ff -; 385e0 - - - -AI_Setup: ; 385e0 -; Use stat-modifying moves on turn 1. - -; 50% chance to greatly encourage stat-up moves during the first turn of enemy's Pokemon. -; 50% chance to greatly encourage stat-down moves during the first turn of player's Pokemon. -; Almost 90% chance to greatly discourage stat-modifying moves otherwise. - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - inc hl - ld a, [de] - and a - ret z - - inc de - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - - cp EFFECT_ATTACK_UP - jr c, .checkmove - cp EFFECT_EVASION_UP + 1 - jr c, .statup - -; cp EFFECT_ATTACK_DOWN - 1 - jr z, .checkmove - cp EFFECT_EVASION_DOWN + 1 - jr c, .statdown - - cp EFFECT_ATTACK_UP_2 - jr c, .checkmove - cp EFFECT_EVASION_UP_2 + 1 - jr c, .statup - -; cp EFFECT_ATTACK_DOWN_2 - 1 - jr z, .checkmove - cp EFFECT_EVASION_DOWN_2 + 1 - jr c, .statdown - - jr .checkmove - -.statup - ld a, [EnemyTurnsTaken] - and a - jr nz, .discourage - - jr .encourage - -.statdown - ld a, [PlayerTurnsTaken] - and a - jr nz, .discourage - -.encourage - call AI_50_50 - jr c, .checkmove - - dec [hl] - dec [hl] - jr .checkmove - -.discourage - call Random - cp 12 percent - jr c, .checkmove - inc [hl] - inc [hl] - jr .checkmove -; 38635 - - - -AI_Types: ; 38635 -; Dismiss any move that the player is immune to. -; Encourage super-effective moves. -; Discourage not very effective moves unless -; all damaging moves are of the same type. - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - inc hl - ld a, [de] - and a - ret z - - inc de - call AIGetEnemyMove - - push hl - push bc - push de - ld a, 1 - ld [hBattleTurn], a - callfar BattleCheckTypeMatchup - pop de - pop bc - pop hl - - ld a, [wd265] - and a - jr z, .immune - cp 10 ; 1.0 - jr z, .checkmove - jr c, .noteffective - -; effective - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .checkmove - dec [hl] - jr .checkmove - -.noteffective -; Discourage this move if there are any moves -; that do damage of a different type. - push hl - push de - push bc - ld a, [wEnemyMoveStruct + MOVE_TYPE] - ld d, a - ld hl, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 - ld c, 0 -.checkmove2 - dec b - jr z, .asm_38693 - - ld a, [hli] - and a - jr z, .asm_38693 - - call AIGetEnemyMove - ld a, [wEnemyMoveStruct + MOVE_TYPE] - cp d - jr z, .checkmove2 - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr nz, .asm_38692 - jr .checkmove2 - -.asm_38692 - ld c, a -.asm_38693 - ld a, c - pop bc - pop de - pop hl - and a - jr z, .checkmove - inc [hl] - jr .checkmove - -.immune - call AIDiscourageMove - jr .checkmove -; 386a2 - - - -AI_Offensive: ; 386a2 -; Greatly discourage non-damaging moves. - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - inc hl - ld a, [de] - and a - ret z - - inc de - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr nz, .checkmove - - inc [hl] - inc [hl] - jr .checkmove -; 386be - - - -AI_Smart: ; 386be -; Context-specific scoring. - - ld hl, Buffer1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - ld a, [de] - inc de - and a - ret z - - push de - push bc - push hl - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - ld hl, .table_386f2 - ld de, 3 - call IsInArray - - inc hl - jr nc, .nextmove - - ld a, [hli] - ld e, a - ld d, [hl] - - pop hl - push hl - - ld bc, .nextmove - push bc - - push de - ret - -.nextmove - pop hl - pop bc - pop de - inc hl - jr .checkmove - -.table_386f2 - dbw EFFECT_SLEEP, AI_Smart_Sleep - dbw EFFECT_LEECH_HIT, AI_Smart_LeechHit - dbw EFFECT_SELFDESTRUCT, AI_Smart_Selfdestruct - dbw EFFECT_DREAM_EATER, AI_Smart_DreamEater - dbw EFFECT_MIRROR_MOVE, AI_Smart_MirrorMove - dbw EFFECT_EVASION_UP, AI_Smart_EvasionUp - dbw EFFECT_ALWAYS_HIT, AI_Smart_AlwaysHit - dbw EFFECT_ACCURACY_DOWN, AI_Smart_AccuracyDown - dbw EFFECT_RESET_STATS, AI_Smart_ResetStats - dbw EFFECT_BIDE, AI_Smart_Bide - dbw EFFECT_FORCE_SWITCH, AI_Smart_ForceSwitch - dbw EFFECT_HEAL, AI_Smart_Heal - dbw EFFECT_TOXIC, AI_Smart_Toxic - dbw EFFECT_LIGHT_SCREEN, AI_Smart_LightScreen - dbw EFFECT_OHKO, AI_Smart_Ohko - dbw EFFECT_RAZOR_WIND, AI_Smart_RazorWind - dbw EFFECT_SUPER_FANG, AI_Smart_SuperFang - dbw EFFECT_TRAP_TARGET, AI_Smart_TrapTarget - dbw EFFECT_UNUSED_2B, AI_Smart_Unused2B - dbw EFFECT_CONFUSE, AI_Smart_Confuse - dbw EFFECT_SP_DEF_UP_2, AI_Smart_SpDefenseUp2 - dbw EFFECT_REFLECT, AI_Smart_Reflect - dbw EFFECT_PARALYZE, AI_Smart_Paralyze - dbw EFFECT_SPEED_DOWN_HIT, AI_Smart_SpeedDownHit - dbw EFFECT_SUBSTITUTE, AI_Smart_Substitute - dbw EFFECT_HYPER_BEAM, AI_Smart_HyperBeam - dbw EFFECT_RAGE, AI_Smart_Rage - dbw EFFECT_MIMIC, AI_Smart_Mimic - dbw EFFECT_LEECH_SEED, AI_Smart_LeechSeed - dbw EFFECT_DISABLE, AI_Smart_Disable - dbw EFFECT_COUNTER, AI_Smart_Counter - dbw EFFECT_ENCORE, AI_Smart_Encore - dbw EFFECT_PAIN_SPLIT, AI_Smart_PainSplit - dbw EFFECT_SNORE, AI_Smart_Snore - dbw EFFECT_CONVERSION2, AI_Smart_Conversion2 - dbw EFFECT_LOCK_ON, AI_Smart_LockOn - dbw EFFECT_DEFROST_OPPONENT, AI_Smart_DefrostOpponent - dbw EFFECT_SLEEP_TALK, AI_Smart_SleepTalk - dbw EFFECT_DESTINY_BOND, AI_Smart_DestinyBond - dbw EFFECT_REVERSAL, AI_Smart_Reversal - dbw EFFECT_SPITE, AI_Smart_Spite - dbw EFFECT_HEAL_BELL, AI_Smart_HealBell - dbw EFFECT_PRIORITY_HIT, AI_Smart_PriorityHit - dbw EFFECT_THIEF, AI_Smart_Thief - dbw EFFECT_MEAN_LOOK, AI_Smart_MeanLook - dbw EFFECT_NIGHTMARE, AI_Smart_Nightmare - dbw EFFECT_FLAME_WHEEL, AI_Smart_FlameWheel - dbw EFFECT_CURSE, AI_Smart_Curse - dbw EFFECT_PROTECT, AI_Smart_Protect - dbw EFFECT_FORESIGHT, AI_Smart_Foresight - dbw EFFECT_PERISH_SONG, AI_Smart_PerishSong - dbw EFFECT_SANDSTORM, AI_Smart_Sandstorm - dbw EFFECT_ENDURE, AI_Smart_Endure - dbw EFFECT_ROLLOUT, AI_Smart_Rollout - dbw EFFECT_SWAGGER, AI_Smart_Swagger - dbw EFFECT_FURY_CUTTER, AI_Smart_FuryCutter - dbw EFFECT_ATTRACT, AI_Smart_Attract - dbw EFFECT_SAFEGUARD, AI_Smart_Safeguard - dbw EFFECT_MAGNITUDE, AI_Smart_Magnitude - dbw EFFECT_BATON_PASS, AI_Smart_BatonPass - dbw EFFECT_PURSUIT, AI_Smart_Pursuit - dbw EFFECT_RAPID_SPIN, AI_Smart_RapidSpin - dbw EFFECT_MORNING_SUN, AI_Smart_MorningSun - dbw EFFECT_SYNTHESIS, AI_Smart_Synthesis - dbw EFFECT_MOONLIGHT, AI_Smart_Moonlight - dbw EFFECT_HIDDEN_POWER, AI_Smart_HiddenPower - dbw EFFECT_RAIN_DANCE, AI_Smart_RainDance - dbw EFFECT_SUNNY_DAY, AI_Smart_SunnyDay - dbw EFFECT_BELLY_DRUM, AI_Smart_BellyDrum - dbw EFFECT_PSYCH_UP, AI_Smart_PsychUp - dbw EFFECT_MIRROR_COAT, AI_Smart_MirrorCoat - dbw EFFECT_SKULL_BASH, AI_Smart_SkullBash - dbw EFFECT_TWISTER, AI_Smart_Twister - dbw EFFECT_EARTHQUAKE, AI_Smart_Earthquake - dbw EFFECT_FUTURE_SIGHT, AI_Smart_FutureSight - dbw EFFECT_GUST, AI_Smart_Gust - dbw EFFECT_STOMP, AI_Smart_Stomp - dbw EFFECT_SOLARBEAM, AI_Smart_Solarbeam - dbw EFFECT_THUNDER, AI_Smart_Thunder - dbw EFFECT_FLY, AI_Smart_Fly - db $ff -; 387e3 - - -AI_Smart_Sleep: ; 387e3 -; Greatly encourage sleep inducing moves if the enemy has either Dream Eater or Nightmare. -; 50% chance to greatly encourage sleep inducing moves otherwise. - - ld b, EFFECT_DREAM_EATER - call AIHasMoveEffect - jr c, .asm_387f0 - - ld b, EFFECT_NIGHTMARE - call AIHasMoveEffect - ret nc - -.asm_387f0 - call AI_50_50 - ret c - dec [hl] - dec [hl] - ret -; 387f7 - - -AI_Smart_LeechHit: ; 387f7 - push hl - ld a, 1 - ld [hBattleTurn], a - callfar BattleCheckTypeMatchup - pop hl - -; 60% chance to discourage this move if not very effective. - ld a, [wd265] - cp 10 ; 1.0 - jr c, .asm_38815 - -; Do nothing if effectiveness is neutral. - ret z - -; Do nothing if enemy's HP is full. - call AICheckEnemyMaxHP - ret c - -; 80% chance to encourage this move otherwise. - call AI_80_20 - ret c - - dec [hl] - ret - -.asm_38815 - call Random - cp 39 percent + 1 - ret c - - inc [hl] - ret -; 3881d - - -AI_Smart_LockOn: ; 3881d - ld a, [PlayerSubStatus5] - bit SUBSTATUS_LOCK_ON, a - jr nz, .asm_38882 - - push hl - call AICheckEnemyQuarterHP - jr nc, .asm_38877 - - call AICheckEnemyHalfHP - jr c, .asm_38834 - - call AICompareSpeed - jr nc, .asm_38877 - -.asm_38834 - ld a, [PlayerEvaLevel] - cp $a - jr nc, .asm_3887a - cp $8 - jr nc, .asm_38875 - - ld a, [EnemyAccLevel] - cp $5 - jr c, .asm_3887a - cp $7 - jr c, .asm_38875 - - ld hl, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 -.asm_3884f - dec c - jr z, .asm_38877 - - ld a, [hli] - and a - jr z, .asm_38877 - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_ACC] - cp 180 - jr nc, .asm_3884f - - ld a, $1 - ld [hBattleTurn], a - - push hl - push bc - farcall BattleCheckTypeMatchup - ld a, [wd265] - cp $a - pop bc - pop hl - jr c, .asm_3884f - -.asm_38875 - pop hl - ret - -.asm_38877 - pop hl - inc [hl] - ret - -.asm_3887a - pop hl - call AI_50_50 - ret c - - dec [hl] - dec [hl] - ret - -.asm_38882 - push hl - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 - -.asm_3888b - inc hl - dec c - jr z, .asm_388a2 - - ld a, [de] - and a - jr z, .asm_388a2 - - inc de - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_ACC] - cp 180 - jr nc, .asm_3888b - - dec [hl] - dec [hl] - jr .asm_3888b - -.asm_388a2 - pop hl - jp AIDiscourageMove -; 388a6 - - -AI_Smart_Selfdestruct: ; 388a6 -; Selfdestruct, Explosion - -; Unless this is the enemy's last Pokemon... - push hl - farcall FindAliveEnemyMons - pop hl - jr nc, .asm_388b7 - -; ...greatly discourage this move unless this is the player's last Pokemon too. - push hl - call AICheckLastPlayerMon - pop hl - jr nz, .asm_388c6 - -.asm_388b7 -; Greatly discourage this move if enemy's HP is above 50%. - call AICheckEnemyHalfHP - jr c, .asm_388c6 - -; Do nothing if enemy's HP is below 25%. - call AICheckEnemyQuarterHP - ret nc - -; If enemy's HP is between 25% and 50%, -; over 90% chance to greatly discourage this move. - call Random - cp 9 percent - 2 - ret c - -.asm_388c6 - inc [hl] - inc [hl] - inc [hl] - ret -; 388ca - - -AI_Smart_DreamEater: ; 388ca -; 90% chance to greatly encourage this move. -; The AI_Basic layer will make sure that -; Dream Eater is only used against sleeping targets. - call Random - cp 10 percent - ret c - dec [hl] - dec [hl] - dec [hl] - ret -; 388d4 - - -AI_Smart_EvasionUp: ; 388d4 - -; Dismiss this move if enemy's evasion can't raise anymore. - ld a, [EnemyEvaLevel] - cp $d - jp nc, AIDiscourageMove - -; If enemy's HP is full... - call AICheckEnemyMaxHP - jr nc, .asm_388f2 - -; ...greatly encourage this move if player is badly poisoned. - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_388ef - -; ...70% chance to greatly encourage this move if player is not badly poisoned. - call Random - cp 70 percent - jr nc, .asm_38911 - -.asm_388ef - dec [hl] - dec [hl] - ret - -.asm_388f2 - -; Greatly discourage this move if enemy's HP is below 25%. - call AICheckEnemyQuarterHP - jr nc, .asm_3890f - -; If enemy's HP is above 25% but not full, 4% chance to greatly encourage this move. - call Random - cp 4 percent - jr c, .asm_388ef - -; If enemy's HP is between 25% and 50%,... - call AICheckEnemyHalfHP - jr nc, .asm_3890a - -; If enemy's HP is above 50% but not full, 20% chance to greatly encourage this move. - call AI_80_20 - jr c, .asm_388ef - jr .asm_38911 - -.asm_3890a -; ...50% chance to greatly discourage this move. - call AI_50_50 - jr c, .asm_38911 - -.asm_3890f - inc [hl] - inc [hl] - -; 30% chance to end up here if enemy's HP is full and player is not badly poisoned. -; 77% chance to end up here if enemy's HP is above 50% but not full. -; 96% chance to end up here if enemy's HP is between 25% and 50%. -; 100% chance to end up here if enemy's HP is below 25%. -; In other words, we only end up here if the move has not been encouraged or dismissed. -.asm_38911 - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_38938 - - ld a, [PlayerSubStatus4] - bit SUBSTATUS_LEECH_SEED, a - jr nz, .asm_38941 - -; Discourage this move if enemy's evasion level is higher than player's accuracy level. - ld a, [EnemyEvaLevel] - ld b, a - ld a, [PlayerAccLevel] - cp b - jr c, .asm_38936 - -; Greatly encourage this move if the player is in the middle of Fury Cutter or Rollout. - ld a, [PlayerFuryCutterCount] - and a - jr nz, .asm_388ef - - ld a, [PlayerSubStatus1] - bit SUBSTATUS_ROLLOUT, a - jr nz, .asm_388ef - - -.asm_38936 - inc [hl] - ret - -; Player is badly poisoned. -; 70% chance to greatly encourage this move. -; This would counter any previous discouragement. -.asm_38938 - call Random - cp 31 percent + 1 - ret c - dec [hl] - dec [hl] - ret - -; Player is seeded. -; 50% chance to encourage this move. -; This would partly counter any previous discouragement. -.asm_38941 - call AI_50_50 - ret c - - dec [hl] - ret -; 38947 - - -AI_Smart_AlwaysHit: ; 38947 -; 80% chance to greatly encourage this move if either... - -; ...enemy's accuracy level has been lowered three or more stages - ld a, [EnemyAccLevel] - cp $5 - jr c, .asm_38954 - -; ...or player's evasion level has been raised three or more stages. - ld a, [PlayerEvaLevel] - cp $a - ret c - -.asm_38954 - call AI_80_20 - ret c - - dec [hl] - dec [hl] - ret -; 3895b - - -AI_Smart_MirrorMove: ; 3895b - -; If the player did not use any move last turn... - ld a, [LastPlayerCounterMove] - and a - jr nz, .asm_38968 - -; ...do nothing if enemy is slower than player - call AICompareSpeed - ret nc - -; ...or dismiss this move if enemy is faster than player. - jp AIDiscourageMove - -; If the player did use a move last turn... -.asm_38968 - push hl - ld hl, UsefulMoves - ld de, 1 - call IsInArray - pop hl - -; ...do nothing if he didn't use a useful move. - ret nc - -; If he did, 50% chance to encourage this move... - call AI_50_50 - ret c - - dec [hl] - -; ...and 90% chance to encourage this move again if the enemy is faster. - call AICompareSpeed - ret nc - - call Random - cp 10 percent - ret c - - dec [hl] - ret -; 38985 - - -AI_Smart_AccuracyDown: ; 38985 - -; If player's HP is full... - call AICheckPlayerMaxHP - jr nc, .asm_389a0 - -; ...and enemy's HP is above 50%... - call AICheckEnemyHalfHP - jr nc, .asm_389a0 - -; ...greatly encourage this move if player is badly poisoned. - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_3899d - -; ...70% chance to greatly encourage this move if player is not badly poisoned. - call Random - cp 70 percent - jr nc, .asm_389bf - -.asm_3899d - dec [hl] - dec [hl] - ret - -.asm_389a0 - -; Greatly discourage this move if player's HP is below 25%. - call AICheckPlayerQuarterHP - jr nc, .asm_389bd - -; If player's HP is above 25% but not full, 4% chance to greatly encourage this move. - call Random - cp 4 percent - jr c, .asm_3899d - -; If player's HP is between 25% and 50%,... - call AICheckPlayerHalfHP - jr nc, .asm_389b8 - -; If player's HP is above 50% but not full, 20% chance to greatly encourage this move. - call AI_80_20 - jr c, .asm_3899d - jr .asm_389bf - -; ...50% chance to greatly discourage this move. -.asm_389b8 - call AI_50_50 - jr c, .asm_389bf - -.asm_389bd - inc [hl] - inc [hl] - -; We only end up here if the move has not been already encouraged. -.asm_389bf - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_389e6 - - ld a, [PlayerSubStatus4] - bit SUBSTATUS_LEECH_SEED, a - jr nz, .asm_389ef - -; Discourage this move if enemy's evasion level is higher than player's accuracy level. - ld a, [EnemyEvaLevel] - ld b, a - ld a, [PlayerAccLevel] - cp b - jr c, .asm_389e4 - -; Greatly encourage this move if the player is in the middle of Fury Cutter or Rollout. - ld a, [PlayerFuryCutterCount] - and a - jr nz, .asm_3899d - - ld a, [PlayerSubStatus1] - bit SUBSTATUS_ROLLOUT, a - jr nz, .asm_3899d - -.asm_389e4 - inc [hl] - ret - -; Player is badly poisoned. -; 70% chance to greatly encourage this move. -; This would counter any previous discouragement. -.asm_389e6 - call Random - cp 31 percent + 1 - ret c - dec [hl] - dec [hl] - ret - -; Player is seeded. -; 50% chance to encourage this move. -; This would partly counter any previous discouragement. -.asm_389ef - call AI_50_50 - ret c - - dec [hl] - ret -; 389f5 - - -AI_Smart_ResetStats: ; 389f5 - -; 85% chance to encourage this move if any of enemy's stat levels is lower than -2. - push hl - ld hl, EnemyAtkLevel - ld c, $8 -.asm_389fb - dec c - jr z, .asm_38a05 - ld a, [hli] - cp $5 - jr c, .asm_38a12 - jr .asm_389fb - -; 85% chance to encourage this move if any of player's stat levels is higher than +2. -.asm_38a05 - ld hl, PlayerAtkLevel - ld c, $8 -.asm_38a0a - dec c - jr z, .asm_38a1b - ld a, [hli] - cp $a - jr c, .asm_38a0a - -.asm_38a12 - pop hl - call Random - cp 16 percent - ret c - dec [hl] - ret - -; Discourage this move if neither: -; Any of enemy's stat levels is lower than -2. -; Any of player's stat levels is higher than +2. -.asm_38a1b - pop hl - inc [hl] - ret -; 38a1e - - -AI_Smart_Bide: ; 38a1e -; 90% chance to discourage this move unless enemy's HP is full. - - call AICheckEnemyMaxHP - ret c - call Random - cp 10 percent - ret c - inc [hl] - ret -; 38a2a - - -AI_Smart_ForceSwitch: ; 38a2a -; Whirlwind, Roar. - -; Discourage this move if the player has not shown -; a super-effective move against the enemy. -; Consider player's type(s) if its moves are unknown. - - push hl - callfar CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 ; neutral - pop hl - ret c - inc [hl] - ret -; 38a3a - - -AI_Smart_Heal: -AI_Smart_MorningSun: -AI_Smart_Synthesis: -AI_Smart_Moonlight: ; 38a3a -; 90% chance to greatly encourage this move if enemy's HP is below 25%. -; Discourage this move if enemy's HP is higher than 50%. -; Do nothing otherwise. - - call AICheckEnemyQuarterHP - jr nc, .asm_38a45 - call AICheckEnemyHalfHP - ret nc - inc [hl] - ret - -.asm_38a45 - call Random - cp 10 percent - ret c - dec [hl] - dec [hl] - ret -; 38a4e - - -AI_Smart_Toxic: -AI_Smart_LeechSeed: ; 38a4e -; Discourage this move if player's HP is below 50%. - - call AICheckPlayerHalfHP - ret c - inc [hl] - ret -; 38a54 - - -AI_Smart_LightScreen: -AI_Smart_Reflect: ; 38a54 -; Over 90% chance to discourage this move unless enemy's HP is full. - - call AICheckEnemyMaxHP - ret c - call Random - cp 8 percent - ret c - inc [hl] - ret -; 38a60 - - -AI_Smart_Ohko: ; 38a60 -; Dismiss this move if player's level is higher than enemy's level. -; Else, discourage this move is player's HP is below 50%. - - ld a, [BattleMonLevel] - ld b, a - ld a, [EnemyMonLevel] - cp b - jp c, AIDiscourageMove - call AICheckPlayerHalfHP - ret c - inc [hl] - ret -; 38a71 - - -AI_Smart_TrapTarget: ; 38a71 -; Bind, Wrap, Fire Spin, Clamp - -; 50% chance to discourage this move if the player is already trapped. - ld a, [wPlayerWrapCount] - and a - jr nz, .asm_38a8b - -; 50% chance to greatly encourage this move if player is either -; badly poisoned, in love, identified, stuck in Rollout, or has a Nightmare. - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_38a91 - - ld a, [PlayerSubStatus1] - and 1<<SUBSTATUS_IN_LOVE | 1<<SUBSTATUS_ROLLOUT | 1<<SUBSTATUS_IDENTIFIED | 1<<SUBSTATUS_NIGHTMARE - jr nz, .asm_38a91 - -; Else, 50% chance to greatly encourage this move if it's the player's Pokemon first turn. - ld a, [PlayerTurnsTaken] - and a - jr z, .asm_38a91 - -; 50% chance to discourage this move otherwise. -.asm_38a8b - call AI_50_50 - ret c - inc [hl] - ret - -.asm_38a91 - call AICheckEnemyQuarterHP - ret nc - call AI_50_50 - ret c - dec [hl] - dec [hl] - ret -; 38a9c - - -AI_Smart_RazorWind: -AI_Smart_Unused2B: ; 38a9c - ld a, [EnemySubStatus1] - bit SUBSTATUS_PERISH, a - jr z, .asm_38aaa - - ld a, [EnemyPerishCount] - cp 3 - jr c, .asm_38ad3 - -.asm_38aaa - push hl - ld hl, PlayerUsedMoves - ld c, 4 - -.asm_38ab0 - ld a, [hli] - and a - jr z, .asm_38ac1 - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - cp EFFECT_PROTECT - jr z, .asm_38ad5 - dec c - jr nz, .asm_38ab0 - -.asm_38ac1 - pop hl - ld a, [EnemySubStatus3] - bit SUBSTATUS_CONFUSED, a - jr nz, .asm_38acd - - call AICheckEnemyHalfHP - ret c - -.asm_38acd - call Random - cp 79 percent - 1 - ret c - -.asm_38ad3 - inc [hl] - ret - -.asm_38ad5 - pop hl - ld a, [hl] - add 6 - ld [hl], a - ret -; 38adb - - -AI_Smart_Confuse: ; 38adb - -; 90% chance to discourage this move if player's HP is between 25% and 50%. - call AICheckPlayerHalfHP - ret c - call Random - cp 10 percent - jr c, .asm_38ae7 - inc [hl] - -.asm_38ae7 -; Discourage again if player's HP is below 25%. - call AICheckPlayerQuarterHP - ret c - inc [hl] - ret -; 38aed - - -AI_Smart_SpDefenseUp2: ; 38aed - -; Discourage this move if enemy's HP is lower than 50%. - call AICheckEnemyHalfHP - jr nc, .asm_38b10 - -; Discourage this move if enemy's special defense level is higher than +3. - ld a, [EnemySDefLevel] - cp $b - jr nc, .asm_38b10 - -; 80% chance to greatly encourage this move if -; enemy's Special Defense level is lower than +2, and the player is of a special type. - cp $9 - ret nc - - ld a, [BattleMonType1] - cp SPECIAL - jr nc, .asm_38b09 - ld a, [BattleMonType2] - cp SPECIAL - ret c - -.asm_38b09 - call AI_80_20 - ret c - dec [hl] - dec [hl] - ret - -.asm_38b10 - inc [hl] - ret -; 38b12 - - -AI_Smart_Fly: ; 38b12 -; Fly, Dig - -; Greatly encourage this move if the player is -; flying or underground, and slower than the enemy. - - ld a, [PlayerSubStatus3] - and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND - ret z - - call AICompareSpeed - ret nc - - dec [hl] - dec [hl] - dec [hl] - ret -; 38b20 - - -AI_Smart_SuperFang: ; 38b20 -; Discourage this move if player's HP is below 25%. - - call AICheckPlayerQuarterHP - ret c - inc [hl] - ret -; 38b26 - - -AI_Smart_Paralyze: ; 38b26 - -; 50% chance to discourage this move if player's HP is below 25%. - call AICheckPlayerQuarterHP - jr nc, .asm_38b3a - -; 80% chance to greatly encourage this move -; if enemy is slower than player and its HP is above 25%. - call AICompareSpeed - ret c - call AICheckEnemyQuarterHP - ret nc - call AI_80_20 - ret c - dec [hl] - dec [hl] - ret - -.asm_38b3a - call AI_50_50 - ret c - inc [hl] - ret -; 38b40 - - -AI_Smart_SpeedDownHit: ; 38b40 -; Icy Wind - -; Almost 90% chance to greatly encourage this move if the following conditions all meet: -; Enemy's HP is higher than 25%. -; It's the first turn of player's Pokemon. -; Player is faster than enemy. - - ld a, [wEnemyMoveStruct + MOVE_ANIM] - cp ICY_WIND - ret nz - call AICheckEnemyQuarterHP - ret nc - ld a, [PlayerTurnsTaken] - and a - ret nz - call AICompareSpeed - ret c - call Random - cp 12 percent - ret c - dec [hl] - dec [hl] - ret -; 38b5c - - -AI_Smart_Substitute: ; 38b5c -; Dismiss this move if enemy's HP is below 50%. - - call AICheckEnemyHalfHP - ret c - jp AIDiscourageMove -; 38b63 - - -AI_Smart_HyperBeam: ; 38b63 - call AICheckEnemyHalfHP - jr c, .asm_38b72 - -; 50% chance to encourage this move if enemy's HP is below 25%. - call AICheckEnemyQuarterHP - ret c - call AI_50_50 - ret c - dec [hl] - ret - -.asm_38b72 -; If enemy's HP is above 50%, discourage this move at random - call Random - cp 16 percent - ret c - inc [hl] - call AI_50_50 - ret c - inc [hl] - ret -; 38b7f - - -AI_Smart_Rage: ; 38b7f - ld a, [EnemySubStatus4] - bit SUBSTATUS_RAGE, a - jr z, .asm_38b9b - -; If enemy's Rage is building, 50% chance to encourage this move. - call AI_50_50 - jr c, .asm_38b8c - - dec [hl] - -; Encourage this move based on Rage's counter. -.asm_38b8c - ld a, [wEnemyRageCounter] - cp $2 - ret c - dec [hl] - ld a, [wEnemyRageCounter] - cp $3 - ret c - dec [hl] - ret - -.asm_38b9b -; If enemy's Rage is not building, discourage this move if enemy's HP is below 50%. - call AICheckEnemyHalfHP - jr nc, .asm_38ba6 - -; 50% chance to encourage this move otherwise. - call AI_80_20 - ret nc - dec [hl] - ret - -.asm_38ba6 - inc [hl] - ret -; 38ba8 - - -AI_Smart_Mimic: ; 38ba8 - ld a, [LastPlayerCounterMove] - and a - jr z, .asm_38be9 - - call AICheckEnemyHalfHP - jr nc, .asm_38bef - - push hl - ld a, [LastPlayerCounterMove] - call AIGetEnemyMove - - ld a, $1 - ld [hBattleTurn], a - callfar BattleCheckTypeMatchup - - ld a, [wd265] - cp $a - pop hl - jr c, .asm_38bef - jr z, .asm_38bd4 - - call AI_50_50 - jr c, .asm_38bd4 - - dec [hl] - -.asm_38bd4 - ld a, [LastPlayerCounterMove] - push hl - ld hl, UsefulMoves - ld de, 1 - call IsInArray - - pop hl - ret nc - call AI_50_50 - ret c - dec [hl] - ret - -.asm_38be9 - call AICompareSpeed - jp c, AIDiscourageMove - -.asm_38bef - inc [hl] - ret -; 38bf1 - - -AI_Smart_Counter: ; 38bf1 - push hl - ld hl, PlayerUsedMoves - ld c, 4 - ld b, 0 - -.asm_38bf9 - ld a, [hli] - and a - jr z, .asm_38c0e - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .asm_38c0e - - ld a, [wEnemyMoveStruct + MOVE_TYPE] - cp SPECIAL - jr nc, .asm_38c0e - - inc b - -.asm_38c0e - dec c - jr nz, .asm_38bf9 - - pop hl - ld a, b - and a - jr z, .asm_38c39 - - cp $3 - jr nc, .asm_38c30 - - ld a, [LastPlayerCounterMove] - and a - jr z, .asm_38c38 - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .asm_38c38 - - ld a, [wEnemyMoveStruct + MOVE_TYPE] - cp SPECIAL - jr nc, .asm_38c38 - - -.asm_38c30 - call Random - cp 39 percent + 1 - jr c, .asm_38c38 - - dec [hl] - -.asm_38c38 - ret - -.asm_38c39 - inc [hl] - ret -; 38c3b - - -AI_Smart_Encore: ; 38c3b - call AICompareSpeed - jr nc, .asm_38c81 - - ld a, [LastPlayerMove] - and a - jp z, AIDiscourageMove - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .asm_38c68 - - push hl - ld a, [wEnemyMoveStruct + MOVE_TYPE] - ld hl, EnemyMonType1 - predef CheckTypeMatchup - - pop hl - ld a, [wd265] - cp $a - jr nc, .asm_38c68 - - and a - ret nz - jr .asm_38c78 - -.asm_38c68 - push hl - ld a, [LastPlayerCounterMove] - ld hl, .EncoreMoves - ld de, 1 - call IsInArray - pop hl - jr nc, .asm_38c81 - -.asm_38c78 - call Random - cp 28 percent - 1 - ret c - dec [hl] - dec [hl] - ret - -.asm_38c81 - inc [hl] - inc [hl] - inc [hl] - ret - -.EncoreMoves: - db SWORDS_DANCE - db WHIRLWIND - db LEER - db ROAR - db DISABLE - db MIST - db LEECH_SEED - db GROWTH - db POISONPOWDER - db STRING_SHOT - db MEDITATE - db AGILITY - db TELEPORT - db SCREECH - db HAZE - db FOCUS_ENERGY - db DREAM_EATER - db POISON_GAS - db SPLASH - db SHARPEN - db CONVERSION - db SUPER_FANG - db SUBSTITUTE - db TRIPLE_KICK - db SPIDER_WEB - db MIND_READER - db FLAME_WHEEL - db AEROBLAST - db COTTON_SPORE - db POWDER_SNOW - db $ff -; 38ca4 - - -AI_Smart_PainSplit: ; 38ca4 -; Discourage this move if [enemy's current HP * 2 > player's current HP]. - - push hl - ld hl, EnemyMonHP - ld b, [hl] - inc hl - ld c, [hl] - sla c - rl b - ld hl, BattleMonHP + 1 - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop hl - ret nc - inc [hl] - ret -; 38cba - - -AI_Smart_Snore: -AI_Smart_SleepTalk: ; 38cba -; Greatly encourage this move if enemy is fast asleep. -; Greatly discourage this move otherwise. - - ld a, [EnemyMonStatus] - and $7 - cp $1 - jr z, .asm_38cc7 - - dec [hl] - dec [hl] - dec [hl] - ret - -.asm_38cc7 - inc [hl] - inc [hl] - inc [hl] - ret -; 38ccb - - -AI_Smart_DefrostOpponent: ; 38ccb -; Greatly encourage this move if enemy is frozen. -; No move has EFFECT_DEFROST_OPPONENT, so this layer is unused. - - ld a, [EnemyMonStatus] - and $20 - ret z - dec [hl] - dec [hl] - dec [hl] - ret -; 38cd5 - - -AI_Smart_Spite: ; 38cd5 - ld a, [LastPlayerCounterMove] - and a - jr nz, .asm_38ce7 - - call AICompareSpeed - jp c, AIDiscourageMove - - call AI_50_50 - ret c - inc [hl] - ret - -.asm_38ce7 - push hl - ld b, a - ld c, 4 - ld hl, BattleMonMoves - ld de, BattleMonPP - -.asm_38cf1 - ld a, [hli] - cp b - jr z, .asm_38cfb - - inc de - dec c - jr nz, .asm_38cf1 - - pop hl - ret - -.asm_38cfb - pop hl - ld a, [de] - cp $6 - jr c, .asm_38d0d - cp $f - jr nc, .asm_38d0b - - call Random - cp 39 percent + 1 - ret nc - -.asm_38d0b - inc [hl] - ret - -.asm_38d0d - call Random - cp 39 percent + 1 - ret c - dec [hl] - dec [hl] - ret -; 38d16 - - -Function_0x38d16; 38d16 - jp AIDiscourageMove -; 38d19 - - -AI_Smart_DestinyBond: -AI_Smart_Reversal: -AI_Smart_SkullBash: ; 38d19 -; Discourage this move if enemy's HP is above 25%. - - call AICheckEnemyQuarterHP - ret nc - inc [hl] - ret -; 38d1f - - -AI_Smart_HealBell: ; 38d1f -; Dismiss this move if none of the opponent's Pokemon is statused. -; Encourage this move if the enemy is statused. -; 50% chance to greatly encourage this move if the enemy is fast asleep or frozen. - - push hl - ld a, [OTPartyCount] - ld b, a - ld c, 0 - ld hl, OTPartyMon1HP - ld de, PARTYMON_STRUCT_LENGTH - -.loop - push hl - ld a, [hli] - or [hl] - jr z, .next - - ; status - dec hl - dec hl - dec hl - ld a, [hl] - or c - ld c, a - -.next - pop hl - add hl, de - dec b - jr nz, .loop - - pop hl - ld a, c - and a - jr z, .no_status - - ld a, [EnemyMonStatus] - and a - jr z, .ok - dec [hl] -.ok - and 1 << FRZ | SLP - ret z - call AI_50_50 - ret c - dec [hl] - dec [hl] - ret - -.no_status - ld a, [EnemyMonStatus] - and a - ret nz - jp AIDiscourageMove - -; 38d5a - - -AI_Smart_PriorityHit: ; 38d5a - call AICompareSpeed - ret c - -; Dismiss this move if the player is flying or underground. - ld a, [PlayerSubStatus3] - and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND - jp nz, AIDiscourageMove - -; Greatly encourage this move if it will KO the player. - ld a, $1 - ld [hBattleTurn], a - push hl - callfar EnemyAttackDamage - callfar BattleCommand_DamageCalc - callfar BattleCommand_Stab - pop hl - ld a, [CurDamage + 1] - ld c, a - ld a, [CurDamage] - ld b, a - ld a, [BattleMonHP + 1] - cp c - ld a, [BattleMonHP] - sbc b - ret nc - dec [hl] - dec [hl] - dec [hl] - ret -; 38d93 - - -AI_Smart_Thief: ; 38d93 -; Don't use Thief unless it's the only move available. - - ld a, [hl] - add $1e - ld [hl], a - ret -; 38d98 - - -AI_Smart_Conversion2: ; 38d98 - ld a, [LastPlayerMove] - and a - jr nz, .asm_38dc9 - - push hl - dec a - ld hl, Moves + MOVE_TYPE - ld bc, MOVE_LENGTH - call AddNTimes - - ld a, BANK(Moves) - call GetFarByte - ld [wPlayerMoveStruct + MOVE_TYPE], a - - xor a - ld [hBattleTurn], a - - callfar BattleCheckTypeMatchup - - ld a, [wd265] - cp $a - pop hl - jr c, .asm_38dc9 - ret z - - call AI_50_50 - ret c - - dec [hl] - ret - -.asm_38dc9 - call Random - cp 10 percent - ret c - inc [hl] - ret -; 38dd1 - - -AI_Smart_Disable: ; 38dd1 - call AICompareSpeed - jr nc, .asm_38df3 - - push hl - ld a, [LastPlayerCounterMove] - ld hl, UsefulMoves - ld de, 1 - call IsInArray - - pop hl - jr nc, .asm_38dee - - call Random - cp 39 percent + 1 - ret c - dec [hl] - ret - -.asm_38dee - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - ret nz - -.asm_38df3 - call Random - cp 8 percent - ret c - inc [hl] - ret -; 38dfb - - -AI_Smart_MeanLook: ; 38dfb - call AICheckEnemyHalfHP - jr nc, .asm_38e24 - - push hl - call AICheckLastPlayerMon - pop hl - jp z, AIDiscourageMove - -; 80% chance to greatly encourage this move if the enemy is badly poisoned (buggy). -; Should check PlayerSubStatus5 instead. - ld a, [EnemySubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_38e26 - -; 80% chance to greatly encourage this move if the player is either -; in love, identified, stuck in Rollout, or has a Nightmare. - ld a, [PlayerSubStatus1] - and 1<<SUBSTATUS_IN_LOVE | 1<<SUBSTATUS_ROLLOUT | 1<<SUBSTATUS_IDENTIFIED | 1<<SUBSTATUS_NIGHTMARE - jr nz, .asm_38e26 - -; Otherwise, discourage this move unless the player only has not very effective moves against the enemy. - push hl - callfar CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp $b ; not very effective - pop hl - ret nc - -.asm_38e24 - inc [hl] - ret - -.asm_38e26 - call AI_80_20 - ret c - dec [hl] - dec [hl] - dec [hl] - ret -; 38e2e - - -AICheckLastPlayerMon: ; 38e2e - ld a, [PartyCount] - ld b, a - ld c, 0 - ld hl, PartyMon1HP - ld de, PARTYMON_STRUCT_LENGTH - -.loop - ld a, [CurBattleMon] - cp c - jr z, .asm_38e44 - - ld a, [hli] - or [hl] - ret nz - dec hl - -.asm_38e44 - add hl, de - inc c - dec b - jr nz, .loop - - ret -; 38e4a - - -AI_Smart_Nightmare: ; 38e4a -; 50% chance to encourage this move. -; The AI_Basic layer will make sure that -; Dream Eater is only used against sleeping targets. - - call AI_50_50 - ret c - dec [hl] - ret -; 38e50 - - -AI_Smart_FlameWheel: ; 38e50 -; Use this move if the enemy is frozen. - - ld a, [EnemyMonStatus] - bit FRZ, a - ret z -rept 5 - dec [hl] -endr - ret -; 38e5c - - -AI_Smart_Curse: ; 38e5c - ld a, [EnemyMonType1] - cp GHOST - jr z, .ghostcurse - ld a, [EnemyMonType2] - cp GHOST - jr z, .ghostcurse - - call AICheckEnemyHalfHP - jr nc, .asm_38e93 - - ld a, [EnemyAtkLevel] - cp $b - jr nc, .asm_38e93 - cp $9 - ret nc - - ld a, [BattleMonType1] - cp GHOST - jr z, .asm_38e92 - cp SPECIAL - ret nc - ld a, [BattleMonType2] - cp SPECIAL - ret nc - call AI_80_20 - ret c - dec [hl] - dec [hl] - ret - -.asm_38e90 - inc [hl] - inc [hl] -.asm_38e92 - inc [hl] -.asm_38e93 - inc [hl] - ret - -.ghostcurse - ld a, [PlayerSubStatus1] - bit SUBSTATUS_CURSE, a - jp nz, AIDiscourageMove - - push hl - farcall FindAliveEnemyMons - pop hl - jr nc, .asm_38eb0 - - push hl - call AICheckLastPlayerMon - pop hl - jr nz, .asm_38e90 - - jr .asm_38eb7 - - -.asm_38eb0 - push hl - call AICheckLastPlayerMon - pop hl - jr z, .asm_38ecb - - -.asm_38eb7 - call AICheckEnemyQuarterHP - jp nc, .asm_38e90 - - call AICheckEnemyHalfHP - jr nc, .asm_38e92 - - call AICheckEnemyMaxHP - ret nc - - ld a, [PlayerTurnsTaken] - and a - ret nz - -.asm_38ecb - call AI_50_50 - ret c - - dec [hl] - dec [hl] - ret -; 38ed2 - - -AI_Smart_Protect: ; 38ed2 - ld a, [EnemyProtectCount] - and a - jr nz, .asm_38f13 - - ld a, [PlayerSubStatus5] - bit SUBSTATUS_LOCK_ON, a - jr nz, .asm_38f14 - - ld a, [PlayerFuryCutterCount] - cp 3 - jr nc, .asm_38f0d - - ld a, [PlayerSubStatus3] - bit SUBSTATUS_CHARGED, a - jr nz, .asm_38f0d - - ld a, [PlayerSubStatus5] - bit SUBSTATUS_TOXIC, a - jr nz, .asm_38f0d - ld a, [PlayerSubStatus4] - bit SUBSTATUS_LEECH_SEED, a - jr nz, .asm_38f0d - ld a, [PlayerSubStatus1] - bit SUBSTATUS_CURSE, a - jr nz, .asm_38f0d - - bit SUBSTATUS_ROLLOUT, a - jr z, .asm_38f14 - - ld a, [PlayerRolloutCount] - cp 3 - jr c, .asm_38f14 - -.asm_38f0d - call AI_80_20 - ret c - dec [hl] - ret - -.asm_38f13 - inc [hl] - -.asm_38f14 - call Random - cp 8 percent - ret c - inc [hl] - inc [hl] - ret -; 38f1d - - -AI_Smart_Foresight: ; 38f1d - ld a, [EnemyAccLevel] - cp $5 - jr c, .asm_38f41 - ld a, [PlayerEvaLevel] - cp $a - jr nc, .asm_38f41 - - ld a, [BattleMonType1] - cp GHOST - jr z, .asm_38f41 - ld a, [BattleMonType2] - cp GHOST - jr z, .asm_38f41 - - call Random - cp 8 percent - ret c - inc [hl] - ret - -.asm_38f41 - call Random - cp 39 percent + 1 - ret c - dec [hl] - dec [hl] - ret -; 38f4a - - -AI_Smart_PerishSong: ; 38f4a - push hl - callfar FindAliveEnemyMons - pop hl - jr c, .no - - ld a, [PlayerSubStatus5] - bit SUBSTATUS_CANT_RUN, a - jr nz, .yes - - push hl - callfar CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 ; 1.0 - pop hl - ret c - - call AI_50_50 - ret c - - inc [hl] - ret - -.yes - call AI_50_50 - ret c - - dec [hl] - ret - -.no - ld a, [hl] - add 5 - ld [hl], a - ret -; 38f7a - - -AI_Smart_Sandstorm: ; 38f7a - -; Greatly discourage this move if the player is immune to Sandstorm damage. - ld a, [BattleMonType1] - push hl - ld hl, .SandstormImmuneTypes - ld de, 1 - call IsInArray - pop hl - jr c, .asm_38fa5 - - ld a, [BattleMonType2] - push hl - ld hl, .SandstormImmuneTypes - ld de, 1 - call IsInArray - pop hl - jr c, .asm_38fa5 - -; Discourage this move if player's HP is below 50%. - call AICheckPlayerHalfHP - jr nc, .asm_38fa6 - -; 50% chance to encourage this move otherwise. - call AI_50_50 - ret c - - dec [hl] - ret - -.asm_38fa5 - inc [hl] - -.asm_38fa6 - inc [hl] - ret - -.SandstormImmuneTypes: - db ROCK - db GROUND - db STEEL - db $ff -; 38fac - - -AI_Smart_Endure: ; 38fac - ld a, [EnemyProtectCount] - and a - jr nz, .asm_38fd8 - - call AICheckEnemyMaxHP - jr c, .asm_38fd8 - - call AICheckEnemyQuarterHP - jr c, .asm_38fd9 - - ld b, EFFECT_REVERSAL - call AIHasMoveEffect - jr nc, .asm_38fcb - - call AI_80_20 - ret c - - dec [hl] - dec [hl] - dec [hl] - ret - -.asm_38fcb - ld a, [EnemySubStatus5] - bit SUBSTATUS_LOCK_ON, a - ret z - - call AI_50_50 - ret c - - dec [hl] - dec [hl] - ret - -.asm_38fd8 - inc [hl] - -.asm_38fd9 - inc [hl] - ret -; 38fdb - - -AI_Smart_FuryCutter: ; 38fdb -; Encourage this move based on Fury Cutter's count. - - ld a, [EnemyFuryCutterCount] - and a - jr z, .end - dec [hl] - - cp 2 - jr c, .end - dec [hl] - dec [hl] - - cp 3 - jr c, .end - dec [hl] - dec [hl] - dec [hl] - -.end - - ; fallthrough -; 38fef - - -AI_Smart_Rollout: ; 38fef -; Rollout, Fury Cutter - -; 80% chance to discourage this move if the enemy is in love, confused, or paralyzed. - ld a, [EnemySubStatus1] - bit SUBSTATUS_IN_LOVE, a - jr nz, .asm_39020 - - ld a, [EnemySubStatus3] - bit SUBSTATUS_CONFUSED, a - jr nz, .asm_39020 - - ld a, [EnemyMonStatus] - bit PAR, a - jr nz, .asm_39020 - -; 80% chance to discourage this move if the enemy's HP is below 25%, -; or if accuracy or evasion modifiers favour the player. - call AICheckEnemyQuarterHP - jr nc, .asm_39020 - - ld a, [EnemyAccLevel] - cp 7 - jr c, .asm_39020 - ld a, [PlayerEvaLevel] - cp 8 - jr nc, .asm_39020 - -; Otherwise, 80% chance to greatly encourage this move. - call Random - cp 79 percent - 1 - ret nc - dec [hl] - dec [hl] - ret - -.asm_39020 - call AI_80_20 - ret c - inc [hl] - ret -; 39026 - - -AI_Smart_Swagger: -AI_Smart_Attract: ; 39026 -; 80% chance to encourage this move during the first turn of player's Pokemon. -; 80% chance to discourage this move otherwise. - - ld a, [PlayerTurnsTaken] - and a - jr z, .first_turn - - call AI_80_20 - ret c - inc [hl] - ret - -.first_turn - call Random - cp 79 percent - 1 - ret nc - dec [hl] - ret -; 3903a - - -AI_Smart_Safeguard: ; 3903a -; 80% chance to discourage this move if player's HP is below 50%. - - call AICheckPlayerHalfHP - ret c - call AI_80_20 - ret c - inc [hl] - ret -; 39044 - - -AI_Smart_Magnitude: -AI_Smart_Earthquake: ; 39044 - -; Greatly encourage this move if the player is underground and the enemy is faster. - ld a, [LastPlayerCounterMove] - cp DIG - ret nz - - ld a, [PlayerSubStatus3] - bit SUBSTATUS_UNDERGROUND, a - jr z, .could_dig - - call AICompareSpeed - ret nc - dec [hl] - dec [hl] - ret - -.could_dig - ; Try to predict if the player will use Dig this turn. - - ; 50% chance to encourage this move if the enemy is slower than the player. - call AICompareSpeed - ret c - - call AI_50_50 - ret c - - dec [hl] - ret -; 39062 - - -AI_Smart_BatonPass: ; 39062 -; Discourage this move if the player hasn't shown super-effective moves against the enemy. -; Consider player's type(s) if its moves are unknown. - - push hl - callfar CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 ; neutral - pop hl - ret c - inc [hl] - ret -; 39072 - - -AI_Smart_Pursuit: ; 39072 -; 50% chance to greatly encourage this move if player's HP is below 25%. -; 80% chance to discourage this move otherwise. - - call AICheckPlayerQuarterHP - jr nc, .asm_3907d - call AI_80_20 - ret c - inc [hl] - ret - -.asm_3907d - call AI_50_50 - ret c - dec [hl] - dec [hl] - ret -; 39084 - - -AI_Smart_RapidSpin: ; 39084 -; 80% chance to greatly encourage this move if the enemy is -; trapped (Bind effect), seeded, or scattered with spikes. - - ld a, [wEnemyWrapCount] - and a - jr nz, .asm_39097 - - ld a, [EnemySubStatus4] - bit SUBSTATUS_LEECH_SEED, a - jr nz, .asm_39097 - - ld a, [EnemyScreens] - bit SCREENS_SPIKES, a - ret z - -.asm_39097 - call AI_80_20 - ret c - - dec [hl] - dec [hl] - ret -; 3909e - - -AI_Smart_HiddenPower: ; 3909e - push hl - ld a, 1 - ld [hBattleTurn], a - -; Calculate Hidden Power's type and base power based on enemy's DVs. - callfar HiddenPowerDamage - callfar BattleCheckTypeMatchup - pop hl - -; Discourage Hidden Power if not very effective. - ld a, [wd265] - cp 10 - jr c, .bad - -; Discourage Hidden Power if its base power is lower than 50. - ld a, d - cp 50 - jr c, .bad - -; Encourage Hidden Power if super-effective. - ld a, [wd265] - cp 11 - jr nc, .good - -; Encourage Hidden Power if its base power is 70. - ld a, d - cp 70 - ret c - -.good - dec [hl] - ret - -.bad - inc [hl] - ret -; 390cb - - -AI_Smart_RainDance: ; 390cb - -; Greatly discourage this move if it would favour the player type-wise. -; Particularly, if the player is a Water-type. - ld a, [BattleMonType1] - cp WATER - jr z, AIBadWeatherType - cp FIRE - jr z, AIGoodWeatherType - - ld a, [BattleMonType2] - cp WATER - jr z, AIBadWeatherType - cp FIRE - jr z, AIGoodWeatherType - - push hl - ld hl, RainDanceMoves - jr AI_Smart_WeatherMove -; 390e7 - -RainDanceMoves: ; 390e7 - db WATER_GUN - db HYDRO_PUMP - db SURF - db BUBBLEBEAM - db THUNDER - db WATERFALL - db CLAMP - db BUBBLE - db CRABHAMMER - db OCTAZOOKA - db WHIRLPOOL - db $ff -; 390f3 - - -AI_Smart_SunnyDay: ; 390f3 - -; Greatly discourage this move if it would favour the player type-wise. -; Particularly, if the player is a Fire-type. - ld a, [BattleMonType1] - cp FIRE - jr z, AIBadWeatherType - cp WATER - jr z, AIGoodWeatherType - - ld a, [BattleMonType2] - cp FIRE - jr z, AIBadWeatherType - cp WATER - jr z, AIGoodWeatherType - - push hl - ld hl, SunnyDayMoves - - ; fallthrough -; 3910d - - -AI_Smart_WeatherMove: ; 3910d -; Rain Dance, Sunny Day - -; Greatly discourage this move if the enemy doesn't have -; one of the useful Rain Dance or Sunny Day moves. - call AIHasMoveInArray - pop hl - jr nc, AIBadWeatherType - -; Greatly discourage this move if player's HP is below 50%. - call AICheckPlayerHalfHP - jr nc, AIBadWeatherType - -; 50% chance to encourage this move otherwise. - call AI_50_50 - ret c - - dec [hl] - ret -; 3911e - -AIBadWeatherType: ; 3911e - inc [hl] - inc [hl] - inc [hl] - ret -; 39122 - -AIGoodWeatherType: ; 39122 -; Rain Dance, Sunny Day - -; Greatly encourage this move if it would disfavour the player type-wise and player's HP is above 50%... - call AICheckPlayerHalfHP - ret nc - -; ...as long as one of the following conditions meet: -; It's the first turn of the player's Pokemon. - ld a, [PlayerTurnsTaken] - and a - jr z, .good - -; Or it's the first turn of the enemy's Pokemon. - ld a, [EnemyTurnsTaken] - and a - ret nz - -.good - dec [hl] - dec [hl] - ret -; 39134 - - -SunnyDayMoves: ; 39134 - db FIRE_PUNCH - db EMBER - db FLAMETHROWER - db FIRE_SPIN - db FIRE_BLAST - db SACRED_FIRE - db MORNING_SUN - db SYNTHESIS - db $ff -; 3913d - - -AI_Smart_BellyDrum: ; 3913d -; Dismiss this move if enemy's attack is higher than +2 or if enemy's HP is below 50%. -; Else, discourage this move if enemy's HP is not full. - - ld a, [EnemyAtkLevel] - cp $a - jr nc, .asm_3914d - - call AICheckEnemyMaxHP - ret c - - inc [hl] - - call AICheckEnemyHalfHP - ret c - -.asm_3914d - ld a, [hl] - add $5 - ld [hl], a - ret -; 39152 - - -AI_Smart_PsychUp: ; 39152 - push hl - ld hl, EnemyAtkLevel - ld b, $8 - ld c, 100 - -; Calculate the sum of all enemy's stat level modifiers. Add 100 first to prevent underflow. -; Put the result in c. c will range between 58 and 142. -.asm_3915a - ld a, [hli] - sub $7 - add c - ld c, a - dec b - jr nz, .asm_3915a - -; Calculate the sum of all player's stat level modifiers. Add 100 first to prevent underflow. -; Put the result in d. d will range between 58 and 142. - ld hl, PlayerAtkLevel - ld b, $8 - ld d, 100 - -.asm_39169 - ld a, [hli] - sub $7 - add d - ld d, a - dec b - jr nz, .asm_39169 - -; Greatly discourage this move if enemy's stat levels are higher than player's (if c>=d). - ld a, c - sub d - pop hl - jr nc, .asm_39188 - -; Else, 80% chance to encourage this move unless player's accuracy level is lower than -1... - ld a, [PlayerAccLevel] - cp $6 - ret c - -; ...or enemy's evasion level is higher than +0. - ld a, [EnemyEvaLevel] - cp $8 - ret nc - - call AI_80_20 - ret c - - dec [hl] - ret - -.asm_39188 - inc [hl] - inc [hl] - ret -; 3918b - - -AI_Smart_MirrorCoat: ; 3918b - push hl - ld hl, PlayerUsedMoves - ld c, $4 - ld b, $0 - -.asm_39193 - ld a, [hli] - and a - jr z, .asm_391a8 - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .asm_391a8 - - ld a, [wEnemyMoveStruct + MOVE_TYPE] - cp SPECIAL - jr c, .asm_391a8 - - inc b - -.asm_391a8 - dec c - jr nz, .asm_39193 - - pop hl - ld a, b - and a - jr z, .asm_391d3 - - cp $3 - jr nc, .asm_391ca - - ld a, [LastPlayerCounterMove] - and a - jr z, .asm_391d2 - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .asm_391d2 - - ld a, [wEnemyMoveStruct + MOVE_TYPE] - cp SPECIAL - jr c, .asm_391d2 - - -.asm_391ca - call Random - cp 100 - jr c, .asm_391d2 - dec [hl] - -.asm_391d2 - ret - -.asm_391d3 - inc [hl] - ret -; 391d5 - - -AI_Smart_Twister: -AI_Smart_Gust: ; 391d5 - -; Greatly encourage this move if the player is flying and the enemy is faster. - ld a, [LastPlayerCounterMove] - cp FLY - ret nz - - ld a, [PlayerSubStatus3] - bit SUBSTATUS_FLYING, a - jr z, .couldFly - - call AICompareSpeed - ret nc - - dec [hl] - dec [hl] - ret - -; Try to predict if the player will use Fly this turn. -.couldFly - -; 50% chance to encourage this move if the enemy is slower than the player. - call AICompareSpeed - ret c - call AI_50_50 - ret c - dec [hl] - ret -; 391f3 - - -AI_Smart_FutureSight: ; 391f3 -; Greatly encourage this move if the player is -; flying or underground, and slower than the enemy. - - call AICompareSpeed - ret nc - - ld a, [PlayerSubStatus3] - and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND - ret z - - dec [hl] - dec [hl] - ret -; 39200 - - -AI_Smart_Stomp: ; 39200 -; 80% chance to encourage this move if the player has used Minimize. - - ld a, [wPlayerMinimized] - and a - ret z - - call AI_80_20 - ret c - - dec [hl] - ret -; 3920b - - -AI_Smart_Solarbeam: ; 3920b -; 80% chance to encourage this move when it's sunny. -; 90% chance to discourage this move when it's raining. - - ld a, [Weather] - cp WEATHER_SUN - jr z, .asm_3921e - - cp WEATHER_RAIN - ret nz - - call Random - cp 10 percent - ret c - - inc [hl] - inc [hl] - ret - -.asm_3921e - call AI_80_20 - ret c - - dec [hl] - dec [hl] - ret -; 39225 - - -AI_Smart_Thunder: ; 39225 -; 90% chance to discourage this move when it's sunny. - - ld a, [Weather] - cp WEATHER_SUN - ret nz - - call Random - cp 10 percent - ret c - - inc [hl] - ret -; 39233 - - -AICompareSpeed: ; 39233 -; Return carry if enemy is faster than player. - - push bc - ld a, [EnemyMonSpeed + 1] - ld b, a - ld a, [BattleMonSpeed + 1] - cp b - ld a, [EnemyMonSpeed] - ld b, a - ld a, [BattleMonSpeed] - sbc b - pop bc - ret -; 39246 - - -AICheckPlayerMaxHP: ; 39246 - push hl - push de - push bc - ld de, BattleMonHP - ld hl, BattleMonMaxHP - jr AICheckMaxHP -; 39251 - - -AICheckEnemyMaxHP: ; 39251 - push hl - push de - push bc - ld de, EnemyMonHP - ld hl, EnemyMonMaxHP - ; fallthrough -; 3925a - - -AICheckMaxHP: ; 3925a -; Return carry if hp at de matches max hp at hl. - - ld a, [de] - inc de - cp [hl] - jr nz, .asm_39269 - - inc hl - ld a, [de] - cp [hl] - jr nz, .asm_39269 - - pop bc - pop de - pop hl - scf - ret - -.asm_39269 - pop bc - pop de - pop hl - and a - ret -; 3926e - - -AICheckPlayerHalfHP: ; 3926e - push hl - ld hl, BattleMonHP - ld b, [hl] - inc hl - ld c, [hl] - sla c - rl b - inc hl - inc hl - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop hl - ret -; 39281 - - -AICheckEnemyHalfHP: ; 39281 - push hl - push de - push bc - ld hl, EnemyMonHP - ld b, [hl] - inc hl - ld c, [hl] - sla c - rl b - inc hl - inc hl - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop bc - pop de - pop hl - ret -; 39298 - - -AICheckEnemyQuarterHP: ; 39298 - push hl - push de - push bc - ld hl, EnemyMonHP - ld b, [hl] - inc hl - ld c, [hl] - sla c - rl b - sla c - rl b - inc hl - inc hl - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop bc - pop de - pop hl - ret -; 392b3 - - -AICheckPlayerQuarterHP: ; 392b3 - push hl - ld hl, BattleMonHP - ld b, [hl] - inc hl - ld c, [hl] - sla c - rl b - sla c - rl b - inc hl - inc hl - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop hl - ret -; 392ca - - -AIHasMoveEffect: ; 392ca -; Return carry if the enemy has move b. - - push hl - ld hl, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves - -.checkmove - ld a, [hli] - and a - jr z, .no - - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - cp b - jr z, .yes - - dec c - jr nz, .checkmove - -.no - pop hl - and a - ret - -.yes - pop hl - scf - ret -; 392e6 - - -AIHasMoveInArray: ; 392e6 -; Return carry if the enemy has a move in array hl. - - push hl - push de - push bc - -.next - ld a, [hli] - cp $ff - jr z, .done - - ld b, a - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 - ld de, EnemyMonMoves - -.check - dec c - jr z, .next - - ld a, [de] - inc de - cp b - jr nz, .check - - scf - -.done - pop bc - pop de - pop hl - ret -; 39301 - - -UsefulMoves: ; 39301 -; Moves that are usable all-around. - db DOUBLE_EDGE - db SING - db FLAMETHROWER - db HYDRO_PUMP - db SURF - db ICE_BEAM - db BLIZZARD - db HYPER_BEAM - db SLEEP_POWDER - db THUNDERBOLT - db THUNDER - db EARTHQUAKE - db TOXIC - db PSYCHIC_M - db HYPNOSIS - db RECOVER - db FIRE_BLAST - db SOFTBOILED - db SUPER_FANG - db $ff -; 39315 - - -AI_Opportunist: ; 39315 -; Discourage stall moves when the enemy's HP is low. - -; Do nothing if enemy's HP is above 50%. - call AICheckEnemyHalfHP - ret c - -; Discourage stall moves if enemy's HP is below 25%. - call AICheckEnemyQuarterHP - jr nc, .asm_39322 - -; 50% chance to discourage stall moves if enemy's HP is between 25% and 50%. - call AI_50_50 - ret c - -.asm_39322 - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - inc hl - dec c - jr z, .asm_39347 - - ld a, [de] - inc de - and a - jr z, .asm_39347 - - push hl - push de - push bc - ld hl, .stallmoves - ld de, 1 - call IsInArray - - pop bc - pop de - pop hl - jr nc, .checkmove - - inc [hl] - jr .checkmove - -.asm_39347 - ret - -.stallmoves - db SWORDS_DANCE - db TAIL_WHIP - db LEER - db GROWL - db DISABLE - db MIST - db COUNTER - db LEECH_SEED - db GROWTH - db STRING_SHOT - db MEDITATE - db AGILITY - db RAGE - db MIMIC - db SCREECH - db HARDEN - db WITHDRAW - db DEFENSE_CURL - db BARRIER - db LIGHT_SCREEN - db HAZE - db REFLECT - db FOCUS_ENERGY - db BIDE - db AMNESIA - db TRANSFORM - db SPLASH - db ACID_ARMOR - db SHARPEN - db CONVERSION - db SUBSTITUTE - db FLAME_WHEEL - db $ff -; 39369 - - - -AI_Aggressive: ; 39369 -; Use whatever does the most damage. - -; Discourage all damaging moves but the one that does the most damage. -; If no damaging move deals damage to the player (immune), -; no move will be discouraged - -; Figure out which attack does the most damage and put it in c. - ld hl, EnemyMonMoves - ld bc, 0 - ld de, 0 -.checkmove - inc b - ld a, b - cp EnemyMonMovesEnd - EnemyMonMoves + 1 - jr z, .gotstrongestmove - - ld a, [hli] - and a - jr z, .gotstrongestmove - - push hl - push de - push bc - call AIGetEnemyMove - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .nodamage - call AIDamageCalc - pop bc - pop de - pop hl - -; Update current move if damage is highest so far - ld a, [CurDamage + 1] - cp e - ld a, [CurDamage] - sbc d - jr c, .checkmove - - ld a, [CurDamage + 1] - ld e, a - ld a, [CurDamage] - ld d, a - ld c, b - jr .checkmove - -.nodamage - pop bc - pop de - pop hl - jr .checkmove - -.gotstrongestmove -; Nothing we can do if no attacks did damage. - ld a, c - and a - jr z, .done - -; Discourage moves that do less damage unless they're reckless too. - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, 0 -.checkmove2 - inc b - ld a, b - cp EnemyMonMovesEnd - EnemyMonMoves + 1 - jr z, .done - -; Ignore this move if it is the highest damaging one. - cp c - ld a, [de] - inc de - inc hl - jr z, .checkmove2 - - call AIGetEnemyMove - -; Ignore this move if its power is 0 or 1. -; Moves such as Seismic Toss, Hidden Power, -; Counter and Fissure have a base power of 1. - ld a, [wEnemyMoveStruct + MOVE_POWER] - cp 2 - jr c, .checkmove2 - -; Ignore this move if it is reckless. - push hl - push de - push bc - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - ld hl, .RecklessMoves - ld de, 1 - call IsInArray - pop bc - pop de - pop hl - jr c, .checkmove2 - -; If we made it this far, discourage this move. - inc [hl] - jr .checkmove2 - -.done - ret - -.RecklessMoves: - db EFFECT_SELFDESTRUCT - db EFFECT_RAMPAGE - db EFFECT_MULTI_HIT - db EFFECT_DOUBLE_HIT - db $ff -; 393e7 - - -AIDamageCalc: ; 393e7 - ld a, 1 - ld [hBattleTurn], a - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - ld de, 1 - ld hl, .ConstantDamageEffects - call IsInArray - jr nc, .asm_39400 - callfar BattleCommand_ConstantDamage - ret - -.asm_39400 - callfar EnemyAttackDamage - callfar BattleCommand_DamageCalc - callfar BattleCommand_Stab - ret - -.ConstantDamageEffects: - db EFFECT_SUPER_FANG - db EFFECT_STATIC_DAMAGE - db EFFECT_LEVEL_DAMAGE - db EFFECT_PSYWAVE - db $ff -; 39418 - - -AI_Cautious: ; 39418 -; 90% chance to discourage moves with residual effects after the first turn. - - ld a, [EnemyTurnsTaken] - and a - ret z - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 -.asm_39425 - inc hl - dec c - ret z - - ld a, [de] - inc de - and a - ret z - - push hl - push de - push bc - ld hl, .residualmoves - ld de, 1 - call IsInArray - - pop bc - pop de - pop hl - jr nc, .asm_39425 - - call Random - cp 90 percent + 1 - ret nc - - inc [hl] - jr .asm_39425 - -.residualmoves - db MIST - db LEECH_SEED - db POISONPOWDER - db STUN_SPORE - db THUNDER_WAVE - db FOCUS_ENERGY - db BIDE - db POISON_GAS - db TRANSFORM - db CONVERSION - db SUBSTITUTE - db SPIKES - db $ff -; 39453 - - - -AI_Status: ; 39453 -; Dismiss status moves that don't affect the player. - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - dec b - ret z - - inc hl - ld a, [de] - and a - ret z - - inc de - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - cp EFFECT_TOXIC - jr z, .poisonimmunity - cp EFFECT_POISON - jr z, .poisonimmunity - cp EFFECT_SLEEP - jr z, .typeimmunity - cp EFFECT_PARALYZE - jr z, .typeimmunity - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .checkmove - - jr .typeimmunity - -.poisonimmunity - ld a, [BattleMonType1] - cp POISON - jr z, .immune - ld a, [BattleMonType2] - cp POISON - jr z, .immune - -.typeimmunity - push hl - push bc - push de - ld a, 1 - ld [hBattleTurn], a - callfar BattleCheckTypeMatchup - pop de - pop bc - pop hl - - ld a, [wd265] - and a - jr nz, .checkmove - -.immune - call AIDiscourageMove - jr .checkmove -; 394a9 - - - -AI_Risky: ; 394a9 -; Use any move that will KO the target. -; Risky moves will often be an exception (see below). - - ld hl, Buffer1 - 1 - ld de, EnemyMonMoves - ld c, EnemyMonMovesEnd - EnemyMonMoves + 1 -.checkmove - inc hl - dec c - ret z - - ld a, [de] - inc de - and a - ret z - - push de - push bc - push hl - call AIGetEnemyMove - - ld a, [wEnemyMoveStruct + MOVE_POWER] - and a - jr z, .nextmove - -; Don't use risky moves at max hp. - ld a, [wEnemyMoveStruct + MOVE_EFFECT] - ld de, 1 - ld hl, .RiskyMoves - call IsInArray - jr nc, .checkko - - call AICheckEnemyMaxHP - jr c, .nextmove - -; Else, 80% chance to exclude them. - call Random - cp 79 percent - 1 - jr c, .nextmove - -.checkko - call AIDamageCalc - - ld a, [CurDamage + 1] - ld e, a - ld a, [CurDamage] - ld d, a - ld a, [BattleMonHP + 1] - cp e - ld a, [BattleMonHP] - sbc d - jr nc, .nextmove - - pop hl -rept 5 - dec [hl] -endr - push hl - -.nextmove - pop hl - pop bc - pop de - jr .checkmove - -.RiskyMoves: - db EFFECT_SELFDESTRUCT - db EFFECT_OHKO - db $ff -; 39502 - - - -AI_None: ; 39502 - ret -; 39503 - - -AIDiscourageMove: ; 39503 - ld a, [hl] - add 10 - ld [hl], a - ret -; 39508 - - -AIGetEnemyMove: ; 39508 -; Load attributes of move a into ram - - push hl - push de - push bc - dec a - ld hl, Moves - ld bc, MOVE_LENGTH - call AddNTimes - - ld de, wEnemyMoveStruct - ld a, BANK(Moves) - call FarCopyBytes - - pop bc - pop de - pop hl - ret -; 39521 - - -AI_80_20: ; 39521 - call Random - cp 20 percent - 1 - ret -; 39527 - - -AI_50_50: ; 39527 - call Random - cp 50 percent + 1 - ret -; 3952d diff --git a/battle/ai/switch.asm b/battle/ai/switch.asm deleted file mode 100755 index c2f83fa1f..000000000 --- a/battle/ai/switch.asm +++ /dev/null @@ -1,672 +0,0 @@ -CheckPlayerMoveTypeMatchups: ; 3484e -; Check how well the moves you've already used -; fare against the enemy's Pokemon. Used to -; score a potential switch. - push hl - push de - push bc - ld a, 10 - ld [wEnemyAISwitchScore], a - ld hl, PlayerUsedMoves - ld a, [hl] - and a - jr z, .unknown_moves - - ld d, NUM_MOVES - ld e, 0 -.loop - ld a, [hli] - and a - jr z, .exit - push hl - dec a - ld hl, Moves + MOVE_POWER - call GetMoveAttr - and a - jr z, .next - - inc hl - call GetMoveByte - ld hl, EnemyMonType - call CheckTypeMatchup - ld a, [wTypeMatchup] - cp 10 + 1 ; 1.0 + 0.1 - jr nc, .super_effective - and a - jr z, .next - cp 10 ; 1.0 - jr nc, .neutral - -.not_very_effective - ld a, e - cp 1 ; 0.1 - jr nc, .next - ld e, 1 - jr .next - -.neutral - ld e, 2 - jr .next - -.super_effective - call .DecreaseScore - pop hl - jr .done - -.next - pop hl - dec d - jr nz, .loop - -.exit - ld a, e - cp 2 - jr z, .done - call .IncreaseScore - ld a, e - and a - jr nz, .done - call .IncreaseScore - jr .done - -.unknown_moves - ld a, [BattleMonType1] - ld b, a - ld hl, EnemyMonType1 - call CheckTypeMatchup - ld a, [wTypeMatchup] - cp 10 + 1 ; 1.0 + 0.1 - jr c, .ok - call .DecreaseScore -.ok - ld a, [BattleMonType2] - cp b - jr z, .ok2 - call CheckTypeMatchup - ld a, [wTypeMatchup] - cp 10 + 1 ; 1.0 + 0.1 - jr c, .ok2 - call .DecreaseScore -.ok2 - -.done - call .CheckEnemyMoveMatchups - pop bc - pop de - pop hl - ret -; 348de - - -.CheckEnemyMoveMatchups: ; 348de - ld de, EnemyMonMoves - ld b, NUM_MOVES + 1 - ld c, 0 - - ld a, [wTypeMatchup] - push af -.loop2 - dec b - jr z, .exit2 - - ld a, [de] - and a - jr z, .exit2 - - inc de - dec a - ld hl, Moves + MOVE_POWER - call GetMoveAttr - and a - jr z, .loop2 - - inc hl - call GetMoveByte - ld hl, BattleMonType1 - call CheckTypeMatchup - - ld a, [wTypeMatchup] - ; immune - and a - jr z, .loop2 - - ; not very effective - inc c - cp 10 - jr c, .loop2 - - ; neutral - inc c - inc c - inc c - inc c - inc c - cp 10 - jr z, .loop2 - - ; super effective - ld c, 100 - jr .loop2 - -.exit2 - pop af - ld [wTypeMatchup], a - - ld a, c - and a - jr z, .doubledown ; double down - cp 5 - jr c, .DecreaseScore ; down - cp 100 - ret c - jr .IncreaseScore ; up - -.doubledown - call .DecreaseScore -.DecreaseScore: ; 34931 - ld a, [wEnemyAISwitchScore] - dec a - ld [wEnemyAISwitchScore], a - ret -; 34939 - -.IncreaseScore: ; 34939 - ld a, [wEnemyAISwitchScore] - inc a - ld [wEnemyAISwitchScore], a - ret -; 34941 - -CheckAbleToSwitch: ; 34941 - xor a - ld [wEnemySwitchMonParam], a - call FindAliveEnemyMons - ret c - - ld a, [EnemySubStatus1] - bit SUBSTATUS_PERISH, a - jr z, .no_perish - - ld a, [EnemyPerishCount] - cp 1 - jr nz, .no_perish - - ; Perish count is 1 - - call FindAliveEnemyMons - call FindEnemyMonsWithAtLeastQuarterMaxHP - call FindEnemyMonsThatResistPlayer - call FindAliveEnemyMonsWithASuperEffectiveMove - - ld a, e - cp 2 - jr nz, .not_2 - - ld a, [wEnemyAISwitchScore] - add $30 ; maximum chance - ld [wEnemySwitchMonParam], a - ret - -.not_2 - call FindAliveEnemyMons - sla c - sla c - ld b, $ff - -.loop1 - inc b - sla c - jr nc, .loop1 - - ld a, b - add $30 ; maximum chance - ld [wEnemySwitchMonParam], a - ret - -.no_perish - call CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 11 - ret nc - - ld a, [LastPlayerCounterMove] - and a - jr z, .no_last_counter_move - - call FindEnemyMonsImmuneToLastCounterMove - ld a, [wEnemyAISwitchScore] - and a - jr z, .no_last_counter_move - - ld c, a - call FindEnemyMonsWithASuperEffectiveMove - ld a, [wEnemyAISwitchScore] - cp $ff - ret z - - ld b, a - ld a, e - cp 2 - jr z, .not_2_again - - call CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 - ret nc - - ld a, b - add $10 - ld [wEnemySwitchMonParam], a - ret - -.not_2_again - ld c, $10 - call CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 - jr nc, .okay - ld c, $20 - -.okay - ld a, b - add c - ld [wEnemySwitchMonParam], a - ret - -.no_last_counter_move - call CheckPlayerMoveTypeMatchups - ld a, [wEnemyAISwitchScore] - cp 10 - ret nc - - call FindAliveEnemyMons - call FindEnemyMonsWithAtLeastQuarterMaxHP - call FindEnemyMonsThatResistPlayer - call FindAliveEnemyMonsWithASuperEffectiveMove - - ld a, e - cp $2 - ret nz - - ld a, [wEnemyAISwitchScore] - add $10 - ld [wEnemySwitchMonParam], a - ret -; 349f4 - - -FindAliveEnemyMons: ; 349f4 - ld a, [OTPartyCount] - cp 2 - jr c, .only_one - - ld d, a - ld e, 0 - ld b, 1 << (PARTY_LENGTH - 1) - ld c, 0 - ld hl, OTPartyMon1HP - -.loop - ld a, [CurOTMon] - cp e - jr z, .next - - push bc - ld b, [hl] - inc hl - ld a, [hld] - or b - pop bc - jr z, .next - - ld a, c - or b - ld c, a - -.next - srl b - push bc - ld bc, PARTYMON_STRUCT_LENGTH - add hl, bc - pop bc - inc e - dec d - jr nz, .loop - - ld a, c - and a - jr nz, .more_than_one - -.only_one - scf - ret - -.more_than_one - and a - ret -; 34a2a - - -FindEnemyMonsImmuneToLastCounterMove: ; 34a2a - ld hl, OTPartyMon1 - ld a, [OTPartyCount] - ld b, a - ld c, 1 << (PARTY_LENGTH - 1) - ld d, 0 - xor a - ld [wEnemyAISwitchScore], a - -.loop - ld a, [CurOTMon] - cp d - push hl - jr z, .next - - push hl - push bc - - ; If the Pokemon has at least 1 HP... - ld bc, MON_HP - add hl, bc - pop bc - ld a, [hli] - or [hl] - pop hl - jr z, .next - - ld a, [hl] - ld [CurSpecies], a - call GetBaseData - - ; the player's last move is damaging... - ld a, [LastPlayerCounterMove] - dec a - ld hl, Moves + MOVE_POWER - call GetMoveAttr - and a - jr z, .next - - ; and the Pokemon is immune to it... - inc hl - call GetMoveByte - ld hl, BaseType - call CheckTypeMatchup - ld a, [wTypeMatchup] - and a - jr nz, .next - - ; ... encourage that Pokemon. - ld a, [wEnemyAISwitchScore] - or c - ld [wEnemyAISwitchScore], a -.next - pop hl - dec b - ret z - - push bc - ld bc, PARTYMON_STRUCT_LENGTH - add hl, bc - pop bc - - inc d - srl c - jr .loop -; 34a85 - - -FindAliveEnemyMonsWithASuperEffectiveMove: ; 34a85 - push bc - ld a, [OTPartyCount] - ld e, a - ld hl, OTPartyMon1HP - ld b, 1 << (PARTY_LENGTH - 1) - ld c, 0 -.loop - ld a, [hli] - or [hl] - jr z, .next - - ld a, b - or c - ld c, a - -.next - srl b - push bc - ld bc, PartyMon2HP - (PartyMon1HP + 1) - add hl, bc - pop bc - dec e - jr nz, .loop - - ld a, c - pop bc - - and c - ld c, a -FindEnemyMonsWithASuperEffectiveMove: ; 34aa7 - - ld a, -1 - ld [wEnemyAISwitchScore], a - ld hl, OTPartyMon1Moves - ld b, 1 << (PARTY_LENGTH - 1) - ld d, 0 - ld e, 0 -.loop - ld a, b - and c - jr z, .next - - push hl - push bc - ; for move on mon: - ld b, NUM_MOVES - ld c, 0 -.loop3 - ; if move is None: break - ld a, [hli] - and a - push hl - jr z, .break3 - - ; if move has no power: continue - dec a - ld hl, Moves + MOVE_POWER - call GetMoveAttr - and a - jr z, .nope - - ; check type matchups - inc hl - call GetMoveByte - ld hl, BattleMonType1 - call CheckTypeMatchup - - ; if immune or not very effective: continue - ld a, [wTypeMatchup] - cp 10 - jr c, .nope - - ; if neutral: load 1 and continue - ld e, 1 - cp 10 + 1 - jr c, .nope - - ; if super-effective: load 2 and break - ld e, 2 - jr .break3 - -.nope - pop hl - dec b - jr nz, .loop3 - - jr .done - -.break3 - pop hl -.done - ld a, e - pop bc - pop hl - cp 2 - jr z, .done2 ; at least one move is super-effective - cp 1 - jr nz, .next ; no move does more than half damage - - ; encourage this pokemon - ld a, d - or b - ld d, a - jr .next ; such a long jump - -.next - ; next pokemon? - push bc - ld bc, PARTYMON_STRUCT_LENGTH - add hl, bc - pop bc - srl b - jr nc, .loop - - ; if no pokemon has a super-effective move: return - ld a, d - ld b, a - and a - ret z - -.done2 - ; convert the bit flag to an int and return - push bc - sla b - sla b - ld c, $ff -.loop2 - inc c - sla b - jr nc, .loop2 - - ld a, c - ld [wEnemyAISwitchScore], a - pop bc - ret -; 34b20 - - -FindEnemyMonsThatResistPlayer: ; 34b20 - push bc - ld hl, OTPartySpecies - ld b, 1 << (PARTY_LENGTH - 1) - ld c, 0 - -.loop - ld a, [hli] - cp $ff - jr z, .done - - push hl - ld [CurSpecies], a - call GetBaseData - ld a, [LastPlayerCounterMove] - and a - jr z, .skip_move - - dec a - ld hl, Moves + MOVE_POWER - call GetMoveAttr - and a - jr z, .skip_move - - inc hl - call GetMoveByte - jr .check_type - -.skip_move - ld a, [BattleMonType1] - ld hl, BaseType - call CheckTypeMatchup - ld a, [wTypeMatchup] - cp 10 + 1 - jr nc, .dont_choose_mon - ld a, [BattleMonType2] - -.check_type - ld hl, BaseType - call CheckTypeMatchup - ld a, [wTypeMatchup] - cp 10 + 1 - jr nc, .dont_choose_mon - - ld a, b - or c - ld c, a - -.dont_choose_mon - srl b - pop hl - jr .loop - -.done - ld a, c - pop bc - and c - ld c, a - ret -; 34b77 - - -FindEnemyMonsWithAtLeastQuarterMaxHP: ; 34b77 - push bc - ld de, OTPartySpecies - ld b, 1 << (PARTY_LENGTH - 1) - ld c, 0 - ld hl, OTPartyMon1HP - -.loop - ld a, [de] - inc de - cp $ff - jr z, .done - - push hl - push bc - ld b, [hl] - inc hl - ld c, [hl] - inc hl - inc hl -; hl = MaxHP + 1 -; bc = [CurHP] * 4 - srl c - rl b - srl c - rl b -; if bc >= [hl], encourage - ld a, [hld] - cp c - ld a, [hl] - sbc b - pop bc - jr nc, .next - - ld a, b - or c - ld c, a - -.next - srl b - pop hl - push bc - ld bc, PARTYMON_STRUCT_LENGTH - add hl, bc - pop bc - jr .loop - -.done - ld a, c - pop bc - and c - ld c, a - ret -; 34bb1 |