KDLPro

Switch AI Code v5.1

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