diff --git a/data/mods/crossoverchaos/abilities.js b/data/mods/crossoverchaos/abilities.js index 6333418238..1cc9c80de8 100644 --- a/data/mods/crossoverchaos/abilities.js +++ b/data/mods/crossoverchaos/abilities.js @@ -1,7 +1,7 @@ 'use strict'; exports.BattleAbilities = { "karmicretribution": { - desc: "This Pokemon's damaging moves become multi-hit moves that hit four times. The second hit has its damage quartered. Does not affect moves that have multiple targets or moves that use the target's attacking stats instead of the user's.", + desc: "This Pokemon's damaging moves become multi-hit moves that hit four times. Does not affect moves that have multiple targets or moves that use the target's attacking stats instead of the user's.", shortDesc: "This Pokemon's damaging moves hit four times (not Foul Play).", onPrepareHit(source, target, move) { if (['iceball', 'rollout'].includes(move.id) || move.useTargetOffensive || move.useSourceDefensive) return; @@ -31,9 +31,9 @@ exports.BattleAbilities = { desc: "This Pokemon's Psychic-type attacks are super-effective against Dark-types and its Fairy-type attacks are super-effective against Poison-types. Psychic-type attacks ignore the Dark-type's immunity.", shortDesc: "User's Psychic- and Fairy-type moves are SE against Dark and Poison, respectively, ignoring immunities if applicable.", onModifyMovePriority: -5, - onModifyMove(move) { + onModifyMove(move, source, target) { if (!move.ignoreImmunity) move.ignoreImmunity = {}; - if (move.ignoreImmunity !== true) { + if (move.ignoreImmunity !== true && target.hasType('Dark')) { move.ignoreImmunity['Psychic'] = true; } }, @@ -169,7 +169,7 @@ exports.BattleAbilities = { name: "Crystal Barrier", }, "powershield": { - shortDesc: "This Pokemon's moves of over 90 base power have 90 base power instead.", + shortDesc: "Incoming moves of over 90 base power have 90 base power instead.", onBasePowerPriority: 8, onSourceBasePower(basePower, attacker, defender, move) { if (basePower > 90) { @@ -276,6 +276,459 @@ exports.BattleAbilities = { id: "powerofsummer", name: "Power of Summer", }, + "baneoflight": { + desc: "This Pokemon's Dark-type attacks are super-effective against Fairy-types, and its Poison-type attacks are super-effective against Psychic-types.", + shortDesc: "User's Dark- and Poison-type moves are SE against Fairy and Psychic, respectively.", + onSourceEffectiveness(typeMod, target, type, move) { + if (move && ((type === 'Fairy' && move.type === 'Dark') || (type === 'Psychic' && move.type === 'Poison'))) return 1; + return typeMod; + }, + id: "baneoflight", + name: "Bane of Light", + }, + "fourofakind": { + desc: "This Pokemon's damaging moves become multi-hit moves that hit four times. Does not affect moves that have multiple targets or moves that use the target's attacking stats instead of the user's.", + shortDesc: "This Pokemon's damaging moves hit four times, but have x0.25 power and halved secondary chances.", + onModifyMovePriority: -2, + onModifyMove(move) { + if (move.secondaries && move.multihitType === 'parentalbond') { + this.debug('halving secondary chance'); + for (const secondary of move.secondaries) { + if (secondary.chance) secondary.chance /= 2; + } + } + }, + onPrepareHit(source, target, move) { + if (['iceball', 'rollout'].includes(move.id)) return; + if (move.category !== 'Status' && !move.selfdestruct && !move.multihit && !move.flags['charge'] && !move.spreadHit && !move.isZ) { + move.multihit = 4; + move.multihitType = 'parentalbond'; + if (move.secondaries) { + this.debug('halving secondary chance'); + for (const secondary of move.secondaries) { + if (secondary.chance) secondary.chance /= 2; + } + } + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, pokemon, target, move) { + if (move.multihitType === 'parentalbond') return this.chainModify(0.25); + }, + onSourceModifySecondaries(secondaries, target, source, move) { + if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 4) { + // hack to prevent accidentally suppressing King's Rock/Razor Fang + return secondaries.filter(effect => effect.volatileStatus === 'flinch'); + } + }, + id: "fourofakind", + name: "Four of a Kind", + }, + "fourheads": { + desc: "This Pokemon's damaging moves become multi-hit moves that hit four times. Does not affect moves that have multiple targets or moves that use the target's attacking stats instead of the user's.", + shortDesc: "This Pokemon's damaging moves hit four times, but have x0.3 power and halved secondary chances.", + onModifyMovePriority: -2, + onModifyMove(move) { + if (move.secondaries && move.multihitType === 'fourheads') { + this.debug('halving secondary chance'); + for (const secondary of move.secondaries) { + if (secondary.chance) secondary.chance /= 2; + } + } + }, + onPrepareHit(source, target, move) { + if (['iceball', 'rollout'].includes(move.id)) return; + if (move.category !== 'Status' && !move.selfdestruct && !move.multihit && !move.flags['charge'] && !move.spreadHit && !move.isZ) { + move.multihit = 4; + move.multihitType = 'fourheads'; + if (move.secondaries) { + this.debug('halving secondary chance'); + for (const secondary of move.secondaries) { + if (secondary.chance) secondary.chance /= 2; + } + } + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, pokemon, target, move) { + if (move.multihitType === 'fourheads') return this.chainModify(0.3); + }, + onSourceModifySecondaries(secondaries, target, source, move) { + if (move.multihitType === 'fourheads' && move.id === 'secretpower' && move.hit < 4) { + // hack to prevent accidentally suppressing King's Rock/Razor Fang + return secondaries.filter(effect => effect.volatileStatus === 'flinch'); + } + }, + id: "fourheads", + name: "Four Heads", + }, + "abilitytodestroyanything": { + shortDesc: "Sniper + Sheer Force + Super Luck + This Pokemon's moves that would otherwise lack recoil now deal 25% of damage dealt back to the user.", + onModifyMove(move, pokemon) { + if (move.secondaries) { + delete move.secondaries; + // Technically not a secondary effect, but it is negated + if (move.id === 'clangoroussoulblaze') delete move.selfBoost; + // Actual negation of `AfterMoveSecondary` effects implemented in scripts.js + move.hasSheerForce = true; + } + if (!move.recoil){ + move.recoil = [1, 4]; + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, pokemon, target, move) { + if (move.hasSheerForce) return this.chainModify([0x14CD, 0x1000]); + }, + onModifyDamage(damage, source, target, move) { + if (target.getMoveHitData(move).crit) { + this.debug('Sniper boost'); + return this.chainModify(1.5); + } + }, + onModifyCritRatio(critRatio) { + return critRatio + 1; + }, + id: "abilitytodestroyanything", + name: "Ability to Destroy Anything", + }, + "miner": { + shortDesc: "This Pokemon's attacking stat is multiplied by 1.5 while using a Rock-type attack.", + onModifyAtkPriority: 5, + onModifyAtk(atk, attacker, defender, move) { + if (move.type === 'Rock') { + this.debug('Miner boost (except not really because x1.5 multiplier)'); + return this.chainModify(1.5); + } + }, + onModifySpAPriority: 5, + onModifySpA(atk, attacker, defender, move) { + if (move.type === 'Rock') { + this.debug('Miner boost (except not really because x1.5 multiplier)'); + return this.chainModify(1.5); + } + }, + id: "miner", + name: "Miner", + }, + "noncorporeal": { + shortDesc: "This Pokemon can only be damaged by supereffective or Rock-type moves and indirect damage.", + onTryHit(target, source, move) { + if (target === source || move.category === 'Status' || move.type === '???' ||| move.type === 'Rock' || move.id === 'struggle') return; + this.debug('Wonder Guard immunity: ' + move.id); + if (target.runEffectiveness(move) <= 0) { + this.add('-immune', target, '[from] ability: Noncorporeal'); + return null; + } + }, + id: "noncorporeal", + name: "Noncorporeal", + }, + "kalibersfury": { + shortDesc: "Any attacks with 60 bp or less get a +1 to priority.", + onModifyPriority: function(priority, pokemon, target, move, basePower) { + if (move.category !== 'Status' && move.basePower <= 60) return priority + 1; + }, + id: "kalibersfury", + name: "Kaliber's Fury", + }, + "unsteadyhood": { + desc: "If this Pokemon is Hyness, the first hit taken in battle deals halved damage and causes a forme-change into Unhooded Hyness. Confusion damage also breaks the disguise.", + shortDesc: "If this Pokemon is Hyness, the first hit taken in battle deals halved damage and causes a forme-change into Hyness-Unhooded.", + onDamagePriority: 1, + onDamage(damage, target, source, effect) { + if (effect && effect.effectType === 'Move' && target.template.speciesid === 'hyness' && !target.transformed) { + this.add('-activate', target, 'ability: Unsteady Hood'); + this.effectData.busted = true; + return damage / 2; + } + }, + onUpdate(pokemon) { + if (pokemon.template.speciesid === 'hyness' && this.effectData.busted) { + pokemon.formeChange('Hyness-Unhooded', this.effect, true); + } + }, + id: "unsteadyhood", + name: "Unsteady Hood", + }, + "moonstruckblossom": { + desc: "This Pokemon's moon-based moves have their power multiplied by 1.5. Moonlight now restores 1.5x more HP. If this Pokemon is a Grass-type, then the weaknesses of said type are negated.", + shortDesc: "x1.5 power to Moon moves; Moonlight heals 1.5x more HP to the user; Weaknesses from the Grass type are negated.", + onBasePowerPriority: 8, + onBasePower(basePower, attacker, defender, move) { + if (['moonblast', 'moongeistbeam', 'menacingmoonrazemaelstrom'].includes(move.id)) { + return this.chainModify(1.5); + } + }, + onTryHeal(damage, target, source, effect) { + this.debug("Heal is occurring: " + target + " <- " + source + " :: " + effect.id); + if (effect.id === 'moonlight') { + return damage * 1.5; + } + }, + onEffectiveness(typeMod, target, type, move) { + if (move && type === 'Grass' && typeMod > 0) return 0; + }, + id: "moonstruckblossom", + name: "Moonstruck Blossom", + }, + "soul0system": { + desc: "This Pokemon is immune to Ghost. If this Pokemon is Star Dream Soul 0S's Clockwork Star forme, a situation that would cause it to faint instead forme-changes it into Star Dream Soul 0S-Heart, restoring back to full HP. This Pokemon's Psychic-type moves become Ghost-type moves and have their power multiplied by 1.2. This effect comes after other effects that change a move's type, but before Electrify's effects.", + shortDesc: "This Pokemon's Psychic-type moves become Ghost type and have 1.2x power. This Pokemon is immune to Ghost. If Star Dream Soul 0S-Clockwork Star, becomes Star Dream Soul 0S-Heart when it would faint and restores to full HP.", + onTryHit(target, source, move) { + if (target !== source && move.type === 'Ghost') { + this.add('-immune', target, '[from] ability: Soul 0 System'); + return null; + } + }, + onDamagePriority: -100, + onDamage(damage, target, source, effect) { + if (damage >= target.hp && target.template.speciesid === 'stardreamsoulosclockworkstar') { + this.damage(target.hp - 1, target, target); + target.formeChange('Star Dream-Soul OS-Heart', this.effect, false, '[msg]'); + this.heal(target.maxhp); + return null; + } + }, + onModifyMovePriority: -1, + onModifyMove(move, pokemon) { + if (move.type === 'Psychic' && !['judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'weatherball'].includes(move.id) && !(move.isZ && move.category !== 'Status')) { + move.type = 'Ghost'; + move.soul0SBoosted = true; + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, pokemon, target, move) { + if (move.soul0SBoosted) return this.chainModify([0x1333, 0x1000]); + }, + id: "soul0system", + name: "Soul 0 System", + }, + "shadesoul": { + desc: "If this Pokemon is The Knight, a situation that would cause it to faint instead forme-changes it into The Knight-Shade.", + shortDesc: "If The Knight, becomes The Knight-Shade it would otherwise faint and restores to full HP.", + onDamagePriority: -100, + onDamage(damage, target, source, effect) { + if (damage >= target.hp && target.template.speciesid === 'theknight') { + this.damage(target.hp - 1, target, target); + target.formeChange('The Knight-Shade', this.effect, false, '[msg]'); + this.heal(target.maxhp); + return null; + } + }, + id: "shadesoul", + name: "Shade Soul", + }, + "physicalbreakdown": { + desc: "If this Pokemon is the Chaos Kin, a situation that would cause it to faint instead forme-changes it into its ashen forme.", + shortDesc: "If Chaos Kin, becomes Chaos Kin-Ash if it would otherwise faint and restores to half HP.", + onDamagePriority: -100, + onDamage(damage, target, source, effect) { + if (damage >= target.hp && target.template.speciesid === 'chaoskin') { + this.damage(target.hp - 1, target, target); + target.formeChange('Chaos Kin-Ash', this.effect, false, '[msg]'); + this.heal(target.maxhp / 2); + return null; + } + }, + id: "physicalbreakdown", + name: "Physical Breakdown", + }, + "lastditcheffort": { + desc: "If this Pokemon is 0, a situation that would cause it to faint instead causes the iris to burst out, changing formes and restoring HP.", + shortDesc: "If Zero (Kirby), becomes Zero-Iris if it would otherwise faint and restores to full HP.", + onDamagePriority: -100, + onDamage(damage, target, source, effect) { + if (damage >= target.hp && target.template.speciesid === 'zerokirby') { + this.damage(target.hp - 1, target, target); + target.formeChange('Zero-Iris', this.effect, false, '[msg]'); + this.heal(target.maxhp); + return null; + } + }, + id: "lastditcheffort", + name: "Last-Ditch Effort", + }, + "eternalbeauty": { + desc: "This Pokemon's attacking stat is multiplied by 1.5 while using a Grass- or Fairy-type attack. If this Pokemon is Soul of Sectonia, she changes forme and unroots herself if she has 1/2 or less of her maximum HP, and changes to Meteor Form if it has more than 1/2 its maximum HP. This check is done on switch-in and at the end of each turn. While in its Meteor Form, it cannot become affected by major status conditions. Moongeist Beam, Sunsteel Strike, and the Mold Breaker, Teravolt, and Turboblaze Abilities cannot ignore this Ability.", + shortDesc: "This Pokemon's attacking stat is multiplied by 1.5 while using a Grass- or Fairy-type attack. If Sectonia-Soul, end of turn changes to Soul-Unrooted at 1/2 max HP or less.", + onResidualOrder: 27, + onResidual(pokemon) { + if (pokemon.baseTemplate.baseSpecies !== 'Sectonia' || pokemon.transformed || !pokemon.hp) return; + if (pokemon.hp <= pokemon.maxhp / 2) { + if (pokemon.template.speciesid === 'sectoniasoul') { + pokemon.formeChange('Sectonia-Soul-Unrooted'); + } + } + }, + onModifyAtkPriority: 5, + onModifyAtk(atk, attacker, defender, move) { + if (move.type === 'Grass' || move.type === 'Fairy') { + this.debug('Eternal Beauty boost'); + return this.chainModify(1.5); + } + }, + onModifySpAPriority: 5, + onModifySpA(atk, attacker, defender, move) { + if (move.type === 'Grass' || move.type === 'Fairy') { + this.debug('Eternal Beauty boost'); + return this.chainModify(1.5); + } + }, + id: "eternalbeauty", + name: "Eternal Beauty", + }, + "incorporeal": { + shortDesc: "This Pokemon's attacks do not make contact with the target. Any moves that otherwise would have 1.2x power.", + onModifyMove(move) { + if (move.flags['contact']){ + delete move.flags['contact']; + move.incorporealBoosted = true; + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, pokemon, target, move) { + if (move.incorporealBoosted) return this.chainModify([0x1333, 0x1000]); + }, + id: "incorporeal", + name: "Incorporeal", + }, + "supercharge": { + desc: "If this Pokemon is a Creeper and takes damage from an Electric-type Attack, it forme-changes into a Charged Creeper.", + shortDesc: "If Creeper, forme-change into Creeper-Charged after taking damage from an Electric-type attack.", + onAfterDamageOrder: 1, + onAfterDamage(damage, target, source, move) { + if (source && source !== target && move && move.type === 'Electric' && target.template.speciesid === 'creeper') { + target.formeChange('Creeper-Charged', this.effect, false, '[msg]'); + } + }, + id: "supercharge", + name: "Supercharge", + }, + "kroganrage": { + desc: "This Pokemon's Attack and Speed are both raised by 1 stage if it attacks and knocks out another Pokemon with a Physical attack.", + shortDesc: "This Pokemon's Attack and Speed are raised by 1 stage if it attacks and KOes another Pokemon via Physical move.", + onSourceFaint(target, source, effect) { + if (effect && effect.effectType === 'Move' && effect.category === 'Physical') { + this.boost({atk: 1, spe: 1}, source); + } + }, + id: "kroganrage", + name: "Krogan Rage", + }, + "knightmare": { + desc: "This Pokemon's slash-based moves deal x1.3 damage and bypass type-based immunities.", + shortDesc: "This Pokemon's slash-based moves deal x1.3 damage and bypass immunities.", + onModifyMovePriority: -1, + onModifyMove(move, pokemon) { + if (['sacredsword', 'leafblade', 'cut', 'nightslash', 'crosspoison', 'slash', 'razorwind', 'airslash', 'furycutter', 'falseswipe', 'psychocut', 'secretsword', 'xscissor', 'swordrainbeta', 'machtornado', 'solarblade', 'invisibleair', 'foilflourish', 'zsaber', 'risingphoenix', 'chargedsaber', 'dashslash', 'greatslash', 'cycloneslash', 'swordofhisou', 'excaliburswordofpromisedvictory', 'rosaichthys', 'underworldkingslash', 'laevateinn', 'demonicrend'].includes(move.id)) { + move.ignoreImmunity = true; + move.knightmareBoosted = true; + } + }, + onBasePowerPriority: 8, + onBasePower(basePower, attacker, defender, move) { + if (move.knightmareBoosted) { + this.debug('Knightmare boost'); + return this.chainModify([0x14CD, 0x1000]); + } + }, + id: "knightmare", + name: "Knightmare", + }, + "swordofswords": { + shortDesc: "This Pokemon deals x1.33 damage with slash-based moves and takes x0.667 damage from slash-based moves.", + onModifyMovePriority: -1, + onAnyModifyMove(move, pokemon) { + if (['sacredsword', 'leafblade', 'cut', 'nightslash', 'crosspoison', 'slash', 'razorwind', 'airslash', 'furycutter', 'falseswipe', 'psychocut', 'secretsword', 'xscissor', 'swordrainbeta', 'machtornado', 'solarblade', 'invisibleair', 'foilflourish', 'zsaber', 'risingphoenix', 'chargedsaber', 'dashslash', 'greatslash', 'cycloneslash', 'swordofhisou', 'excaliburswordofpromisedvictory', 'gladiusanusblauserium', 'rosaichthys', 'underworldkingslash', 'laevateinn', 'demonicrend'].includes(move.id)) { + move.swordOfSwordsBoosted = true; + } + }, + onBasePowerPriority: 8, + onAnyBasePower(basePower, attacker, defender, move) { + if (move.swordOfSwordsBoosted && [attacker, defender].includes(this.effectData.target)) { + this.debug('Sword of Swords - Altering damage taken.'); + return this.chainModify([((defender === this.effectData.target) ? 0x0AAC : 0x1547), 0x1000]); + } + }, + id: "swordofswords", + name: "Sword of Swords", + }, + "swordspirit": { + shortDesc: "This Pokemon deals x1.5 damage with slash-based moves and takes x0.5 damage from slash-based moves.", + onModifyMovePriority: -1, + onAnyModifyMove(move, pokemon) { + if (['sacredsword', 'leafblade', 'cut', 'nightslash', 'crosspoison', 'slash', 'razorwind', 'airslash', 'furycutter', 'falseswipe', 'psychocut', 'secretsword', 'xscissor', 'swordrainbeta', 'machtornado', 'solarblade', 'invisibleair', 'foilflourish', 'zsaber', 'risingphoenix', 'chargedsaber', 'dashslash', 'greatslash', 'cycloneslash', 'swordofhisou', 'excaliburswordofpromisedvictory', 'gladiusanusblauserium', 'rosaichthys', 'underworldkingslash', 'laevateinn', 'demonicrend'].includes(move.id)) { + move.swordSpiritBoosted = true; + } + }, + onBasePowerPriority: 8, + onAnyBasePower(basePower, attacker, defender, move) { + if (move.swordSpiritBoosted && [attacker, defender].includes(this.effectData.target)) { + this.debug('Sword Spirit - Altering damage taken.'); + return this.chainModify(((defender === this.effectData.target) ? 0.5 : 1.5)); + } + }, + id: "swordspirit", + name: "Sword Spirit", + }, + "saberclass": { + shortDesc: "This Pokemon deals x1.33 damage with slash-based moves.", + onBasePowerPriority: 8, + onBasePower(basePower, attacker, defender, move) { + if (['sacredsword', 'leafblade', 'cut', 'nightslash', 'crosspoison', 'slash', 'razorwind', 'airslash', 'furycutter', 'falseswipe', 'psychocut', 'secretsword', 'xscissor', 'swordrainbeta', 'machtornado', 'solarblade', 'invisibleair', 'foilflourish', 'zsaber', 'risingphoenix', 'chargedsaber', 'dashslash', 'greatslash', 'cycloneslash', 'swordofhisou', 'excaliburswordofpromisedvictory', 'gladiusanusblauserium', 'rosaichthys', 'underworldkingslash', 'laevateinn', 'demonicrend'].includes(move.id)) { + this.debug('Saber Class - Boosting Damage.'); + return this.chainModify([0x1547, 0x1000]); + } + }, + id: "saberclass", + name: "Saber Class", + }, + + //These vanilla abilities are overridden, though mostly just to account for custom elements (For instance, Damp blocking Creeper Blast, etc.) + + "mummy": { + desc: "Pokemon making contact with this Pokemon have their Ability changed to Mummy. Does not affect the Battle Bond, Comatose, Disguise, Multitype, Power Construct, RKS System, Schooling, Shields Down, Stance Change, and Zen Mode Abilities.", + shortDesc: "Pokemon making contact with this Pokemon have their Ability changed to Mummy.", + id: "mummy", + name: "Mummy", + onAfterDamage(damage, target, source, move) { + if (source && source !== target && move && move.flags['contact'] && source.ability !== 'mummy') { + let oldAbility = source.setAbility('mummy', target); + if (oldAbility) { + this.add('-activate', target, 'ability: Mummy', this.getAbility(oldAbility).name, '[of] ' + source); + } + } + }, + onBasePower(basePower, pokemon, target, move) { + if (move.multihitType === 'parentalbond' && move.hit > 1) return this.chainModify(0.25); + if (move.multihitType === 'fourheads' && move.hit > 1) return this.chainModify(0.3); + }, + rating: 2.5, + num: 152, + }, + "damp": { + desc: "While this Pokemon is active, Explosion, Mind Blown, Self-Destruct, and the Aftermath Ability are prevented from having an effect.", + shortDesc: "Prevents Explosion/Mind Blown/Self-Destruct/Creeper Blast/Aftermath while this Pokemon is active.", + id: "damp", + onAnyTryMove(target, source, effect) { + if (['explosion', 'mindblown', 'selfdestruct', 'creeperblast'].includes(effect.id)) { + this.attrLastMove('[still]'); + this.add('cant', this.effectData.target, 'ability: Damp', effect, '[of] ' + target); + return false; + } + }, + onAnyDamage(damage, target, source, effect) { + if (effect && effect.id === 'aftermath') { + return false; + } + }, + name: "Damp", + rating: 1, + num: 6, + }, + //Expanded abilities start here. + "cursed": { shortDesc: "This Pokemon hits Fairy super-effectively with Dark moves, but is weak to Water and takes an additional 2x damage.", onSourceEffectiveness(typeMod, target, type, move) { @@ -283,7 +736,7 @@ exports.BattleAbilities = { return typeMod; }, onEffectiveness(typeMod, target, type, move) { - if (move && move.type === 'Water') return 1; + if (move && move.type === 'Water') return (target.types[0] === type ? 1 : 0); return typeMod; }, /* I don't know how to force a 4x weakness so I'm going to do a pro gamer move */ onSourceModifyAtkPriority: 6, @@ -307,16 +760,16 @@ exports.BattleAbilities = { shortDesc: "Punching moves 1.5x power, sound moves Physical.", onBasePowerPriority: 8, onBasePower(basePower, attacker, defender, move) { - if (move.flags['punch']) { + if (move.flags['sound']) { this.debug('voiceless boost'); return this.chainModify(1.5); } - if {move.flags['sound']) { - this.debug('voiceless category change'); - if (move.category === 'Status') return; + }, + onModifyMove(move) { + if (move.flags['sound'] && move.category !== 'Status') { move.category = 'Physical'; - /* idk how to remove flags from moves since i haven't seen any other ability that does it */ - }, + delete move.flags['sound']; + } }, id: "voiceless", name: "voiceless", diff --git a/data/mods/crossoverchaos/items.js b/data/mods/crossoverchaos/items.js index 80c970be02..64e3c54114 100644 --- a/data/mods/crossoverchaos/items.js +++ b/data/mods/crossoverchaos/items.js @@ -31,5 +31,42 @@ exports.BattleItems = { zMoveUser: ["SiIvaGunner"], desc: "If held by SiIvaGunner with Snow Halation, he can use Stone Halation.", }, - + "chaosemeralds": { + id: "chaosemeralds", + name: "Chaos Emeralds", + megaStone: "Sonic-Super", + megaEvolves: "Sonic", + onTakeItem(item, source) { + if (item.megaEvolves === source.baseTemplate.baseSpecies) return false; + return true; + }, + desc: "If held by Sonic, this item allows him to become Super Sonic in battle." + }, + "zeromiumz": { + id: "zeromiumz", + name: "Zeromium Z", + onTakeItem: false, + zMove: "Big Bang", + zMoveFrom: "Thunder", + zMoveUser: ["True Zeromus"], + desc: "If held by True Zeromus with Thunder, he can use Big Bang.", + }, + "galeemiumz": { + id: "galeemiumz", + name: "Galeemium Z", + onTakeItem: false, + zMove: "Spear of Light", + zMoveFrom: "Angelic Flare", + zMoveUser: ["Galeem"], + desc: "If held by Galeem with Angelic Flare, it can use Spear of Light.", + }, + "dharkoniumz": { + id: "dharkoniumz", + name: "Dharkonium Z", + onTakeItem: false, + zMove: "Hammer of Darkness", + zMoveFrom: "Demonic Rend", + zMoveUser: ["Dharkon"], + desc: "If held by Dharkon with Demonic Rend, it can use Hammer of Darkness.", + }, }; diff --git a/data/mods/crossoverchaos/learnsets.js b/data/mods/crossoverchaos/learnsets.js index 47735a02c7..a147d6fe36 100644 --- a/data/mods/crossoverchaos/learnsets.js +++ b/data/mods/crossoverchaos/learnsets.js @@ -5744,6 +5744,7 @@ kyoko: {learnset: { irondefense: ["7L1"], iciclespear: ["7L1"], barrier: ["7L1"], + safeguard: ["7L1"], }}, steve: {learnset: { explosion: ["7L1"], diff --git a/data/mods/crossoverchaos/moves.js b/data/mods/crossoverchaos/moves.js index ebc9c24dcf..c61fb3821a 100644 --- a/data/mods/crossoverchaos/moves.js +++ b/data/mods/crossoverchaos/moves.js @@ -74,12 +74,20 @@ let BattleMovedex = { basePower: 80, category: "Special", desc: "The target's Ability is rendered ineffective as long as it remains active. If the target uses Baton Pass, the replacement will remain under this effect. If the target's Ability is Battle Bond, Comatose, Disguise, Multitype, Power Construct, RKS System, Schooling, Shields Down, Stance Change, or Zen Mode, this effect does not happen, and receiving the effect through Baton Pass ends the effect immediately.", - shortDesc: "Nullifies the target's Ability.", + shortDesc: "Nullifies the target's Ability. Damages user for 25% of HP if not Shulk or Chibiterasu.", id: "monadopurge", name: "Monado Purge", pp: 15, priority: 0, flags: {protect: 1, mirror: 1}, + mindBlownRecoil: true, + onAfterMove(pokemon, target, move) { + if (['Shulk', 'Chibiterasu'].includes(pokemon.template.species)){ + move.mindBlownRecoil = false; + } else if (move.mindBlownRecoil && !move.multihit) { + this.damage(Math.round(pokemon.maxhp / 4), pokemon, pokemon, this.getEffect('Monado Purge'), true); + } + }, volatileStatus: 'gastroacid', secondary: null, target: "normal", @@ -103,6 +111,18 @@ let BattleMovedex = { pp: 5, priority: 0, flags: {protect: 1, mirror: 1}, + mindBlownRecoil: true, + onHit(target) { + target.clearBoosts(); + this.add('-clearboost', target); + }, + onAfterMove(pokemon, target, move) { + if (['Shulk', 'Chibiterasu'].includes(pokemon.template.species)){ + move.mindBlownRecoil = false; + } else if (move.mindBlownRecoil && !move.multihit) { + this.damage(Math.round(pokemon.maxhp / 4), pokemon, pokemon, this.getEffect('Monado Eater'), true); + } + }, secondary: null, target: "normal", type: "Fighting", @@ -431,7 +451,7 @@ let BattleMovedex = { priority: 0, flags: {snatch: 1, heal: 1}, onHit(pokemon) { - if (['', 'slp', 'frz'].includes(pokemon.status)) return false; + if (['', 'slp', 'frz'].includes(pokemon.status) && pokemon.hp >= pokemon.maxhp) return false; pokemon.cureStatus(); }, heal: [1, 2], @@ -454,7 +474,7 @@ let BattleMovedex = { pp: 5, priority: 0, flags: {contact: 1, protect: 1, mirror: 1}, - self: { + selfBoost: { boosts: { def: -1, spe: -1, @@ -665,7 +685,7 @@ let BattleMovedex = { name: "Dedede Hammer Throw", pp: 15, priority: 0, - flags: {contact: 1, protect: 1, mirror: 1}, + flags: {protect: 1, mirror: 1}, secondary: { chance: 10, status: 'brn', @@ -688,7 +708,7 @@ let BattleMovedex = { name: "Battle Rifle", pp: 10, priority: 0, - flags: {protect: 1, mirror: 1}, + flags: {bullet: 1, protect: 1, mirror: 1}, multihit: 3, secondary: null, target: "normal", @@ -720,8 +740,12 @@ let BattleMovedex = { if (type === 'Ground') return false; }, onResidualOrder: 15, + onResidual(pokemon) { + if (!pokemon.hp) return; + pokemon.removeVolatile('cycloneslash'); + }, onEnd(target) { - this.add('-end', target, 'Magnet Rise'); + this.add('-end', target, 'Cyclone Slash'); }, }, secondary: null, @@ -730,6 +754,222 @@ let BattleMovedex = { zMovePower: 140, contestType: "Cool", }, + "spearoflight": { + num: 40027, + accuracy: true, + basePower: 150, + category: "Special", + desc: "This move is always a critical hit unless the target is under the effect of Lucky Chant or has the Battle Armor or Shell Armor Abilities.", + shortDesc: "Always results in a critical hit.", + id: "spearoflight", + name: "Spear of Light", + pp: 1, + priority: 0, + flags: {}, + isZ: "galeemiumz", + willCrit: true, + secondary: null, + target: "normal", + type: "Fairy", + contestType: "Beautiful", + }, + "demonicrend": { + num: 40028, + accuracy: 100, + basePower: 110, + category: "Physical", + desc: "Has a 40% chance to lower each target's Speed by 1 stage.", + shortDesc: "40% chance to lower each target's Speed by 1.", + id: "demonicrend", + isViable: true, + name: "Demonic Rend", + pp: 5, + priority: 0, + flags: {protect: 1, mirror: 1, contact: 1}, + secondary: { + chance: 40, + boosts: { + spe: -1, + }, + }, + target: "allAdjacentFoes", + type: "Dark", + zMovePower: 185, + contestType: "Tough", + }, + "hammerofdarkness": { + num: 40029, + accuracy: true, + basePower: 195, + category: "Physical", + desc: "Has a 100% chance to lower the target's Speed by 1 stage.", + shortDesc: "100% chance to lower the target's Speed by 1.", + id: "hammerofdarkness", + name: "Hammer of Darkness", + pp: 1, + priority: 0, + flags: {contact: 1}, + isZ: "dharkoniumz", + secondary: { + chance: 100, + boosts: { + spe: -1, + }, + }, + target: "normal", + type: "Dark", + contestType: "Tough", + }, + "finaldeathbloom": { + num: 40030, + accuracy: 90, + basePower: 140, + category: "Special", + desc: "If the target lost HP, the user takes recoil damage equal to 1/2 the HP lost by the target, rounded half up, but not less than 1 HP.", + shortDesc: "Has 1/2 recoil.", + id: "finaldeathbloom", + isViable: true, + name: "Final Death Bloom", + pp: 5, + priority: 0, + flags: {protect: 1, mirror: 1}, + isUnreleased: true, + recoil: [1, 2], + secondary: null, + target: "normal", + type: "Grass", + zMovePower: 200, + contestType: "Beautiful", + }, + "katamaridash": { + num: 40031, + accuracy: 100, + basePower: 80, + category: "Physical", + desc: "No additional effect.", + shortDesc: "Nearly always goes first.", + id: "katamaridash", + isViable: true, + name: "Katamari Dash", + pp: 5, + priority: 2, + flags: {bullet: 1, contact: 1, protect: 1, mirror: 1}, + secondary: null, + target: "normal", + type: "Psychic", + zMovePower: 160, + contestType: "Clever", + }, + "creeperblast": { + num: 40032, + accuracy: 100, + basePower: 500, + category: "Physical", + desc: "The user faints after using this move, even if this move fails for having no target. This move is prevented from executing if any active Pokemon has the Damp Ability.", + shortDesc: "Hits adjacent Pokemon. The user faints.", + id: "creeperblast", + isViable: true, + name: "Creeper Blast", + pp: 5, + priority: 0, + flags: {protect: 1, mirror: 1}, + selfdestruct: "always", + secondary: null, + target: "allAdjacent", + type: "Grass", + zMovePower: 200, + contestType: "Clever", + }, + "flarecannon": { + num: 40033, + accuracy: 90, + basePower: 100, + category: "Special", + desc: "Has a 20% chance to burn the target.", + shortDesc: "20% chance to burn adjacent Pokemon.", + id: "flarecannon", + isViable: true, + name: "Flare Cannon", + pp: 10, + priority: 0, + flags: {protect: 1, mirror: 1}, + secondary: { + chance: 20, + status: 'brn', + }, + target: "allAdjacentFoes", + type: "Fire", + zMovePower: 180, + contestType: "Tough", + }, + "shocktherapist": { + num: 40034, + accuracy: 90, + basePower: 100, + category: "Special", + desc: "Has a 20% chance to paralyze the target.", + shortDesc: "20% chance to paralyze adjacent Pokemon.", + id: "shocktherapist", + isViable: true, + name: "Shock Therapist", + pp: 10, + priority: 0, + flags: {protect: 1, mirror: 1}, + secondary: { + chance: 20, + status: 'par', + }, + target: "allAdjacentFoes", + type: "Electric", + zMovePower: 180, + contestType: "Cool", + }, + "monsterpump": { + num: 40035, + accuracy: 90, + basePower: 100, + category: "Special", + desc: "Has a 20% chance to lower the target's Attack by 1 stage.", + shortDesc: "20% chance to lower the foe(s) Attack by 1.", + id: "monsterpump", + isViable: true, + name: "Monster Pump", + pp: 10, + priority: 0, + flags: {protect: 1, mirror: 1}, + secondary: { + chance: 20, + boosts: { + atk: -1, + }, + }, + target: "allAdjacentFoes", + type: "Water", + zMovePower: 180, + contestType: "Beautiful", + }, + "comedybomb": { + num: 40036, + accuracy: 90, + basePower: 100, + category: "Special", + desc: "Has a 20% chance to poison the target.", + shortDesc: "20% chance to poison adjacent Pokemon.", + id: "comedybomb", + isViable: true, + name: "Comedy Bomb", + pp: 10, + priority: 0, + flags: {protect: 1, mirror: 1}, + secondary: { + chance: 20, + status: 'psn', + }, + target: "allAdjacentFoes", + type: "Poison", + zMovePower: 180, + contestType: "Clever", + }, "suicideride": { num: 50001, accuracy: 100, @@ -793,7 +1033,7 @@ let BattleMovedex = { zMovePower: 190, contestType: "Beautiful", }, - "meettheflinstones": { + "meettheflintstones": { num: 50004, accuracy: 100, basePower: 95, diff --git a/data/mods/crossoverchaos/pokedex.js b/data/mods/crossoverchaos/pokedex.js index b327e9a5bc..7cc09bd6d2 100644 --- a/data/mods/crossoverchaos/pokedex.js +++ b/data/mods/crossoverchaos/pokedex.js @@ -458,6 +458,7 @@ stardream: { abilities: {0: "Levitate", H: "Soul-Heart"}, heightm: 20, weightkg: 250, + color: "Gray", otherFormes: ["stardreamaccessark", "stardreamclockworkstar", "stardreamsoulos", "stardreamsoulosaccessark", "stardreamsoulosclockworkstar", "stardreamsoulosheart"], }, stardreamaccessark: { @@ -468,10 +469,11 @@ stardreamaccessark: { formeLetter: "A", types: ["Steel", "Psychic"], gender: "N", - baseStats: {hp: 120, atk: 130, def: 140, spa: 130, spd: 110, spe: 70}, + baseStats: {hp: 120, atk: 130, def: 140, spa: 110, spd: 110, spe: 70}, abilities: {0: "Levitate", H: "Soul-Heart"}, heightm: 12700000, weightkg: 999.9, + color: "Gray", }, stardreamclockworkstar: { num: 6000015, @@ -481,10 +483,11 @@ stardreamclockworkstar: { formeLetter: "C", types: ["Steel", "Psychic"], gender: "N", - baseStats: {hp: 120, atk: 120, def: 120, spa: 160, spd: 110, spe: 90}, + baseStats: {hp: 120, atk: 120, def: 100, spa: 160, spd: 110, spe: 70}, abilities: {0: "Levitate", H: "Soul-Heart"}, heightm: 12700000, weightkg: 999.9, + color: "Gray", }, stardreamsoulos: { num: 6000015, @@ -498,6 +501,7 @@ stardreamsoulos: { abilities: {0: "Soul 0 System"}, heightm: 20, weightkg: 250, + color: "Black", }, stardreamsoulosaccessark: { num: 6000015, @@ -507,10 +511,11 @@ stardreamsoulosaccessark: { formeLetter: "S", types: ["Steel", "Ghost"], gender: "N", - baseStats: {hp: 120, atk: 160, def: 160, spa: 160, spd: 130, spe: 70}, + baseStats: {hp: 120, atk: 160, def: 160, spa: 140, spd: 130, spe: 70}, abilities: {0: "Soul 0 System"}, heightm: 12700000, weightkg: 999.9, + color: "Gray", }, stardreamsoulosclockworkstar: { num: 6000015, @@ -520,10 +525,11 @@ stardreamsoulosclockworkstar: { formeLetter: "S", types: ["Steel", "Ghost"], gender: "N", - baseStats: {hp: 120, atk: 140, def: 140, spa: 200, spd: 130, spe: 90}, + baseStats: {hp: 120, atk: 140, def: 120, spa: 200, spd: 130, spe: 70}, abilities: {0: "Soul 0 System"}, heightm: 12700000, weightkg: 999.9, + color: "Yellow", }, stardreamsoulosheart: { num: 6000015, @@ -537,6 +543,7 @@ stardreamsoulosheart: { abilities: {0: "Soul 0 System"}, heightm: 0.5, weightkg: 25, + color: "Pink", }, daroach: { num: 6000016, @@ -841,7 +848,7 @@ theknight: { gender: "N", baseStats: {hp: 60, atk: 115, def: 95, spa: 115, spd: 95, spe: 120}, abilities: {0: "Shade Soul"}, - weightkg: 0.4, + weightkg: 4, otherFormes: ["theknightshade"], }, theknightshade: { @@ -863,7 +870,7 @@ falseknight: { gender: "M", baseStats: {hp: 50, atk: 150, def: 140, spa: 50, spd: 90, spe: 80}, abilities: {0: "Stolen Armour"}, - weightkg: 20, + weightkg: 200, otherFormes: ["falseknightunarmored"], }, falseknightunarmored: { @@ -876,8 +883,8 @@ falseknightunarmored: { gender: "M", baseStats: {hp: 50, atk: 75, def: 70, spa: 25, spd: 45, spe: 40}, abilities: {0: "Stolen Armour"}, - heightm: 0.1, - weightkg: 0.5, + heightm: 1, + weightkg: 5, }, sans: { num: 6000039, @@ -1072,7 +1079,7 @@ zerokirby: { abilities: {0: "Last-Ditch Effort", H: "Levitate"}, heightm: 1.3, weightkg: 400, - otherFormes: ["iris0"], + otherFormes: ["zeroiris", "zero2"], }, zeroiris: { //Writing it as "0iris" would've done problems. num: 6000048, @@ -1090,6 +1097,9 @@ zeroiris: { //Writing it as "0iris" would've done problems. zero2: { num: 6000048, species: "Zero^2", + baseSpecies: "Zero (Kirby)", + forme: "2", + formeLetter: "2", types: ["Dark", "Poison"], gender: "N", baseStats: {hp: 120, atk: 90, def: 150, spa: 140, spd: 110, spe: 70}, @@ -1288,8 +1298,8 @@ galeem: { gender: "N", baseStats: {hp: 100, atk: 40, def: 40, spa: 160, spd: 160, spe: 100}, abilities: {0: "Bane of Darkness"}, - heightm: 5, - weightkg: 20, + heightm: 8, + weightkg: 66.6, }, isabelle: { num: 6000063, @@ -1308,7 +1318,7 @@ joker: { baseStats: {hp: 70, atk: 120, def: 70, spa: 120, spd: 70, spe: 140}, abilities: {0: "Moxie", 1: "Mold Breaker", H: "Persona Change"}, heightm: 1.76, - weightkg: 50, + weightkg: 55, }, riki: { num: 6000065, @@ -1659,8 +1669,8 @@ cirno: { gender: "F", baseStats: {hp: 99, atk: 99, def: 99, spa: 99, spd: 99, spe: 99}, abilities: {0: "Snow Warning", 1: "Levitate", H: "Freeze Atmosphere"}, - heightm: 1.3, - weightkg: 30, + heightm: 1.4, + weightkg: 38, otherFormes: ["cirnotanned"], }, cirnotanned: { @@ -1673,8 +1683,8 @@ cirnotanned: { gender: "F", baseStats: {hp: 99, atk: 99, def: 99, spa: 99, spd: 99, spe: 99}, abilities: {0: "Power of Summer"}, - heightm: 1.3, - weightkg: 30, + heightm: 1.4, + weightkg: 38, }, monokuma: { num: 6000094, @@ -1757,7 +1767,7 @@ kyoko: { gender: "F", baseStats: {hp: 90, atk: 50, def: 60, spa: 60, spd: 60, spe: 50}, abilities: {0: "Crystal Barrier"}, - heightm: 1.8, + heightm: 1.7, weightkg: 55, }, steve: { @@ -1767,8 +1777,8 @@ steve: { gender: "M", baseStats: {hp: 95, atk: 95, def: 95, spa: 95, spd: 95, spe: 95}, abilities: {0: "Battle Armor", 1: "Hunger", H: "Miner"}, - heightm: 1.8, - weightkg: 55, + heightm: 1.85, + weightkg: 80, }, dimentio: { num: 6000101, @@ -1777,7 +1787,7 @@ dimentio: { gender: "M", baseStats: {hp: 80, atk: 64, def: 64, spa: 144, spd: 112, spe: 96}, abilities: {0: "Dimensional Mastery", H: "Levitate"}, - heightm: 1.5, + heightm: 1.7, weightkg: 55, }, dimentiosuper: { @@ -1810,8 +1820,8 @@ archer: { gender: "M", baseStats: {hp: 80, atk: 100, def: 80, spa: 50, spd: 80, spe: 90}, abilities: {0: "Justified", 1: "Protean", H: "Trace"}, - heightm: 1.8, - weightkg: 55, + heightm: 1.7, + weightkg: 60, }, magus: { num: 6000104, @@ -1821,7 +1831,7 @@ magus: { baseStats: {hp: 110, atk: 96, def: 90, spa: 140, spd: 120, spe: 110}, abilities: {0: "Dark Aura", H: "Barrier Change"}, heightm: 1.8, - weightkg: 55, + weightkg: 70, }, silver: { num: 6000105, @@ -1884,13 +1894,13 @@ tamamonomaeninetails: { }, knuckles: { num: 6000107, - species: "Knuckles", /* Fate/EXTRA */ + species: "Knuckles", /* Sonic the Hedgehog series */ types: ["Ground", "Fighting"], gender: "M", baseStats: {hp: 85, atk: 135, def: 105, spa: 70, spd: 85, spe: 110}, abilities: {0: "Iron Fist", H: "Scrappy"}, - heightm: 1, - weightkg: 35, + heightm: 1.1, + weightkg: 40, }, hrh: { num: 6000108, @@ -1939,8 +1949,8 @@ sectonia: { gender: "F", baseStats: {hp: 80, atk: 125, def: 75, spa: 115, spd: 85, spe: 120}, abilities: {0: "Queenly Majesty", 1: "Pressure", H: "Levitate"}, - heightm: 2, - weightkg: 69, + heightm: 0.9, + weightkg: 20, }, sectoniadreamstalk: { num: 6000112, @@ -1968,7 +1978,7 @@ sectoniasoul: { heightm: 2700, weightkg: 999.9, }, -sectoniasoul: { +sectoniasoulunrooted: { num: 6000112, species: "Sectonia-Soul-Unrooted", baseSpecies: "Sectonia", @@ -1978,16 +1988,17 @@ sectoniasoul: { gender: "F", baseStats: {hp: 75, atk: 160, def: 115, spa: 170, spd: 120, spe: 140}, abilities: {0: "Eternal Beauty"}, - heightm: 0.2, + heightm: 0.4, weightkg: 5, }, creeper: { num: 6000113, species: "Creeper", /* Minecraft */ types: ["Grass"], + gender: "N", baseStats: {hp: 95, atk: 120, def: 50, spa: 55, spd: 50, spe: 50}, abilities: {0: "Supercharge"}, - heightm: 1.8, + heightm: 1.625, weightkg: 55, }, creepercharged: { @@ -1997,15 +2008,17 @@ creepercharged: { forme: "Charged", formeLetter: "C", types: ["Grass"], + gender: "N", baseStats: {hp: 95, atk: 180, def: 50, spa: 55, spd: 50, spe: 50}, abilities: {0: "Supercharge"}, - heightm: 1.8, + heightm: 1.625, weightkg: 55, }, darkmind: { num: 6000114, species: "Dark Mind", /* Kirby and the Amazing Mirror */ types: ["Rock", "Fire"], + gender: "N", baseStats: {hp: 60, atk: 60, def: 110, spa: 130, spd: 110, spe: 110}, abilities: {0: "Levitate", H: "Emergency Exit"}, heightm: 1.8, @@ -2018,11 +2031,54 @@ darkmindtrue: { forme: "True", formeLetter: "T", types: ["Rock", "Fire"], + gender: "N", baseStats: {hp: 120, atk: 60, def: 100, spa: 140, spd: 100, spe: 80}, abilities: {0: "Levitate", H: "Emergency Exit"}, heightm: 2, weightkg: 50, }, +flandrescarlet: { + num: 6000115, + species: "Flandre Scarlet", /* Touhou */ + types: ["Fire", "Dark"], + gender: "F", + baseStats: {hp: 90, atk: 150, def: 50, spa: 150, spd: 50, spe: 130}, + abilities: {0: "Four of a Kind", H: "Ability to Destroy Anything"}, + heightm: 1.4, + weightkg: 35, +}, +zeromus: { + num: 6000116, + species: "Zeromus", /* Final Fantasy IV / XII */ + types: ["Ghost"], + gender: "M", + baseStats: {hp: 40, atk: 40, def: 40, spa: 100, spd: 40, spe: 40}, + abilities: {0: "Noncorporeal"}, + heightm: 5, + weightkg: 100, + evos: ["truezeromus"] +}, +truezeromus: { + num: 6000117, + species: "True Zeromus", + types: ["Ghost", "Dark"], + gender: "M", + baseStats: {hp: 150, atk: 158, def: 148, spa: 101, spd: 52, spe: 59}, + abilities: {0: "Flash Fire"}, + heightm: 6.5, + weightkg: 500, + prevo: "zeromus" +}, +dharkon: { + num: 6000118, + species: "Dharkon", /* Super Smash Bros. */ + types: ["Dark", "Poison"], + gender: "N", + baseStats: {hp: 97, atk: 142, def: 101, spa: 65, spd: 88, spe: 100}, + abilities: {0: "Bane of Light"}, + heightm: 8, + weightkg: 666, +}, walle: { num: 7000001, species: "WALL-E", /* WALL-E */ @@ -2063,7 +2119,7 @@ oktaviavonseckendorff: { abilities: {0: "Regenerator", H: "Unaware"}, heightm: 10, weightkg: 480, - prevo: ["sayakamiki"] + prevo: "sayakamiki" }, skipper: { num: 7000005, @@ -2377,7 +2433,7 @@ sakinikaido: { majinbuu: { num: 7000025, species: "Majin Buu", /* Dragon Ball */ - types: ["Dark", "Ghost"], + types: ["Fairy", "Fighting"], gender: "M", baseStats: {hp: 160, atk: 105, def: 50, spa: 115, spd: 100, spe: 100}, abilities: {0: "Regenerator", 1: "Magic Bounce", H: "Gluttony"}, diff --git a/data/mods/crossoverchaos/scripts.js b/data/mods/crossoverchaos/scripts.js index 2a1aa79b56..6b2c8743eb 100644 --- a/data/mods/crossoverchaos/scripts.js +++ b/data/mods/crossoverchaos/scripts.js @@ -2,38 +2,170 @@ exports.BattleScripts = { + useMoveInner(moveOrMoveName, pokemon, target, sourceEffect, zMove) { + if (!sourceEffect && this.effect.id) sourceEffect = this.effect; + if (sourceEffect && ['instruct', 'custapberry'].includes(sourceEffect.id)) sourceEffect = null; + + let move = this.getActiveMove(moveOrMoveName); + if (move.id === 'weatherball' && zMove) { + // Z-Weather Ball only changes types if it's used directly, + // not if it's called by Z-Sleep Talk or something. + this.singleEvent('ModifyMove', move, null, pokemon, target, move, move); + if (move.type !== 'Normal') sourceEffect = move; + } + if (zMove || (move.category !== 'Status' && sourceEffect && sourceEffect.isZ)) { + move = this.getActiveZMove(move, pokemon); + } + + if (this.activeMove) { + move.priority = this.activeMove.priority; + if (!move.hasBounced) move.pranksterBoosted = this.activeMove.pranksterBoosted; + } + let baseTarget = move.target; + if (target === undefined) target = this.resolveTarget(pokemon, move); + if (move.target === 'self' || move.target === 'allies') { + target = pokemon; + } + if (sourceEffect) { + move.sourceEffect = sourceEffect.id; + move.ignoreAbility = false; + } + let moveResult = false; + + this.setActiveMove(move, pokemon, target); + + this.singleEvent('ModifyMove', move, null, pokemon, target, move, move); + if (baseTarget !== move.target) { + // Target changed in ModifyMove, so we must adjust it here + // Adjust before the next event so the correct target is passed to the + // event + target = this.resolveTarget(pokemon, move); + } + move = this.runEvent('ModifyMove', pokemon, target, move, move); + if (baseTarget !== move.target) { + // Adjust again + target = this.resolveTarget(pokemon, move); + } + if (!move || pokemon.fainted) { + return false; + } + + let attrs = ''; + + let movename = move.name; + if (move.id === 'hiddenpower') movename = 'Hidden Power'; + if (sourceEffect) attrs += '|[from]' + this.getEffect(sourceEffect); + if (zMove && move.isZ === true) { + attrs = '|[anim]' + movename + attrs; + movename = 'Z-' + movename; + } + this.addMove('move', pokemon, movename, target + attrs); + + if (zMove) this.runZPower(move, pokemon); + + if (!target) { + this.attrLastMove('[notarget]'); + this.add(this.gen >= 5 ? '-fail' : '-notarget', pokemon); + return false; + } + + const {targets, pressureTargets} = pokemon.getMoveTargets(move, target); + + if (!sourceEffect || sourceEffect.id === 'pursuit') { + let extraPP = 0; + for (const source of pressureTargets) { + let ppDrop = this.runEvent('DeductPP', source, pokemon, move); + if (ppDrop !== true) { + extraPP += ppDrop || 0; + } + } + if (extraPP > 0) { + pokemon.deductPP(move, extraPP); + } + } + + if (!this.singleEvent('TryMove', move, null, pokemon, target, move) || + !this.runEvent('TryMove', pokemon, target, move)) { + move.mindBlownRecoil = false; + return false; + } + + this.singleEvent('UseMoveMessage', move, null, pokemon, target, move); + + if (move.ignoreImmunity === undefined) { + move.ignoreImmunity = (move.category === 'Status'); + } + + if (this.gen !== 4 && move.selfdestruct === 'always') { + this.faint(pokemon, pokemon, move); + } + + /** @type {number | false | undefined | ''} */ + let damage = false; + if (move.target === 'all' || move.target === 'foeSide' || move.target === 'allySide' || move.target === 'allyTeam') { + damage = this.tryMoveHit(target, pokemon, move); + if (damage === this.NOT_FAIL) pokemon.moveThisTurnResult = null; + if (damage || damage === 0 || damage === undefined) moveResult = true; + } else { + if (!targets.length) { + this.attrLastMove('[notarget]'); + this.add(this.gen >= 5 ? '-fail' : '-notarget', pokemon); + return false; + } + if (this.gen === 4 && move.selfdestruct === 'always') { + this.faint(pokemon, pokemon, move); + } + moveResult = this.trySpreadMoveHit(targets, pokemon, move); + } + if (move.selfBoost && moveResult) this.moveHit(pokemon, pokemon, move, move.selfBoost, false, true); + if (!pokemon.hp) { + this.faint(pokemon, pokemon, move); + } + + if (!moveResult) { + this.singleEvent('MoveFail', move, null, target, pokemon, move); + return false; + } + + if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility(['sheerforce', 'abilitytodestroyanything']))) { + this.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move); + this.runEvent('AfterMoveSecondarySelf', pokemon, target, move); + } + + return true; + }, pokemon: { - getHealth = () => { - if (!this.hp) return {side: this.side.id, secret: '0 fnt', shared: '0 fnt'}; - let secret = `${this.hp}/${this.maxhp}`; - let shared; - const ratio = ((!!('tippedarrowpsychic' in this.volatiles) ? 1 : this.hp) / this.maxhp); - if (this.battle.reportExactHP) { - shared = secret; - } else if (this.battle.reportPercentages) { - // HP Percentage Mod mechanics - let percentage = Math.ceil(ratio * 100); - if ((percentage === 100) && (ratio < 1.0)) { - percentage = 99; - } - shared = `${percentage}/100`; - } else { - // In-game accurate pixel health mechanics - const pixels = Math.floor(ratio * 48) || 1; - shared = `${pixels}/48`; - if ((pixels === 9) && (ratio > 0.2)) { - shared += 'y'; // force yellow HP bar - } else if ((pixels === 24) && (ratio > 0.5)) { - shared += 'g'; // force green HP bar - } - } - if (this.status) { - secret += ` ${this.status}`; - shared += ` ${this.status}`; - } - return {side: this.side.id, secret, shared}; - }; +// getHealth = () => { +// if (!this.hp) return {side: this.side.id, secret: '0 fnt', shared: '0 fnt'}; +// let secret = `${this.hp}/${this.maxhp}`; +// let shared; +// const ratio = ((!!('tippedarrowpsychic' in this.volatiles) ? 1 : this.hp) / this.maxhp); +// if (this.battle.reportExactHP) { +// shared = secret; +// } else if (this.battle.reportPercentages) { +// // HP Percentage Mod mechanics +// let percentage = Math.ceil(ratio * 100); +// if ((percentage === 100) && (ratio < 1.0)) { +// percentage = 99; +// } +// shared = `${percentage}/100`; +// } else { +// // In-game accurate pixel health mechanics +// const pixels = Math.floor(ratio * 48) || 1; +// shared = `${pixels}/48`; +// if ((pixels === 9) && (ratio > 0.2)) { +// shared += 'y'; // force yellow HP bar +// } else if ((pixels === 24) && (ratio > 0.5)) { +// shared += 'g'; // force green HP bar +// } +// } +// if (this.status) { +// secret += ` ${this.status}`; +// shared += ` ${this.status}`; +// } +// return {side: this.side.id, secret, shared}; +// }; isGrounded(negateImmunity: boolean = false) { if ('gravity' in this.battle.field.pseudoWeather) return true;