Advertisement
KDLPro

Smart AI Switching

Mar 13th, 2021 (edited)
591
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. CheckAbleToSwitch:
  2. ; added stat drop checks for Ultimate
  3.     xor a
  4.     ld [wEnemySwitchMonParam], a
  5.     call FindAliveEnemyMons
  6.     ret c
  7.  
  8.     ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
  9.    
  10.     ld a, [wTrainerClass]
  11.     dec a
  12.     ld bc, NUM_TRAINER_ATTRIBUTES
  13.     call AddNTimes
  14.    
  15.     ld a, BANK(TrainerClassAttributes)
  16.     call GetFarByte
  17.     bit SWITCH_OFTEN_F, a
  18.     jr nz, .checkstat
  19.     bit SWITCH_SOMETIMES_F, a
  20.     jr nz, .checkstat
  21.     jr .checkperish
  22. .checkstat
  23.      ; Checks if non-spd stat (because of Curse) is below -2
  24.      ; Checks if Accuracy is below -1
  25.      ; Checks if Evasion is greater than 0
  26.     ld a, [wEnemyEvaLevel]
  27.     cp BASE_STAT_LEVEL
  28.     ret c
  29.     ld a, [wEnemyAccLevel]
  30.     cp BASE_STAT_LEVEL - 1
  31.     jr c, .rollswitch
  32.     ld hl, wEnemyStatLevels
  33.     ld c, NUM_LEVEL_STATS - 1
  34.     ld b, 0
  35. .checkstatbuff
  36.     ld a, [hli]
  37.     inc d
  38.     ld e, a
  39.     sub BASE_STAT_LEVEL
  40.      ; b holds the stat buffs
  41.     ld a, [hl]
  42.     cp BASE_STAT_LEVEL
  43.     jr nc, .checkstatbuff
  44.     ld a, b
  45.     add e
  46.     ld b, a
  47.     dec c
  48.     jr z, .cont_check
  49.     jr .checkstatbuff
  50. .cont_check
  51.      ; Checks if the player has at least 2 stat buffs
  52.      ; If yes, the AI will not switch. Otherwise, continue checking for stat drops.
  53.      ; +1 = 1 stat buff, +2 = 2 stat buffs
  54.      ; 0 and lower = no stat buffs
  55.     ld a, b
  56.     cp 1
  57.     jr c, .checkperish
  58.      ; Checks for stat drops
  59.     ld a, [wEnemyAtkLevel]
  60.     cp BASE_STAT_LEVEL - 2
  61.     jr c, .rollswitch
  62.     ld a, [wEnemyDefLevel]
  63.     cp BASE_STAT_LEVEL - 2
  64.     jr c, .rollswitch
  65.     ld a, [wEnemySAtkLevel]
  66.     cp BASE_STAT_LEVEL - 2
  67.     jr c, .rollswitch
  68.     ld a, [wEnemySDefLevel]
  69.     cp BASE_STAT_LEVEL - 2
  70.     jr c, .rollswitch
  71.     jr .checkperish
  72. .rollswitch
  73.     call Random
  74.     cp 65 percent
  75.     jr c, .switch
  76.     jr .checkperish
  77.    
  78. .checkperish
  79.     ld a, [wEnemySubStatus1]
  80.     bit SUBSTATUS_PERISH, a
  81.     jr z, .no_perish
  82.  
  83.     ld a, [wEnemyPerishCount]
  84.     cp 1
  85.     jr nz, .no_perish
  86.  
  87.     ; Try to switch
  88. .switch
  89.     call FindAliveEnemyMons
  90.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  91.     call FindEnemyMonsThatResistPlayer
  92.     call FindAliveEnemyMonsWithASuperEffectiveMove
  93.  
  94.     ld a, e
  95.     cp 2
  96.     jr nz, .not_2
  97.  
  98.     ld a, [wEnemyAISwitchScore]
  99.     add $30 ; maximum chance
  100.     ld [wEnemySwitchMonParam], a
  101.     ret
  102.  
  103. .not_2
  104.     call FindAliveEnemyMons
  105.     sla c
  106.     sla c
  107.     ld b, $ff
  108.  
  109. .loop1
  110.     inc b
  111.     sla c
  112.     jr nc, .loop1
  113.  
  114.     ld a, b
  115.     add $30 ; maximum chance
  116.     ld [wEnemySwitchMonParam], a
  117.     ret
  118.  
  119. .no_perish
  120.     call CheckPlayerMoveTypeMatchups
  121.     ld a, [wEnemyAISwitchScore]
  122.     cp 11
  123.     ret nc
  124.  
  125.     ld a, [wLastPlayerCounterMove]
  126.     and a
  127.     jr z, .no_last_counter_move
  128.  
  129.     call FindEnemyMonsImmuneToLastCounterMove
  130.     ld a, [wEnemyAISwitchScore]
  131.     and a
  132.     jr z, .no_last_counter_move
  133.  
  134.     ld c, a
  135.     call FindEnemyMonsWithASuperEffectiveMove
  136.     ld a, [wEnemyAISwitchScore]
  137.     cp $ff
  138.     ret z
  139.  
  140.     ld b, a
  141.     ld a, e
  142.     cp 2
  143.     jr z, .not_2_again
  144.  
  145.     call CheckPlayerMoveTypeMatchups
  146.     ld a, [wEnemyAISwitchScore]
  147.     cp 11
  148.     ret nc
  149.  
  150.     ld a, b
  151.     add $20
  152.     ld [wEnemySwitchMonParam], a
  153.     ret
  154.  
  155. .not_2_again
  156.     ld c, $10
  157.     call CheckPlayerMoveTypeMatchups
  158.     ld a, [wEnemyAISwitchScore]
  159.     cp 10
  160.     jr nc, .okay
  161.     ld c, $20
  162.  
  163. .okay
  164.     ld a, b
  165.     add c
  166.     ld [wEnemySwitchMonParam], a
  167.     ret
  168.  
  169.  ; Smart switching
  170. .smartswitch
  171.     call Random
  172.     cp 80 percent
  173.     jr c, .no_switch
  174.  
  175.     ld a, e
  176.     cp 2
  177.     jr nz, .not_2
  178.    
  179.     ld a, [wEnemyAISwitchScore]
  180.     add $20
  181.     ld [wEnemySwitchMonParam], a
  182.     ret
  183.    
  184. .no_switch
  185.     ld a, e
  186.     cp $2
  187.     ret nz
  188.  
  189. .no_last_counter_move
  190.     call CheckPlayerMoveTypeMatchups
  191.     ld a, [wEnemyAISwitchScore]
  192.     cp 11
  193.     ret nc
  194.  
  195.     ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
  196.    
  197.     ld a, [wTrainerClass]
  198.     dec a
  199.     ld bc, NUM_TRAINER_ATTRIBUTES
  200.     call AddNTimes
  201.    
  202.     ld a, BANK(TrainerClassAttributes)
  203.     call GetFarByte
  204.     bit SWITCH_OFTEN_F, a
  205.     jr nz, .smartcheck
  206.     jr .defaultcheck
  207.    
  208.  ; Randomize switch check only for SWITCH_OFTEN AI
  209. .smartcheck:
  210.     call Random
  211.     cp 35 percent
  212.     jr c, .algorithm2
  213.      ; Algorithm 1
  214.     call FindAliveEnemyMons
  215.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  216.     call FindEnemyMonsThatResistPlayer
  217.     call FindAliveEnemyMonsWithASuperEffectiveMove
  218.     jp .smartswitch
  219.    
  220. .algorithm2
  221.     call FindAliveEnemyMons
  222.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  223.     call FindEnemyMonsThatResistPlayer
  224.     jp .smartswitch
  225.  ; Default switch check for SWITCH_SOMETIMES and SWITCH_RARELY
  226. .defaultcheck  
  227.     call FindAliveEnemyMons
  228.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  229.     call FindEnemyMonsThatResistPlayer
  230.     call FindAliveEnemyMonsWithASuperEffectiveMove
  231.  
  232.     ld a, e
  233.     cp $2
  234.     ret nz
  235.    
  236.     ld a, [wEnemyAISwitchScore]
  237.     add $10
  238.     ld [wEnemySwitchMonParam], a
  239.     ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement