KDLPro

Switch AI Code 4.0

Mar 19th, 2021 (edited)
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. CheckPlayerMoveTypeMatchups:
  2. ; Check how well the moves you've already used
  3. ; fare against the enemy's Pokemon.  Used to
  4. ; score a potential switch.
  5.     push hl
  6.     push de
  7.     push bc
  8.     ld a, BASE_AI_SWITCH_SCORE
  9.     ld [wEnemyAISwitchScore], a
  10.     ld hl, wPlayerUsedMoves
  11.     ld a, [hl]
  12.     and a
  13.     jr z, .unknown_moves
  14.  
  15.     ld d, NUM_MOVES
  16.     ld e, 0
  17. .loop
  18.     ld a, [hli]
  19.     and a
  20.     jr z, .exit
  21.     push hl
  22.     dec a
  23.     ld hl, Moves + MOVE_POWER
  24.     call GetMoveAttr
  25.     and a
  26.     jr z, .next
  27.  
  28.     inc hl
  29.     call GetMoveByte
  30.     ld hl, wEnemyMonType
  31.     call CheckTypeMatchup
  32.     ld a, [wTypeMatchup]
  33.     cp EFFECTIVE ; 1.0 + 0.1
  34.     jr c, .super_effective
  35.     jr z, .neutral
  36.    
  37. ; not very effective
  38.     ld a, e
  39.     cp 1 ; 0.1
  40.     jr nc, .next
  41.     ld e, 1
  42.     jr .next
  43.  
  44. .neutral
  45.     ld e, 2
  46.     jr .next
  47.  
  48. .super_effective
  49.     call .doubledown
  50.     pop hl
  51.     jr .done
  52.  
  53. .next
  54.     pop hl
  55.     dec d
  56.     jr nz, .loop
  57.  
  58. .exit
  59.     ld a, e
  60.     cp 2
  61.     jr z, .done
  62.     call .IncreaseScore
  63.     ld a, e
  64.     and a
  65.     jr nz, .done
  66.     call .IncreaseScore
  67.  
  68. .done
  69.     call .CheckEnemyMoveMatchups
  70.     pop bc
  71.     pop de
  72.     pop hl
  73.     ret
  74.  
  75. .unknown_moves
  76.     ld a, [wBattleMonType1]
  77.     ld b, a
  78.     ld hl, wEnemyMonType1
  79.     call CheckTypeMatchup
  80.     ld a, [wTypeMatchup]
  81.     cp EFFECTIVE ; 1.0 + 0.1
  82.     jr z, .ok
  83.     jr c, .se
  84.     call .IncreaseScore
  85.     jr .ok
  86. .se
  87.     call .DecreaseScore
  88. .ok
  89.     ld a, [wBattleMonType2]
  90.     cp b
  91.     jr z, .done
  92.     call CheckTypeMatchup
  93.     ld a, [wTypeMatchup]
  94.     cp EFFECTIVE ; 1.0 + 0.1
  95.     jr z, .done
  96.     jr c, .se2
  97.     call .IncreaseScore
  98.     jr .done
  99. .se2
  100.     call .DecreaseScore
  101.     jr .done
  102.  
  103. .CheckEnemyMoveMatchups:
  104.     ld de, wEnemyMonMoves
  105.     ld b, NUM_MOVES + 1
  106.     ld c, 0
  107.  
  108.     ld a, [wTypeMatchup]
  109.     push af
  110. .loop2
  111.     dec b
  112.     jr z, .exit2
  113.  
  114.     ld a, [de]
  115.     and a
  116.     jr z, .exit2
  117.  
  118.     inc de
  119.     dec a
  120.     ld hl, Moves + MOVE_POWER
  121.     call GetMoveAttr
  122.     and a
  123.     jr z, .loop2
  124.  
  125.     inc hl
  126.     call GetMoveByte
  127.     ld hl, wBattleMonType1
  128.     call CheckTypeMatchup
  129.  
  130.     ld a, [wTypeMatchup]
  131.      ; immune
  132.     and a
  133.     jr z, .loop2
  134.      ; not very effective
  135.     inc c
  136.     cp EFFECTIVE
  137.     jr c, .loop2
  138.      ; neutral
  139.     inc c
  140.     inc c
  141.     inc c
  142.     inc c
  143.     inc c
  144.     cp EFFECTIVE
  145.     jr z, .loop2
  146.      ; super effective
  147.     ld c, 100
  148.     call .IncreaseScore
  149.     jr .loop2
  150.  
  151. .exit2
  152.     pop af
  153.     ld [wTypeMatchup], a
  154.  
  155.     ld a, c
  156.     and a
  157.     jr z, .doubledown ; double down
  158.     cp 5
  159.     jr c, .DecreaseScore ; down
  160.     cp 100
  161.     ret c
  162.     jr .IncreaseScore ; up
  163.  
  164. .doubledown
  165.     call .DecreaseScore
  166. .DecreaseScore:
  167.     ld a, [wEnemyAISwitchScore]
  168.     dec a
  169.     ld [wEnemyAISwitchScore], a
  170.     ret
  171.  
  172. .IncreaseScore:
  173.     ld a, [wEnemyAISwitchScore]
  174.     inc a
  175.     ld [wEnemyAISwitchScore], a
  176.     ret
  177.  
  178. CheckAbleToSwitch:
  179.     xor a
  180.     ld [wEnemySwitchMonParam], a
  181.     call FindAliveEnemyMons
  182.     ret c
  183.  
  184.     ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
  185.    
  186.     ld a, [wTrainerClass]
  187.     dec a
  188.     ld bc, NUM_TRAINER_ATTRIBUTES
  189.     call AddNTimes
  190.    
  191.     ld a, BANK(TrainerClassAttributes)
  192.     call GetFarByte
  193.     bit SWITCH_OFTEN_F, a
  194.     jr nz, .checkstat
  195.     bit SWITCH_SOMETIMES_F, a
  196.     jr nz, .checkstat
  197.     jr .checkperish
  198. .checkstat
  199.      ; Checks if Evasion is greater than 0
  200.     ld a, [wEnemyEvaLevel]
  201.     cp BASE_STAT_LEVEL + 1
  202.     ret nc
  203.      ; Checks if Accuracy is below -1
  204.     ld a, [wEnemyAccLevel]
  205.     cp BASE_STAT_LEVEL - 1
  206.     jr c, .rollswitch
  207.     ld hl, wPlayerStatLevels
  208.     ld c, NUM_LEVEL_STATS - 1
  209.     ld b, 0
  210.     ld e, 0
  211. .checkplayerbuff  ; Check player's stat buffs
  212.     dec c
  213.     jr z, .checkpt2
  214.     ld a, [hli]
  215.     cp BASE_STAT_LEVEL
  216.     jr nc, .checkplayerbuff2
  217.     jr .checkplayerbuff
  218. .checkplayerbuff2
  219.     sub a, BASE_STAT_LEVEL
  220.     add b    ; b holds the stat buffs
  221.     ld b, a
  222.     jr .checkplayerbuff
  223.  
  224. .checkpt2
  225.     ld hl, wEnemyStatLevels
  226.     ld c, 7
  227. .checkenemybuff  ; Check AI's stat buffs
  228.     dec c
  229.     jr z, .cont_check
  230.     ld a, [hli]
  231.     cp BASE_STAT_LEVEL
  232.     jr nc, .checkenemybuff2
  233.     jr .checkenemybuff
  234. .checkenemybuff2
  235.     sub a, BASE_STAT_LEVEL
  236.     add e    ; e holds the stat buffs
  237.     ld e, a
  238.     jr .checkenemybuff
  239. .cont_check
  240.      ; Checks if AI has no boosts
  241.     ld a, e
  242.     cp 0
  243.     jr c, .cont_check_2
  244.     jr z, .cont_check_2
  245.      ; Check if player is has 2 stat buffs
  246.     ld a, b
  247.     cp 2
  248.     ret nc
  249.      ; Otherwise, roll to check other clauses or not
  250.     call Random
  251.     cp 20 percent
  252.     ret c
  253.     jr .checkperish
  254. .cont_check_2 ; Checks if non-spd stat (because of Curse) is below -2
  255.     ld a, [wEnemyAtkLevel]
  256.     cp BASE_STAT_LEVEL - 2
  257.     jr c, .rollswitch
  258.     ld a, [wEnemyDefLevel]
  259.     cp BASE_STAT_LEVEL - 2
  260.     jr c, .rollswitch
  261.     ld a, [wEnemySAtkLevel]
  262.     cp BASE_STAT_LEVEL - 2
  263.     jr c, .rollswitch
  264.     ld a, [wEnemySDefLevel]
  265.     cp BASE_STAT_LEVEL - 2
  266.     jr c, .rollswitch
  267.     jr .checkperish
  268. .rollswitch
  269.     call Random
  270.     cp 65 percent
  271.     jr c, .switch
  272.     jr .checkperish
  273.    
  274. .checkperish
  275.     ld a, [wEnemySubStatus1]
  276.     bit SUBSTATUS_PERISH, a
  277.     jr z, .no_perish
  278.  
  279.     ld a, [wEnemyPerishCount]
  280.     cp 1
  281.     jr nz, .no_perish
  282.  
  283. .switch ; Try to switch
  284.     call FindAliveEnemyMons
  285.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  286.     call FindEnemyMonsThatResistPlayer
  287.     call FindAliveEnemyMonsWithASuperEffectiveMove
  288.     ld a, e
  289.     cp 2
  290.     jr nz, .not_2
  291.  
  292.     ld a, [wEnemyAISwitchScore]
  293.     add $30 ; maximum chance
  294.     ld [wEnemySwitchMonParam], a
  295.     ret
  296.  
  297. .not_2
  298.     call FindAliveEnemyMons
  299.     sla c
  300.     sla c
  301.     ld b, $ff
  302.  
  303. .loop1
  304.     inc b
  305.     sla c
  306.     jr nc, .loop1
  307.     ld a, b
  308.     add $30 ; maximum chance
  309.     ld [wEnemySwitchMonParam], a
  310.     ret
  311.  
  312. .no_perish
  313.     call CheckPlayerMoveTypeMatchups
  314.     ld a, [wEnemyAISwitchScore]
  315.     cp 11
  316.     ret nc
  317.  
  318.     ld a, [wLastPlayerCounterMove]
  319.     and a
  320.     jr z, .no_last_counter_move
  321.  
  322.     call FindEnemyMonsImmuneToLastCounterMove
  323.     ld a, [wEnemyAISwitchScore]
  324.     and a
  325.     jr z, .no_last_counter_move
  326.  
  327.     ld c, a
  328.     call FindEnemyMonsWithASuperEffectiveMove
  329.     ld a, [wEnemyAISwitchScore]
  330.     cp $ff
  331.     ret z
  332.  
  333.     ld b, a
  334.     ld a, e
  335.     cp 2
  336.     jr z, .not_2_again
  337.  
  338.     call CheckPlayerMoveTypeMatchups
  339.     ld a, [wEnemyAISwitchScore]
  340.     cp 11
  341.     ret nc
  342.  
  343.     ld a, b
  344.     add $20
  345.     ld [wEnemySwitchMonParam], a
  346.     ret
  347.  
  348. .not_2_again
  349.     ld c, $10
  350.     call CheckPlayerMoveTypeMatchups
  351.     ld a, [wEnemyAISwitchScore]
  352.     cp 10
  353.     jr nc, .okay
  354.     ld c, $20
  355.  
  356. .okay
  357.     ld a, b
  358.     add c
  359.     ld [wEnemySwitchMonParam], a
  360.     ret
  361.  ; Smart switching
  362. .smartswitch
  363.     ld a, [wEnemyAISwitchScore]
  364.     ld b, a
  365.     call CheckPlayerMoveTypeMatchups
  366.     ld a, [wEnemyAISwitchScore]
  367.     cp b
  368.     ret c
  369.    
  370.     ld a, e
  371.     cp 2
  372.     jr nz, .not_2
  373.     ld a, b
  374.     add $20
  375.     ld [wEnemySwitchMonParam], a
  376.     ret
  377.  
  378. .no_last_counter_move
  379.     call CheckPlayerMoveTypeMatchups
  380.     ld a, [wEnemyAISwitchScore]
  381.     cp 10
  382.     ret nc
  383.  
  384.     ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
  385.     ld a, [wTrainerClass]
  386.     dec a
  387.     ld bc, NUM_TRAINER_ATTRIBUTES
  388.     call AddNTimes
  389.     ld a, BANK(TrainerClassAttributes)
  390.     call GetFarByte
  391.     bit SWITCH_OFTEN_F, a
  392.     jr nz, .smartcheck
  393.     ret
  394.  ; Randomize switch check only for SWITCH_OFTEN AI
  395. .smartcheck:
  396.     call Random
  397.     cp 55 percent
  398.     ret c
  399.     call Random
  400.     cp 35 percent
  401.     jr c, .algorithm2
  402.      ; Algorithm 1
  403.     call FindAliveEnemyMons
  404.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  405.     call FindEnemyMonsThatResistPlayer
  406.     call FindAliveEnemyMonsWithASuperEffectiveMove
  407.     jp .smartswitch
  408. .algorithm2
  409.     call FindAliveEnemyMons
  410.     call FindEnemyMonsWithAtLeastQuarterMaxHP
  411.     call FindEnemyMonsThatResistPlayer
  412.     jp .smartswitch
  413.  
  414. FindAliveEnemyMons:
  415.     ld a, [wOTPartyCount]
  416.     cp 2
  417.     jr c, .only_one
  418.  
  419.     ld d, a
  420.     ld e, 0
  421.     ld b, 1 << (PARTY_LENGTH - 1)
  422.     ld c, 0
  423.     ld hl, wOTPartyMon1HP
  424.  
  425. .loop
  426.     ld a, [wCurOTMon]
  427.     cp e
  428.     jr z, .next
  429.  
  430.     push bc
  431.     ld b, [hl]
  432.     inc hl
  433.     ld a, [hld]
  434.     or b
  435.     pop bc
  436.     jr z, .next
  437.  
  438.     ld a, c
  439.     or b
  440.     ld c, a
  441.  
  442. .next
  443.     srl b
  444.     push bc
  445.     ld bc, PARTYMON_STRUCT_LENGTH
  446.     add hl, bc
  447.     pop bc
  448.     inc e
  449.     dec d
  450.     jr nz, .loop
  451.  
  452.     ld a, c
  453.     and a
  454.     jr nz, .more_than_one
  455.  
  456. .only_one
  457.     scf
  458.     ret
  459.  
  460. .more_than_one
  461.     and a
  462.     ret
  463.  
  464. FindEnemyMonsImmuneToLastCounterMove:
  465.     ld hl, wOTPartyMon1
  466.     ld a, [wOTPartyCount]
  467.     ld b, a
  468.     ld c, 1 << (PARTY_LENGTH - 1)
  469.     ld d, 0
  470.     xor a
  471.     ld [wEnemyAISwitchScore], a
  472.  
  473. .loop
  474.     ld a, [wCurOTMon]
  475.     cp d
  476.     push hl
  477.     jr z, .next
  478.  
  479.     push hl
  480.     push bc
  481.     ; If the Pokemon has at least 1 HP...
  482.     ld bc, MON_HP
  483.     add hl, bc
  484.     pop bc
  485.     ld a, [hli]
  486.     or [hl]
  487.     pop hl
  488.     jr z, .next
  489.  
  490.     ld a, [hl]
  491.     ld [wCurSpecies], a
  492.     call GetBaseData
  493.     ; the player's last move is damaging...
  494.     ld a, [wLastPlayerCounterMove]
  495.     dec a
  496.     ld hl, Moves + MOVE_POWER
  497.     call GetMoveAttr
  498.     and a
  499.     jr z, .next
  500.     ; and the Pokemon is immune to it...
  501.     inc hl
  502.     call GetMoveByte
  503.     ld hl, wBaseType
  504.     call CheckTypeMatchup
  505.     ld a, [wTypeMatchup]
  506.     and a
  507.     jr nz, .next
  508.     ; ... encourage that Pokemon.
  509.     ld a, [wEnemyAISwitchScore]
  510.     or c
  511.     ld [wEnemyAISwitchScore], a
  512. .next
  513.     pop hl
  514.     dec b
  515.     ret z
  516.  
  517.     push bc
  518.     ld bc, PARTYMON_STRUCT_LENGTH
  519.     add hl, bc
  520.     pop bc
  521.  
  522.     inc d
  523.     srl c
  524.     jr .loop
  525.  
  526. FindAliveEnemyMonsWithASuperEffectiveMove:
  527.     push bc
  528.     ld a, [wOTPartyCount]
  529.     ld e, a
  530.     ld hl, wOTPartyMon1HP
  531.     ld b, 1 << (PARTY_LENGTH - 1)
  532.     ld c, 0
  533. .loop
  534.     ld a, [hli]
  535.     or [hl]
  536.     jr z, .next
  537.  
  538.     ld a, b
  539.     or c
  540.     ld c, a
  541.  
  542. .next
  543.     srl b
  544.     push bc
  545.     ld bc, wPartyMon2HP - (wPartyMon1HP + 1)
  546.     add hl, bc
  547.     pop bc
  548.     dec e
  549.     jr nz, .loop
  550.  
  551.     ld a, c
  552.     pop bc
  553.  
  554.     and c
  555.     ld c, a
  556.     ; fallthrough
  557. FindEnemyMonsWithASuperEffectiveMove:
  558.     ld a, -1
  559.     ld [wEnemyAISwitchScore], a
  560.     ld hl, wOTPartyMon1Moves
  561.     ld b, 1 << (PARTY_LENGTH - 1)
  562.     ld d, 0
  563.     ld e, 0
  564. .loop
  565.     ld a, b
  566.     and c
  567.     jr z, .next
  568.  
  569.     push hl
  570.     push bc
  571.     ; for move on mon:
  572.     ld b, NUM_MOVES
  573.     ld c, 0
  574. .loop3
  575.     ; if move is None: break
  576.     ld a, [hli]
  577.     and a
  578.     push hl
  579.     jr z, .break3
  580.  
  581.     ; if move has no power: continue
  582.     dec a
  583.     ld hl, Moves + MOVE_POWER
  584.     call GetMoveAttr
  585.     and a
  586.     jr z, .nope
  587.  
  588.     ; check type matchups
  589.     inc hl
  590.     call GetMoveByte
  591.     ld hl, wBattleMonType1
  592.     call CheckTypeMatchup
  593.  
  594.     ; if immune or not very effective: continue
  595.     ld a, [wTypeMatchup]
  596.     cp 10
  597.     jr c, .nope
  598.  
  599.     ; if neutral: load 1 and continue
  600.     ld e, 1
  601.     cp EFFECTIVE + 1
  602.     jr c, .nope
  603.  
  604.     ; if super-effective: load 2 and break
  605.     ld e, 2
  606.     jr .break3
  607.  
  608. .nope
  609.     pop hl
  610.     dec b
  611.     jr nz, .loop3
  612.  
  613.     jr .done
  614.  
  615. .break3
  616.     pop hl
  617. .done
  618.     ld a, e
  619.     pop bc
  620.     pop hl
  621.     cp 2
  622.     jr z, .done2 ; at least one move is super-effective
  623.     cp 1
  624.     jr nz, .next ; no move does more than half damage
  625.  
  626.     ; encourage this pokemon
  627.     ld a, d
  628.     or b
  629.     ld d, a
  630.     jr .next ; such a long jump
  631.  
  632. .next
  633.     ; next pokemon?
  634.     push bc
  635.     ld bc, PARTYMON_STRUCT_LENGTH
  636.     add hl, bc
  637.     pop bc
  638.     srl b
  639.     jr nc, .loop
  640.  
  641.     ; if no pokemon has a super-effective move: return
  642.     ld a, d
  643.     ld b, a
  644.     and a
  645.     ret z
  646.  
  647. .done2
  648.     ; convert the bit flag to an int and return
  649.     push bc
  650.     sla b
  651.     sla b
  652.     ld c, $ff
  653. .loop2
  654.     inc c
  655.     sla b
  656.     jr nc, .loop2
  657.  
  658.     ld a, c
  659.     ld [wEnemyAISwitchScore], a
  660.     pop bc
  661.     ret
  662.  
  663. FindEnemyMonsThatResistPlayer:
  664.     push bc
  665.     ld hl, wOTPartySpecies
  666.     ld b, 1 << (PARTY_LENGTH - 1)
  667.     ld c, 0
  668.  
  669. .loop
  670.     ld a, [hli]
  671.     cp $ff
  672.     jr z, .done
  673.  
  674.     push hl
  675.     ld [wCurSpecies], a
  676.     call GetBaseData
  677.     ld a, [wLastPlayerCounterMove]
  678.     and a
  679.     jr z, .skip_move
  680.  
  681.     dec a
  682.     ld hl, Moves + MOVE_POWER
  683.     call GetMoveAttr
  684.     and a
  685.     jr z, .skip_move
  686.  
  687.     inc hl
  688.     call GetMoveByte
  689.     jr .check_type
  690.  
  691. .skip_move
  692.     ld a, [wBattleMonType1]
  693.     ld hl, wBaseType
  694.     call CheckTypeMatchup
  695.     ld a, [wTypeMatchup]
  696.     cp 10 + 1
  697.     jr nc, .dont_choose_mon
  698.     ld a, [wBattleMonType2]
  699.  
  700. .check_type
  701.     ld hl, wBaseType
  702.     call CheckTypeMatchup
  703.     ld a, [wTypeMatchup]
  704.     cp EFFECTIVE + 1
  705.     jr nc, .dont_choose_mon
  706.  
  707.     ld a, b
  708.     or c
  709.     ld c, a
  710.  
  711. .dont_choose_mon
  712.     srl b
  713.     pop hl
  714.     jr .loop
  715.  
  716. .done
  717.     ld a, c
  718.     pop bc
  719.     and c
  720.     ld c, a
  721.     ret
  722.  
  723. FindEnemyMonsWithAtLeastQuarterMaxHP:
  724.     push bc
  725.     ld de, wOTPartySpecies
  726.     ld b, 1 << (PARTY_LENGTH - 1)
  727.     ld c, 0
  728.     ld hl, wOTPartyMon1HP
  729.  
  730. .loop
  731.     ld a, [de]
  732.     inc de
  733.     cp $ff
  734.     jr z, .done
  735.  
  736.     push hl
  737.     push bc
  738.     ld b, [hl]
  739.     inc hl
  740.     ld c, [hl]
  741.     inc hl
  742.     inc hl
  743. ; hl = MaxHP + 1
  744. ; bc = [CurHP] * 4
  745.     srl c
  746.     rl b
  747.     srl c
  748.     rl b
  749. ; if bc >= [hl], encourage
  750.     ld a, [hld]
  751.     cp c
  752.     ld a, [hl]
  753.     sbc b
  754.     pop bc
  755.     jr nc, .next
  756.  
  757.     ld a, b
  758.     or c
  759.     ld c, a
  760.  
  761. .next
  762.     srl b
  763.     pop hl
  764.     push bc
  765.     ld bc, PARTYMON_STRUCT_LENGTH
  766.     add hl, bc
  767.     pop bc
  768.     jr .loop
  769.  
  770. .done
  771.     ld a, c
  772.     pop bc
  773.     and c
  774.     ld c, a
  775.     ret
  776.  
Add Comment
Please, Sign In to add comment