Advertisement
KDLPro

Switch AI Code 3.0

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