Advertisement
KDLPro

AI Switch Code 4.1

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