Advertisement
KDLPro

Switch AI Code v5.0

Mar 24th, 2021
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.67 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 nc, .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 nc, .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 nc, .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 60 percent
  328. ret c
  329. call FindAliveEnemyMons
  330. call FindEnemyMonsWithAtLeastQuarterMaxHP
  331. call FindEnemyMonsThatResistPlayer
  332. call FindAliveEnemyMonsWithASuperEffectiveMove
  333. jp .not_2
  334.  
  335. FindAliveEnemyMons:
  336. ld a, [wOTPartyCount]
  337. cp 2
  338. jr c, .only_one
  339.  
  340. ld d, a
  341. ld e, 0
  342. ld b, 1 << (PARTY_LENGTH - 1)
  343. ld c, 0
  344. ld hl, wOTPartyMon1HP
  345.  
  346. .loop
  347. ld a, [wCurOTMon]
  348. cp e
  349. jr z, .next
  350.  
  351. push bc
  352. ld b, [hl]
  353. inc hl
  354. ld a, [hld]
  355. or b
  356. pop bc
  357. jr z, .next
  358.  
  359. ld a, c
  360. or b
  361. ld c, a
  362.  
  363. .next
  364. srl b
  365. push bc
  366. ld bc, PARTYMON_STRUCT_LENGTH
  367. add hl, bc
  368. pop bc
  369. inc e
  370. dec d
  371. jr nz, .loop
  372.  
  373. ld a, c
  374. and a
  375. jr nz, .more_than_one
  376.  
  377. .only_one
  378. scf
  379. ret
  380.  
  381. .more_than_one
  382. and a
  383. ret
  384.  
  385. FindEnemyMonsImmuneToLastCounterMove:
  386. ld hl, wOTPartyMon1
  387. ld a, [wOTPartyCount]
  388. ld b, a
  389. ld c, 1 << (PARTY_LENGTH - 1)
  390. ld d, 0
  391. xor a
  392. ld [wEnemyAISwitchScore], a
  393.  
  394. .loop
  395. ld a, [wCurOTMon]
  396. cp d
  397. push hl
  398. jr z, .next
  399.  
  400. push hl
  401. push bc
  402. ; If the Pokemon has at least 1 HP...
  403. ld bc, MON_HP
  404. add hl, bc
  405. pop bc
  406. ld a, [hli]
  407. or [hl]
  408. pop hl
  409. jr z, .next
  410.  
  411. ld a, [hl]
  412. ld [wCurSpecies], a
  413. call GetBaseData
  414. ; the player's last move is damaging...
  415. ld a, [wLastPlayerCounterMove]
  416. dec a
  417. ld hl, Moves + MOVE_POWER
  418. call GetMoveAttr
  419. and a
  420. jr z, .next
  421. ; and the Pokemon is immune to it...
  422. inc hl
  423. call GetMoveByte
  424. ld hl, wBaseType
  425. call CheckTypeMatchup
  426. ld a, [wTypeMatchup]
  427. and a
  428. jr nz, .next
  429. ; ... encourage that Pokemon.
  430. ld a, [wEnemyAISwitchScore]
  431. or c
  432. ld [wEnemyAISwitchScore], a
  433. .next
  434. pop hl
  435. dec b
  436. ret z
  437.  
  438. push bc
  439. ld bc, PARTYMON_STRUCT_LENGTH
  440. add hl, bc
  441. pop bc
  442.  
  443. inc d
  444. srl c
  445. jr .loop
  446.  
  447. FindAliveEnemyMonsWithASuperEffectiveMove:
  448. push bc
  449. ld a, [wOTPartyCount]
  450. ld e, a
  451. ld hl, wOTPartyMon1HP
  452. ld b, 1 << (PARTY_LENGTH - 1)
  453. ld c, 0
  454. .loop
  455. ld a, [hli]
  456. or [hl]
  457. jr z, .next
  458.  
  459. ld a, b
  460. or c
  461. ld c, a
  462.  
  463. .next
  464. srl b
  465. push bc
  466. ld bc, wPartyMon2HP - (wPartyMon1HP + 1)
  467. add hl, bc
  468. pop bc
  469. dec e
  470. jr nz, .loop
  471.  
  472. ld a, c
  473. pop bc
  474.  
  475. and c
  476. ld c, a
  477. ; fallthrough
  478. FindEnemyMonsWithASuperEffectiveMove:
  479. ld a, -1
  480. ld [wEnemyAISwitchScore], a
  481. ld hl, wOTPartyMon1Moves
  482. ld b, 1 << (PARTY_LENGTH - 1)
  483. ld d, 0
  484. ld e, 0
  485. .loop
  486. ld a, b
  487. and c
  488. jr z, .next
  489.  
  490. push hl
  491. push bc
  492. ; for move on mon:
  493. ld b, NUM_MOVES
  494. ld c, 0
  495. .loop3
  496. ; if move is None: break
  497. ld a, [hli]
  498. and a
  499. push hl
  500. jr z, .break3
  501.  
  502. ; if move has no power: continue
  503. dec a
  504. ld hl, Moves + MOVE_POWER
  505. call GetMoveAttr
  506. and a
  507. jr z, .nope
  508.  
  509. ; check type matchups
  510. inc hl
  511. call GetMoveByte
  512. ld hl, wBattleMonType1
  513. call CheckTypeMatchup
  514.  
  515. ; if immune or not very effective: continue
  516. ld a, [wTypeMatchup]
  517. cp 10
  518. jr c, .nope
  519.  
  520. ; if neutral: load 1 and continue
  521. ld e, 1
  522. cp EFFECTIVE + 1
  523. jr c, .nope
  524.  
  525. ; if super-effective: load 2 and break
  526. ld e, 2
  527. jr .break3
  528.  
  529. .nope
  530. pop hl
  531. dec b
  532. jr nz, .loop3
  533.  
  534. jr .done
  535.  
  536. .break3
  537. pop hl
  538. .done
  539. ld a, e
  540. pop bc
  541. pop hl
  542. cp 2
  543. jr z, .done2 ; at least one move is super-effective
  544. cp 1
  545. jr nz, .next ; no move does more than half damage
  546.  
  547. ; encourage this pokemon
  548. ld a, d
  549. or b
  550. ld d, a
  551. jr .next ; such a long jump
  552.  
  553. .next
  554. ; next pokemon?
  555. push bc
  556. ld bc, PARTYMON_STRUCT_LENGTH
  557. add hl, bc
  558. pop bc
  559. srl b
  560. jr nc, .loop
  561.  
  562. ; if no pokemon has a super-effective move: return
  563. ld a, d
  564. ld b, a
  565. and a
  566. ret z
  567.  
  568. .done2
  569. ; convert the bit flag to an int and return
  570. push bc
  571. sla b
  572. sla b
  573. ld c, $ff
  574. .loop2
  575. inc c
  576. sla b
  577. jr nc, .loop2
  578.  
  579. ld a, c
  580. ld [wEnemyAISwitchScore], a
  581. pop bc
  582. ret
  583.  
  584. FindEnemyMonsThatResistPlayer:
  585. push bc
  586. ld hl, wOTPartySpecies
  587. ld b, 1 << (PARTY_LENGTH - 1)
  588. ld c, 0
  589.  
  590. .loop
  591. ld a, [hli]
  592. cp $ff
  593. jr z, .done
  594.  
  595. push hl
  596. ld [wCurSpecies], a
  597. call GetBaseData
  598. ld a, [wLastPlayerCounterMove]
  599. and a
  600. jr z, .skip_move
  601.  
  602. dec a
  603. ld hl, Moves + MOVE_POWER
  604. call GetMoveAttr
  605. and a
  606. jr z, .skip_move
  607.  
  608. inc hl
  609. call GetMoveByte
  610. jr .check_type
  611.  
  612. .skip_move
  613. ld a, [wBattleMonType1]
  614. ld hl, wBaseType
  615. call CheckTypeMatchup
  616. ld a, [wTypeMatchup]
  617. cp 10 + 1
  618. jr nc, .dont_choose_mon
  619. ld a, [wBattleMonType2]
  620.  
  621. .check_type
  622. ld hl, wBaseType
  623. call CheckTypeMatchup
  624. ld a, [wTypeMatchup]
  625. cp EFFECTIVE + 1
  626. jr nc, .dont_choose_mon
  627.  
  628. ld a, b
  629. or c
  630. ld c, a
  631.  
  632. .dont_choose_mon
  633. srl b
  634. pop hl
  635. jr .loop
  636.  
  637. .done
  638. ld a, c
  639. pop bc
  640. and c
  641. ld c, a
  642. ret
  643.  
  644. FindEnemyMonsWithAtLeastQuarterMaxHP:
  645. push bc
  646. ld de, wOTPartySpecies
  647. ld b, 1 << (PARTY_LENGTH - 1)
  648. ld c, 0
  649. ld hl, wOTPartyMon1HP
  650.  
  651. .loop
  652. ld a, [de]
  653. inc de
  654. cp $ff
  655. jr z, .done
  656.  
  657. push hl
  658. push bc
  659. ld b, [hl]
  660. inc hl
  661. ld c, [hl]
  662. inc hl
  663. inc hl
  664. ; hl = MaxHP + 1
  665. ; bc = [CurHP] * 4
  666. srl c
  667. rl b
  668. srl c
  669. rl b
  670. ; if bc >= [hl], encourage
  671. ld a, [hld]
  672. cp c
  673. ld a, [hl]
  674. sbc b
  675. pop bc
  676. jr nc, .next
  677.  
  678. ld a, b
  679. or c
  680. ld c, a
  681.  
  682. .next
  683. srl b
  684. pop hl
  685. push bc
  686. ld bc, PARTYMON_STRUCT_LENGTH
  687. add hl, bc
  688. pop bc
  689. jr .loop
  690.  
  691. .done
  692. ld a, c
  693. pop bc
  694. and c
  695. ld c, a
  696. ret
  697.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement