Advertisement
Guest User

Untitled

a guest
Mar 15th, 2018
674
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.22 KB | None | 0 0
  1. 'use strict';
  2.  
  3. exports.BattleAbilities = {
  4. // Surge abilities
  5. "pollensurge": {
  6. onStart: function (source) {
  7. let foeactive = source.side.foe.active;
  8. let scorchedEarth = false;
  9. for (let i = 0; i < foeactive.length; i++) {
  10. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  11. }
  12. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('pollenterrain');
  13. },
  14. id: "pollensurge",
  15. name: "Pollen Surge",
  16. },
  17. "murkysurge": {
  18. onStart: function (source) {
  19. let foeactive = source.side.foe.active;
  20. let scorchedEarth = false;
  21. for (let i = 0; i < foeactive.length; i++) {
  22. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  23. }
  24. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('murkyterrain');
  25. },
  26. id: "murkysurge",
  27. name: "Murky Surge",
  28. },
  29. "regalsurge": {
  30. onStart: function (source) {
  31. let foeactive = source.side.foe.active;
  32. let scorchedEarth = false;
  33. for (let i = 0; i < foeactive.length; i++) {
  34. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  35. }
  36. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('regalterrain');
  37. },
  38. id: "regalsurge",
  39. name: "Regal Surge",
  40. },
  41. "electricsurge": {
  42. inherit: true,
  43. onStart: function (source) {
  44. let foeactive = source.side.foe.active;
  45. let scorchedEarth = false;
  46. for (let i = 0; i < foeactive.length; i++) {
  47. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  48. }
  49. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('electricterrain');
  50. },
  51. },
  52. "mistysurge": {
  53. inherit: true,
  54. onStart: function (source) {
  55. let foeactive = source.side.foe.active;
  56. let scorchedEarth = false;
  57. for (let i = 0; i < foeactive.length; i++) {
  58. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  59. }
  60. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('mistyterrain');
  61. },
  62. },
  63. "fierysurge": {
  64. onStart: function (source) {
  65. let foeactive = source.side.foe.active;
  66. let scorchedEarth = false;
  67. for (let i = 0; i < foeactive.length; i++) {
  68. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  69. }
  70. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('fieryterrain');
  71. },
  72. id: "fierysurge",
  73. name: "Fiery Surge",
  74. },
  75. "chakrasurge": {
  76. onStart: function (source) {
  77. let foeactive = source.side.foe.active;
  78. let scorchedEarth = false;
  79. for (let i = 0; i < foeactive.length; i++) {
  80. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  81. }
  82. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('chakraterrain');
  83. },
  84. id: "chakrasurge",
  85. name: "Chakra Surge",
  86. },
  87. "elevatedsurge": {
  88. onStart: function (source) {
  89. let foeactive = source.side.foe.active;
  90. let scorchedEarth = false;
  91. for (let i = 0; i < foeactive.length; i++) {
  92. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  93. }
  94. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('elevatedterrain');
  95. },
  96. id: "elevatedsurge",
  97. name: "Elevated Surge",
  98. },
  99. "ominoussurge": {
  100. onStart: function (source) {
  101. let foeactive = source.side.foe.active;
  102. let scorchedEarth = false;
  103. for (let i = 0; i < foeactive.length; i++) {
  104. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  105. }
  106. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('ominousterrain');
  107. },
  108. id: "ominoussurge",
  109. name: "Ominous Surge",
  110. },
  111. "grassysurge": {
  112. inherit: true,
  113. onStart: function (source) {
  114. let foeactive = source.side.foe.active;
  115. let scorchedEarth = false;
  116. for (let i = 0; i < foeactive.length; i++) {
  117. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  118. }
  119. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('grassyterrain');
  120. },
  121. },
  122. "sandysurge": {
  123. onStart: function (source) {
  124. let foeactive = source.side.foe.active;
  125. let scorchedEarth = false;
  126. for (let i = 0; i < foeactive.length; i++) {
  127. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  128. }
  129. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('sandyterrain');
  130. },
  131. id: "sandysurge",
  132. name: "Sandy Surge",
  133. },
  134. "frostysurge": {
  135. onStart: function (source) {
  136. let foeactive = source.side.foe.active;
  137. let scorchedEarth = false;
  138. for (let i = 0; i < foeactive.length; i++) {
  139. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  140. }
  141. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('frostyterrain');
  142. },
  143. id: "frostysurge",
  144. name: "Frosty Surge",
  145. },
  146. "cloudysurge": {
  147. onStart: function (source) {
  148. let foeactive = source.side.foe.active;
  149. let scorchedEarth = false;
  150. for (let i = 0; i < foeactive.length; i++) {
  151. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  152. }
  153. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('cloudyterrain');
  154. },
  155. id: "cloudysurge",
  156. name: "Cloudy Surge",
  157. },
  158. "rockysurge": {
  159. onStart: function (source) {
  160. let foeactive = source.side.foe.active;
  161. let scorchedEarth = false;
  162. for (let i = 0; i < foeactive.length; i++) {
  163. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  164. }
  165. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('rockyterrain');
  166. },
  167. id: "rockysurge",
  168. name: "Rocky Surge",
  169. },
  170. "corrosivesurge": {
  171. onStart: function (source) {
  172. let foeactive = source.side.foe.active;
  173. let scorchedEarth = false;
  174. for (let i = 0; i < foeactive.length; i++) {
  175. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  176. }
  177. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('corrosiveterrain');
  178. },
  179. id: "corrosivesurge",
  180. name: "Corrosive Surge",
  181. },
  182. "psychicsurge": {
  183. inherit: true,
  184. onStart: function (source) {
  185. let foeactive = source.side.foe.active;
  186. let scorchedEarth = false;
  187. for (let i = 0; i < foeactive.length; i++) {
  188. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  189. }
  190. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('psychicterrain');
  191. },
  192. },
  193. "metallicsurge": {
  194. onStart: function (source) {
  195. let foeactive = source.side.foe.active;
  196. let scorchedEarth = false;
  197. for (let i = 0; i < foeactive.length; i++) {
  198. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  199. }
  200. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('metallicterrain');
  201. },
  202. id: "metallicsurge",
  203. name: "Metallic Surge",
  204. },
  205. "seasurge": {
  206. onStart: function (source) {
  207. let foeactive = source.side.foe.active;
  208. let scorchedEarth = false;
  209. for (let i = 0; i < foeactive.length; i++) {
  210. if (foeactive[i].ability === 'scorchedearth') scorchedEarth = true;
  211. }
  212. if (!this.isTerrain('fieryterrain') || !scorchedEarth) this.setTerrain('seaterrain');
  213. },
  214. id: "seasurge",
  215. name: "Sea Surge",
  216. },
  217.  
  218. // Pollen terrain
  219. "beehivecall": {
  220. onPrepareHit: function (source, target, move) {
  221. if (this.isTerrain('pollenterrain') && move.type === 'Bug' && move.category !== 'Status' && !move.selfdestruct && !move.multihit && !move.flags['charge'] && !move.spreadHit && !move.isZ) {
  222. move.multihit = 4;
  223. move.hasParentalBond = true;
  224. move.hit = 0;
  225. }
  226. },
  227. onBasePowerPriority: 8,
  228. onBasePower: function (basePower, pokemon, target, move) {
  229. if (move.hasParentalBond && ++move.hit > 1) return this.chainModify(1.0/9.0);
  230. },
  231. id: "beehivecall",
  232. name: "Beehive Call",
  233. },
  234. "pollenshield": {
  235. onModifyDefPriority: 6,
  236. onModifyDef: function (pokemon) {
  237. if (this.isTerrain('pollenterrain')) return this.chainModify(1.5);
  238. },
  239. id: "pollenshield",
  240. name: "Pollen Shield",
  241. },
  242. "pollinatorzeal": {
  243. onModifySpe: function (spe, pokemon) {
  244. if (this.isTerrain('pollenterrain')) {
  245. return this.chainModify(2);
  246. }
  247. },
  248. onResidualOrder: 5,
  249. onResidualSubOrder: 3,
  250. onResidual: function (pokemon) {
  251. if (this.isTerrain('pollenterrain')) {
  252. this.heal(pokemon.maxhp / 16);
  253. }
  254. },
  255. id: "pollinatorzeal",
  256. name: "Pollinator Zeal",
  257. },
  258.  
  259. // Murky terrain abilities
  260. "dirtyfighting": {
  261. onBasePowerPriority: 8,
  262. onBasePower: function (basePower, attacker, defender, move) {
  263. if (this.isTerrain('murkyterrain')) {
  264. if (move.type === 'Dark' || move.type === 'Fighting' || move.type === 'Poison') {
  265. this.debug('Dirty Fighting boost');
  266. return this.chainModify([0x14CD, 0x1000]);
  267. }
  268. }
  269. },
  270. id: "dirtyfighting",
  271. name: "Dirty Fighting",
  272. },
  273. "disenchanted": {
  274. onTryHit: function (target, source, move) {
  275. if (this.isTerrain('murkyterrain') && move.type === 'Fairy') {
  276. this.add('-immune', target, '[msg]', '[from] ability: Disenchanted');
  277. return null;
  278. }
  279. },
  280. id: "disenchanted",
  281. name: "Disenchanted",
  282. },
  283. "murkycover": {
  284. onModifySpe: function (spe, pokemon) {
  285. if (this.isTerrain('murkyterrain')) {
  286. return this.chainModify(1.5);
  287. }
  288. },
  289. onSourceModifyAccuracy: function (accuracy) {
  290. if (typeof accuracy !== 'number') return;
  291. this.debug('murkycover - enhancing accuracy');
  292. if (this.isTerrain('murkyterrain')) return accuracy * (4.0/3.0);
  293. },
  294. id: "murkycover",
  295. name: "Murky Cover",
  296. },
  297.  
  298. // Regal terrain abilities
  299. "auraofdestruction": {
  300. onStart: function (pokemon) {
  301. if (this.isTerrain('regalterrain')) {
  302. let foeactive = pokemon.side.foe.active;
  303. let activated = false;
  304. for (let i = 0; i < foeactive.length; i++) {
  305. if (!foeactive[i] || !this.isAdjacent(foeactive[i], pokemon)) continue;
  306. if (!activated) {
  307. this.add('-ability', pokemon, 'Aura of Destruction');
  308. activated = true;
  309. }
  310. foeactive[i].addVolatile('gastroacid');
  311. }
  312. }
  313. },
  314. onModifyMove: function (move) {
  315. if (this.isTerrain('regalterrain')) move.ignoreAbility = true;
  316. },
  317. id: "auraofdestruction",
  318. name: "Aura of Destruction",
  319. },
  320. "teethbared": {
  321. onModifyMove: function (move, pokemon) {
  322. if (this.isTerrain('regalterrain') && move.flags['bite']) {
  323. move.willCrit = true;
  324. }
  325. },
  326. id: "teethbared",
  327. name: "Teeth Bared",
  328. },
  329. "tyranny": {
  330. onModifyAtkPriority: 5,
  331. onModifyAtk: function (spa, pokemon) {
  332. if (this.isTerrain('regalterrain')) {
  333. return this.chainModify(4.0/3.0);
  334. }
  335. },
  336. onModifySpAPriority: 5,
  337. onModifySpA: function (spa, pokemon) {
  338. if (this.isTerrain('regalterrain')) {
  339. return this.chainModify(4.0/3.0);
  340. }
  341. },
  342. id: "tyranny",
  343. name: "Tyranny",
  344. },
  345.  
  346. // Electric terrain abilities
  347. "electriccharger": {
  348. onStart: function (pokemon) {
  349. if (this.isTerrain('electricterrain')) {
  350. pokemon.addVolatile('charge');
  351. }
  352. },
  353. id: "electriccharger",
  354. name: "Electric Charger",
  355. },
  356. "overcharge": {
  357. onModifyAtkPriority: 5,
  358. onModifyAtk: function (spa, pokemon) {
  359. if (this.isTerrain('electricterrain')) {
  360. return this.chainModify(1.5);
  361. }
  362. },
  363. onResidualOrder: 1,
  364. onResidual: function (pokemon) {
  365. if (this.isTerrain('electricterrain')) {
  366. this.damage(pokemon.maxhp / 16, pokemon, pokemon);
  367. }
  368. },
  369. id: "overcharge",
  370. name: "Overcharge",
  371. },
  372.  
  373. // Misty terrain abilities
  374. "magicessence": {
  375. // implemented in moves.js:mistyterrain
  376. id: "magicessence",
  377. name: "Magic Essence",
  378. },
  379. "mistybliss": {
  380. onModifySpDPriority: 6,
  381. onModifySpD: function (spa, pokemon) {
  382. if (this.isTerrain('mistyterrain')) {
  383. return this.chainModify(1.5);
  384. }
  385. },
  386. onModifyAtkPriority: 6,
  387. onSourceModifyAtk: function (atk, attacker, defender, move) {
  388. if (this.isTerrain('mistyterrain') && (move.type === 'Poison' || move.type === 'Steel')) {
  389. this.debug('Misty Bliss weaken');
  390. return this.chainModify(2.0/3.0);
  391. }
  392. },
  393. onModifySpAPriority: 5,
  394. onSourceModifySpA: function (atk, attacker, defender, move) {
  395. if (this.isTerrain('mistyterrain') && (move.type === 'Poison' || move.type === 'Steel')) {
  396. this.debug('Misty Bliss weaken');
  397. return this.chainModify(2.0/3.0);
  398. }
  399. },
  400. id: "mistybliss",
  401. name: "Misty Bliss",
  402. },
  403. "mistydamp": {
  404. onBasePowerPriority: 8,
  405. onBasePower: function (basePower, attacker, defender, move) {
  406. if (this.isTerrain('mistyterrain')) {
  407. if (move.type === 'Fairy' || move.type === 'Ice' || move.type === 'Water') {
  408. this.debug('Misty Damp boost');
  409. return this.chainModify([0x14CD, 0x1000]);
  410. }
  411. }
  412. },
  413. id: "mistydamp",
  414. name: "Misty Damp",
  415. },
  416.  
  417. // Chakra terrain abilities
  418. "innerpeace": {
  419. onModifyDefPriority: 6,
  420. onModifyDef: function (spa, pokemon) {
  421. if (this.isTerrain('chakraterrain')) {
  422. return this.chainModify(1.5);
  423. }
  424. },
  425. onModifySpDPriority: 6,
  426. onModifySpD: function (spa, pokemon) {
  427. if (this.isTerrain('chakraterrain')) {
  428. return this.chainModify(1.5);
  429. }
  430. },
  431. id: "innerpeace",
  432. name: "Inner Peace",
  433. },
  434. "perfectzen": {
  435. onBasePowerPriority: 8,
  436. onBasePower: function (basePower, attacker, defender, move) {
  437. if (this.isTerrain('chakraterrain') && move.isZ) {
  438. this.debug('Perfect Zen boost');
  439. return this.chainModify(1.5);
  440. }
  441. },
  442. id: "perfectzen",
  443. name: "Perfect Zen",
  444. },
  445. "quickdraw": {
  446. onModifyPriority: function (priority, pokemon, target, move) {
  447. if (this.isTerrain('chakraterrain') && target.hp === target.maxhp && move.category !== 'Status') {
  448. return priority + 0.1;
  449. }
  450. },
  451. onModifyDamage: function (damage, source, target, move) {
  452. if (this.isTerrain('chakraterrain') && target.hp === target.maxhp && move.category !== 'Status') {
  453. return this.chainModify(2);
  454. }
  455. },
  456. id: "quickdraw",
  457. name: "Quick Draw",
  458. },
  459.  
  460. // Fiery terrain abilities
  461. "hotheaded": {
  462. onModifySpe: function (spe, pokemon) {
  463. if (this.isTerrain('fieryterrain')) {
  464. return this.chainModify(1.5);
  465. }
  466. },
  467. onModifyDamage: function (damage, source, target, move) {
  468. if (this.isTerrain('fieryterrain') && move.typeMod < 0) {
  469. this.debug('Hot-Headed boost');
  470. return this.chainModify(1.5);
  471. }
  472. },
  473. id: "hotheaded",
  474. name: "Hot-Headed",
  475. },
  476. "scorchedearth": {
  477. // implemented in surge abilities and moves.js:fieryterrain; that was one huge pain
  478. id: "scorchedearth",
  479. name: "Scorched Earth",
  480. },
  481. "soulburn": {
  482. onModifyMove: function (move, source, target) {
  483. if (this.isTerrain('fieryterrain') && move.category === 'Special' && !move.drain && !move.recoil && move.id !== 'mindblown') {
  484. move.drain = [1, 2];
  485. }
  486. },
  487. id: "soulburn",
  488. name: "Soul Burn",
  489. },
  490.  
  491. // Elevated terrain abilities
  492. "eagleeye": {
  493. onModifyCritRatio: function (critRatio) {
  494. if (this.isTerrain('elevatedterrain')) return critRatio + 1;
  495. },
  496. onSourceModifyAccuracy: function (accuracy) {
  497. this.debug('eagleeye - enhancing accuracy');
  498. if (this.isTerrain('elevatedterrain')) return true;
  499. },
  500. id: "eagleeye",
  501. name: "Eagle Eye",
  502. },
  503. "galeforce": {
  504. onStart: function (pokemon) {
  505. if (this.isTerrain('elevatedterrain')) {
  506. pokemon.side.addSideCondition('tailwind');
  507. }
  508. },
  509. onModifyMove: function (move, source, target) {
  510. if (move.id === 'elevatedterrain') {
  511. move.sideCondition = 'tailwind';
  512. }
  513. },
  514. id: "galeforce",
  515. name: "Gale Force",
  516. },
  517. "weightless": {
  518. onModifySpe: function (spe, pokemon) {
  519. if (this.isTerrain('elevatedterrain')) {
  520. return this.chainModify(2);
  521. }
  522. },
  523. id: "weightless",
  524. name: "Weightless",
  525. },
  526.  
  527. // Ominous terrain abilities
  528. "graveguardian": {
  529. onModifyAtkPriority: 5,
  530. onModifyAtk: function (spa, pokemon) {
  531. if (this.isTerrain('ominousterrain')) {
  532. return this.chainModify(1.5);
  533. }
  534. },
  535. onModifyDamage: function (damage, source, target, move) {
  536. if (this.isTerrain('ominousterrain') && target.types.indexOf('Dark') >= 0) {
  537. return this.chainModify(2);
  538. }
  539. },
  540. id: "graveguardian",
  541. name: "Grave Guardian",
  542. },
  543. "seance": {
  544. onStart: function (pokemon) {
  545. if (this.isTerrain('ominousterrain')) {
  546. let foeactive = pokemon.side.foe.active;
  547. for (let i = 0; i < foeactive.length; i++) {
  548. if (!foeactive[i] || foeactive[i].fainted) continue;
  549. if (foeactive[i].item) {
  550. this.add('-ability', pokemon, 'Se\u0301ance');
  551. this.add('-item', foeactive[i], foeactive[i].getItem().name, '[from] ability: Se\u0301ance', '[of] ' + pokemon, '[identify]');
  552. }
  553. }
  554. }
  555. },
  556. onSourceModifyAccuracy: function (accuracy) {
  557. if (typeof accuracy !== 'number') return;
  558. this.debug('seance - enhancing accuracy');
  559. if (this.isTerrain('ominousterrain')) return accuracy * (4.0/3.0);
  560. },
  561. id: "seance",
  562. name: "Se\u0301ance",
  563. },
  564. "trickster": {
  565. onModifyMovePriority: -2,
  566. onModifyMove: function (move) {
  567. if (this.isTerrain('ominousterrain') && move.secondaries) {
  568. for (let i = 0; i < move.secondaries.length; i++) {
  569. if (move.secondaries[i].status || move.id === 'triattack') move.secondaries[i].chance = 100;
  570. }
  571. }
  572. },
  573. id: "trickster",
  574. name: "Trickster",
  575. },
  576.  
  577. // Grassy terrain abilities
  578. "herbalsprout": {
  579. onResidualOrder: 26,
  580. onResidualSubOrder: 1,
  581. onResidual: function (pokemon) {
  582. if (this.isTerrain('grassyterrain')) {
  583. if (pokemon.hp && !pokemon.item && this.getItem(pokemon.lastItem).name.substr(-4) === 'Herb') {
  584. pokemon.setItem(pokemon.lastItem);
  585. pokemon.lastItem = '';
  586. this.add('-item', pokemon, pokemon.getItem(), '[from] ability: Herbal Sprout');
  587. }
  588. }
  589. },
  590. id: "herbalsprout",
  591. name: "Herbal Sprout",
  592. },
  593. "leafyshield": {
  594. onModifyAtkPriority: 6,
  595. onSourceModifyAtk: function (atk, attacker, defender, move) {
  596. if (this.isTerrain('grassyterrain') && (move.type in {'Bug':1, 'Fire':1, 'Flying':1, 'Ice':1, 'Poison':1,})) {
  597. this.debug('Leafy Shield weaken');
  598. return this.chainModify(0.5);
  599. }
  600. },
  601. onModifySpAPriority: 5,
  602. onSourceModifySpA: function (atk, attacker, defender, move) {
  603. if (this.isTerrain('grassyterrain') && (move.type in {'Bug':1, 'Fire':1, 'Flying':1, 'Ice':1, 'Poison':1,})) {
  604. this.debug('Leafy Shield weaken');
  605. return this.chainModify(0.5);
  606. }
  607. },
  608. id: "leafyshield",
  609. name: "Leafy Shield",
  610. },
  611.  
  612. // Sandy terrain abilities
  613. "fairydust": {
  614. onModifyAtkPriority: 6,
  615. onSourceModifyAtk: function (atk, attacker, defender, move) {
  616. if (this.isTerrain('sandyterrain') && (move.type in {'Bug':1, 'Dark':1, 'Fighting':1,})) {
  617. this.debug('Fairy Dust weaken');
  618. return this.chainModify(0.5);
  619. }
  620. },
  621. onModifySpAPriority: 5,
  622. onSourceModifySpA: function (atk, attacker, defender, move) {
  623. if (this.isTerrain('sandyterrain') && (move.type in {'Bug':1, 'Dark':1, 'Fighting':1,})) {
  624. this.debug('Fairy Dust weaken');
  625. return this.chainModify(0.5);
  626. }
  627. },
  628. onTryHit: function (target, source, move) {
  629. if (this.isTerrain('sandyterrain') && (move.type === 'Dragon' || move.type === 'Ground')) {
  630. this.add('-immune', target, '[msg]', '[from] ability: Fairy Dust');
  631. return null;
  632. }
  633. },
  634. id: "fairydust",
  635. name: "Fairy Dust",
  636. },
  637. "earthshattering": {
  638. onModifyDamage: function (damage, source, target, move) {
  639. if (this.isTerrain('sandyterrain') && move.typeMod > 0) {
  640. return this.chainModify(2);
  641. }
  642. },
  643. id: "earthshattering",
  644. name: "Earth Shattering",
  645. },
  646. "stickysand": {
  647. onBoost: function (boost, target, source, effect) {
  648. if (!this.isTerrain('sandyterrain')) return;
  649. if (source && target === source) return;
  650. let showMsg = false;
  651. for (let i in boost) {
  652. if (boost[i] < 0) {
  653. delete boost[i];
  654. showMsg = true;
  655. }
  656. }
  657. if (showMsg && !effect.secondaries) this.add("-fail", target, "unboost", "[from] ability: Sticky Sand", "[of] " + target);
  658. },
  659. onResidualOrder: 5,
  660. onResidualSubOrder: 3,
  661. onResidual: function (pokemon) {
  662. if (this.isTerrain('sandyterrain')) {
  663. this.heal(pokemon.maxhp / 8);
  664. } else if (this.isTerrain('rockyterrain')) {
  665. this.damage(pokemon.maxhp / 8);
  666. }
  667. },
  668. id: "stickysand",
  669. name: "Sticky Sand",
  670. },
  671.  
  672. // Frosty terrain abilities
  673. "coldhearted": {
  674. onStart: function (pokemon) {
  675. if (this.isTerrain('frostyterrain')) this.boost({atk: 1, def: -1, spa: 1, spd: -1, spe: 1,});
  676. },
  677. id: "coldhearted",
  678. name: "Cold-Hearted",
  679. },
  680. "coldshoulder": {
  681. onAnyModifyBoost: function (boosts, target) {
  682. if (this.isTerrain('frostyterrain')) {
  683. let source = this.effectData.target;
  684. if (source === target) return;
  685. if (source === this.activePokemon && target === this.activeTarget) {
  686. boosts['def'] = 0;
  687. boosts['spd'] = 0;
  688. boosts['evasion'] = 0;
  689. }
  690. if (target === this.activePokemon && source === this.activeTarget) {
  691. boosts['atk'] = 0;
  692. boosts['spa'] = 0;
  693. boosts['accuracy'] = 0;
  694. }
  695. }
  696. },
  697. onModifyMove: function (move) {
  698. if (this.isTerrain('frostyterrain')) move.infiltrates = true;
  699. },
  700. id: "coldshoulder",
  701. name: "Cold Shoulder",
  702. },
  703. "snapfreeze": {
  704. onSourceHit: function (target, source, move) {
  705. if (this.isTerrain('frostyterrain') && move.type === 'Ice' && move.category !== 'Status') this.damage(target.maxhp / 8, target, source, 'Snap Freeze');
  706. },
  707. id: "snapfreeze",
  708. name: "Snap Freeze",
  709. },
  710.  
  711. // Cloudy terrain abilities
  712. "clearskies": {
  713. onModifyAtkPriority: 5,
  714. onModifyAtk: function (spa, pokemon) {
  715. if (this.isTerrain('cloudyterrain')) {
  716. return this.chainModify(1.2);
  717. }
  718. },
  719. onModifyDefPriority: 5,
  720. onModifyDef: function (spa, pokemon) {
  721. if (this.isTerrain('cloudyterrain')) {
  722. return this.chainModify(1.2);
  723. }
  724. },
  725. onModifySpAPriority: 5,
  726. onModifySpA: function (spa, pokemon) {
  727. if (this.isTerrain('cloudyterrain')) {
  728. return this.chainModify(1.2);
  729. }
  730. },
  731. onModifySpDPriority: 5,
  732. onModifySpD: function (spa, pokemon) {
  733. if (this.isTerrain('cloudyterrain')) {
  734. return this.chainModify(1.2);
  735. }
  736. },
  737. onModifySpe: function (spa, pokemon) {
  738. if (this.isTerrain('cloudyterrain')) {
  739. return this.chainModify(1.2);
  740. }
  741. },
  742. id: "clearskies",
  743. name: "Clear Skies",
  744. },
  745. "cloudcleanse": {
  746. onStart: function (pokemon) {
  747. if (this.isTerrain('cloudyterrain')) {
  748. this.add('-activate', pokemon, 'ability: Cloud Cleanse');
  749. let side = pokemon.side;
  750. let success = false;
  751. for (const ally of side.pokemon) {
  752. if (ally.hasAbility('soundproof')) continue;
  753. if (ally.cureStatus()) success = true;
  754. }
  755. return success;
  756. }
  757. },
  758. id: "cloudcleanse",
  759. name: "Cloud Cleanse",
  760. },
  761. "nimbusforce": {
  762. onModifyMovePriority: -5,
  763. onModifyMove: function (move) {
  764. if (!move.ignoreImmunity) move.ignoreImmunity = {};
  765. if (this.isTerrain('cloudyterrain') && move.ignoreImmunity !== true) {
  766. move.ignoreImmunity['Normal'] = true;
  767. }
  768. },
  769. onModifyDamage: function (damage, source, target, move) {
  770. if (this.isTerrain('cloudyterrain') && move.type === 'Normal' && target.types.indexOf('Ghost') >= 0) {
  771. return this.chainModify(2);
  772. }
  773. },
  774. id: "nimbusforce",
  775. name: "Nimbus Force",
  776. },
  777.  
  778. //Corrosive terrain abilities
  779. "cauldronbubble": {
  780. onAfterDamage: function (damage, target, source, move) {
  781. if (this.isTerrain('corrosiveterrain') && move && move.flags['contact']) {
  782. source.addVolatile('curse', this.effectData.target);
  783. }
  784. },
  785. onModifySpAPriority: 5,
  786. onModifySpA: function (spa, pokemon) {
  787. if (this.isTerrain('corrosiveterrain')) {
  788. return this.chainModify(1.5);
  789. }
  790. },
  791. onModifySpDPriority: 5,
  792. onModifySpD: function (spa, pokemon) {
  793. if (this.isTerrain('corrosiveterrain')) {
  794. return this.chainModify(1.5);
  795. }
  796. },
  797. id: "cauldronbubble",
  798. name: "Cauldron Bubble",
  799. },
  800. "neurotoxin": {
  801. onModifyMove: function (move, source, target) {
  802. if (this.isTerrain('corrosiveterrain') && move.category === 'Special' && !move.drain && !move.recoil && move.id !== 'mindblown') {
  803. move.drain = [1, 2];
  804. }
  805. },
  806. id: "neurotoxin",
  807. name: "Neurotoxin",
  808. },
  809. "toxicwaste": {
  810. onModifyMovePriority: -2,
  811. onModifyMove: function (move) {
  812. if (this.isTerrain('corrosiveterrain')) {
  813. if (move.status && move.status === 'psn') move.status = 'tox';
  814. if (move.secondaries) {
  815. for (let i = 0; i < move.secondaries.length; i++) {
  816. if (move.secondaries[i].status && move.secondaries[i].status === 'psn') move.secondaries[i].status = 'tox';
  817. }
  818. }
  819. }
  820. },
  821. // Toxic Spikes buff implemented in moves.js:toxicspikes
  822. id: "toxicwaste",
  823. name: "Toxic Waste",
  824. },
  825.  
  826. // Psychic terrain abilities
  827. "enchantedregalia": {
  828. onStart: function (pokemon) {
  829. if (this.isTerrain('psychicterrain')) {
  830. let foeactive = pokemon.side.foe.active;
  831. let activated = false;
  832. for (let i = 0; i < foeactive.length; i++) {
  833. if (!foeactive[i] || !this.isAdjacent(foeactive[i], pokemon)) continue;
  834. if (!activated) {
  835. this.add('-ability', pokemon, 'Enchanted Regalia');
  836. activated = true;
  837. }
  838. foeactive[i].addVolatile('embargo');
  839. }
  840. }
  841. },
  842. onModifyDamage: function (damage, source, target, move) {
  843. if (this.isTerrain('psychicterrain') && source.item) {
  844. return this.chainModify(1.2);
  845. }
  846. },
  847. id: "enchantedregalia",
  848. name: "Enchanted Regalia",
  849. },
  850. "mindovermatter": {
  851. onModifyMove: function (move, pokemon) {
  852. if (this.isTerrain('psychicterrain') && move.category === 'Physical') move.category = 'Special';
  853. },
  854. id: "mindovermatter",
  855. name: "Mind over Matter",
  856. },
  857. "otherwordlyvoice": {
  858. onBasePower: function (basePower, attacker, defender, move) {
  859. if (this.isTerrain('psychicterrain') && move.flags['sound']) {
  860. this.debug('Otherwordly Voice boost');
  861. return this.chainModify([0x14CD, 0x1000]);
  862. }
  863. },
  864. onModifyAtkPriority: 6,
  865. onSourceModifyAtk: function (atk, attacker, defender, move) {
  866. if (this.isTerrain('psychicterrain') && (move.type === 'Dark' || move.type === 'Ghost')) {
  867. this.debug('Otherwordly Voice');
  868. return this.chainModify(0.5);
  869. }
  870. },
  871. onModifySpAPriority: 5,
  872. onSourceModifySpA: function (atk, attacker, defender, move) {
  873. if (this.isTerrain('psychicterrain') && (move.type === 'Dark' || move.type === 'Ghost')) {
  874. this.debug('Otherwordly Voice');
  875. return this.chainModify(0.5);
  876. }
  877. },
  878. id: "otherwordlyvoice",
  879. name: "Otherwordly Voice",
  880. },
  881.  
  882. // Rocky terrain abilities
  883. "gemenergy": {
  884. // implemented in moves.js and statuses.js; that was a pain too
  885. id: "gemenergy",
  886. name: "Gem Energy",
  887. },
  888. "metalcrush": {
  889. // implemented in moves.js:rockyterrain
  890. onModifyMove: function (move, pokemon) {
  891. if (this.isTerrain('rockyterrain') && move && move.type === 'Rock') {
  892. move.metalCrush = true;
  893. }
  894. },
  895. id: "metalcrush",
  896. name: "Metal Crush",
  897. },
  898. "meteorstrike": {
  899. onModifyPriority: function (priority, pokemon, target, move) {
  900. if (this.isTerrain('rockyterrain') && pokemon.activeTurns <= 1 && move.category !== 'Status') {
  901. return priority += 3;
  902. }
  903. },
  904. onModifyDamage: function (damage, source, target, move) {
  905. if (this.isTerrain('rockyterrain') && source.activeTurns <= 1) {
  906. return this.chainModify(2);
  907. }
  908. },
  909. onBeforeMovePriority: 6,
  910. onBeforeMove: function (pokemon, target, move) {
  911. if (this.isTerrain('rockyterrain') && pokemon.activeTurns <= 1 && move.category !== 'Status' && this.getEffectiveness(move.type, target) < 0) {
  912. this.add('cant', pokemon, 'ability: Meteor Strike', move);
  913. return false;
  914. }
  915. },
  916. id: "meteorstrike",
  917. name: "Meteor Strike",
  918. },
  919.  
  920. // Sea terrain
  921. "seafoamsplash": {
  922. onSourceModifyDamage: function (damage, source, target, move) {
  923. if (this.isTerrain('seaterrain')) {
  924. return this.chainModify(0.75);
  925. }
  926. },
  927. onSetStatus: function (status, target, source, effect) {
  928. if (this.isTerrain('seaterrain')) {
  929. if (effect && effect.status) this.add('-immune', target, '[msg]', '[from] ability: Seafoam Splash');
  930. return false;
  931. }
  932. },
  933. onTryAddVolatile: function (status, target) {
  934. if (status.id === 'yawn' && this.isTerrain('seaterrain')) {
  935. this.add('-immune', target, '[msg]', '[from] ability: Seafoam Splash');
  936. return null;
  937. }
  938. },
  939. id: "seafoamsplash",
  940. name: "Seafoam Splash",
  941. },
  942. "stormrage": {
  943. onModifyDamage: function (damage, source, target, move) {
  944. if (this.isTerrain('seaterrain') && target.types.indexOf('Grass') >= 0) {
  945. return this.chainModify(1.5);
  946. }
  947. },
  948. onModifyMove: function (move) {
  949. if (this.isTerrain('seaterrain') && move.type === 'Water') move.ignoreAbility = true;
  950. },
  951. id: "stormrage",
  952. name: "Storm Rage",
  953. },
  954. "waterwalker": {
  955. onModifySpe: function (spe, pokemon) {
  956. if (this.isTerrain('seaterrain')) {
  957. return this.chainModify(4.0/3.0);
  958. }
  959. },
  960. onTryHit: function (target, source, move) {
  961. if (this.isTerrain('seaterrain') && move.type === 'Ground' && move.id !== 'thousandarrows') {
  962. this.add('-immune', target, '[msg]', '[from] ability: Water Walker');
  963. return null;
  964. }
  965. },
  966. onDamage: function (damage, target, source, effect) {
  967. if (!effect) return;
  968. if (this.isTerrain('seaterrain') && effect.id === 'spikes') {
  969. return false;
  970. }
  971. },
  972. onBoost: function (boost, target, source, effect) {
  973. if (!effect) return;
  974. if (this.isTerrain('seaterrain')) {
  975. if (effect.id === 'rototiller') {
  976. delete boost['atk'];
  977. delete boost['spa'];
  978. }
  979. if (effect.id === 'stickyweb') delete boost['spe'];
  980. }
  981. },
  982. onSetStatus: function (status, target, source, effect) {
  983. if (!effect) return false;
  984. if (this.isTerrain('seaterrain') && effect.id === 'toxicspikes') return false;
  985. },
  986. // also implemented in Arena Trap below
  987. id: "waterwalker",
  988. name: "Water Walker",
  989. },
  990.  
  991. "arenatrap": {
  992. inherit: true,
  993. onFoeTrapPokemon: function (pokemon) {
  994. if (!this.isAdjacent(pokemon, this.effectData.target)) return;
  995. if (pokemon.isGrounded() && (!this.isTerrain('seaterrain') || pokemon.ability !== 'waterwalker')) {
  996. pokemon.tryTrap(true);
  997. }
  998. },
  999. onFoeMaybeTrapPokemon: function (pokemon, source) {
  1000. if (!source) source = this.effectData.target;
  1001. if (!this.isAdjacent(pokemon, source)) return;
  1002. if (pokemon.isGrounded(!pokemon.knownType) && (!this.isTerrain('seaterrain') || pokemon.ability !== 'waterwalker')) { // Negate immunity if the type is unknown
  1003. pokemon.maybeTrapped = true;
  1004. }
  1005. },
  1006. },
  1007. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement