Advertisement
Guest User

AI

a guest
Jul 3rd, 2014
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 78.20 KB | None | 0 0
  1. class PokeBattle_Battle
  2. ################################################################################
  3. # Get a score for each move being considered.
  4. # Moves with higher scores are more likely to be chosen.
  5. ################################################################################
  6. def pbGetMoveScore(move,attacker,opponent,skill=100)
  7. score=100
  8. # Alter score depending on the move's function code.
  9. case move.function
  10. when 0x00
  11. if move.priority>0
  12. score+=15
  13. score+=20 if attacker.hp<=(attacker.totalhp/2)
  14. end
  15. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  16. score+=40 if attacker.effects[PBEffects::FocusEnergy]>0
  17. end
  18. when 0x01
  19. score-=100
  20. when 0x02 # Struggle
  21. when 0x03
  22. score-=80 if opponent.status!=0
  23. score-=60 if opponent.effects[PBEffects::Yawn]>0
  24. if move.basedamage==0
  25. score-=70 if !opponent.pbCanSleep?(false)
  26. end
  27. when 0x04
  28. score-=80 if opponent.status!=0
  29. score-=80 if opponent.effects[PBEffects::Yawn]>0
  30. score-=40 if !opponent.pbCanSleep?(false)
  31. when 0x05
  32. score-=15 if opponent.status==PBStatuses::POISON
  33. if move.basedamage==0
  34. score-=90 if !opponent.pbCanPoison?(false)
  35. end
  36. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  37. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  38. end
  39. when 0x06
  40. if move.basedamage==0
  41. if !opponent.pbCanPoison?(false)
  42. score-=90
  43. elsif attacker.turncount<4
  44. score+=90
  45. else
  46. score+=40
  47. end
  48. else
  49. score-=20 if opponent.status==PBStatuses::POISON
  50. end
  51. when 0x07
  52. if move.basedamage==0
  53. if !opponent.pbCanParalyze?(false) || pbTypeModifier(move.type,attacker,opponent)==0
  54. score-=80
  55. else
  56. score+=30 if pbRoughStat(attacker,
  57. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  58. score+=70 if attacker.turncount<3
  59. score+=40 if attacker.turncount>=3
  60. end
  61. else
  62. score+=15 if pbRoughStat(attacker,
  63. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  64. score-=10 if opponent.status==PBStatuses::PARALYSIS
  65. end
  66. when 0x08
  67. score-=50 if pbWeather==PBWeather::SUNNYDAY
  68. score+=30 if pbWeather==PBWeather::RAINDANCE
  69. score+=30 if pbWeather==PBWeather::MOLTENRAIN
  70. when 0x09
  71. score+=15 if pbRoughStat(attacker,
  72. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  73. score-=10 if opponent.status==PBStatuses::PARALYSIS
  74. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  75. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  76. end
  77. when 0x0A
  78. if move.basedamage==0
  79. score-=80 if opponent.status!=0
  80. score-=90 if opponent.pbHasType?(:FIRE)
  81. else
  82. score-=10 if opponent.status==PBStatuses::BURN
  83. score-=40 if opponent.pbHasType?(:FIRE)
  84. end
  85. if (move.flags&0x40)==0 # flag g: Thaws user before moving
  86. score+=70 if attacker.status==PBStatuses::FROZEN
  87. end
  88. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  89. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  90. end
  91. when 0x0B
  92. score-=10 if opponent.status==PBStatuses::BURN
  93. score-=40 if opponent.pbHasType?(:FIRE)
  94. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  95. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  96. end
  97. when 0x0C
  98. if move.basedamage==0
  99. score-=80 if opponent.status!=0
  100. score-=90 if opponent.pbHasType?(:ICE)
  101. else
  102. score-=10 if opponent.status==PBStatuses::FROZEN
  103. end
  104. when 0x0D
  105. score-=10 if opponent.status==PBStatuses::FROZEN
  106. score+=30 if pbWeather==PBWeather::HAIL
  107. when 0x0E
  108. score-=10 if opponent.status==PBStatuses::FROZEN
  109. if (move.flags&0x80)!=0 # flag h: Has high critical hit rate
  110. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  111. end
  112. when 0x0F
  113. score-=10 if isConst?(opponent.ability,PBAbilities,:INNERFOCUS)
  114. when 0x10
  115. score+=40 if opponent.effects[PBEffects::Minimize]
  116. when 0x11
  117. score-=140 if attacker.status!=PBStatuses::SLEEP
  118. score+=70 if attacker.status==PBStatuses::SLEEP
  119. when 0x12
  120. score-=200 if attacker.turncount>=1
  121. when 0x13
  122. if move.basedamage==0
  123. if !opponent.pbCanConfuse?(false)
  124. score-=80
  125. elsif move.accuracy>=75
  126. score+=70 if attacker.turncount<3
  127. score+=40 if attacker.turncount>=3
  128. end
  129. else
  130. score-=10 if !opponent.pbCanConfuse?(false)
  131. end
  132. when 0x14
  133. when 0x15
  134. score-=10 if !opponent.pbCanConfuse?(false)
  135. score-=50 if pbWeather==PBWeather::SUNNYDAY
  136. score+=30 if pbWeather==PBWeather::RAINDANCE
  137. score+=30 if pbWeather==PBWeather::MOLTENRAIN
  138. when 0x16
  139. agender=attacker.gender
  140. ogender=opponent.gender
  141. if agender==2 || ogender==2 || agender==ogender
  142. score-=80
  143. elsif opponent.effects[PBEffects::Attract]>=0
  144. score-=90
  145. end
  146. if isConst?(opponent.ability,PBAbilities,:OBLIVIOUS)
  147. score-=80
  148. end
  149. when 0x17
  150. score-=10 if opponent.status==PBStatuses::BURN
  151. score-=10 if opponent.status==PBStatuses::FROZEN
  152. score-=10 if opponent.status==PBStatuses::PARALYSIS
  153. when 0x18
  154. score-=80 if attacker.status==0
  155. when 0x19
  156. party=pbParty(attacker.index)
  157. statuses=0
  158. for i in 0...party.length
  159. statuses+=1 if party[i] && party[i].status!=0
  160. end
  161. score-=80 if statuses==0
  162. when 0x1A
  163. if attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  164. score-=80
  165. else
  166. score+=30
  167. end
  168. when 0x1B
  169. when 0x1C
  170. if move.basedamage==0
  171. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK)
  172. if skill>=50
  173. hasAttack=false
  174. for thismove in attacker.moves
  175. if thismove.id!=0 && thismove.basedamage>0 &&
  176. thismove.pbIsPhysical?(thismove.type)
  177. hasAttack=true
  178. end
  179. end
  180. score-=80 if !hasAttack
  181. end
  182. if score>20
  183. score-=(attacker.stages[PBStats::ATTACK]*10)
  184. end
  185. else
  186. score+=20 if (attacker.stages[PBStats::ATTACK]<0)
  187. end
  188. when 0x1D
  189. if move.basedamage==0
  190. score-=80 if attacker.pbTooHigh?(PBStats::DEFENSE)
  191. score-=(attacker.stages[PBStats::DEFENSE]*10)
  192. else
  193. score+=20 if (attacker.stages[PBStats::DEFENSE]<0)
  194. end
  195. when 0x1E
  196. score-=(attacker.stages[PBStats::DEFENSE]*10)
  197. when 0x1F
  198. if move.basedamage==0
  199. score-=80 if attacker.pbTooHigh?(PBStats::SPEED)
  200. score-=(attacker.stages[PBStats::SPEED]*10)
  201. else
  202. score+=20 if (attacker.stages[PBStats::SPEED]<0)
  203. end
  204. when 0x20
  205. if move.basedamage==0
  206. score-=80 if attacker.pbTooHigh?(PBStats::SPATK)
  207. score-=(attacker.stages[PBStats::SPATK]*10)
  208. else
  209. score+=20 if (attacker.stages[PBStats::SPATK]<0)
  210. end
  211. when 0x21
  212. found=false
  213. for i in 0...4
  214. if isConst?(attacker.moves[i].type,PBTypes,:ELECTRIC) &&
  215. attacker.moves[i].basedamage>0
  216. found=true
  217. break
  218. end
  219. end
  220. if move.basedamage==0
  221. score-=80 if !found
  222. score-=80 if opponent.effects[PBEffects::Charge]>0
  223. score-=80 if attacker.pbTooHigh?(PBStats::SPDEF)
  224. score-=(attacker.stages[PBStats::SPDEF]*10)
  225. else
  226. score-=20 if !found
  227. score-=20 if opponent.effects[PBEffects::Charge]>0
  228. score+=20 if (attacker.stages[PBStats::SPDEF]<0)
  229. end
  230. when 0x22
  231. if move.basedamage==0
  232. score-=80 if attacker.pbTooHigh?(PBStats::EVASION)
  233. score-=(attacker.stages[PBStats::EVASION]*10)
  234. else
  235. score+=20 if (attacker.stages[PBStats::EVASION]<0)
  236. end
  237. when 0x23
  238. if move.basedamage==0
  239. score-=80 if attacker.effects[PBEffects::FocusEnergy]>0
  240. else
  241. score-=20 if attacker.effects[PBEffects::FocusEnergy]>0
  242. end
  243. when 0x24
  244. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  245. attacker.pbTooHigh?(PBStats::DEFENSE)
  246. if score>20
  247. avg=-(attacker.stages[PBStats::ATTACK]*10)
  248. avg-=(attacker.stages[PBStats::DEFENSE]*10)
  249. score+=avg/2
  250. end
  251. when 0x25
  252. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  253. attacker.pbTooHigh?(PBStats::DEFENSE) &&
  254. attacker.pbTooHigh?(PBStats::ACCURACY)
  255. if score>20
  256. avg=-(attacker.stages[PBStats::ATTACK]*10)
  257. avg-=(attacker.stages[PBStats::DEFENSE]*10)
  258. avg-=(attacker.stages[PBStats::ACCURACY]*10)
  259. score+=avg/3
  260. end
  261. when 0x26 # Dragon Dance tends to be popular
  262. score+=40 if attacker.turncount==0
  263. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  264. attacker.pbTooHigh?(PBStats::SPEED)
  265. if score>20
  266. avg=-(attacker.stages[PBStats::ATTACK]*10)
  267. avg-=(attacker.stages[PBStats::SPEED]*10)
  268. score+=avg/2
  269. end
  270. when 0x27
  271. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  272. attacker.pbTooHigh?(PBStats::SPATK)
  273. if score>20
  274. avg=-(attacker.stages[PBStats::ATTACK]*10)
  275. avg-=(attacker.stages[PBStats::SPATK]*10)
  276. score+=avg/2
  277. end
  278. when 0x28
  279. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  280. attacker.pbTooHigh?(PBStats::SPATK)
  281. if score>20
  282. avg=-(attacker.stages[PBStats::ATTACK]*10)
  283. avg-=(attacker.stages[PBStats::SPATK]*10)
  284. score+=avg/2
  285. end
  286. score+=20 if pbWeather==PBWeather::SUNNYDAY
  287. score+=20 if pbWeather==PBWeather::MOLTENRAIN
  288. when 0x29
  289. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  290. attacker.pbTooHigh?(PBStats::ACCURACY)
  291. if score>20
  292. avg=-(attacker.stages[PBStats::ATTACK]*10)
  293. avg-=(attacker.stages[PBStats::ACCURACY]*10)
  294. score+=avg/2
  295. end
  296. when 0x2A
  297. score-=80 if attacker.pbTooHigh?(PBStats::DEFENSE) &&
  298. attacker.pbTooHigh?(PBStats::SPDEF)
  299. if score>20
  300. avg=-(attacker.stages[PBStats::DEFENSE]*10)
  301. avg-=(attacker.stages[PBStats::SPDEF]*10)
  302. score+=avg/2
  303. end
  304. when 0x2B
  305. score-=80 if attacker.pbTooHigh?(PBStats::SPEED) &&
  306. attacker.pbTooHigh?(PBStats::SPATK) &&
  307. attacker.pbTooHigh?(PBStats::SPDEF)
  308. if score>20
  309. avg=-(attacker.stages[PBStats::SPEED]*10)
  310. avg-=(attacker.stages[PBStats::SPATK]*10)
  311. avg-=(attacker.stages[PBStats::SPDEF]*10)
  312. score+=avg/3
  313. end
  314. when 0x2C # Calm Mind tends to be popular
  315. score+=40 if attacker.turncount==0
  316. score-=80 if attacker.pbTooHigh?(PBStats::SPATK) &&
  317. attacker.pbTooHigh?(PBStats::SPDEF)
  318. if score>20
  319. avg=-(attacker.stages[PBStats::SPATK]*10)
  320. avg-=(attacker.stages[PBStats::SPDEF]*10)
  321. score+=avg/2
  322. end
  323. when 0x2D
  324. score+=10 if (attacker.stages[PBStats::ATTACK]<0)
  325. score+=10 if (attacker.stages[PBStats::DEFENSE]<0)
  326. score+=10 if (attacker.stages[PBStats::SPEED]<0)
  327. score+=10 if (attacker.stages[PBStats::SPATK]<0)
  328. score+=10 if (attacker.stages[PBStats::SPDEF]<0)
  329. when 0x2E
  330. if move.basedamage==0
  331. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK)
  332. if skill>=50
  333. hasAttack=false
  334. for thismove in attacker.moves
  335. if thismove.id!=0 && thismove.basedamage>0 &&
  336. thismove.pbIsPhysical?(thismove.type)
  337. hasAttack=true
  338. end
  339. end
  340. score-=80 if !hasAttack
  341. end
  342. if score>20
  343. score+=60 if attacker.turncount==0
  344. score-=(attacker.stages[PBStats::ATTACK]*20)
  345. end
  346. else
  347. score-=20 if attacker.pbTooHigh?(PBStats::ATTACK)
  348. if skill>=50
  349. hasAttack=false
  350. for thismove in attacker.moves
  351. if thismove.id!=0 && thismove.basedamage>0 &&
  352. thismove.pbIsPhysical?(thismove.type)
  353. hasAttack=true
  354. end
  355. end
  356. score-=20 if !hasAttack
  357. end
  358. if score>20
  359. score+=10 if attacker.turncount==0
  360. score-=(attacker.stages[PBStats::ATTACK]*10)
  361. end
  362. end
  363. when 0x2F
  364. if move.basedamage==0
  365. score-=80 if attacker.pbTooHigh?(PBStats::DEFENSE)
  366. if score>20
  367. score-=(attacker.stages[PBStats::DEFENSE]*20)
  368. end
  369. else
  370. score+=20 if (attacker.stages[PBStats::DEFENSE]<0)
  371. end
  372. when 0x30
  373. if move.basedamage==0
  374. if skill>=70
  375. score-=80 if pbRoughStat(attacker,
  376. PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  377. end
  378. score-=80 if attacker.pbTooHigh?(PBStats::SPEED)
  379. if score>20
  380. score-=(attacker.stages[PBStats::SPEED]*20)
  381. end
  382. else
  383. score+=20 if (attacker.stages[PBStats::SPEED]<0)
  384. end
  385. when 0x31
  386. if skill>=70
  387. score-=80 if pbRoughStat(attacker,
  388. PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  389. end
  390. score-=80 if attacker.pbTooHigh?(PBStats::SPEED)
  391. if score>20
  392. score-=(attacker.stages[PBStats::SPEED]*20)
  393. end
  394. when 0x32
  395. if move.basedamage==0
  396. score-=80 if attacker.pbTooHigh?(PBStats::SPATK)
  397. if skill>=50
  398. hasAttack=false
  399. for thismove in attacker.moves
  400. if thismove.id!=0 && thismove.basedamage>0 &&
  401. !thismove.pbIsPhysical?(thismove.type)
  402. hasAttack=true
  403. end
  404. end
  405. score-=80 if !hasAttack
  406. end
  407. if score>20
  408. score+=60 if attacker.turncount==0
  409. score-=(attacker.stages[PBStats::SPATK]*20)
  410. end
  411. else
  412. score-=20 if attacker.pbTooHigh?(PBStats::SPATK)
  413. if skill>=50
  414. hasAttack=false
  415. for thismove in attacker.moves
  416. if thismove.id!=0 && thismove.basedamage>0 &&
  417. !thismove.pbIsPhysical?(thismove.type)
  418. hasAttack=true
  419. end
  420. end
  421. score-=20 if !hasAttack
  422. end
  423. if score>20
  424. score+=20 if attacker.turncount==0
  425. score-=(attacker.stages[PBStats::SPATK]*10)
  426. end
  427. end
  428. when 0x33
  429. if move.basedamage==0
  430. score-=80 if attacker.pbTooHigh?(PBStats::SPDEF)
  431. if score>20
  432. score-=(attacker.stages[PBStats::SPDEF]*20)
  433. end
  434. else
  435. score-=20 if attacker.pbTooHigh?(PBStats::SPDEF)
  436. if score>20
  437. score-=(attacker.stages[PBStats::SPDEF]*10)
  438. end
  439. end
  440. when 0x34
  441. score-=(attacker.stages[PBStats::EVASION]*10)
  442. when 0x35
  443. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  444. attacker.pbTooHigh?(PBStats::SPEED) &&
  445. attacker.pbTooHigh?(PBStats::SPATK)
  446. if score>20
  447. avg=-(attacker.stages[PBStats::ATTACK]*20)
  448. avg-=(attacker.stages[PBStats::SPEED]*20)
  449. avg-=(attacker.stages[PBStats::SPATK]*20)
  450. score+=avg/3
  451. end
  452. when 0x36
  453. score-=80 if attacker.pbTooHigh?(PBStats::ATTACK) &&
  454. attacker.pbTooHigh?(PBStats::SPEED)
  455. if score>20
  456. avg=-(attacker.stages[PBStats::ATTACK]*10)
  457. avg-=(attacker.stages[PBStats::SPEED]*20)
  458. score+=avg/2
  459. end
  460. when 0x37
  461. when 0x38
  462. if move.basedamage==0
  463. score-=80 if attacker.pbTooHigh?(PBStats::DEFENSE)
  464. score-=(attacker.stages[PBStats::DEFENSE]*30)
  465. else
  466. score+=30 if (attacker.stages[PBStats::DEFENSE]<0)
  467. end
  468. when 0x39
  469. score-=80 if attacker.pbTooHigh?(PBStats::SPATK)
  470. if skill>=50
  471. hasAttack=false
  472. for thismove in attacker.moves
  473. if thismove.id!=0 && thismove.basedamage>0 &&
  474. !thismove.pbIsPhysical?(thismove.type)
  475. hasAttack=true
  476. end
  477. end
  478. score-=80 if !hasAttack
  479. end
  480. if score>20
  481. score-=(attacker.stages[PBStats::SPATK]*30)
  482. end
  483. when 0x3A
  484. if attacker.hp<=attacker.totalhp/2 || attacker.pbTooHigh?(PBStats::ATTACK)
  485. score-=100
  486. end
  487. when 0x3B
  488. avg=(attacker.stages[PBStats::ATTACK]*10)
  489. avg+=(attacker.stages[PBStats::DEFENSE]*10)
  490. score+=avg/2
  491. when 0x3C
  492. avg=(attacker.stages[PBStats::DEFENSE]*10)
  493. avg+=(attacker.stages[PBStats::SPDEF]*10)
  494. score+=avg/2
  495. when 0x3D
  496. avg=(attacker.stages[PBStats::DEFENSE]*10)
  497. avg+=(attacker.stages[PBStats::SPEED]*10)
  498. avg+=(attacker.stages[PBStats::SPDEF]*10)
  499. score+=avg/3
  500. when 0x3E
  501. score+=(attacker.stages[PBStats::SPEED]*10)
  502. when 0x3F
  503. score+=(attacker.stages[PBStats::SPATK]*10)
  504. when 0x40
  505. if !opponent.pbCanConfuse?(false)
  506. score-=90
  507. elsif opponent.stages[PBStats::SPATK]<0
  508. score+=30
  509. end
  510. when 0x41
  511. if !opponent.pbCanConfuse?(false)
  512. score-=90
  513. elsif opponent.stages[PBStats::ATTACK]<0
  514. score+=30
  515. end
  516. when 0x42
  517. if move.basedamage==0
  518. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::ATTACK)
  519. if score>20
  520. score+=(opponent.stages[PBStats::ATTACK]*10)
  521. end
  522. else
  523. score-=10 if opponent.stages[PBStats::ATTACK]<0
  524. end
  525. when 0x43
  526. if move.basedamage==0
  527. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE)
  528. if score>20
  529. score+=(opponent.stages[PBStats::DEFENSE]*10)
  530. end
  531. else
  532. score-=10 if opponent.stages[PBStats::DEFENSE]<0
  533. end
  534. when 0x44
  535. if move.basedamage==0
  536. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPEED)
  537. score-=80 if pbRoughStat(attacker,
  538. PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  539. if score>20
  540. score+=(opponent.stages[PBStats::SPEED]*10)
  541. end
  542. else
  543. score-=10 if opponent.stages[PBStats::SPEED]<0
  544. end
  545. when 0x45
  546. if move.basedamage==0
  547. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPATK)
  548. if score>20
  549. score+=(opponent.stages[PBStats::SPATK]*10)
  550. end
  551. else
  552. score-=10 if opponent.stages[PBStats::SPATK]<0
  553. end
  554. when 0x46
  555. if move.basedamage==0
  556. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPDEF)
  557. if score>20
  558. score+=(opponent.stages[PBStats::SPDEF]*10)
  559. end
  560. else
  561. score-=10 if opponent.stages[PBStats::SPDEF]<0
  562. end
  563. when 0x47
  564. if move.basedamage==0
  565. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::ACCURACY)
  566. if score>20
  567. score+=(opponent.stages[PBStats::ACCURACY]*10)
  568. end
  569. else
  570. score-=10 if opponent.stages[PBStats::ACCURACY]<0
  571. end
  572. when 0x48
  573. if move.basedamage==0
  574. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::EVASION)
  575. if score>20
  576. score+=(opponent.stages[PBStats::EVASION]*10)
  577. end
  578. else
  579. score-=10 if opponent.stages[PBStats::EVASION]<0
  580. end
  581. when 0x49
  582. if move.basedamage==0
  583. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::EVASION)
  584. if score>20
  585. score+=(opponent.stages[PBStats::EVASION]*10)
  586. end
  587. score-=60 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0 ||
  588. attacker.pbOwnSide.effects[PBEffects::Mist]>0 ||
  589. attacker.pbOwnSide.effects[PBEffects::Reflect]>0 ||
  590. attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  591. score+=30 if attacker.pbOwnSide.effects[PBEffects::Spikes]>0
  592. else
  593. score-=10 if opponent.stages[PBStats::EVASION]<0
  594. score-=20 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0 ||
  595. attacker.pbOwnSide.effects[PBEffects::Mist]>0 ||
  596. attacker.pbOwnSide.effects[PBEffects::Reflect]>0 ||
  597. attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  598. score+=10 if attacker.pbOwnSide.effects[PBEffects::Spikes]>0
  599. end
  600. when 0x4A
  601. avg=(opponent.stages[PBStats::ATTACK]*10)
  602. avg+=(opponent.stages[PBStats::DEFENSE]*10)
  603. score+=avg/2
  604. when 0x4B
  605. if move.basedamage==0
  606. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::ATTACK)
  607. if score>20
  608. score+=(opponent.stages[PBStats::ATTACK]*20)
  609. end
  610. else
  611. score-=20 if opponent.stages[PBStats::ATTACK]<0
  612. end
  613. when 0x4C
  614. if move.basedamage==0
  615. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE)
  616. if score>20
  617. score+=(opponent.stages[PBStats::DEFENSE]*20)
  618. end
  619. else
  620. score-=20 if opponent.stages[PBStats::DEFENSE]<0
  621. end
  622. when 0x4D
  623. if move.basedamage==0
  624. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPEED)
  625. score-=80 if pbRoughStat(attacker,
  626. PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  627. if score>20
  628. score+=(opponent.stages[PBStats::SPEED]*20)
  629. end
  630. else
  631. score-=20 if opponent.stages[PBStats::SPEED]<0
  632. end
  633. when 0x4E
  634. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPATK)
  635. if score>20
  636. score+=(opponent.stages[PBStats::SPATK]*20)
  637. end
  638. agender=attacker.gender
  639. ogender=opponent.gender
  640. if agender==2 || ogender==2 || agender==ogender
  641. score-=80
  642. end
  643. if isConst?(opponent.ability,PBAbilities,:OBLIVIOUS)
  644. score-=80
  645. end
  646. when 0x4F
  647. if move.basedamage==0
  648. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::SPDEF)
  649. if score>20
  650. score+=(opponent.stages[PBStats::SPDEF]*20)
  651. end
  652. else
  653. score-=20 if opponent.stages[PBStats::SPDEF]<0
  654. end
  655. when 0x50
  656. when 0x51
  657. stages=0
  658. for i in 0..3
  659. battler=@battlers[i]
  660. stages+=battler.stages[PBStats::ATTACK]
  661. stages+=battler.stages[PBStats::DEFENSE]
  662. stages+=battler.stages[PBStats::SPEED]
  663. stages+=battler.stages[PBStats::SPATK]
  664. stages+=battler.stages[PBStats::SPDEF]
  665. stages+=battler.stages[PBStats::EVASION]
  666. stages+=battler.stages[PBStats::ACCURACY]
  667. end
  668. score-=80 if stages==0
  669. when 0x52
  670. when 0x53
  671. when 0x54
  672. when 0x55
  673. equal=true
  674. for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  675. PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  676. score+=10 if opponent.stages[i]>attacker.stages[i]
  677. score-=10 if opponent.stages[i]<attacker.stages[i]
  678. equal=false if opponent.stages[i]!=attacker.stages[i]
  679. end
  680. score-=80 if equal
  681. when 0x56
  682. score-=80 if attacker.pbOwnSide.effects[PBEffects::Mist]>0
  683. when 0x57
  684. when 0x58
  685. when 0x59
  686. when 0x5A
  687. oldahp=attacker.hp
  688. oldohp=opponent.hp
  689. avghp=((opponent.hp+attacker.hp)/2).floor
  690. attackerhp=avghp
  691. opponenthp=avghp
  692. attackerhp=attacker.totalhp if attackerhp>attacker.totalhp
  693. opponenthp=opponent.totalhp if opponenthp>opponent.totalhp
  694. if opponenthp>opponent.hp || attackerhp<attacker.hp
  695. score-=80
  696. elsif opponent.effects[PBEffects::Substitute]>0
  697. score-=80
  698. else
  699. score+=30
  700. end
  701. when 0x5B
  702. when 0x5C
  703. when 0x5D
  704. when 0x5E
  705. when 0x5F
  706. when 0x60
  707. score-=80 if isConst?(attacker.ability(true),PBAbilities,:MULTITYPE)
  708. envtypes=[:NORMAL, # None
  709. :GRASS, # Grass
  710. :GRASS, # Tall grass
  711. :WATER, # Moving water
  712. :WATER, # Still water
  713. :WATER, # Underwater
  714. :ROCK, # Rock
  715. :ROCK, # Cave
  716. :GROUND] # Sand
  717. type=envtypes[@environment]
  718. score-=80 if attacker.pbHasType?(type)
  719. when 0x61
  720. when 0x62
  721. when 0x63
  722. when 0x64
  723. when 0x65
  724. score-=80 if isConst?(opponent.ability(true),PBAbilities,:WONDERGUARD)
  725. score-=80 if attacker.ability==opponent.ability
  726. when 0x66
  727. score-=80 if isConst?(attacker.ability(true),PBAbilities,:WONDERGUARD)
  728. score-=80 if attacker.ability==opponent.ability
  729. when 0x67
  730. if isConst?(opponent.ability(true),PBAbilities,:WONDERGUARD) ||
  731. isConst?(attacker.ability(true),PBAbilities,:WONDERGUARD)
  732. score-=80
  733. end
  734. if skill>=80
  735. if opponent.ability==attacker.ability ||
  736. (isConst?(opponent.ability(true),PBAbilities,:TRUANT) &&
  737. attacker.pbIsOpposing?(opponent.index)) ||
  738. (isConst?(opponent.ability(true),PBAbilities,:SLOWSTART) &&
  739. attacker.pbIsOpposing?(opponent.index))
  740. (isConst?(opponent.ability(true),PBAbilities,:STONER) &&
  741. attacker.pbIsOpposing?(opponent.index))
  742. score-=90
  743. end
  744. end
  745. score-=40 # don't prefer this move
  746. when 0x68
  747. when 0x69
  748. when 0x6A
  749. if opponent.hp<=20
  750. score+=50
  751. elsif opponent.level>=25
  752. score-=85 # Not useful against high-level Pokemon
  753. end
  754. when 0x6B
  755. score+=50 if opponent.hp<=40
  756. when 0x6C
  757. score-=50
  758. score+=(opponent.hp*100/opponent.totalhp)
  759. when 0x6D
  760. score+=50 if opponent.hp<=attacker.level
  761. when 0x6E
  762. score-=200 if attacker.hp>=opponent.hp
  763. when 0x6F
  764. score+=20 if opponent.hp<=attacker.level
  765. when 0x70
  766. score-=90 if isConst?(opponent.ability,PBAbilities,:STURDY)
  767. score-=80 if attacker.level<opponent.level
  768. when 0x71
  769. attack=pbRoughStat(attacker,PBStats::ATTACK)
  770. spatk=pbRoughStat(attacker,PBStats::SPATK)
  771. if attack<spatk
  772. score-=60
  773. elsif opponent.effects[PBEffects::HyperBeam]>0
  774. score-=90
  775. elsif opponent.lastMoveUsed>0
  776. moveData=PBMoveData.new(opponent.lastMoveUsed)
  777. if moveData.basedamage>0 &&
  778. (USEMOVECATEGORY && moveData.category==2) ||
  779. (!USEMOVECATEGORY && PBTypes.isSpecialType?(moveData.type))
  780. score-=60
  781. end
  782. end
  783. when 0x72
  784. attack=pbRoughStat(attacker,PBStats::ATTACK)
  785. spatk=pbRoughStat(attacker,PBStats::SPATK)
  786. if attack>spatk
  787. score-=60
  788. elsif opponent.effects[PBEffects::HyperBeam]>0
  789. score-=90
  790. elsif opponent.lastMoveUsed>0
  791. moveData=PBMoveData.new(opponent.lastMoveUsed)
  792. if moveData.basedamage>0 &&
  793. (USEMOVECATEGORY && moveData.category==1) ||
  794. (!USEMOVECATEGORY && !PBTypes.isSpecialType?(moveData.type))
  795. score-=60
  796. end
  797. end
  798. when 0x73
  799. when 0x74
  800. when 0x75
  801. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCB # Dive
  802. when 0x76
  803. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCA # Dig
  804. when 0x77
  805. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  806. PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC # Bounce
  807. when 0x78
  808. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  809. PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC # Bounce
  810. when 0x79
  811. when 0x7A
  812. when 0x7B
  813. score+=50 if opponent.status==PBStatuses::POISON
  814. when 0x7C
  815. score+=50 if opponent.status==PBStatuses::PARALYSIS
  816. when 0x7D
  817. score+=50 if opponent.status==PBStatuses::SLEEP
  818. score+=10 if opponent.statusCount<=1
  819. when 0x7E
  820. score+=50 if (attacker.status==PBStatuses::POISON ||
  821. attacker.status==PBStatuses::BURN ||
  822. attacker.status==PBStatuses::PARALYSIS)
  823. when 0x7F
  824. score+=50 if attacker.status!=0
  825. when 0x80
  826. score+=50 if opponent.hp<=opponent.totalhp/2
  827. when 0x81
  828. score+=50 if attacker.lastHPLost>0 && attacker.lastAttacker==opponent.index
  829. when 0x82
  830. score+=50 if opponent.lastHPLost>0
  831. when 0x83
  832. when 0x84
  833. when 0x85
  834. when 0x86
  835. score+=50 if attacker.item==0 || isConst?(opponent.item,PBItems,:FLYINGGEM)
  836. when 0x87
  837. score+=50 if pbWeather!=0
  838. when 0x88
  839. when 0x89
  840. damage=(attacker.happiness*10/25).floor
  841. damage/=2
  842. score+=damage-25
  843. when 0x8A
  844. damage=((255-attacker.happiness)*10/25).floor
  845. damage/=2
  846. score+=damage-25
  847. when 0x8B
  848. score-=50
  849. score+=(attacker.hp*100/attacker.totalhp)
  850. when 0x8C
  851. score-=50
  852. score+=(opponent.hp*100/opponent.totalhp)
  853. when 0x8D
  854. score-=50
  855. attspeed=pbRoughStat(attacker,PBStats::SPEED)
  856. oppspeed=pbRoughStat(opponent,PBStats::SPEED)
  857. score+=(oppspeed*50/attspeed)
  858. when 0x8E
  859. mods=0
  860. for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  861. PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  862. mods+=attacker.stages[i] if attacker.stages[i]>0
  863. end
  864. mods=8 if mods>=8
  865. score+=mods*10
  866. when 0x8F
  867. mods=0
  868. for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  869. PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  870. mods+=opponent.stages[i] if opponent.stages[i]>0
  871. end
  872. mods=7 if mods>=7
  873. score+=mods*10
  874. when 0x90
  875. when 0x91
  876. if attacker.effects[PBEffects::FuryCutter]<5
  877. score+=(attacker.effects[PBEffects::FuryCutter]*10)
  878. end
  879. when 0x92
  880. when 0x93
  881. score+=25 if attacker.effects[PBEffects::Rage]
  882. when 0x94
  883. when 0x95
  884. when 0x96
  885. when 0x97
  886. score+=(5-move.pp)*10 if move.pp<=2
  887. when 0x98
  888. score+=50
  889. score-=(attacker.hp*100/attacker.totalhp)
  890. when 0x99
  891. score-=20
  892. attspeed=pbRoughStat(attacker,PBStats::SPEED)
  893. oppspeed=pbRoughStat(opponent,PBStats::SPEED)
  894. score+=(attspeed*20/oppspeed)
  895. when 0x9A
  896. when 0x9B
  897. when 0x9C
  898. score-=80 if attacker.pbPartner.hp==0
  899. when 0x9D
  900. score-=80 if attacker.effects[PBEffects::MudSport]
  901. when 0x9E
  902. score-=80 if attacker.effects[PBEffects::WaterSport]
  903. when 0x9F
  904. when 0xA0
  905. when 0xA1
  906. when 0xA2
  907. score-=80 if attacker.pbOwnSide.effects[PBEffects::Reflect]>0
  908. when 0xA3
  909. score-=80 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0
  910. when 0xA4
  911. when 0xA5
  912. score+=10
  913. when 0xA6
  914. score-=80 if opponent.effects[PBEffects::LockOn]>0
  915. when 0xA7
  916. score-=35 if opponent.stages[PBStats::EVASION]<=0
  917. score-=45 if !attacker.pbHasType?(:GHOST)
  918. score-=80 if opponent.effects[PBEffects::Foresight]
  919. when 0xA8
  920. score-=35 if opponent.stages[PBStats::EVASION]<=0
  921. score-=45 if !attacker.pbHasType?(:DARK)
  922. score-=80 if opponent.effects[PBEffects::MiracleEye]
  923. when 0xA9
  924. when 0xAA
  925. if skill>=50
  926. score-=90 if attacker.effects[PBEffects::ProtectRate]>1
  927. score-=90 if opponent.effects[PBEffects::HyperBeam]>0
  928. else
  929. score-=(attacker.effects[PBEffects::ProtectRate]*40)
  930. end
  931. if score>=40
  932. score+=50 if attacker.turncount==0
  933. score+=30 if opponent.effects[PBEffects::TwoTurnAttack]!=0
  934. end
  935. when 0xAB
  936. when 0xAC
  937. when 0xAD
  938. when 0xAE
  939. score-=80 if attacker.effects[PBEffects::MirrorMove]<=0
  940. when 0xAF
  941. when 0xB0
  942. when 0xB1
  943. when 0xB2
  944. when 0xB3
  945. when 0xB4
  946. score-=140 if attacker.status!=PBStatuses::SLEEP
  947. score+=70 if attacker.status==PBStatuses::SLEEP
  948. when 0xB5
  949. when 0xB6
  950. when 0xB7
  951. score-=80 if opponent.effects[PBEffects::Torment]
  952. when 0xB8
  953. score-=80 if attacker.effects[PBEffects::Imprison]
  954. when 0xB9
  955. score-=80 if opponent.effects[PBEffects::Disable]>0
  956. when 0xBA
  957. score-=80 if opponent.effects[PBEffects::Taunt]>0
  958. when 0xBB
  959. when 0xBC
  960. greaterSpeed=pbRoughStat(attacker,
  961. PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  962. if opponent.lastMoveUsed<=0 && greaterSpeed
  963. score-=70
  964. elsif opponent.effects[PBEffects::Encore]>0
  965. score-=80
  966. elsif opponent.lastMoveUsed>0 && greaterSpeed
  967. moveData=PBMoveData.new(opponent.lastMoveUsed)
  968. if moveData.basedamage==0 && (moveData.target==0x10 || moveData.target==0x20)
  969. score+=60
  970. elsif moveData.basedamage!=0 && moveData.target==0x00 &&
  971. pbTypeModifier(moveData.type,opponent,attacker)==0
  972. score+=60
  973. end
  974. end
  975. when 0xBD
  976. when 0xBE
  977. score-=10 if !opponent.pbCanPoison?(false)
  978. when 0xBF
  979. when 0xC0
  980. when 0xC1
  981. score-=70 if attacker.pbPartner.hp==0 && attacker.pbNonActivePokemonCount()==0
  982. if skill>=50 && opponent.level>=50
  983. # Damage too small to be useful
  984. score-=80
  985. end
  986. when 0xC2
  987. when 0xC3
  988. when 0xC4
  989. score+=30 if pbWeather==PBWeather::SUNNYDAY
  990. score+=30 if pbWeather==PBWeather::MOLTENRAIN
  991. score-=30 if pbWeather==PBWeather::RAINDANCE
  992. score-=30 if pbWeather==PBWeather::SANDSTORM
  993. score-=30 if pbWeather==PBWeather::HAIL
  994. when 0xC5
  995. score+=15 if pbRoughStat(attacker,
  996. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  997. score-=10 if opponent.status==PBStatuses::PARALYSIS
  998. when 0xC6
  999. score-=10 if opponent.status==PBStatuses::BURN
  1000. score-=40 if opponent.pbHasType?(:FIRE)
  1001. when 0xC7
  1002. score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  1003. when 0xC8
  1004. score+=10 if attacker.stages[PBStats::DEFENSE]<0
  1005. when 0xC9
  1006. when 0xCA
  1007. when 0xCB
  1008. when 0xCC
  1009. when 0xCD
  1010. when 0xCE
  1011. when 0xCF
  1012. score-=30 if opponent.effects[PBEffects::MultiTurn]>0
  1013. when 0xD0
  1014. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCB # Fly
  1015. when 0xD1
  1016. when 0xD2
  1017. score-=20 if !opponent.pbCanConfuse?(false)
  1018. when 0xD3
  1019. score+=40 if attacker.effects[PBEffects::DefenseCurl]
  1020. when 0xD4
  1021. when 0xD5
  1022. if attacker.hp==attacker.totalhp
  1023. score-=80
  1024. else
  1025. score+=50
  1026. score-=(attacker.hp*100/attacker.totalhp)
  1027. end
  1028. when 0xD6
  1029. if attacker.hp==attacker.totalhp
  1030. score-=80
  1031. else
  1032. score+=50
  1033. score-=(attacker.hp*100/attacker.totalhp)
  1034. end
  1035. when 0xD7
  1036. score-=80 if attacker.effects[PBEffects::Wish]>0
  1037. when 0xD8
  1038. if attacker.hp==attacker.totalhp
  1039. score-=80
  1040. else
  1041. score+=30 if pbWeather==PBWeather::SUNNYDAY
  1042. score+=30 if pbWeather==PBWeather::MOLTENRAIN
  1043. score-=30 if pbWeather==PBWeather::RAINDANCE
  1044. score-=30 if pbWeather==PBWeather::SANDSTORM
  1045. score-=30 if pbWeather==PBWeather::HAIL
  1046. score+=70
  1047. score-=(attacker.hp*140/attacker.totalhp)
  1048. end
  1049. when 0xD9
  1050. if attacker.hp==attacker.totalhp || attacker.status==PBStatuses::SLEEP
  1051. score-=80
  1052. else
  1053. score+=70
  1054. score-=(attacker.hp*140/attacker.totalhp)
  1055. score+=30 if attacker.status!=0
  1056. end
  1057. when 0xDA
  1058. when 0xDB
  1059. score-=80 if attacker.effects[PBEffects::Ingrain]
  1060. when 0xDC
  1061. score-=80 if opponent.effects[PBEffects::LeechSeed]>=0
  1062. score-=80 if opponent.pbHasType?(:GRASS)
  1063. if score>20
  1064. score+=60 if attacker.turncount==0
  1065. end
  1066. when 0xDD
  1067. score-=20 if isConst?(opponent.ability,PBAbilities,:LIQUIDOOZE)
  1068. score+=20 if attacker.hp<=(attacker.totalhp/2)
  1069. when 0xDE
  1070. if opponent.status!=PBStatuses::SLEEP
  1071. score-=200
  1072. score-=50 if isConst?(opponent.ability,PBAbilities,:LIQUIDOOZE)
  1073. else
  1074. score-=50 if isConst?(opponent.ability,PBAbilities,:LIQUIDOOZE)
  1075. score+=20 if attacker.hp<=(attacker.totalhp/2)
  1076. end
  1077. when 0xDF
  1078. score-=80
  1079. when 0xE0
  1080. if pbCheckGlobalAbility(:DAMP)
  1081. score-=100
  1082. elsif skill>50 && attacker.pbNonActivePokemonCount()==0 &&
  1083. attacker.pbOppositeOpposing.pbNonActivePokemonCount()>0
  1084. score-=200
  1085. elsif skill>80 && attacker.pbNonActivePokemonCount()==0 &&
  1086. attacker.pbOppositeOpposing.pbNonActivePokemonCount()==0
  1087. score-=200
  1088. else
  1089. score+=50
  1090. score-=(attacker.hp*100/attacker.totalhp)
  1091. end
  1092. when 0xE1
  1093. when 0xE2
  1094. score-=80 if !opponent.pbCanReduceStatStage?(PBStats::ATTACK) &&
  1095. !opponent.pbCanReduceStatStage?(PBStats::SPATK)
  1096. score-=80 if attacker.pbNonActivePokemonCount()==0
  1097. if score>20
  1098. avg=(opponent.stages[PBStats::ATTACK]*10)
  1099. avg+=(opponent.stages[PBStats::SPATK]*10)
  1100. score+=avg
  1101. score+=50
  1102. score-=(attacker.hp*100/attacker.totalhp)
  1103. end
  1104. when 0xE3
  1105. when 0xE4
  1106. when 0xE5
  1107. if attacker.pbNonActivePokemonCount()==0
  1108. score-=100
  1109. else
  1110. score-=80 if opponent.effects[PBEffects::PerishSong]>0
  1111. end
  1112. when 0xE6
  1113. score+=50
  1114. score-=(attacker.hp*100/attacker.totalhp)
  1115. score+=15 if attacker.hp<=(attacker.totalhp/10)
  1116. when 0xE7
  1117. score+=50
  1118. score-=(attacker.hp*100/attacker.totalhp)
  1119. score+=15 if attacker.hp<=(attacker.totalhp/10)
  1120. when 0xE8
  1121. score-=25 if attacker.hp>(attacker.totalhp/2)
  1122. if skill>=50
  1123. score-=90 if attacker.effects[PBEffects::ProtectRate]>1
  1124. score-=90 if opponent.effects[PBEffects::HyperBeam]>0
  1125. else
  1126. score-=(attacker.effects[PBEffects::ProtectRate]*40)
  1127. end
  1128. when 0xE9
  1129. score-=25
  1130. score+=(opponent.hp*50/opponent.totalhp)
  1131. when 0xEA
  1132. score-=100 if @opponent
  1133. when 0xEB
  1134. party=pbParty(opponent.index)
  1135. ch=0
  1136. for i in 0...party.length
  1137. ch+=1 if pbCanSwitchLax?(opponent.index,i,false)
  1138. end
  1139. score-=90 if ch==0
  1140. score-=90 if opponent.effects[PBEffects::Ingrain]
  1141. score-=90 if isConst?(opponent.ability,PBAbilities,:SUCTIONCUPS)
  1142. if score>20
  1143. score+=50 if opponent.pbOwnSide.effects[PBEffects::Spikes]>0
  1144. end
  1145. when 0xEC
  1146. when 0xED
  1147. score-=80 if !pbCanChooseNonActive?(attacker.index)
  1148. score-=50 if attacker.effects[PBEffects::Confusion]>0
  1149. total=0
  1150. total+=(attacker.stages[PBStats::ATTACK]*10)
  1151. total+=(attacker.stages[PBStats::DEFENSE]*10)
  1152. total+=(attacker.stages[PBStats::SPEED]*10)
  1153. total+=(attacker.stages[PBStats::SPATK]*10)
  1154. total+=(attacker.stages[PBStats::SPDEF]*10)
  1155. total+=(attacker.stages[PBStats::EVASION]*10)
  1156. total+=(attacker.stages[PBStats::ACCURACY]*10)
  1157. total+=10 if attacker.effects[PBEffects::Wish]>0
  1158. if total==0 || attacker.turncount==0
  1159. score-=60
  1160. elsif score>20
  1161. score+=total
  1162. # special case: attacker has no damaging moves
  1163. hasDamagingMove=false
  1164. for m in attacker.moves
  1165. if move.id!=0 && move.basedamage>0
  1166. hasDamagingMove=true
  1167. end
  1168. end
  1169. if !hasDamagingMove
  1170. score+=75
  1171. end
  1172. end
  1173. when 0xEE
  1174. when 0xEF
  1175. score-=80 if opponent.effects[PBEffects::MeanLook]>=0
  1176. when 0xF0
  1177. score-=20 if opponent.item==0
  1178. score+=20 if opponent.item!=0
  1179. when 0xF1
  1180. score-=20 if attacker.item!=0
  1181. when 0xF2
  1182. if attacker.item==0 && opponent.item==0
  1183. score-=80
  1184. elsif isConst?(opponent.ability,PBAbilities,:STICKYHOLD)
  1185. score-=80
  1186. elsif isConst?(attacker.item,PBItems,:LAXINCENSE) ||
  1187. isConst?(attacker.item,PBItems,:IRONBALL) ||
  1188. isConst?(attacker.item,PBItems,:CHOICEBAND)
  1189. score+=50
  1190. elsif attacker.item==0 && opponent.item!=0
  1191. score-=40
  1192. score-=30 if PBMoveData.new(attacker.lastMoveUsed).function==0xF2 # Trick/Switcheroo
  1193. end
  1194. when 0xF3
  1195. when 0xF4
  1196. when 0xF5
  1197. when 0xF6
  1198. score-=80 if attacker.pokemon.itemRecycle==0 || attacker.item!=0
  1199. score+=30 if attacker.pokemon.itemRecycle!=0
  1200. when 0xF7
  1201. when 0xF8
  1202. when 0xF9
  1203. when 0xFA
  1204. score-=25
  1205. score+=(attacker.hp*50/attacker.totalhp)
  1206. when 0xFB
  1207. score-=25
  1208. score+=(attacker.hp*50/attacker.totalhp)
  1209. when 0xFC
  1210. score-=25
  1211. score+=(attacker.hp*50/attacker.totalhp)
  1212. when 0xFD
  1213. score-=25
  1214. score+=(attacker.hp*50/attacker.totalhp)
  1215. score+=15 if pbRoughStat(attacker,
  1216. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  1217. score-=10 if opponent.status==PBStatuses::PARALYSIS
  1218. when 0xFE
  1219. score-=25
  1220. score+=(attacker.hp*50/attacker.totalhp)
  1221. score-=10 if opponent.status==PBStatuses::BURN
  1222. score-=40 if opponent.pbHasType?(:FIRE)
  1223. when 0xFF
  1224. score-=90 if pbCheckGlobalAbility(:AIRLOCK)
  1225. score-=90 if pbCheckGlobalAbility(:CLOUDNINE)
  1226. score-=80 if weather==PBWeather::SUNNYDAY
  1227. score-=80 if weather==PBWeather::MOLTENRAIN
  1228. if score>=50
  1229. for move in attacker.moves
  1230. if move.basedamage>0 && move.id!=0 &&
  1231. isConst?(move.type,PBTypes,:FIRE)
  1232. score+=20
  1233. end
  1234. end
  1235. end
  1236. when 0x100
  1237. score-=90 if pbCheckGlobalAbility(:AIRLOCK)
  1238. score-=90 if pbCheckGlobalAbility(:CLOUDNINE)
  1239. score-=80 if weather==PBWeather::RAINDANCE
  1240. score-=80 if weather==PBWeather::MOLTENRAIN
  1241. if score>=50
  1242. for move in attacker.moves
  1243. if move.basedamage>0 && move.id!=0 &&
  1244. isConst?(move.type,PBTypes,:WATER)
  1245. score+=20
  1246. end
  1247. end
  1248. end
  1249. when 0x101
  1250. score-=90 if pbCheckGlobalAbility(:AIRLOCK)
  1251. score-=90 if pbCheckGlobalAbility(:CLOUDNINE)
  1252. score-=80 if @weather==PBWeather::SANDSTORM
  1253. when 0x102
  1254. score-=90 if pbCheckGlobalAbility(:AIRLOCK)
  1255. score-=90 if pbCheckGlobalAbility(:CLOUDNINE)
  1256. score-=80 if @weather==PBWeather::HAIL
  1257. when 0x103
  1258. if attacker.pbOpposingSide.effects[PBEffects::Spikes]>=3
  1259. score-=90
  1260. elsif !pbCanChooseNonActive?(attacker.pbOpposing1.index) &&
  1261. !pbCanChooseNonActive?(attacker.pbOpposing2.index)
  1262. # No active Pokemon remains on opposing side
  1263. score-=90
  1264. elsif attacker.pbOpposingSide.effects[PBEffects::Spikes]>=0
  1265. score+=[40,26,13][attacker.pbOpposingSide.effects[PBEffects::Spikes]]
  1266. score-=5*attacker.pbOppositeOpposing.pbNonActivePokemonCount()
  1267. end
  1268. when 0x104
  1269. when 0x105
  1270. when 0x106
  1271. when 0x107
  1272. when 0x108
  1273. when 0x109
  1274. when 0x10A
  1275. score+=30 if attacker.pbOpposingSide.effects[PBEffects::Reflect]>0
  1276. score+=30 if attacker.pbOpposingSide.effects[PBEffects::LightScreen]>0
  1277. when 0x10B
  1278. score+=10*(attacker.stages[PBStats::ACCURACY]-opponent.stages[PBStats::EVASION])
  1279. when 0x10C
  1280. score-=80 if attacker.effects[PBEffects::Substitute]>0
  1281. score-=90 if attacker.hp<=(attacker.totalhp/4)
  1282. if score>20
  1283. score+=60 if attacker.effects[PBEffects::Substitute]==0
  1284. end
  1285. when 0x10D
  1286. if attacker.pbHasType?(:GHOST)
  1287. if attacker.hp<=(attacker.totalhp/2)
  1288. score-=40
  1289. score-=40 if @shiftStyle
  1290. score-=40 if attacker.pbNonActivePokemonCount()==0
  1291. end
  1292. score-=80 if opponent.effects[PBEffects::Curse]
  1293. else
  1294. avg=(attacker.stages[PBStats::SPEED]*10)
  1295. avg-=(attacker.stages[PBStats::ATTACK]*10)
  1296. avg-=(attacker.stages[PBStats::DEFENSE]*10)
  1297. score+=avg/3
  1298. end
  1299. when 0x10E
  1300. when 0x10F
  1301. score-=80 if opponent.status!=PBStatuses::SLEEP
  1302. when 0x110
  1303. score+=30 if attacker.effects[PBEffects::MultiTurn]>0
  1304. score+=30 if attacker.effects[PBEffects::LeechSeed]>=0
  1305. score+=80 if attacker.pbOwnSide.effects[PBEffects::Spikes]>0
  1306. when 0x111
  1307. score-=110 if opponent.effects[PBEffects::FutureSight]>0
  1308. # Future Sight tends to be wasteful if down to last Pokemon
  1309. score-=70 if attacker.pbNonActivePokemonCount()==0
  1310. when 0x112
  1311. if attacker.effects[PBEffects::Stockpile]>=3
  1312. score-=80
  1313. end
  1314. # More preferable if user also has Spit Up/Swallow
  1315. foundmove=false
  1316. for move in attacker.moves
  1317. if move.function==0x113 || move.function==0x114 # Spit Up, Swallow
  1318. foundmove=true
  1319. end
  1320. end
  1321. if foundmove # Spit Up/Swallow found
  1322. score+=20
  1323. end
  1324. when 0x113
  1325. score-=110 if attacker.effects[PBEffects::Stockpile]==0
  1326. when 0x114
  1327. score-=90 if attacker.effects[PBEffects::Stockpile]==0 || attacker.hp==attacker.totalhp
  1328. when 0x115
  1329. score+=50 if opponent.effects[PBEffects::HyperBeam]>0
  1330. score-=35 if opponent.hp<=(opponent.totalhp/2)
  1331. score-=70 if opponent.hp<=(opponent.totalhp/4)
  1332. when 0x116
  1333. when 0x117
  1334. score-=80 if attacker.pbPartner.hp==0
  1335. when 0x118
  1336. when 0x119
  1337. when 0x11A
  1338. when 0x11B
  1339. score+=40 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  1340. PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC # Bounce
  1341. when 0x11C
  1342. when 0x11D
  1343. when 0x11E
  1344. when 0x11F
  1345. when 0x120
  1346. when 0x121
  1347. when 0x122
  1348. when 0x123
  1349. when 0x124
  1350. when 0x125
  1351. when 0x126
  1352. score+=20 # Shadow moves are more preferable
  1353. when 0x127
  1354. score+=20 # Shadow moves are more preferable
  1355. score+=15 if pbRoughStat(attacker,
  1356. PBStats::SPEED)<pbRoughStat(opponent,PBStats::SPEED)
  1357. score-=10 if opponent.status==PBStatuses::PARALYSIS
  1358. when 0x128
  1359. score+=20 # Shadow moves are more preferable
  1360. score-=10 if opponent.status==PBStatuses::BURN
  1361. score-=40 if opponent.pbHasType?(:FIRE)
  1362. when 0x129
  1363. score+=20 # Shadow moves are more preferable
  1364. score-=10 if opponent.status==PBStatuses::FROZEN
  1365. score-=40 if opponent.pbHasType?(:ICE)
  1366. when 0x12A
  1367. score+=20 # Shadow moves are more preferable
  1368. if !opponent.pbCanConfuse?(false)
  1369. score-=100
  1370. elsif move.accuracy>=75
  1371. score+=70 if attacker.turncount<3
  1372. score+=40 if attacker.turncount>=3
  1373. end
  1374. when 0x12B
  1375. score+=20 # Shadow moves are more preferable
  1376. score-=100 if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE)
  1377. if score>20
  1378. score+=(opponent.stages[PBStats::DEFENSE]*20)
  1379. end
  1380. when 0x12C
  1381. score+=20 # Shadow moves are more preferable
  1382. score-=100 if !opponent.pbCanReduceStatStage?(PBStats::EVASION)
  1383. if score>20
  1384. score+=(opponent.stages[PBStats::EVASION]*10)
  1385. end
  1386. when 0x12D
  1387. score+=20 # Shadow moves are more preferable
  1388. score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCB # Dive
  1389. when 0x12E
  1390. score+=20 # Shadow moves are more preferable
  1391. when 0x12F
  1392. score+=20 # Shadow moves are more preferable
  1393. score-=100 if opponent.effects[PBEffects::MeanLook]>=0
  1394. when 0x130
  1395. score+=20 # Shadow moves are more preferable
  1396. score-=25
  1397. score+=(attacker.hp*50/attacker.totalhp)
  1398. when 0x131
  1399. score+=20 # Shadow moves are more preferable
  1400. score-=90 if pbCheckGlobalAbility(:AIRLOCK)
  1401. score-=90 if pbCheckGlobalAbility(:CLOUDNINE)
  1402. score-=100 if @weather==PBWeather::SHADOWSKY
  1403. when 0x132
  1404. score+=20 # Shadow moves are more preferable
  1405. score+=30 if attacker.pbOpposingSide.effects[PBEffects::Reflect]>0
  1406. score+=30 if attacker.pbOpposingSide.effects[PBEffects::LightScreen]>0
  1407. score+=30 if attacker.pbOpposingSide.effects[PBEffects::Safeguard]>0
  1408. score-=90 if attacker.pbOwnSide.effects[PBEffects::Reflect]>0
  1409. score-=90 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0
  1410. score-=90 if attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  1411. end
  1412. # Other score modifications.
  1413. opponent=attacker.pbOppositeOpposing if !opponent
  1414. opponent=opponent.pbPartner if opponent && opponent.hp==0
  1415. if skill>=70
  1416. # Endgame
  1417. if attacker.pbNonActivePokemonCount()==0 &&
  1418. opponent.pbNonActivePokemonCount()==0 &&
  1419. pbParty(attacker.index).length>1 && pbParty(opponent.index).length>1
  1420. if move.basedamage==0
  1421. score/=2 # Don't prefer nondamaging move
  1422. elsif attacker.hp<=attacker.totalhp/2 && opponent.hp<=opponent.totalhp/2
  1423. PBDebug.log("[Preferring damaging move]") if $INTERNAL
  1424. score=score*3/2 # Prefer damaging move if game is close
  1425. end
  1426. end
  1427. # Certain two-turn attacks
  1428. invulmove=PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function
  1429. if move.accuracy>0 && # checks accuracy
  1430. [0xC9,0xCA,0xCB,0xCC,0xCD,0xCE].include?(invulmove) && # Fly, Dig, Dive, Bounce, Shadow Force, Sky Drop
  1431. pbRoughStat(attacker,PBStats::SPEED)>pbRoughStat(opponent,PBStats::SPEED)
  1432. score-=80 # Don't prefer if opponent would be semi-invulnerable when attacked
  1433. end
  1434. end
  1435. if skill>50
  1436. if isConst?(attacker.item,PBItems,:CHOICEBAND) ||
  1437. isConst?(attacker.item,PBItems,:CHOICESPECS) ||
  1438. isConst?(attacker.item,PBItems,:CHOICESCARF)
  1439. if move.basedamage>=60
  1440. score+=70
  1441. elsif move.basedamage>0
  1442. score+=35
  1443. elsif move.function==0xF2 # Trick
  1444. score+=70
  1445. else
  1446. score-=60
  1447. end
  1448. end
  1449. # Prefer a move usable while asleep if user is asleep.
  1450. if attacker.status==PBStatuses::SLEEP &&
  1451. move.function!=0x11 && move.function!=0xB4 # Snore or Sleep Talk
  1452. hasSleepMove=false
  1453. for m in attacker.moves
  1454. if m.function==0x11 || m.function==0xB4 # Snore or Sleep Talk
  1455. hasSleepMove=true; break
  1456. end
  1457. end
  1458. score-=75 if hasSleepMove
  1459. end
  1460. # Prefer a self-thawing move if user is frozen.
  1461. if attacker.status==PBStatuses::FROZEN &&
  1462. (move.flags&0x40)==0 # flag g: Thaws user before moving
  1463. hasFreezeMove=false
  1464. for m in attacker.moves
  1465. if (m.flags&0x40)!=0 # flag g: Thaws user before moving
  1466. hasFreezeMove=true; break
  1467. end
  1468. end
  1469. score-=75 if hasFreezeMove
  1470. end
  1471. end
  1472. if move.basedamage>0
  1473. typemod=pbTypeModifier(move.type,attacker,opponent)
  1474. if typemod==0 || score<=0
  1475. score=0
  1476. elsif isConst?(move.type,PBTypes,:GROUND) && isConst?(opponent.ability,PBAbilities,:LEVITATE)
  1477. score=0
  1478. elsif isConst?(move.type,PBTypes,:FIRE) && isConst?(opponent.ability,PBAbilities,:FLASHFIRE)
  1479. score=0
  1480. elsif isConst?(move.type,PBTypes,:GRASS) && isConst?(opponent.ability,PBAbilities,:SAPSIPPER)
  1481. score=0
  1482. elsif isConst?(move.type,PBTypes,:ELECTRIC) && isConst?(opponent.ability,PBAbilities,:VOLTABSORB)
  1483. score=0
  1484. elsif isConst?(move.type,PBTypes,:ELECTRIC) && isConst?(opponent.ability,PBAbilities,:LIGHTNINGROD)
  1485. score=0
  1486. elsif isConst?(move.type,PBTypes,:ELECTRIC) && isConst?(opponent.ability,PBAbilities,:MOTORDRIVE)
  1487. score=0
  1488. elsif isConst?(move.type,PBTypes,:WATER) && isConst?(opponent.ability,PBAbilities,:WATERABSORB)
  1489. score=0
  1490. elsif isConst?(move.type,PBTypes,:WATER) && isConst?(opponent.ability,PBAbilities,:STORMDRAIN)
  1491. score=0
  1492. elsif isConst?(move.type,PBTypes,:WATER) && isConst?(opponent.ability,PBAbilities,:DRYSKIN)
  1493. score=0
  1494. elsif skill>50 && typemod<=4 && isConst?(opponent.ability,PBAbilities,:WONDERGUARD)
  1495. score=0
  1496. else
  1497. realBaseDamage=move.basedamage
  1498. realBaseDamage=50 if move.basedamage==1
  1499. basedamage=realBaseDamage
  1500. attack=pbRoughStat(attacker,PBStats::ATTACK)
  1501. spatk=pbRoughStat(attacker,PBStats::SPATK)
  1502. defense=pbRoughStat(opponent,PBStats::DEFENSE)
  1503. spdef=pbRoughStat(opponent,PBStats::SPDEF)
  1504. isPhysical=move.pbIsPhysical?(move.type)
  1505. if skill>=90
  1506. if isPhysical
  1507. basedamage=basedamage*attack/[defense,1].max
  1508. basedamage=basedamage*3/2 if isConst?(attacker.item,PBItems,:CHOICEBAND)
  1509. basedamage/=2 if opponent.pbOwnSide.effects[PBEffects::Reflect]>0
  1510. else
  1511. basedamage=basedamage*spatk/[spdef,1].max
  1512. basedamage/=2 if opponent.pbOwnSide.effects[PBEffects::LightScreen]>0
  1513. end
  1514. end
  1515. # STAB
  1516. if skill>=50
  1517. basedamage=basedamage*3/2 if attacker.pbHasType?(move.type)
  1518. end
  1519. # Type effectiveness
  1520. basedamage=basedamage*typemod/4
  1521. # Weather
  1522. w=pbWeather()
  1523. if w==PBWeather::SUNNYDAY
  1524. basedamage=basedamage*3/2 if isConst?(move.type,PBTypes,:FIRE)
  1525. basedamage/=2 if isConst?(move.type,PBTypes,:WATER)
  1526. elsif w==PBWeather::RAINDANCE
  1527. basedamage=basedamage*3/2 if isConst?(move.type,PBTypes,:WATER)
  1528. basedamage/=2 if isConst?(move.type,PBTypes,:FIRE)
  1529. end
  1530. basedamage=basedamage*3/2 if attacker.effects[PBEffects::Charge]>0 &&
  1531. isConst?(move.type,PBTypes,:ELECTRIC)
  1532. # Two turn attacks
  1533. if move.pbTwoTurnAttack(attacker)
  1534. # Damage is effectively halved due to having to skip a turn
  1535. basedamage/=2
  1536. # Don't prefer if down to last Pokemon
  1537. basedamage/=2 if attacker.pbNonActivePokemonCount()==0
  1538. end
  1539. # Don't prefer weak attacks
  1540. basedamage/=2 if basedamage<40
  1541. # Prefer damaging attack if level difference is significantly high
  1542. basedamage=basedamage*7/5 if typemod>=4 && attacker.level-10>opponent.level
  1543. # Low accuracy attack
  1544. if move.accuracy<=70 && typemod>=4
  1545. basedamage=basedamage*3/2 if opponent.effects[PBEffects::LockOn]>0 &&
  1546. opponent.effects[PBEffects::LockOnPos]==attacker.index
  1547. end
  1548. if basedamage>realBaseDamage
  1549. basedamage=basedamage*5/6 # slightly weaken score increase
  1550. end
  1551. # Adjust score
  1552. basedamage=600 if basedamage>600
  1553. oldscore=score
  1554. score+=basedamage/4
  1555. score=score*basedamage/[realBaseDamage,1].max
  1556. if $INTERNAL
  1557. PBDebug.log(sprintf("%s: %d=>%d",PBMoves.getName(move.id),realBaseDamage,basedamage))
  1558. PBDebug.log(sprintf(" change: %d=>%d",oldscore,score))
  1559. end
  1560. end
  1561. else
  1562. score-=10
  1563. score-=10 if score<=10 && skill>=70
  1564. end
  1565. score=0 if score<0
  1566. return score
  1567. end
  1568.  
  1569. ################################################################################
  1570. # Get type effectiveness and approximate stats.
  1571. ################################################################################
  1572. def pbTypeModifier(type,attacker,opponent)
  1573. return 4 if type<0
  1574. return 4 if isConst?(type,PBTypes,:GROUND) && opponent.pbHasType?(:FLYING) &&
  1575. isConst?(opponent.item,PBItems,:IRONBALL)
  1576. atype=type
  1577. otype1=opponent.type1
  1578. otype2=opponent.type2
  1579. if isConst?(otype1,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  1580. if isConst?(otype2,PBTypes,:FLYING)
  1581. otype1=getConst(PBTypes,:NORMAL) || 0
  1582. else
  1583. otype1=otype2
  1584. end
  1585. end
  1586. if isConst?(otype2,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  1587. otype2=otype1
  1588. end
  1589. mod1=PBTypes.getEffectiveness(atype,otype1)
  1590. mod2=(otype1==otype2) ? 2 : PBTypes.getEffectiveness(atype,otype2)
  1591. if isConst?(attacker.ability,PBAbilities,:SCRAPPY) || opponent.effects[PBEffects::Foresight]
  1592. mod1=2 if isConst?(otype1,PBTypes,:GHOST) &&
  1593. (isConst?(atype,PBTypes,:NORMAL) || isConst?(atype,PBTypes,:FIGHTING))
  1594. mod2=2 if isConst?(otype2,PBTypes,:GHOST) &&
  1595. (isConst?(atype,PBTypes,:NORMAL) || isConst?(atype,PBTypes,:FIGHTING))
  1596. end
  1597. if opponent.effects[PBEffects::MiracleEye]
  1598. mod1=2 if isConst?(otype1,PBTypes,:DARK) && isConst?(atype,PBTypes,:PSYCHIC)
  1599. mod2=2 if isConst?(otype2,PBTypes,:DARK) && isConst?(atype,PBTypes,:PSYCHIC)
  1600. end
  1601. return mod1*mod2
  1602. end
  1603.  
  1604. def pbTypeModifier2(battlerThis,battlerOther)
  1605. if battlerThis.type1==battlerThis.type2
  1606. return 4*pbTypeModifier(battlerThis.type1,battlerThis,battlerOther)
  1607. else
  1608. ret=pbTypeModifier(battlerThis.type1,battlerThis,battlerOther)
  1609. ret*=pbTypeModifier(battlerThis.type2,battlerThis,battlerOther)
  1610. return ret # 0,1,2,4,8,_16_,32,64,128,256
  1611. end
  1612. end
  1613.  
  1614. def pbRoughStat(battler,stat)
  1615. stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40]
  1616. stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10]
  1617. stage=battler.stages[stat]
  1618. value=0
  1619. value=battler.attack if stat==PBStats::ATTACK
  1620. value=battler.defense if stat==PBStats::DEFENSE
  1621. value=battler.speed if stat==PBStats::SPEED
  1622. value=battler.spatk if stat==PBStats::SPATK
  1623. value=battler.spdef if stat==PBStats::SPDEF
  1624. return (value*stagemul[stage]/stagediv[stage]).floor
  1625. end
  1626.  
  1627. ################################################################################
  1628. # Choose a move to use.
  1629. ################################################################################
  1630. def pbChooseMoves(index)
  1631. # if $INTERNAL && !pbIsOpposing?(index)
  1632. # pbChooseMovesOld(index)
  1633. # return
  1634. # end
  1635. attacker=@battlers[index]
  1636. scores=[0,0,0,0]
  1637. targets=nil
  1638. myChoices=[]
  1639. totalscore=0
  1640. target=-1
  1641. wildbattle=!@opponent && pbIsOpposing?(index)
  1642. if wildbattle # If wild battle
  1643. for i in 0...4
  1644. if pbCanChooseMove?(index,i,false)
  1645. scores[i]=100
  1646. myChoices.push(i)
  1647. totalscore+=100
  1648. end
  1649. end
  1650. else
  1651. skill=pbGetOwner(attacker.index).skill || 0
  1652. opponent=attacker.pbOppositeOpposing
  1653. if @doublebattle && opponent.hp>0 && opponent.pbPartner.hp>0
  1654. # Choose a target and move. Also care about partner.
  1655. otheropp=opponent.pbPartner
  1656. scoresAndTargets=[]
  1657. targets=[-1,-1,-1,-1]
  1658. maxscore1=0
  1659. maxscore2=0
  1660. totalscore1=0
  1661. totalscore2=0
  1662. for i in 0...4
  1663. if pbCanChooseMove?(index,i,false)
  1664. score1=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill)
  1665. score2=pbGetMoveScore(attacker.moves[i],attacker,otheropp,skill)
  1666. if (attacker.moves[i].target&0x20)!=0
  1667. if attacker.pbPartner.hp<=0 # No partner
  1668. score1=score1*5/3
  1669. score2=score2*5/3
  1670. else
  1671. # If this move can also target the partner, get the partner's
  1672. # score too
  1673. s=pbGetMoveScore(attacker.moves[i],attacker,attacker.pbPartner,skill)
  1674. if s>=100 # Highly effective
  1675. score1=score1*1/3
  1676. score2=score2*1/3
  1677. elsif s>=70 # Very effective
  1678. score1=score1*2/3
  1679. score2=score2*2/3
  1680. elsif s<=40 # Less effective
  1681. score1=score1*4/3
  1682. score2=score2*4/3
  1683. elsif s<=10 # Hardly effective
  1684. score1=score1*5/3
  1685. score2=score2*5/3
  1686. end
  1687. end
  1688. end
  1689. myChoices.push(i)
  1690. scoresAndTargets.push([i*2,i,score1,opponent.index])
  1691. scoresAndTargets.push([i*2+1,i,score2,otheropp.index])
  1692. end
  1693. end
  1694. scoresAndTargets.sort!{|a,b|
  1695. if a[2]==b[2] # if scores are equal
  1696. a[0]<=>b[0] # sort by index (for stable comparison)
  1697. else
  1698. b[2]<=>a[2]
  1699. end
  1700. }
  1701. for i in 0...scoresAndTargets.length
  1702. idx=scoresAndTargets[i][1]
  1703. thisScore=scoresAndTargets[i][2]
  1704. if thisScore>0
  1705. if scores[idx]==0 || ((scores[idx]==thisScore && pbAIRandom(10)<5) ||
  1706. (scores[idx]!=thisScore && pbAIRandom(10)<3))
  1707. scores[idx]=thisScore
  1708. targets[idx]=scoresAndTargets[i][3]
  1709. end
  1710. end
  1711. end
  1712. for i in 0...4
  1713. scores[i]=0 if scores[i]<0
  1714. totalscore+=scores[i]
  1715. end
  1716. else
  1717. # Choose a move.
  1718. if @doublebattle && opponent.hp<=0
  1719. opponent=opponent.pbPartner
  1720. end
  1721. for i in 0...4
  1722. if pbCanChooseMove?(index,i,false)
  1723. scores[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill)
  1724. myChoices.push(i)
  1725. end
  1726. scores[i]=0 if scores[i]<0
  1727. totalscore+=scores[i]
  1728. end
  1729. end
  1730. end
  1731. maxscore=scores[0]
  1732. maxscore=scores[1] if maxscore<scores[1]
  1733. maxscore=scores[2] if maxscore<scores[2]
  1734. maxscore=scores[3] if maxscore<scores[3]
  1735. if $INTERNAL
  1736. x="[#{attacker.pbThis}:"
  1737. j=0
  1738. for i in 0...4
  1739. if attacker.moves[i].id!=0
  1740. x+=", " if j>0
  1741. x+=PBMoves.getName(attacker.moves[i].id)+"="+scores[i].to_s
  1742. j+=1
  1743. end
  1744. end
  1745. PBDebug.log(x)
  1746. end
  1747. if !wildbattle && maxscore>100
  1748. stdev=pbStdDev(scores)
  1749. if stdev>=100 && pbAIRandom(10)!=0
  1750. # If standard deviation is 100 or more
  1751. # there is a highly preferred move. Choose it.
  1752. preferredMoves=[]
  1753. for i in 0...4
  1754. if attacker.moves[i].id!=0 && (scores[i]==maxscore || scores[i]>=350)
  1755. preferredMoves.push(i)
  1756. if scores[i]==maxscore
  1757. preferredMoves.push(i)
  1758. end
  1759. end
  1760. end
  1761. if preferredMoves.length>0
  1762. i=preferredMoves[pbAIRandom(preferredMoves.length)]
  1763. if $INTERNAL
  1764. PBDebug.log("[Prefer "+PBMoves.getName(attacker.moves[i].id)+"]")
  1765. end
  1766. pbRegisterMove(index,i,false)
  1767. target=targets[i] if targets
  1768. if @doublebattle && target>=0
  1769. pbRegisterTarget(index,target)
  1770. end
  1771. return
  1772. end
  1773. end
  1774. end
  1775. if !wildbattle && attacker.turncount
  1776. badmoves=false
  1777. if ((maxscore<=10 && attacker.turncount>5) ||
  1778. (maxscore<=0 && attacker.turncount>2)) && pbAIRandom(10)<8
  1779. badmoves=true
  1780. end
  1781. if totalscore<100 && attacker.turncount>1
  1782. badmoves=true
  1783. movecount=0
  1784. for i in 0...4
  1785. if attacker.moves[i].id!=0
  1786. if scores[i]>0 && attacker.moves[i].basedamage>0
  1787. badmoves=false
  1788. end
  1789. movecount+=1
  1790. end
  1791. end
  1792. badmoves=badmoves && pbAIRandom(10)!=0
  1793. end
  1794. if badmoves
  1795. # Attacker has terrible moves, try switching instead
  1796. if pbEnemyShouldWithdrawEx?(index,true)
  1797. if $INTERNAL
  1798. PBDebug.log("Switching due to terrible moves")
  1799. PBDebug.log([index,@choices[index][0],@choices[index][1],
  1800. pbCanChooseNonActive?(index),
  1801. @battlers[index].pbNonActivePokemonCount()].inspect)
  1802. end
  1803. return
  1804. end
  1805. end
  1806. end
  1807. if maxscore<=0
  1808. # If all scores are 0 or less choose a move at random
  1809. if myChoices.length>0
  1810. pbRegisterMove(index,myChoices[pbAIRandom(myChoices.length)],false)
  1811. else
  1812. pbAutoChooseMove(index)
  1813. end
  1814. else
  1815. randnum=pbAIRandom(totalscore)
  1816. cumtotal=0
  1817. for i in 0...4
  1818. if scores[i]>0
  1819. cumtotal+=scores[i]
  1820. if randnum<cumtotal
  1821. pbRegisterMove(index,i,false)
  1822. target=targets[i] if targets
  1823. break
  1824. end
  1825. end
  1826. end
  1827. end
  1828. if @doublebattle && target>=0
  1829. pbRegisterTarget(index,target)
  1830. end
  1831. end
  1832.  
  1833. ################################################################################
  1834. # Decide whether the opponent should Mega Evolve their Pokémon.
  1835. ################################################################################
  1836. def pbEnemyShouldMegaEvolve?(index)
  1837. # Simple "always should if possible"
  1838. return pbCanMegaEvolve?(index)
  1839. end
  1840.  
  1841. ################################################################################
  1842. # Decide whether the opponent should use an item on the Pokémon.
  1843. ################################################################################
  1844. def pbEnemyShouldUseItem?(index)
  1845. item=pbEnemyItemToUse(index)
  1846. if item>0
  1847. pbRegisterItem(index,item,nil)
  1848. return true
  1849. end
  1850. return false
  1851. end
  1852.  
  1853. def pbEnemyItemAlreadyUsed?(index,item,items)
  1854. if @choices[1][0]==3 && @choices[1][1]==item
  1855. qty=0
  1856. for i in items
  1857. qty+=1 if i==item
  1858. end
  1859. return true if qty<=1
  1860. end
  1861. return false
  1862. end
  1863.  
  1864. def pbEnemyItemToUse(index)
  1865. return 0 if !@internalbattle
  1866. items=pbGetOwnerItems(index)
  1867. return 0 if !items
  1868. hashpitem=false
  1869. battler=@battlers[index]
  1870. return 0 if battler.hp<=0
  1871. for i in items
  1872. next if pbEnemyItemAlreadyUsed?(index,i,items)
  1873. if isConst?(i,PBItems,:POTION) ||
  1874. isConst?(i,PBItems,:SUPERPOTION) ||
  1875. isConst?(i,PBItems,:HYPERPOTION) ||
  1876. isConst?(i,PBItems,:MAXPOTION) ||
  1877. isConst?(i,PBItems,:FULLRESTORE)
  1878. hashpitem=true
  1879. end
  1880. end
  1881. for i in items
  1882. next if pbEnemyItemAlreadyUsed?(index,i,items)
  1883. if isConst?(i,PBItems,:POTION) ||
  1884. isConst?(i,PBItems,:SUPERPOTION) ||
  1885. isConst?(i,PBItems,:HYPERPOTION) ||
  1886. isConst?(i,PBItems,:MAXPOTION)
  1887. return i if battler.hp<=(battler.totalhp/4).floor
  1888. return i if battler.hp<=(battler.totalhp/2).floor && (pbAIRandom(10)<2)
  1889. elsif isConst?(i,PBItems,:FULLRESTORE)
  1890. return i if battler.hp<=(battler.totalhp/4).floor
  1891. return i if battler.hp<=(battler.totalhp/2).floor && (pbAIRandom(10)<2)
  1892. return i if battler.hp<=(battler.totalhp*2/3).floor && (battler.status>0 ||
  1893. battler.effects[PBEffects::Confusion]>0) && (pbAIRandom(10)<2)
  1894. elsif isConst?(i,PBItems,:FULLHEAL)
  1895. return i if !hashpitem && (battler.status>0 || battler.effects[PBEffects::Confusion]>0)
  1896. elsif isConst?(i,PBItems,:XATTACK)
  1897. return i if !battler.pbTooHigh?(PBStats::ATTACK)
  1898. elsif isConst?(i,PBItems,:XDEFEND)
  1899. return i if !battler.pbTooHigh?(PBStats::DEFENSE)
  1900. elsif isConst?(i,PBItems,:XSPEED)
  1901. return i if !battler.pbTooHigh?(PBStats::SPEED)
  1902. elsif isConst?(i,PBItems,:XSPECIAL)
  1903. return i if !battler.pbTooHigh?(PBStats::SPATK)
  1904. elsif isConst?(i,PBItems,:XSPDEF)
  1905. return i if !battler.pbTooHigh?(PBStats::SPDEF)
  1906. elsif isConst?(i,PBItems,:XACCURACY)
  1907. return i if !battler.pbTooHigh?(PBStats::ACCURACY)
  1908. end
  1909. end
  1910. return 0
  1911. end
  1912.  
  1913. ################################################################################
  1914. # Decide whether the opponent should switch Pokémon.
  1915. ################################################################################
  1916. def pbEnemyShouldWithdraw?(index)
  1917. if $INTERNAL && !pbIsOpposing?(index)
  1918. return pbEnemyShouldWithdrawOld?(index)
  1919. end
  1920. return pbEnemyShouldWithdrawEx?(index,false)
  1921. end
  1922.  
  1923. def pbEnemyShouldWithdrawEx?(index,alwaysSwitch)
  1924. return false if !@opponent
  1925. shouldswitch=alwaysSwitch
  1926. typecheck=false
  1927. batonpass=-1
  1928. movetype=-1
  1929. skill=pbGetOwner(index).skill || 0
  1930. if @opponent && !shouldswitch && @battlers[index].turncount>0
  1931. if skill>=70 # Experienced trainers only
  1932. opponent=@battlers[index].pbOppositeOpposing
  1933. if opponent.hp==0
  1934. opponent=opponent.pbPartner
  1935. end
  1936. if opponent.hp>0 && opponent.lastMoveUsed>0 &&
  1937. (opponent.level-@battlers[index].level).abs<=6
  1938. move=PBMoveData.new(opponent.lastMoveUsed)
  1939. typemod=pbTypeModifier(move.type,@battlers[index],@battlers[index])
  1940. movetype=move.type
  1941. if move.basedamage>70 && typemod>4
  1942. shouldswitch=pbAIRandom(100)<30
  1943. movetype=move.type
  1944. elsif move.basedamage>50 && typemod>4
  1945. shouldswitch=pbAIRandom(100)<20
  1946. movetype=move.type
  1947. end
  1948. end
  1949. end
  1950. end
  1951. if !pbCanChooseMove?(index,0,false) &&
  1952. !pbCanChooseMove?(index,1,false) &&
  1953. !pbCanChooseMove?(index,2,false) &&
  1954. !pbCanChooseMove?(index,3,false) &&
  1955. @battlers[index].turncount &&
  1956. @battlers[index].turncount>5
  1957. shouldswitch=true
  1958. end
  1959. if skill>=70 && @battlers[index].effects[PBEffects::PerishSong]!=1
  1960. for i in 0...4
  1961. move=@battlers[index].moves[i]
  1962. if move.id!=0 && pbCanChooseMove?(index,i,false) &&
  1963. move.function==0xED # Baton Pass
  1964. batonpass=i
  1965. break
  1966. end
  1967. end
  1968. end
  1969. if skill>=80
  1970. if @battlers[index].status==PBStatuses::POISON &&
  1971. @battlers[index].statusCount>0
  1972. toxicHP=(@battlers[index].totalhp/16)
  1973. nextToxicHP=toxicHP*(@battlers[index].effects[PBEffects::Toxic]+1)
  1974. if nextToxicHP>=@battlers[index].hp &&
  1975. toxicHP<@battlers[index].hp && pbAIRandom(100)<80
  1976. PBDebug.log("Should switch to reduce toxic effects") if $INTERNAL
  1977. shouldswitch=true
  1978. end
  1979. end
  1980. end
  1981. if skill>=60
  1982. if @battlers[index].effects[PBEffects::Encore]>0
  1983. scoreSum=0
  1984. scoreCount=0
  1985. attacker=@battlers[index]
  1986. encoreIndex=@battlers[index].effects[PBEffects::EncoreIndex]
  1987. if attacker.pbOpposing1.hp>0
  1988. scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
  1989. attacker,attacker.pbOpposing1,skill)
  1990. scoreCount+=1
  1991. end
  1992. if attacker.pbOpposing2.hp>0
  1993. scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
  1994. attacker,attacker.pbOpposing2,skill)
  1995. scoreCount+=1
  1996. end
  1997. if scoreCount>0 && scoreSum/scoreCount<=20 && pbAIRandom(10)<8
  1998. shouldswitch=true
  1999. end
  2000. end
  2001. end
  2002. if skill>=70
  2003. if !@doublebattle && @battlers[index].pbOppositeOpposing.hp>0
  2004. opp=@battlers[index].pbOppositeOpposing
  2005. if (opp.effects[PBEffects::HyperBeam]>0 ||
  2006. (isConst?(opp.ability,PBAbilities,:TRUANT) &&
  2007. opp.effects[PBEffects::Truant])) && pbAIRandom(100)<80 ||
  2008. (isConst?(opp.ability,PBAbilities,:STONER) &&
  2009. opp.effects[PBEffects::Stoner]) && pbAIRandom(100)<80
  2010. shouldswitch=false
  2011. end
  2012. end
  2013. end
  2014. if @rules["suddendeath"]
  2015. if @battlers[index].hp<=(@battlers[index].totalhp/4) && pbAIRandom(10)<3 &&
  2016. @battlers[index].turncount>0
  2017. shouldswitch=true
  2018. elsif @battlers[index].hp<=(@battlers[index].totalhp/2) && pbAIRandom(10)<8 &&
  2019. @battlers[index].turncount>0
  2020. shouldswitch=true
  2021. end
  2022. end
  2023. if @battlers[index].effects[PBEffects::PerishSong]==1
  2024. shouldswitch=true
  2025. end
  2026. if shouldswitch
  2027. list=[]
  2028. party=pbParty(index)
  2029. for i in 0...party.length
  2030. if pbCanSwitch?(index,i,false)
  2031. # If perish count is 1, it may be worth it to switch
  2032. # even with Spikes, since Perish Song's effect will end
  2033. if @battlers[index].effects[PBEffects::PerishSong]!=1
  2034. # Will contain effects that recommend against switching
  2035. spikes=@battlers[index].pbOwnSide.effects[PBEffects::Spikes]
  2036. if (spikes==1 && party[i].hp<=(party[i].totalhp/8)) ||
  2037. (spikes==2 && party[i].hp<=(party[i].totalhp/6)) ||
  2038. (spikes==3 && party[i].hp<=(party[i].totalhp/4))
  2039. if !party[i].hasType?(:FLYING) &&
  2040. !isConst?(party[i].ability,PBAbilities,:LEVITATE)
  2041. # Don't switch to this if too little HP
  2042. next
  2043. end
  2044. end
  2045. end
  2046. if movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])==0
  2047. weight=65
  2048. if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)<16
  2049. # Greater weight if new Pokemon's type is effective against opponent
  2050. weight=85
  2051. end
  2052. if pbAIRandom(100)<weight
  2053. list.unshift(i) # put this Pokemon first
  2054. end
  2055. elsif movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])<4
  2056. weight=40
  2057. if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)<16
  2058. # Greater weight if new Pokemon's type is effective against opponent
  2059. weight=60
  2060. end
  2061. if pbAIRandom(100)<weight
  2062. list.unshift(i) # put this Pokemon first
  2063. end
  2064. else
  2065. list.push(i) # put this Pokemon last
  2066. end
  2067. end
  2068. end
  2069. if list.length>0
  2070. if batonpass!=-1
  2071. if !pbRegisterMove(index,batonpass,false)
  2072. return pbRegisterSwitch(index,list[0])
  2073. end
  2074. return true
  2075. else
  2076. return pbRegisterSwitch(index,list[0])
  2077. end
  2078. end
  2079. end
  2080. return false
  2081. end
  2082.  
  2083. def pbDefaultChooseNewEnemy(index,party)
  2084. enemies=[]
  2085. for i in 0..party.length-1
  2086. if pbCanSwitchLax?(index,i,false)
  2087. enemies.push(i)
  2088. end
  2089. end
  2090. if enemies.length>0
  2091. return pbChooseBestNewEnemy(index,party,enemies)
  2092. end
  2093. return -1
  2094. end
  2095.  
  2096. def pbChooseBestNewEnemy(index,party,enemies)
  2097. return -1 if !enemies || enemies.length==0
  2098. $PokemonTemp=PokemonTemp.new if !$PokemonTemp
  2099. o1=@battlers[index].pbOpposing1
  2100. o2=@battlers[index].pbOpposing2
  2101. o1=nil if o1 && o1.hp<=0
  2102. o2=nil if o2 && o2.hp<=0
  2103. best=-1
  2104. bestSum=0
  2105. for e in enemies
  2106. pkmn=party[e]
  2107. sum=0
  2108. for move in pkmn.moves
  2109. next if move.id==0
  2110. md=PBMoveData.new(move.id)
  2111. next if md.basedamage==0
  2112. if o1
  2113. sum+=PBTypes.getCombinedEffectiveness(md.type,o1.type1,o1.type2)
  2114. end
  2115. if o2
  2116. sum+=PBTypes.getCombinedEffectiveness(md.type,o2.type1,o2.type2)
  2117. end
  2118. end
  2119. if best==-1 || sum>bestSum
  2120. best=e
  2121. bestSum=sum
  2122. end
  2123. end
  2124. return best
  2125. end
  2126.  
  2127. ################################################################################
  2128. # Choose an action.
  2129. ################################################################################
  2130. def pbDefaultChooseEnemyCommand(index)
  2131. if !pbCanShowFightMenu?(index)
  2132. return if pbEnemyShouldUseItem?(index)
  2133. return if pbEnemyShouldWithdraw?(index)
  2134. pbAutoChooseMove(index)
  2135. return
  2136. else
  2137. return if pbEnemyShouldUseItem?(index)
  2138. return if pbEnemyShouldWithdraw?(index)
  2139. return if pbAutoFightMenu(index)
  2140. pbRegisterMegaEvolution(index) if pbEnemyShouldMegaEvolve?(index)
  2141. pbChooseMoves(index)
  2142. end
  2143. end
  2144.  
  2145. ################################################################################
  2146. # Other functions.
  2147. ################################################################################
  2148. def pbDbgPlayerOnly?(idx)
  2149. return true if !$INTERNAL
  2150. return pbOwnedByPlayer?(idx.index) if idx.respond_to?("index")
  2151. return pbOwnedByPlayer?(idx)
  2152. end
  2153.  
  2154. def pbStdDev(scores)
  2155. n=0
  2156. sum=0
  2157. scores.each{|s| sum+=s; n+=1 }
  2158. return 0 if n==0
  2159. mean=sum.to_f/n.to_f
  2160. varianceTimesN=0
  2161. for i in 0...scores.length
  2162. if scores[i]>0
  2163. deviation=scores[i].to_f-mean
  2164. varianceTimesN+=deviation*deviation
  2165. end
  2166. end
  2167. # Using population standard deviation
  2168. # [(n-1) makes it a sample std dev, would be 0 with only 1 sample]
  2169. return Math.sqrt(varianceTimesN/n)
  2170. end
  2171. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement