diff --git a/data/mods/gen1/moves.ts b/data/mods/gen1/moves.ts index a219633070..0aff641cd6 100644 --- a/data/mods/gen1/moves.ts +++ b/data/mods/gen1/moves.ts @@ -211,22 +211,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, disable: { - num: 50, - accuracy: 55, - basePower: 0, - category: "Status", - name: "Disable", - pp: 20, - priority: 0, - flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 }, - volatileStatus: 'disable', + inherit: true, onTryHit(target) { - // This function should not return if the checks are met. Adding && undefined ensures this happens. - return target.moveSlots.some(ms => ms.pp > 0) && - !('disable' in target.volatiles) && - undefined; + return target.moveSlots.some(ms => ms.pp > 0); }, condition: { + inherit: true, + durationCallback: undefined, onStart(pokemon) { // disable can only select moves that have pp > 0, hence the onTryHit modification const moveSlot = this.sample(pokemon.moveSlots.filter(ms => ms.pp > 0)); @@ -235,9 +226,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { // 1-8 turns (which will in effect translate to 0-7 missed turns for the target) this.effectState.time = this.random(1, 9); }, - onEnd(pokemon) { - this.add('-end', pokemon, 'Disable'); - }, onBeforeMovePriority: 6, onBeforeMove(pokemon, target, move) { pokemon.volatiles['disable'].time--; @@ -252,17 +240,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { return false; } }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id === this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, }, - secondary: null, - target: "normal", - type: "Normal", }, dizzypunch: { inherit: true, @@ -319,11 +297,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { focusenergy: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'move: Focus Energy'); - }, + inherit: true, // This does nothing as it's dealt with on critical hit calculation. - onModifyMove() {}, + onModifyCritRatio() {}, }, }, glare: { @@ -408,9 +384,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, onHit() {}, condition: { - onStart(target) { - this.add('-start', target, 'move: Leech Seed'); - }, + inherit: true, onAfterMoveSelfPriority: 1, onAfterMoveSelf(pokemon) { const leecher = this.getAtSlot(pokemon.volatiles['leechseed'].sourceSlot); @@ -436,15 +410,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, lightscreen: { - num: 113, - accuracy: true, - basePower: 0, - category: "Status", - name: "Light Screen", - pp: 30, - priority: 0, - flags: { metronome: 1 }, + inherit: true, volatileStatus: 'lightscreen', + sideCondition: undefined, onTryHit(pokemon) { if (pokemon.volatiles['lightscreen']) { return false; @@ -456,7 +424,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, target: "self", - type: "Psychic", }, metronome: { inherit: true, @@ -497,6 +464,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.add('-start', source, 'Mimic', move.name); }, }, + minimize: { + inherit: true, + condition: { + inherit: true, + onSourceModifyDamage() {}, + }, + }, mirrormove: { inherit: true, onHit(pokemon) { @@ -511,9 +485,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { mist: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'Mist'); - }, + inherit: true, onTryBoost(boost, target, source, effect) { if (effect.effectType === 'Move' && effect.category !== 'Status') return; if (source && target !== source) { @@ -629,15 +601,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, reflect: { - num: 115, - accuracy: true, - basePower: 0, - category: "Status", - name: "Reflect", - pp: 20, - priority: 0, - flags: { metronome: 1 }, + inherit: true, volatileStatus: 'reflect', + sideCondition: undefined, onTryHit(pokemon) { if (pokemon.volatiles['reflect']) { return false; @@ -648,9 +614,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.add('-start', pokemon, 'Reflect'); }, }, - secondary: null, target: "self", - type: "Psychic", }, rest: { inherit: true, @@ -782,15 +746,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { onModifyMove() {}, }, substitute: { - num: 164, - accuracy: true, - basePower: 0, - category: "Status", - name: "Substitute", - pp: 10, - priority: 0, - flags: { metronome: 1 }, - volatileStatus: 'substitute', + inherit: true, onTryHit(target) { if (target.volatiles['substitute']) { this.add('-fail', target, 'move: Substitute'); @@ -810,11 +766,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, condition: { + inherit: true, onStart(target) { this.add('-start', target, 'Substitute'); this.effectState.hp = Math.floor(target.maxhp / 4) + 1; - delete target.volatiles['partiallytrapped']; + if (target.volatiles['partiallytrapped']) { + this.add('-end', target, target.volatiles['partiallytrapped'].sourceEffect, '[partiallytrapped]', '[silent]'); + delete target.volatiles['partiallytrapped']; + } }, + onTryPrimaryHit() {}, onTryHitPriority: -1, onTryHit(target, source, move) { if (move.category === 'Status') { @@ -878,13 +839,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } return 0; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, - secondary: null, - target: "self", - type: "Normal", }, superfang: { inherit: true, diff --git a/data/mods/gen1jpn/moves.ts b/data/mods/gen1jpn/moves.ts index 3e26d6af8e..75dbc55f6e 100644 --- a/data/mods/gen1jpn/moves.ts +++ b/data/mods/gen1jpn/moves.ts @@ -13,12 +13,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { substitute: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'Substitute'); - this.effectState.hp = Math.floor(target.maxhp / 4) + 1; - delete target.volatiles['partiallytrapped']; - }, - onTryHitPriority: -1, + inherit: true, onTryHit(target, source, move) { if (move.drain) { this.add('-miss', source); @@ -76,9 +71,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } return accuracy; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, }, swift: { diff --git a/data/mods/gen1stadium/moves.ts b/data/mods/gen1stadium/moves.ts index 275351378c..3f125e606a 100644 --- a/data/mods/gen1stadium/moves.ts +++ b/data/mods/gen1stadium/moves.ts @@ -160,11 +160,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { volatileStatus: 'rage', }, condition: { + inherit: true, // Rage lock onStart(target, source, effect) { this.effectState.move = 'rage'; }, - onLockMove: 'rage', onHit(target, source, move) { if (target.boosts.atk < 6 && (move.category !== 'Status' || move.id === 'disable')) { this.boost({ atk: 1 }); @@ -220,12 +220,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, condition: { - onStart(target) { - this.add('-start', target, 'Substitute'); - this.effectState.hp = Math.floor(target.maxhp / 4); - delete target.volatiles['partiallytrapped']; - }, - onTryHitPriority: -1, + inherit: true, onTryHit(target, source, move) { if (target === source) { this.debug('sub bypass: self hit'); @@ -275,9 +270,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } return 0; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, secondary: null, target: "self", diff --git a/data/mods/gen2/moves.ts b/data/mods/gen2/moves.ts index a93ee5c525..93c28999fb 100644 --- a/data/mods/gen2/moves.ts +++ b/data/mods/gen2/moves.ts @@ -51,64 +51,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { bide: { inherit: true, condition: { - duration: 3, + inherit: true, durationCallback(target, source, effect) { return this.random(3, 5); }, - onLockMove: 'bide', - onStart(pokemon) { - this.effectState.totalDamage = 0; - this.add('-start', pokemon, 'move: Bide'); - }, - onDamagePriority: -101, - onDamage(damage, target, source, move) { - if (!move || move.effectType !== 'Move' || !source) return; - this.effectState.totalDamage += damage; - this.effectState.lastDamageSource = source; - }, - onBeforeMove(pokemon, target, move) { - if (this.effectState.duration === 1) { - this.add('-end', pokemon, 'move: Bide'); - if (!this.effectState.totalDamage) { - this.add('-fail', pokemon); - return false; - } - target = this.effectState.lastDamageSource; - if (!target) { - this.add('-fail', pokemon); - return false; - } - if (!target.isActive) { - const possibleTarget = this.getRandomTarget(pokemon, this.dex.moves.get('pound')); - if (!possibleTarget) { - this.add('-miss', pokemon); - return false; - } - target = possibleTarget; - } - const moveData = { - id: 'bide', - name: "Bide", - accuracy: 100, - damage: this.effectState.totalDamage * 2, - category: "Physical", - priority: 0, - flags: { contact: 1, protect: 1 }, - effectType: 'Move', - type: 'Normal', - } as unknown as ActiveMove; - this.actions.tryMoveHit(target, pokemon, moveData); - pokemon.removeVolatile('bide'); - return false; - } - this.add('-activate', pokemon, 'move: Bide'); - }, - onMoveAborted(pokemon) { - pokemon.removeVolatile('bide'); - }, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Bide', '[silent]'); - }, }, }, counter: { @@ -139,12 +85,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { curse: { inherit: true, condition: { - onStart(pokemon, source) { - this.add('-start', pokemon, 'Curse', `[of] ${source}`); - }, + inherit: true, + onAfterMoveSelfPriority: 0, // explicit onAfterMoveSelf(pokemon) { this.damage(pokemon.baseMaxhp / 4); }, + onResidual() {}, }, }, detect: { @@ -157,10 +103,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { return source.status !== 'slp'; }, condition: { - duration: 2, - onImmunity(type, pokemon) { - if (type === 'sandstorm') return false; - }, + inherit: true, onInvulnerability(target, source, move) { if (move.id === 'earthquake' || move.id === 'magnitude' || move.id === 'fissure') { return; @@ -172,6 +115,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { if (source.volatiles['lockon'] && target === source.volatiles['lockon'].source) return; return false; }, + onSourceModifyDamage() {}, onSourceBasePower(basePower, target, source, move) { if (move.id === 'earthquake' || move.id === 'magnitude') { return this.chainModify(2); @@ -186,9 +130,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { encore: { inherit: true, condition: { - durationCallback() { - return this.random(3, 7); - }, + inherit: true, onStart(target) { const lockedMove = target.lastMoveEncore?.id || ''; const moveSlot = lockedMove ? target.getMoveData(lockedMove) : null; @@ -199,30 +141,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.effectState.move = lockedMove; this.add('-start', target, 'Encore'); }, - onOverrideAction(pokemon) { - return this.effectState.move; - }, onResidualOrder: 13, - onResidual(target) { - const lockedMoveSlot = target.getMoveData(this.effectState.move); - if (lockedMoveSlot && lockedMoveSlot.pp <= 0) { - // early termination if you run out of PP - target.removeVolatile('encore'); - } - }, - onEnd(target) { - this.add('-end', target, 'Encore'); - }, - onDisableMove(pokemon) { - if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) { - return; - } - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id !== this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, + onResidualSubOrder: undefined, }, }, endure: { @@ -244,7 +164,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { return source.status !== 'slp'; }, condition: { - duration: 2, + inherit: true, onInvulnerability(target, source, move) { if (move.id === 'gust' || move.id === 'twister' || move.id === 'thunder' || move.id === 'whirlwind') { return; @@ -260,6 +180,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { if (source.volatiles['lockon'] && target === source.volatiles['lockon'].source) return; return false; }, + onSourceModifyDamage() {}, onSourceBasePower(basePower, target, source, move) { if (move.id === 'gust' || move.id === 'twister') { return this.chainModify(2); @@ -270,9 +191,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { focusenergy: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'move: Focus Energy'); - }, + inherit: true, onModifyCritRatio(critRatio) { return critRatio + 1; }, @@ -284,17 +203,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { if (target.volatiles['foresight']) return false; }, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'Foresight'); - }, - onNegateImmunity(pokemon, type) { - if (pokemon.hasType('Ghost') && ['Normal', 'Fighting'].includes(type)) return false; - }, - onModifyBoost(boosts) { - if (boosts.evasion && boosts.evasion > 0) { - boosts.evasion = 0; - } - }, + inherit: true, + noCopy: false, }, }, frustration: { @@ -340,9 +250,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, onHit() {}, condition: { - onStart(target) { - this.add('-start', target, 'move: Leech Seed'); - }, + inherit: true, + onResidual() {}, onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { if (!pokemon.hp) return; @@ -378,10 +287,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { if (target.volatiles['foresight'] || target.volatiles['lockon']) return false; }, condition: { - duration: 2, - onSourceAccuracy(accuracy, target, source, move) { - if (move && source === this.effectState.target && target === this.effectState.source) return true; - }, + inherit: true, + onSourceInvulnerability() {}, }, }, lowkick: { @@ -449,15 +356,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, mist: { - num: 54, - accuracy: true, - basePower: 0, - category: "Status", - name: "Mist", - pp: 30, - priority: 0, - flags: { metronome: 1 }, + inherit: true, volatileStatus: 'mist', + sideCondition: undefined, condition: { onStart(pokemon) { this.add('-start', pokemon, 'Mist'); @@ -478,9 +379,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, }, - secondary: null, target: "self", - type: "Ice", }, moonlight: { inherit: true, @@ -509,13 +408,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { nightmare: { inherit: true, condition: { - noCopy: true, - onStart(pokemon) { - if (pokemon.status !== 'slp') { - return false; - } - this.add('-start', pokemon, 'Nightmare'); - }, + inherit: true, + onResidual() {}, onAfterMoveSelfPriority: 1, onAfterMoveSelf(pokemon) { if (pokemon.status === 'slp') this.damage(pokemon.baseMaxhp / 4); @@ -535,16 +429,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { perishsong: { inherit: true, condition: { - duration: 4, - onEnd(target) { - this.add('-start', target, 'perish0'); - target.faint(); - }, + inherit: true, onResidualOrder: 4, - onResidual(pokemon) { - const duration = pokemon.volatiles['perishsong'].duration; - this.add('-start', pokemon, `perish${duration}`); - }, }, }, petaldance: { @@ -584,7 +470,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, onModifyMove() {}, condition: { - duration: 1, + inherit: true, onBeforeSwitchOut(pokemon) { this.debug('Pursuit start'); let alreadyAdded = false; @@ -684,41 +570,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { safeguard: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasAbility('persistent')) { - this.add('-activate', source, 'ability: Persistent', effect); - return 7; - } - return 5; - }, - onSetStatus(status, target, source, effect) { - if (!effect || !source) return; - if (effect.id === 'yawn') return; - if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; - if (target !== source) { - this.debug('interrupting setStatus'); - if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) { - this.add('-activate', target, 'move: Safeguard'); - } - return null; - } - }, - onTryAddVolatile(status, target, source, effect) { - if (!effect || !source) return; - if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; - if ((status.id === 'confusion' || status.id === 'yawn') && target !== source) { - if (effect.effectType === 'Move' && !effect.secondaries) this.add('-activate', target, 'move: Safeguard'); - return null; - } - }, - onSideStart(side) { - this.add('-sidestart', side, 'Safeguard'); - }, + inherit: true, onSideResidualOrder: 8, - onSideEnd(side) { - this.add('-sideend', side, 'Safeguard'); - }, }, }, selfdestruct: { @@ -784,31 +637,14 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { spikes: { inherit: true, condition: { - // this is a side condition - onSideStart(side) { - if (!this.effectState.layers || this.effectState.layers === 0) { - this.add('-sidestart', side, 'Spikes'); - this.effectState.layers = 1; - } else { - return false; - } - }, - onSwitchIn(pokemon) { - if (!pokemon.runImmunity('Ground')) return; - const damageAmounts = [0, 3]; - this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24); - }, + inherit: true, + onSideRestart: undefined, }, }, substitute: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'Substitute'); - this.effectState.hp = Math.floor(target.maxhp / 4); - delete target.volatiles['partiallytrapped']; - }, - onTryPrimaryHitPriority: -1, + inherit: true, onTryPrimaryHit(target, source, move) { if (move.stallingMove) { this.add('-fail', source); @@ -861,9 +697,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.runEvent('AfterSubDamage', target, source, move, damage); return this.HIT_SUBSTITUTE; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, }, swagger: { diff --git a/data/mods/gen3/abilities.ts b/data/mods/gen3/abilities.ts index 86958fe650..ebb37c42d0 100644 --- a/data/mods/gen3/abilities.ts +++ b/data/mods/gen3/abilities.ts @@ -91,6 +91,8 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, }, lightningrod: { + inherit: true, + onAnyRedirectTarget() {}, onFoeRedirectTarget(target, source, source2, move) { // don't count Hidden Power as Electric-type if (this.dex.moves.get(move.id).type !== 'Electric') return; @@ -98,10 +100,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa return this.effectState.target; } }, - flags: { breakable: 1 }, - name: "Lightning Rod", - rating: 0, - num: 32, }, magnetpull: { inherit: true, diff --git a/data/mods/gen3/items.ts b/data/mods/gen3/items.ts index 30526bd86b..c1dbacdc51 100644 --- a/data/mods/gen3/items.ts +++ b/data/mods/gen3/items.ts @@ -82,6 +82,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { num: 208, gen: 3, isNonstandard: "Unobtainable", + // No competitive use }, fastball: { inherit: true, diff --git a/data/mods/gen3/moves.ts b/data/mods/gen3/moves.ts index 11dccce120..677c3c9cf4 100644 --- a/data/mods/gen3/moves.ts +++ b/data/mods/gen3/moves.ts @@ -26,10 +26,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, astonish: { inherit: true, - basePowerCallback(pokemon, target) { - if (target.volatiles['minimize']) return 60; - return 30; - }, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 }, }, beatup: { inherit: true, @@ -63,18 +60,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { accuracy: 100, priority: 0, condition: { - duration: 3, - onLockMove: 'bide', - onStart(pokemon) { - this.effectState.totalDamage = 0; - this.add('-start', pokemon, 'move: Bide'); - }, - onDamagePriority: -101, - onDamage(damage, target, source, move) { - if (!move || move.effectType !== 'Move' || !source) return; - this.effectState.totalDamage += damage; - this.effectState.lastDamageSource = source; - }, + inherit: true, + onAfterSetStatus() {}, onBeforeMove(pokemon, target, move) { if (this.effectState.duration === 1) { this.add('-end', pokemon, 'move: Bide'); @@ -112,12 +99,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } this.add('-activate', pokemon, 'move: Bide'); }, - onMoveAborted(pokemon) { - pokemon.removeVolatile('bide'); - }, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Bide', '[silent]'); - }, }, }, blizzard: { @@ -183,17 +164,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { counter: { inherit: true, condition: { - duration: 1, - noCopy: true, - onStart(target, source, move) { - this.effectState.slot = null; - this.effectState.damage = 0; - }, - onRedirectTargetPriority: -1, + inherit: true, onRedirectTarget(target, source, source2) { if (source !== this.effectState.target || !this.effectState.slot) return; return this.getAtSlot(this.effectState.slot); }, + onDamagingHit() {}, onDamagePriority: -101, onDamage(damage, target, source, effect) { if ( @@ -227,48 +203,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, accuracy: 55, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 }, - volatileStatus: 'disable', condition: { + inherit: true, durationCallback() { return this.random(2, 6); }, - noCopy: true, - onStart(pokemon) { - if (!this.queue.willMove(pokemon)) { - this.effectState.duration!++; - } - if (!pokemon.lastMove) { - return false; - } - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id === pokemon.lastMove.id) { - if (!moveSlot.pp) { - return false; - } else { - this.add('-start', pokemon, 'Disable', moveSlot.move); - this.effectState.move = pokemon.lastMove.id; - return; - } - } - } - return false; - }, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Disable'); - }, - onBeforeMove(attacker, defender, move) { - if (move.id === this.effectState.move) { - this.add('cant', attacker, 'Disable', move); - return false; - } - }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id === this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, + "onResidualOrder": undefined, + "onResidualSubOrder": undefined, }, }, dive: { @@ -312,51 +253,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, volatileStatus: 'encore', condition: { + inherit: true, durationCallback() { return this.random(3, 7); }, - onStart(target, source) { - const moveSlot = target.lastMove ? target.getMoveData(target.lastMove.id) : null; - if (!target.lastMove || target.lastMove.flags['failencore'] || !moveSlot || moveSlot.pp <= 0) { - // it failed - return false; - } - this.effectState.move = target.lastMove.id; - this.add('-start', target, 'Encore'); - }, - onOverrideAction(pokemon) { - return this.effectState.move; - }, - onResidualOrder: 10, - onResidualSubOrder: 14, - onResidual(target) { - const moveSlot = target.getMoveData(this.effectState.move); - if (moveSlot && moveSlot.pp <= 0) { - // early termination if you run out of PP - target.removeVolatile('encore'); - } - }, - onEnd(target) { - this.add('-end', target, 'Encore'); - }, - onDisableMove(pokemon) { - if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) { - return; - } - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id !== this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, }, }, extrasensory: { inherit: true, - basePowerCallback(pokemon, target) { - if (target.volatiles['minimize']) return 160; - return 80; - }, + flags: { protect: 1, mirror: 1, metronome: 1, minimize: 1 }, }, fakeout: { inherit: true, @@ -401,12 +306,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { volatileStatus: undefined, slotCondition: 'followme', condition: { - duration: 1, + inherit: true, onStart(target, source, effect) { this.add('-singleturn', target, 'move: Follow Me'); this.effectState.slot = target.getSlot(); }, - onFoeRedirectTargetPriority: 1, onFoeRedirectTarget(target, source, source2, move) { const userSlot = this.getAtSlot(this.effectState.slot); if (this.validTarget(userSlot, source, move.target)) { @@ -504,17 +408,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { mirrorcoat: { inherit: true, condition: { - duration: 1, - noCopy: true, - onStart(target, source, move) { - this.effectState.slot = null; - this.effectState.damage = 0; - }, - onRedirectTargetPriority: -1, + inherit: true, onRedirectTarget(target, source, source2) { if (source !== this.effectState.target || !this.effectState.slot) return; return this.getAtSlot(this.effectState.slot); }, + onDamagingHit() {}, onDamagePriority: -101, onDamage(damage, target, source, effect) { if ( @@ -555,10 +454,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, needlearm: { inherit: true, - basePowerCallback(pokemon, target) { - if (target.volatiles['minimize']) return 120; - return 60; - }, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 }, }, nightmare: { inherit: true, @@ -697,28 +593,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { protect: 1, bypasssub: 1, metronome: 1 }, condition: { + inherit: true, duration: 2, - onStart(target) { - this.add('-start', target, 'move: Taunt'); - }, - onResidualOrder: 10, - onResidualSubOrder: 15, + durationCallback: undefined, onEnd(target) { this.add('-end', target, 'move: Taunt', '[silent]'); }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (this.dex.moves.get(moveSlot.move).category === 'Status') { - pokemon.disableMove(moveSlot.id); - } - } - }, - onBeforeMove(attacker, defender, move) { - if (move.category === 'Status') { - this.add('cant', attacker, 'move: Taunt', move); - return false; - } - }, + onBeforeMovePriority: undefined, }, }, teeterdance: { @@ -732,37 +613,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { uproar: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'Uproar'); - // 2-5 turns - this.effectState.duration = this.random(2, 6); - }, - onResidual(target) { - if (target.volatiles['throatchop']) { - target.removeVolatile('uproar'); - return; - } - if (target.lastMove && target.lastMove.id === 'struggle') { - // don't lock - delete target.volatiles['uproar']; - } - this.add('-start', target, 'Uproar', '[upkeep]'); - }, - onResidualOrder: 10, - onResidualSubOrder: 11, - onEnd(target) { - this.add('-end', target, 'Uproar'); - }, - onLockMove: 'uproar', - onAnySetStatus(status, pokemon) { - if (status.id === 'slp') { - if (pokemon === this.effectState.target) { - this.add('-fail', pokemon, 'slp', '[from] Uproar', '[msg]'); - } else { - this.add('-fail', pokemon, 'slp', '[from] Uproar'); - } - return null; - } + inherit: true, + durationCallback() { + return this.random(2, 6); }, }, }, diff --git a/data/mods/gen3rs/items.ts b/data/mods/gen3rs/items.ts index 8e87d4c7e8..33b884939b 100644 --- a/data/mods/gen3rs/items.ts +++ b/data/mods/gen3rs/items.ts @@ -7,10 +7,6 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { inherit: true, isNonstandard: "Unobtainable", }, - enigmaberry: { - inherit: true, - isNonstandard: "Unobtainable", - }, fastball: { inherit: true, isNonstandard: "Unobtainable", diff --git a/data/mods/gen4/abilities.ts b/data/mods/gen4/abilities.ts index e1af9904bf..f75a93d785 100644 --- a/data/mods/gen4/abilities.ts +++ b/data/mods/gen4/abilities.ts @@ -23,6 +23,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa onResidualSubOrder: 10, }, blaze: { + inherit: true, + onModifyAtk() {}, + onModifySpA() {}, onBasePowerPriority: 2, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Fire' && attacker.hp <= attacker.maxhp / 3) { @@ -30,9 +33,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa return this.chainModify(1.5); } }, - name: "Blaze", - rating: 2, - num: 66, }, cloudnine: { inherit: true, @@ -58,7 +58,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa onSourceModifyAccuracy(accuracy) { if (typeof accuracy !== 'number') return; this.debug('compoundeyes - enhancing accuracy'); - return accuracy * 1.3; + return this.chainModify(1.3); }, inherit: true, }, @@ -128,19 +128,15 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa } }, condition: { - noCopy: true, // doesn't get copied by Baton Pass - onStart(target) { - this.add('-start', target, 'ability: Flash Fire'); - }, + inherit: true, + onModifyAtk() {}, + onModifySpA() {}, onModifyDamagePhase1(atk, attacker, defender, move) { if (move.type === 'Fire') { this.debug('Flash Fire boost'); return this.chainModify(1.5); } }, - onEnd(target) { - this.add('-end', target, 'ability: Flash Fire', '[silent]'); - }, }, }, flowergift: { @@ -200,20 +196,19 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa onSourceModifyAccuracyPriority: 7, onSourceModifyAccuracy(accuracy, target, source, move) { if (move.category === 'Physical' && typeof accuracy === 'number') { - return accuracy * 0.8; + return this.chainModify(0.8); } }, }, hydration: { + inherit: true, + onResidual() {}, onWeather(target, source, effect) { if (effect.id === 'raindance' && target.status) { this.add('-activate', target, 'ability: Hydration'); target.cureStatus(); } }, - name: "Hydration", - rating: 1.5, - num: 93, }, insomnia: { inherit: true, @@ -270,31 +265,24 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, }, magicguard: { - onDamage(damage, target, source, effect) { - if (effect.effectType !== 'Move') { - return false; - } - }, + inherit: true, onSetStatus(status, target, source, effect) { if (effect && effect.id === 'toxicspikes') { return false; } }, - name: "Magic Guard", rating: 4.5, - num: 98, }, minus: { + inherit: true, + onModifySpAPriority: undefined, onModifySpA(spa, pokemon) { - for (const ally of pokemon.allies()) { - if (ally.ability === 'plus') { - return spa * 1.5; + for (const allyActive of pokemon.allies()) { + if (allyActive.hasAbility('plus')) { + return this.chainModify(1.5); } } }, - name: "Minus", - rating: 0, - num: 58, }, naturalcure: { inherit: true, @@ -318,6 +306,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, }, overgrow: { + inherit: true, + onModifyAtk() {}, + onModifySpA() {}, onBasePowerPriority: 2, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Grass' && attacker.hp <= attacker.maxhp / 3) { @@ -325,26 +316,23 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa return this.chainModify(1.5); } }, - name: "Overgrow", - rating: 2, - num: 65, }, pickup: { - name: "Pickup", + inherit: true, + onResidual() {}, rating: 0, - num: 53, + // No competitive use }, plus: { + inherit: true, + onModifySpAPriority: undefined, onModifySpA(spa, pokemon) { - for (const ally of pokemon.allies()) { - if (ally.ability === 'minus') { - return spa * 1.5; + for (const allyActive of pokemon.allies()) { + if (allyActive.hasAbility('minus')) { + return this.chainModify(1.5); } } }, - name: "Plus", - rating: 0, - num: 57, }, poisonpoint: { inherit: true, @@ -357,16 +345,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, }, pressure: { - onStart(pokemon) { - this.add('-ability', pokemon, 'Pressure'); - }, + inherit: true, onDeductPP(target, source) { if (target === source) return; return 1; }, - name: "Pressure", rating: 1.5, - num: 46, }, roughskin: { inherit: true, @@ -383,7 +367,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa if (typeof accuracy !== 'number') return; if (this.field.isWeather('sandstorm')) { this.debug('Sand Veil - decreasing accuracy'); - return accuracy * 0.8; + return this.chainModify(0.8); } }, }, @@ -404,16 +388,14 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa onResidualSubOrder: 3, }, simple: { + inherit: true, + onChangeBoost() {}, onModifyBoost(boosts) { let key: BoostID; for (key in boosts) { boosts[key]! *= 2; } }, - flags: { breakable: 1 }, - name: "Simple", - rating: 4, - num: 86, }, snowcloak: { inherit: true, @@ -422,7 +404,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa if (typeof accuracy !== 'number') return; if (this.field.isWeather('hail')) { this.debug('Snow Cloak - decreasing accuracy'); - return accuracy * 0.8; + return this.chainModify(0.8); } }, }, @@ -442,9 +424,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, }, stench: { - name: "Stench", + inherit: true, + onModifyMove() {}, rating: 0, - num: 1, + // No competitive use }, stickyhold: { inherit: true, @@ -466,6 +449,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa rating: 0, }, swarm: { + inherit: true, + onModifyAtk() {}, + onModifySpA() {}, onBasePowerPriority: 2, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Bug' && attacker.hp <= attacker.maxhp / 3) { @@ -473,9 +459,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa return this.chainModify(1.5); } }, - name: "Swarm", - rating: 2, - num: 68, }, synchronize: { inherit: true, @@ -495,23 +478,25 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa if (typeof accuracy !== 'number') return; if (target?.volatiles['confusion']) { this.debug('Tangled Feet - decreasing accuracy'); - return accuracy * 0.5; + return this.chainModify(0.5); } }, }, thickfat: { + inherit: true, + onSourceModifyAtk() {}, + onSourceModifySpA() {}, onSourceBasePowerPriority: 1, onSourceBasePower(basePower, attacker, defender, move) { if (move.type === 'Ice' || move.type === 'Fire') { return this.chainModify(0.5); } }, - flags: { breakable: 1 }, - name: "Thick Fat", - rating: 3.5, - num: 47, }, torrent: { + inherit: true, + onModifyAtk() {}, + onModifySpA() {}, onBasePowerPriority: 2, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Water' && attacker.hp <= attacker.maxhp / 3) { @@ -519,9 +504,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa return this.chainModify(1.5); } }, - name: "Torrent", - rating: 2, - num: 67, }, trace: { inherit: true, diff --git a/data/mods/gen4/items.ts b/data/mods/gen4/items.ts index 1a5577d4aa..b21ef163b2 100644 --- a/data/mods/gen4/items.ts +++ b/data/mods/gen4/items.ts @@ -144,7 +144,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { }, focussash: { inherit: true, - onDamage() { }, + onDamage() {}, onTryHit(target, source, move) { if (target !== source && target.hp === target.maxhp) { target.addVolatile('focussash'); @@ -306,11 +306,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { metronome: { inherit: true, condition: { - onStart(pokemon) { - this.effectState.numConsecutive = 0; - this.effectState.lastMove = ''; - }, - onTryMovePriority: -2, + inherit: true, onTryMove(pokemon, target, move) { if (!pokemon.hasItem('metronome')) { pokemon.removeVolatile('metronome'); @@ -323,6 +319,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { } this.effectState.lastMove = move.id; }, + onModifyDamage() {}, onModifyDamagePhase2(damage, source, target, move) { return damage * (1 + (this.effectState.numConsecutive / 10)); }, @@ -331,7 +328,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = { micleberry: { inherit: true, condition: { - duration: 2, + inherit: true, onSourceModifyAccuracyPriority: 3, onSourceModifyAccuracy(accuracy, target, source) { this.add('-enditem', source, 'Micle Berry'); diff --git a/data/mods/gen4/moves.ts b/data/mods/gen4/moves.ts index 44903ec997..3272bce095 100644 --- a/data/mods/gen4/moves.ts +++ b/data/mods/gen4/moves.ts @@ -37,14 +37,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { metronome: 1 }, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'Aqua Ring'); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 2, - onResidual(pokemon) { - this.heal(pokemon.baseMaxhp / 16); - }, }, }, assist: { @@ -109,18 +104,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { bide: { inherit: true, condition: { - duration: 3, - onLockMove: 'bide', - onStart(pokemon) { - this.effectState.totalDamage = 0; - this.add('-start', pokemon, 'move: Bide'); - }, - onDamagePriority: -101, - onDamage(damage, target, source, move) { - if (!move || move.effectType !== 'Move' || !source) return; - this.effectState.totalDamage += damage; - this.effectState.lastDamageSource = source; - }, + inherit: true, onAfterSetStatus(status, pokemon) { if (status.id === 'slp' || status.id === 'frz') { pokemon.removeVolatile('bide'); @@ -164,12 +148,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } this.add('-activate', pokemon, 'move: Bide'); }, - onMoveAborted(pokemon) { - pokemon.removeVolatile('bide'); - }, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Bide', '[silent]'); - }, }, }, bind: { @@ -303,14 +281,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, condition: { - onStart(pokemon, source) { - this.add('-start', pokemon, 'Curse', `[of] ${source}`); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 8, - onResidual(pokemon) { - this.damage(pokemon.baseMaxhp / 4); - }, }, type: "???", }, @@ -321,36 +294,17 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { detect: { inherit: true, priority: 3, - condition: { - duration: 1, - onStart(target) { - this.add('-singleturn', target, 'Protect'); - }, - onTryHitPriority: 3, - onTryHit(target, source, move) { - if (!move.flags['protect']) return; - this.add('-activate', target, 'Protect'); - const lockedmove = source.getVolatile('lockedmove'); - if (lockedmove) { - // Outrage counter is NOT reset - if (source.volatiles['lockedmove'].trueDuration >= 2) { - source.volatiles['lockedmove'].duration = 2; - } - } - return null; - }, - }, }, disable: { inherit: true, accuracy: 80, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 }, - volatileStatus: 'disable', condition: { + inherit: true, + duration: undefined, durationCallback() { return this.random(4, 8); }, - noCopy: true, onStart(pokemon) { if (!this.queue.willMove(pokemon)) { this.effectState.duration!++; @@ -373,23 +327,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, onResidualOrder: 10, onResidualSubOrder: 13, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Disable'); - }, - onBeforeMovePriority: 7, - onBeforeMove(attacker, defender, move) { - if (move.id === this.effectState.move) { - this.add('cant', attacker, 'Disable', move); - return false; - } - }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id === this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, }, }, doomdesire: { @@ -451,16 +388,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, condition: { - duration: 5, - onStart(pokemon) { - this.add('-start', pokemon, 'Embargo'); - }, - // Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js + inherit: true, onResidualOrder: 10, onResidualSubOrder: 18, - onEnd(pokemon) { - this.add('-end', pokemon, 'Embargo'); - }, }, }, encore: { @@ -468,43 +398,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1, failencore: 1 }, volatileStatus: 'encore', condition: { + inherit: true, + duration: undefined, durationCallback() { return this.random(4, 9); }, - onStart(target, source) { - const moveSlot = target.lastMove ? target.getMoveData(target.lastMove.id) : null; - if (!target.lastMove || target.lastMove.flags['failencore'] || !moveSlot || moveSlot.pp <= 0) { - // it failed - return false; - } - this.effectState.move = target.lastMove.id; - this.add('-start', target, 'Encore'); - }, - onOverrideAction(pokemon) { - return this.effectState.move; - }, onResidualOrder: 10, onResidualSubOrder: 14, - onResidual(target) { - const moveSlot = target.getMoveData(this.effectState.move); - if (moveSlot && moveSlot.pp <= 0) { - // early termination if you run out of PP - target.removeVolatile('encore'); - } - }, - onEnd(target) { - this.add('-end', target, 'Encore'); - }, - onDisableMove(pokemon) { - if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) { - return; - } - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id !== this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, }, }, endeavor: { @@ -619,10 +519,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, basePower: 10, condition: { - duration: 2, - onStart() { - this.effectState.multiplier = 1; - }, + inherit: true, onRestart() { if (this.effectState.multiplier < 16) { this.effectState.multiplier <<= 1; @@ -678,77 +575,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { gravity: { inherit: true, condition: { - duration: 5, - durationCallback(source, effect) { - if (source?.hasAbility('persistent')) { - this.add('-activate', source, 'ability: Persistent', '[move] Gravity'); - return 7; - } - return 5; - }, - onFieldStart(target, source) { - if (source?.hasAbility('persistent')) { - this.add('-fieldstart', 'move: Gravity', '[persistent]'); - } else { - this.add('-fieldstart', 'move: Gravity'); - } - for (const pokemon of this.getAllActive()) { - let applies = false; - if (pokemon.removeVolatile('bounce') || pokemon.removeVolatile('fly')) { - applies = true; - this.queue.cancelMove(pokemon); - pokemon.removeVolatile('twoturnmove'); - } - if (pokemon.volatiles['skydrop']) { - applies = true; - this.queue.cancelMove(pokemon); - - if (pokemon.volatiles['skydrop'].source) { - this.add('-end', pokemon.volatiles['twoturnmove'].source, 'Sky Drop', '[interrupt]'); - } - pokemon.removeVolatile('skydrop'); - pokemon.removeVolatile('twoturnmove'); - } - if (pokemon.volatiles['magnetrise']) { - applies = true; - delete pokemon.volatiles['magnetrise']; - } - if (pokemon.volatiles['telekinesis']) { - applies = true; - delete pokemon.volatiles['telekinesis']; - } - if (applies) this.add('-activate', pokemon, 'move: Gravity'); - } - }, - onModifyAccuracy(accuracy) { - if (typeof accuracy !== 'number') return; - return this.chainModify([6840, 4096]); - }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (this.dex.moves.get(moveSlot.id).flags['gravity']) { - pokemon.disableMove(moveSlot.id); - } - } - }, - // groundedness implemented in battle.engine.js:BattlePokemon#isGrounded - onBeforeMovePriority: 6, - onBeforeMove(pokemon, target, move) { - if (move.flags['gravity'] && !move.isZ) { - this.add('cant', pokemon, 'move: Gravity', move); - return false; - } - }, - onModifyMove(move, pokemon, target) { - if (move.flags['gravity'] && !move.isZ) { - this.add('cant', pokemon, 'move: Gravity', move); - return false; - } - }, + inherit: true, onFieldResidualOrder: 9, - onFieldEnd() { - this.add('-fieldend', 'move: Gravity'); - }, + onFieldResidualSubOrder: undefined, }, }, growth: { @@ -786,36 +615,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { protect: 1, mirror: 1, metronome: 1 }, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasAbility('persistent')) { - this.add('-activate', source, 'ability: Persistent', '[move] Heal Block'); - return 7; - } - return 5; - }, - onStart(pokemon) { - this.add('-start', pokemon, 'move: Heal Block'); - }, - onDisableMove(pokemon) { - for (const moveSlot of pokemon.moveSlots) { - if (this.dex.moves.get(moveSlot.id).flags['heal']) { - pokemon.disableMove(moveSlot.id); - } - } - }, - onBeforeMovePriority: 6, - onBeforeMove(pokemon, target, move) { - if (move.flags['heal']) { - this.add('cant', pokemon, 'move: Heal Block', move); - return false; - } - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 17, - onEnd(pokemon) { - this.add('-end', pokemon, 'move: Heal Block'); - }, onTryHeal(damage, pokemon, source, effect) { if (effect && (effect.id === 'drain' || effect.id === 'leechseed' || effect.id === 'wish')) { return false; @@ -875,22 +677,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { ingrain: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'move: Ingrain'); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 1, - onResidual(pokemon) { - this.heal(pokemon.baseMaxhp / 16); - }, - onTrapPokemon(pokemon) { - pokemon.tryTrap(); - }, - // groundedness implemented in battle.engine.js:BattlePokemon#isGrounded - onDragOut(pokemon) { - this.add('-activate', pokemon, 'move: Ingrain'); - return null; - }, }, }, jumpkick: { @@ -925,34 +714,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { leechseed: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'move: Leech Seed'); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 5, - onResidual(pokemon) { - const target = this.getAtSlot(pokemon.volatiles['leechseed'].sourceSlot); - if (!target || target.fainted || target.hp <= 0) { - this.debug('Nothing to leech into'); - return; - } - const damage = this.damage(pokemon.baseMaxhp / 8, pokemon, target); - if (damage) { - this.heal(damage, target, pokemon); - } - }, }, }, lightscreen: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasItem('lightclay')) { - return 8; - } - return 5; - }, + inherit: true, + onAnyModifyDamage() {}, onAnyModifyDamagePhase1(damage, source, target, move) { if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Special') { if (!target.getMoveHitData(move).crit && !move.infiltrates) { @@ -962,41 +733,24 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } } }, - onSideStart(side) { - this.add('-sidestart', side, 'Light Screen'); - }, onSideResidualOrder: 2, - onSideEnd(side) { - this.add('-sideend', side, 'Light Screen'); - }, + onSideResidualSubOrder: undefined, }, }, lockon: { inherit: true, condition: { - duration: 2, - onSourceInvulnerabilityPriority: 1, - onSourceInvulnerability(target, source, move) { - if (move && source === this.effectState.target && target === this.effectState.source) return 0; - }, - onSourceAccuracy(accuracy, target, source, move) { - if (move && source === this.effectState.target && target === this.effectState.source) return true; - }, + inherit: true, + noCopy: false, }, }, luckychant: { inherit: true, flags: { metronome: 1 }, condition: { - duration: 5, - onSideStart(side) { - this.add('-sidestart', side, 'move: Lucky Chant'); - }, - onCriticalHit: false, + inherit: true, onSideResidualOrder: 6, - onSideEnd(side) { - this.add('-sideend', side, 'move: Lucky Chant'); - }, + onSideResidualSubOrder: undefined, }, }, lunardance: { @@ -1033,8 +787,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { magiccoat: { inherit: true, condition: { - duration: 1, - onTryHitPriority: 2, + inherit: true, onTryHit(target, source, move) { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; @@ -1045,6 +798,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.actions.useMove(newMove, target, { target: source }); return null; }, + onAllyTryHitSide() {}, }, }, magmastorm: { @@ -1056,25 +810,20 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { flags: { gravity: 1, metronome: 1 }, volatileStatus: 'magnetrise', condition: { - duration: 5, + inherit: true, onStart(target) { if (target.volatiles['ingrain'] || target.ability === 'levitate') return false; this.add('-start', target, 'Magnet Rise'); }, - onImmunity(type) { - if (type === 'Ground') return false; - }, onResidualOrder: 10, onResidualSubOrder: 16, - onEnd(target) { - this.add('-end', target, 'Magnet Rise'); - }, }, }, mefirst: { inherit: true, condition: { - duration: 1, + inherit: true, + onBasePower() {}, onModifyDamagePhase2(damage) { return damage * 1.5; }, @@ -1162,30 +911,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { mist: { inherit: true, condition: { - duration: 5, - onTryBoost(boost, target, source, effect) { - if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; - if (source && target !== source) { - let showMsg = false; - let i: BoostID; - for (i in boost) { - if (boost[i]! < 0) { - delete boost[i]; - showMsg = true; - } - } - if (showMsg && !(effect as ActiveMove).secondaries) { - this.add('-activate', target, 'move: Mist'); - } - } - }, - onSideStart(side) { - this.add('-sidestart', side, 'Mist'); - }, + inherit: true, onSideResidualOrder: 3, - onSideEnd(side) { - this.add('-sideend', side, 'Mist'); - }, + onSideResidualSubOrder: undefined, }, }, moonlight: { @@ -1215,9 +943,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { mudsport: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'move: Mud Sport'); - }, + inherit: true, + noCopy: false, onAnyBasePowerPriority: 3, onAnyBasePower(basePower, user, target, move) { if (move.type === 'Electric') { @@ -1237,18 +964,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { nightmare: { inherit: true, condition: { - noCopy: true, - onStart(pokemon) { - if (pokemon.status !== 'slp' && !pokemon.hasAbility('comatose')) { - return false; - } - this.add('-start', pokemon, 'Nightmare'); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 7, - onResidual(pokemon) { - this.damage(pokemon.baseMaxhp / 4); - }, }, }, odorsleuth: { @@ -1278,16 +996,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { perishsong: { inherit: true, condition: { - duration: 4, - onEnd(target) { - this.add('-start', target, 'perish0'); - target.faint(); - }, + inherit: true, onResidualOrder: 12, - onResidual(pokemon) { - const duration = pokemon.volatiles['perishsong'].duration; - this.add('-start', pokemon, `perish${duration}`); - }, }, }, petaldance: { @@ -1308,11 +1018,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, priority: 3, condition: { - duration: 1, - onStart(target) { - this.add('-singleturn', target, 'Protect'); - }, - onTryHitPriority: 3, + inherit: true, onTryHit(target, source, move) { if (!move.flags['protect']) return; this.add('-activate', target, 'Protect'); @@ -1346,7 +1052,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } }, condition: { - duration: 1, + inherit: true, onBeforeSwitchOut(pokemon) { this.debug('Pursuit start'); let alreadyAdded = false; @@ -1403,13 +1109,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { reflect: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasItem('lightclay')) { - return 8; - } - return 5; - }, + inherit: true, + onAnyModifyDamage() {}, onAnyModifyDamagePhase1(damage, source, target, move) { if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Physical') { if (!target.getMoveHitData(move).crit && !move.infiltrates) { @@ -1419,13 +1120,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } } }, - onSideStart(side) { - this.add('-sidestart', side, 'Reflect'); - }, onSideResidualOrder: 1, - onSideEnd(side) { - this.add('-sideend', side, 'Reflect'); - }, + onSideResidualSubOrder: undefined, }, }, reversal: { @@ -1470,45 +1166,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { safeguard: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasAbility('persistent')) { - this.add('-activate', source, 'ability: Persistent', '[move] Safeguard'); - return 7; - } - return 5; - }, - onSetStatus(status, target, source, effect) { - if (!effect || !source) return; - if (effect.id === 'yawn') return; - if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; - if (target !== source) { - this.debug('interrupting setStatus'); - if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) { - this.add('-activate', target, 'move: Safeguard'); - } - return null; - } - }, - onTryAddVolatile(status, target, source, effect) { - if (!effect || !source) return; - if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; - if ((status.id === 'confusion' || status.id === 'yawn') && target !== source) { - if (effect.effectType === 'Move' && !effect.secondaries) this.add('-activate', target, 'move: Safeguard'); - return null; - } - }, - onSideStart(side, source) { - if (source?.hasAbility('persistent')) { - this.add('-sidestart', side, 'Safeguard', '[persistent]'); - } else { - this.add('-sidestart', side, 'Safeguard'); - } - }, + inherit: true, onSideResidualOrder: 4, - onSideEnd(side) { - this.add('-sideend', side, 'Safeguard'); - }, + onSideResidualSubOrder: undefined, }, }, sandtomb: { @@ -1566,11 +1226,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { bypasssub: 1, noassist: 1, failcopycat: 1 }, condition: { - duration: 1, - onStart(pokemon) { - this.add('-singleturn', pokemon, 'Snatch'); - }, - onAnyPrepareHitPriority: -1, + inherit: true, onAnyPrepareHit(source, target, move) { const snatchUser = this.effectState.source; if (snatchUser.isSkyDropped()) return; @@ -1594,16 +1250,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { metronome: 1, mustpressure: 1 }, condition: { - // this is a side condition - onSideStart(side) { - this.add('-sidestart', side, 'Spikes'); - this.effectState.layers = 1; - }, - onSideRestart(side) { - if (this.effectState.layers >= 3) return false; - this.add('-sidestart', side, 'Spikes'); - this.effectState.layers++; - }, + inherit: true, + onSwitchIn() {}, onEntryHazard(pokemon) { if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return; const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4 @@ -1619,10 +1267,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { metronome: 1, mustpressure: 1 }, condition: { - // this is a side condition - onSideStart(side) { - this.add('-sidestart', side, 'move: Stealth Rock'); - }, + inherit: true, + onSwitchIn() {}, onEntryHazard(pokemon) { if (pokemon.hasItem('heavydutyboots')) return; const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6); @@ -1643,12 +1289,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { substitute: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'Substitute'); - this.effectState.hp = Math.floor(target.maxhp / 4); - delete target.volatiles['partiallytrapped']; - }, - onTryPrimaryHitPriority: -1, + inherit: true, onTryPrimaryHit(target, source, move) { if (target === source || move.flags['bypasssub']) { return; @@ -1681,9 +1322,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.runEvent('AfterSubDamage', target, source, move, damage); return this.HIT_SUBSTITUTE; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, }, suckerpunch: { @@ -1735,6 +1373,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { tailwind: { inherit: true, condition: { + inherit: true, duration: 3, durationCallback(target, source, effect) { if (source?.hasAbility('persistent')) { @@ -1743,26 +1382,19 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } return 3; }, - onSideStart(side, source) { - if (source?.hasAbility('persistent')) { - this.add('-sidestart', side, 'move: Tailwind', '[persistent]'); - } else { - this.add('-sidestart', side, 'move: Tailwind'); - } - }, onModifySpe(spe) { return spe * 2; }, onSideResidualOrder: 5, - onSideEnd(side) { - this.add('-sideend', side, 'move: Tailwind'); - }, + onSideResidualSubOrder: undefined, }, }, taunt: { inherit: true, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 }, condition: { + inherit: true, + duration: undefined, durationCallback() { return this.random(3, 6); }, @@ -1771,9 +1403,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, onResidualOrder: 10, onResidualSubOrder: 15, - onEnd(target) { - this.add('-end', target, 'move: Taunt'); - }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { if (this.dex.moves.get(moveSlot.id).category === 'Status') { @@ -1807,16 +1436,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { metronome: 1, mustpressure: 1 }, condition: { - // this is a side condition - onSideStart(side) { - this.add('-sidestart', side, 'move: Toxic Spikes'); - this.effectState.layers = 1; - }, - onSideRestart(side) { - if (this.effectState.layers >= 2) return false; - this.add('-sidestart', side, 'move: Toxic Spikes'); - this.effectState.layers++; - }, + inherit: true, + onSwitchIn() {}, onEntryHazard(pokemon) { if (!pokemon.isGrounded()) return; if (pokemon.hasType('Poison')) { @@ -1846,67 +1467,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { trickroom: { inherit: true, condition: { - duration: 5, - durationCallback(source, effect) { - if (source?.hasAbility('persistent')) { - this.add('-activate', source, 'ability: Persistent', '[move] Trick Room'); - return 7; - } - return 5; - }, - onFieldStart(target, source) { - if (source?.hasAbility('persistent')) { - this.add('-fieldstart', 'move: Trick Room', `[of] ${source}`, '[persistent]'); - } else { - this.add('-fieldstart', 'move: Trick Room', `[of] ${source}`); - } - }, - onFieldRestart(target, source) { - this.field.removePseudoWeather('trickroom'); - }, - // Speed modification is changed in Pokemon.getActionSpeed() in sim/pokemon.js + inherit: true, onFieldResidualOrder: 13, - onFieldEnd() { - this.add('-fieldend', 'move: Trick Room'); - }, + onFieldResidualSubOrder: undefined, }, }, uproar: { inherit: true, basePower: 50, condition: { - onStart(target) { - this.add('-start', target, 'Uproar'); - // 3-6 turns - this.effectState.duration = this.random(3, 7); - }, - onResidual(target) { - if (target.volatiles['throatchop']) { - target.removeVolatile('uproar'); - return; - } - if (target.lastMove && target.lastMove.id === 'struggle') { - // don't lock - delete target.volatiles['uproar']; - } - this.add('-start', target, 'Uproar', '[upkeep]'); + inherit: true, + duration: undefined, + durationCallback() { + return this.random(3, 7); }, onResidualOrder: 10, onResidualSubOrder: 11, - onEnd(target) { - this.add('-end', target, 'Uproar'); - }, - onLockMove: 'uproar', - onAnySetStatus(status, pokemon) { - if (status.id === 'slp') { - if (pokemon === this.effectState.target) { - this.add('-fail', pokemon, 'slp', '[from] Uproar', '[msg]'); - } else { - this.add('-fail', pokemon, 'slp', '[from] Uproar'); - } - return null; - } - }, }, }, volttackle: { @@ -1916,9 +1492,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { watersport: { inherit: true, condition: { - onStart(pokemon) { - this.add('-start', pokemon, 'move: Water Sport'); - }, + inherit: true, + noCopy: false, onAnyBasePowerPriority: 3, onAnyBasePower(basePower, user, target, move) { if (move.type === 'Fire') { @@ -1981,17 +1556,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { yawn: { inherit: true, condition: { - noCopy: true, // doesn't get copied by Baton Pass - duration: 2, - onStart(target, source) { - this.add('-start', target, 'move: Yawn', `[of] ${source}`); - }, + inherit: true, onResidualOrder: 10, onResidualSubOrder: 19, - onEnd(target) { - this.add('-end', target, 'move: Yawn', '[silent]'); - target.trySetStatus('slp', this.effectState.source); - }, }, }, }; diff --git a/data/mods/gen5/moves.ts b/data/mods/gen5/moves.ts index 4328d70e1e..0ab479f34a 100644 --- a/data/mods/gen5/moves.ts +++ b/data/mods/gen5/moves.ts @@ -36,8 +36,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { autotomize: { inherit: true, volatileStatus: 'autotomize', - onHit(pokemon) { - }, + onHit() {}, condition: { noCopy: true, // doesn't get copied by Baton Pass onStart(pokemon) { @@ -78,6 +77,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 }, }, + bodyslam: { + inherit: true, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + }, bounce: { inherit: true, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1 }, @@ -192,6 +195,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { contact: 1, protect: 1, mirror: 1, punch: 1, metronome: 1 }, }, + dragonrush: { + inherit: true, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, + }, dreameater: { inherit: true, flags: { protect: 1, mirror: 1, metronome: 1 }, @@ -260,10 +267,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, basePower: 20, condition: { - duration: 2, - onStart() { - this.effectState.multiplier = 1; - }, + inherit: true, onRestart() { if (this.effectState.multiplier < 8) { this.effectState.multiplier <<= 1; @@ -363,6 +367,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { return success; }, }, + heatcrash: { + inherit: true, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + }, heatwave: { inherit: true, basePower: 100, @@ -494,13 +502,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { lightscreen: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasItem('lightclay')) { - return 8; - } - return 5; - }, + inherit: true, onAnyModifyDamage(damage, source, target, move) { if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Special') { if (!target.getMoveHitData(move).crit && !move.infiltrates) { @@ -510,14 +512,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } } }, - onSideStart(side) { - this.add('-sidestart', side, 'move: Light Screen'); - }, - onSideResidualOrder: 26, - onSideResidualSubOrder: 2, - onSideEnd(side) { - this.add('-sideend', side, 'move: Light Screen'); - }, }, }, lowsweep: { @@ -527,24 +521,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { magiccoat: { inherit: true, condition: { - duration: 1, - onStart(target, source, effect) { - this.add('-singleturn', target, 'move: Magic Coat'); - if (effect?.effectType === 'Move') { - this.effectState.pranksterBoosted = effect.pranksterBoosted; - } - }, - onTryHitPriority: 2, - onTryHit(target, source, move) { - if (target === source || move.hasBounced || !move.flags['reflectable'] || target.isSemiInvulnerable()) { - return; - } - const newMove = this.dex.getActiveMove(move.id); - newMove.hasBounced = true; - newMove.pranksterBoosted = this.effectState.pranksterBoosted; - this.actions.useMove(newMove, target, { target: source }); - return null; - }, + inherit: true, onAllyTryHitSide(target, source, move) { if (target.isAlly(source) || move.hasBounced || !move.flags['reflectable']) { return; @@ -587,12 +564,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, pp: 20, condition: { - noCopy: true, - onSourceModifyDamage(damage, source, target, move) { - if (['stomp', 'steamroller'].includes(move.id)) { - return this.chainModify(2); - } - }, + inherit: true, + onAccuracy() {}, }, }, moonlight: { @@ -689,11 +662,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { source.addVolatile('stall'); }, condition: { - duration: 1, - onSideStart(target, source) { - this.add('-singleturn', source, 'Quick Guard'); - }, - onTryHitPriority: 4, + inherit: true, onTryHit(target, source, effect) { // Quick Guard only blocks moves with a natural positive priority // (e.g. it doesn't block 0 priority moves boosted by Prankster) @@ -720,13 +689,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { reflect: { inherit: true, condition: { - duration: 5, - durationCallback(target, source, effect) { - if (source?.hasItem('lightclay')) { - return 8; - } - return 5; - }, + inherit: true, onAnyModifyDamage(damage, source, target, move) { if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Physical') { if (!target.getMoveHitData(move).crit && !move.infiltrates) { @@ -736,14 +699,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { } } }, - onSideStart(side) { - this.add('-sidestart', side, 'Reflect'); - }, - onSideResidualOrder: 26, - onSideResidualSubOrder: 1, - onSideEnd(side) { - this.add('-sideend', side, 'Reflect'); - }, }, }, relicsong: { @@ -881,12 +836,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { substitute: { inherit: true, condition: { - onStart(target) { - this.add('-start', target, 'Substitute'); - this.effectState.hp = Math.floor(target.maxhp / 4); - delete target.volatiles['partiallytrapped']; - }, - onTryPrimaryHitPriority: -1, + inherit: true, onTryPrimaryHit(target, source, move) { if (target === source || move.flags['bypasssub']) { return; @@ -918,9 +868,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.runEvent('AfterSubDamage', target, source, move, damage); return this.HIT_SUBSTITUTE; }, - onEnd(target) { - this.add('-end', target, 'Substitute'); - }, }, }, submission: { diff --git a/data/mods/gen6/moves.ts b/data/mods/gen6/moves.ts index 07852e3445..538a35bafc 100644 --- a/data/mods/gen6/moves.ts +++ b/data/mods/gen6/moves.ts @@ -34,48 +34,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { }, }, }, - encore: { - inherit: true, - condition: { - duration: 3, - onStart(target) { - const moveSlot = target.lastMove ? target.getMoveData(target.lastMove.id) : null; - if (!target.lastMove || target.lastMove.flags['failencore'] || !moveSlot || moveSlot.pp <= 0) { - // it failed - return false; - } - this.effectState.move = target.lastMove.id; - this.add('-start', target, 'Encore'); - if (!this.queue.willMove(target)) { - this.effectState.duration!++; - } - }, - onOverrideAction(pokemon, target, move) { - if (move.id !== this.effectState.move) return this.effectState.move; - }, - onResidualOrder: 16, - onResidual(target) { - const lockedMoveSlot = target.getMoveData(this.effectState.move); - if (lockedMoveSlot && lockedMoveSlot.pp <= 0) { - // Encore ends early if you run out of PP - target.removeVolatile('encore'); - } - }, - onEnd(target) { - this.add('-end', target, 'Encore'); - }, - onDisableMove(pokemon) { - if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) { - return; - } - for (const moveSlot of pokemon.moveSlots) { - if (moveSlot.id !== this.effectState.move) { - pokemon.disableMove(moveSlot.id); - } - } - }, - }, - }, fellstinger: { inherit: true, basePower: 30, @@ -87,6 +45,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, basePower: 80, }, + heavyslam: { + inherit: true, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + }, leechlife: { inherit: true, basePower: 20, @@ -96,29 +58,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { inherit: true, flags: { protect: 1, bypasssub: 1, noassist: 1, failcopycat: 1, failmefirst: 1, nosleeptalk: 1 }, }, - minimize: { - inherit: true, - condition: { - noCopy: true, - onSourceModifyDamage(damage, source, target, move) { - const boostedMoves = [ - 'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'phantomforce', 'heatcrash', 'shadowforce', - ]; - if (boostedMoves.includes(move.id)) { - return this.chainModify(2); - } - }, - onAccuracy(accuracy, target, source, move) { - const boostedMoves = [ - 'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'phantomforce', 'heatcrash', 'shadowforce', - ]; - if (boostedMoves.includes(move.id)) { - return true; - } - return accuracy; - }, - }, - }, metronome: { inherit: true, flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1 }, @@ -126,39 +65,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { mistyterrain: { inherit: true, condition: { - effectType: 'Terrain', - duration: 5, - durationCallback(source, effect) { - if (source?.hasItem('terrainextender')) { - return 8; - } - return 5; - }, - onSetStatus(status, target, source, effect) { - if (!target.isGrounded() || target.isSemiInvulnerable()) return; - if (effect && ((effect as Move).status || effect.id === 'yawn')) { - this.add('-activate', target, 'move: Misty Terrain'); - } - return false; - }, - onBasePower(basePower, attacker, defender, move) { - if (move.type === 'Dragon' && defender.isGrounded() && !defender.isSemiInvulnerable()) { - this.debug('misty terrain weaken'); - return this.chainModify(0.5); - } - }, - onFieldStart(field, source, effect) { - if (effect?.effectType === 'Ability') { - this.add('-fieldstart', 'move: Misty Terrain', `[from] ability: ${effect}`, `[of] ${source}`); - } else { - this.add('-fieldstart', 'move: Misty Terrain'); - } - }, - onFieldResidualOrder: 27, - onFieldResidualSubOrder: 7, - onFieldEnd() { - this.add('-fieldend', 'Misty Terrain'); - }, + inherit: true, + onTryAddVolatile() {}, }, }, mysticalfire: { @@ -179,28 +87,25 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { this.boost({ atk: -1, spa: -1 }, target, source); }, }, + phantomforce: { + inherit: true, + flags: { contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1, minimize: 1 }, + }, powder: { inherit: true, condition: { - duration: 1, - onStart(target) { - this.add('-singleturn', target, 'Powder'); - }, + inherit: true, onTryMovePriority: 1, - onTryMove(pokemon, target, move) { - if (move.type === 'Fire') { - this.add('-activate', pokemon, 'move: Powder'); - this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1)); - this.attrLastMove('[still]'); - return false; - } - }, }, }, rockblast: { inherit: true, flags: { protect: 1, mirror: 1, metronome: 1 }, }, + shadowforce: { + inherit: true, + flags: { contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1, minimize: 1 }, + }, sheercold: { inherit: true, ohko: true, @@ -263,11 +168,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { wideguard: { inherit: true, condition: { - duration: 1, - onSideStart(target, source) { - this.add('-singleturn', source, 'Wide Guard'); - }, - onTryHitPriority: 4, + inherit: true, onTryHit(target, source, effect) { // Wide Guard blocks damaging spread moves if ( diff --git a/data/mods/gen7/abilities.ts b/data/mods/gen7/abilities.ts index 83905da67e..66905bd080 100644 --- a/data/mods/gen7/abilities.ts +++ b/data/mods/gen7/abilities.ts @@ -72,14 +72,8 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa onTryBoost() {}, }, rattled: { - onDamagingHit(damage, target, source, move) { - if (['Dark', 'Bug', 'Ghost'].includes(move.type)) { - this.boost({ spe: 1 }); - } - }, - name: "Rattled", - rating: 1.5, - num: 155, + inherit: true, + onAfterBoost() {}, }, scrappy: { inherit: true, diff --git a/data/mods/gen7/moves.ts b/data/mods/gen7/moves.ts index 62c55d6c4a..0e5aae3fcc 100644 --- a/data/mods/gen7/moves.ts +++ b/data/mods/gen7/moves.ts @@ -182,47 +182,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { electricterrain: { inherit: true, condition: { - effectType: 'Terrain', - duration: 5, - durationCallback(source, effect) { - if (source?.hasItem('terrainextender')) { - return 8; - } - return 5; - }, - onSetStatus(status, target, source, effect) { - if (status.id === 'slp' && target.isGrounded() && !target.isSemiInvulnerable()) { - if (effect.id === 'yawn' || (effect.effectType === 'Move' && !effect.secondaries)) { - this.add('-activate', target, 'move: Electric Terrain'); - } - return false; - } - }, - onTryAddVolatile(status, target) { - if (!target.isGrounded() || target.isSemiInvulnerable()) return; - if (status.id === 'yawn') { - this.add('-activate', target, 'move: Electric Terrain'); - return null; - } - }, + inherit: true, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Electric' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) { this.debug('electric terrain boost'); return this.chainModify(1.5); } }, - onFieldStart(field, source, effect) { - if (effect && effect.effectType === 'Ability') { - this.add('-fieldstart', 'move: Electric Terrain', `[from] ability: ${effect}`, `[of] ${source}`); - } else { - this.add('-fieldstart', 'move: Electric Terrain'); - } - }, - onFieldResidualOrder: 27, - onFieldResidualSubOrder: 7, - onFieldEnd() { - this.add('-fieldend', 'move: Electric Terrain'); - }, }, }, embargo: { @@ -316,14 +282,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { grassyterrain: { inherit: true, condition: { - effectType: 'Terrain', - duration: 5, - durationCallback(source, effect) { - if (source?.hasItem('terrainextender')) { - return 8; - } - return 5; - }, + inherit: true, onBasePower(basePower, attacker, defender, move) { const weakenedMoves = ['earthquake', 'bulldoze', 'magnitude']; if (weakenedMoves.includes(move.id) && defender.isGrounded() && !defender.isSemiInvulnerable()) { @@ -335,27 +294,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { return this.chainModify(1.5); } }, - onFieldStart(field, source, effect) { - if (effect && effect.effectType === 'Ability') { - this.add('-fieldstart', 'move: Grassy Terrain', `[from] ability: ${effect}`, `[of] ${source}`); - } else { - this.add('-fieldstart', 'move: Grassy Terrain'); - } - }, - onResidualOrder: 5, - onResidualSubOrder: 2, - onResidual(pokemon) { - if (pokemon.isGrounded() && !pokemon.isSemiInvulnerable()) { - this.heal(pokemon.baseMaxhp / 16, pokemon, pokemon); - } else { - this.debug(`Pokemon semi-invuln or not grounded; Grassy Terrain skipped`); - } - }, - onFieldResidualOrder: 27, - onFieldResidualSubOrder: 7, - onFieldEnd() { - this.add('-fieldend', 'move: Grassy Terrain'); - }, }, }, guardianofalola: { @@ -558,11 +496,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { kingsshield: { inherit: true, condition: { - duration: 1, - onStart(target) { - this.add('-singleturn', target, 'Protect'); - }, - onTryHitPriority: 3, + inherit: true, onTryHit(target, source, move) { if (!move.flags['protect'] || move.category === 'Status') { if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true; @@ -780,48 +714,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { psychicterrain: { inherit: true, condition: { - effectType: 'Terrain', - duration: 5, - durationCallback(source, effect) { - if (source?.hasItem('terrainextender')) { - return 8; - } - return 5; - }, - onTryHitPriority: 4, - onTryHit(target, source, effect) { - if (effect && (effect.priority <= 0.1 || effect.target === 'self')) { - return; - } - if (target.isSemiInvulnerable() || target.isAlly(source)) return; - if (!target.isGrounded()) { - const baseMove = this.dex.moves.get(effect.id); - if (baseMove.priority > 0) { - this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground."); - } - return; - } - this.add('-activate', target, 'move: Psychic Terrain'); - return null; - }, + inherit: true, onBasePower(basePower, attacker, defender, move) { if (move.type === 'Psychic' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) { this.debug('psychic terrain boost'); return this.chainModify(1.5); } }, - onFieldStart(field, source, effect) { - if (effect && effect.effectType === 'Ability') { - this.add('-fieldstart', 'move: Psychic Terrain', `[from] ability: ${effect}`, `[of] ${source}`); - } else { - this.add('-fieldstart', 'move: Psychic Terrain'); - } - }, - onFieldResidualOrder: 27, - onFieldResidualSubOrder: 7, - onFieldEnd() { - this.add('-fieldend', 'move: Psychic Terrain'); - }, }, }, psychoboost: { diff --git a/data/mods/gen7letsgo/moves.ts b/data/mods/gen7letsgo/moves.ts index 31f669b0e1..f44ed9d801 100644 --- a/data/mods/gen7letsgo/moves.ts +++ b/data/mods/gen7letsgo/moves.ts @@ -19,6 +19,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { doubleironbash: { inherit: true, isNonstandard: null, + flags: { contact: 1, protect: 1, mirror: 1, punch: 1, minimize: 1 }, }, floatyfall: { inherit: true, diff --git a/data/mods/gen8/moves.ts b/data/mods/gen8/moves.ts index d71af7be7d..b7c3100367 100644 --- a/data/mods/gen8/moves.ts +++ b/data/mods/gen8/moves.ts @@ -59,19 +59,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { charge: { inherit: true, condition: { - onStart(pokemon, source, effect) { - this.add('-start', pokemon, 'Charge'); - }, - onRestart(pokemon, source, effect) { - this.add('-start', pokemon, 'Charge'); - }, - onBasePowerPriority: 9, - onBasePower(basePower, attacker, defender, move) { - if (move.type === 'Electric') { - this.debug('charge boost'); - return this.chainModify(2); - } - }, + inherit: true, onMoveAborted(pokemon, target, move) { if (move.id !== 'charge') { pokemon.removeVolatile('charge'); @@ -82,9 +70,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { pokemon.removeVolatile('charge'); } }, - onEnd(pokemon) { - this.add('-end', pokemon, 'Charge', '[silent]'); - }, }, }, chatter: { @@ -526,9 +511,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { stickyweb: { inherit: true, condition: { - onSideStart(side) { - this.add('-sidestart', side, 'move: Sticky Web'); - }, + inherit: true, onSwitchIn(pokemon) { if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return; this.add('-activate', pokemon, 'move: Sticky Web'); diff --git a/data/mods/gen9dlc1/abilities.ts b/data/mods/gen9dlc1/abilities.ts index 4f06cf465d..dd1bf0c857 100644 --- a/data/mods/gen9dlc1/abilities.ts +++ b/data/mods/gen9dlc1/abilities.ts @@ -19,91 +19,60 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa } }, condition: { - noCopy: true, - onStart(pokemon, source, effect) { - if (effect?.name === 'Booster Energy') { - this.effectState.fromBooster = true; - this.add('-activate', pokemon, 'ability: Protosynthesis', '[fromitem]'); - } else { - this.add('-activate', pokemon, 'ability: Protosynthesis'); - } - this.effectState.bestStat = pokemon.getBestStat(false, true); - this.add('-start', pokemon, 'protosynthesis' + this.effectState.bestStat); - }, - onModifyAtkPriority: 5, - onModifyAtk(atk, pokemon) { + inherit: true, + onModifyAtk() { if (this.effectState.bestStat !== 'atk') return; this.debug('Protosynthesis atk boost'); return this.chainModify([5325, 4096]); }, - onModifyDefPriority: 6, - onModifyDef(def, pokemon) { + onModifyDef() { if (this.effectState.bestStat !== 'def') return; this.debug('Protosynthesis def boost'); return this.chainModify([5325, 4096]); }, - onModifySpAPriority: 5, - onModifySpA(spa, pokemon) { + onModifySpA() { if (this.effectState.bestStat !== 'spa') return; this.debug('Protosynthesis spa boost'); return this.chainModify([5325, 4096]); }, - onModifySpDPriority: 6, - onModifySpD(spd, pokemon) { + onModifySpD() { if (this.effectState.bestStat !== 'spd') return; this.debug('Protosynthesis spd boost'); return this.chainModify([5325, 4096]); }, - onModifySpe(spe, pokemon) { + onModifySpe() { if (this.effectState.bestStat !== 'spe') return; this.debug('Protosynthesis spe boost'); return this.chainModify(1.5); }, - onEnd(pokemon) { - this.add('-end', pokemon, 'Protosynthesis'); - }, }, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1, cantsuppress: 1 }, }, quarkdrive: { inherit: true, condition: { - noCopy: true, - onStart(pokemon, source, effect) { - if (effect?.name === 'Booster Energy') { - this.effectState.fromBooster = true; - this.add('-activate', pokemon, 'ability: Quark Drive', '[fromitem]'); - } else { - this.add('-activate', pokemon, 'ability: Quark Drive'); - } - this.effectState.bestStat = pokemon.getBestStat(false, true); - this.add('-start', pokemon, 'quarkdrive' + this.effectState.bestStat); - }, - onModifyAtkPriority: 5, - onModifyAtk(atk, pokemon) { + inherit: true, + onModifyAtk() { if (this.effectState.bestStat !== 'atk') return; this.debug('Quark Drive atk boost'); return this.chainModify([5325, 4096]); }, - onModifyDefPriority: 6, - onModifyDef(def, pokemon) { + onModifyDef() { if (this.effectState.bestStat !== 'def') return; this.debug('Quark Drive def boost'); return this.chainModify([5325, 4096]); }, - onModifySpAPriority: 5, - onModifySpA(spa, pokemon) { + onModifySpA() { if (this.effectState.bestStat !== 'spa') return; this.debug('Quark Drive spa boost'); return this.chainModify([5325, 4096]); }, - onModifySpDPriority: 6, - onModifySpD(spd, pokemon) { + onModifySpD() { if (this.effectState.bestStat !== 'spd') return; this.debug('Quark Drive spd boost'); return this.chainModify([5325, 4096]); }, - onModifySpe(spe, pokemon) { + onModifySpe() { if (this.effectState.bestStat !== 'spe') return; this.debug('Quark Drive spe boost'); return this.chainModify(1.5); diff --git a/data/moves.ts b/data/moves.ts index 8004f48dfb..1c23fa5522 100644 --- a/data/moves.ts +++ b/data/moves.ts @@ -1644,7 +1644,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Body Slam", pp: 15, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, minimize: 1 }, secondary: { chance: 30, status: 'par', @@ -4349,7 +4349,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Dragon Rush", pp: 10, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 }, secondary: { chance: 20, volatileStatus: 'flinch', @@ -6149,7 +6149,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { category: "Physical", name: "Flying Press", pp: 10, - flags: { contact: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, nonsky: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, nonsky: 1, metronome: 1, minimize: 1 }, onEffectiveness(typeMod, target, type, move) { return typeMod + this.dex.getEffectiveness('Flying', type); }, @@ -8608,7 +8608,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { return false; } }, - onModifyMove(move, pokemon, target) { + onModifyMove(move, pokemon) { if (move.flags['heal'] && !move.isZ && !move.isMax) { this.add('cant', pokemon, 'move: Heal Block', move); return false; @@ -8801,7 +8801,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Heat Crash", pp: 10, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, minimize: 1 }, onTryHit(target, pokemon, move) { if (target.volatiles['dynamax']) { this.add('-fail', pokemon, 'Dynamax'); @@ -8859,7 +8859,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Heavy Slam", pp: 10, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, minimize: 1 }, onTryHit(target, pokemon, move) { if (target.volatiles['dynamax']) { this.add('-fail', pokemon, 'Dynamax'); @@ -11364,7 +11364,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Malicious Moonsault", pp: 1, priority: 0, - flags: { contact: 1 }, + flags: { contact: 1, minimize: 1 }, isZ: "inciniumz", secondary: null, target: "normal", @@ -12365,18 +12365,12 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { noCopy: true, onRestart: () => null, onSourceModifyDamage(damage, source, target, move) { - const boostedMoves = [ - 'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'heatcrash', 'heavyslam', 'maliciousmoonsault', 'supercellslam', - ]; - if (boostedMoves.includes(move.id)) { + if (move.flags['minimize']) { return this.chainModify(2); } }, onAccuracy(accuracy, target, source, move) { - const boostedMoves = [ - 'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'heatcrash', 'heavyslam', 'maliciousmoonsault', 'supercellslam', - ]; - if (boostedMoves.includes(move.id)) { + if (move.flags['minimize']) { return true; } return accuracy; @@ -16174,7 +16168,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return; if (target !== source) { this.debug('interrupting setStatus'); - if (effect.name === 'Synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) { + if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) { this.add('-activate', target, 'move: Safeguard'); } return null; @@ -18520,7 +18514,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Steamroller", pp: 20, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 }, secondary: { chance: 30, volatileStatus: 'flinch', @@ -18702,7 +18696,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Stomp", pp: 20, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, minimize: 1 }, secondary: { chance: 30, volatileStatus: 'flinch', @@ -19131,7 +19125,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { name: "Supercell Slam", pp: 15, priority: 0, - flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 }, + flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 }, hasCrashDamage: true, onMoveFail(target, source, move) { this.damage(source.baseMaxhp / 2, source, source, this.dex.conditions.get('Supercell Slam')); diff --git a/sim/dex-abilities.ts b/sim/dex-abilities.ts index c3af1b2ccf..0b16617967 100644 --- a/sim/dex-abilities.ts +++ b/sim/dex-abilities.ts @@ -1,4 +1,4 @@ -import type { PokemonEventMethods, ConditionData } from './dex-conditions'; +import type { PokemonEventMethods, ConditionData, ModdedConditionData } from './dex-conditions'; import { assignMissingFields, BasicEffect, toID } from './dex-data'; import { Utils } from '../lib/utils'; @@ -24,7 +24,10 @@ export interface AbilityData extends Partial, AbilityEventMethods, Poke name: string; } -export type ModdedAbilityData = AbilityData | Partial & { inherit: true }; +export type ModdedAbilityData = AbilityData | Partial & { + inherit: true, + condition?: ModdedConditionData, +}; export interface AbilityDataTable { [abilityid: IDEntry]: AbilityData } export interface ModdedAbilityDataTable { [abilityid: IDEntry]: ModdedAbilityData } diff --git a/sim/dex-items.ts b/sim/dex-items.ts index d8558177e7..137b27cd42 100644 --- a/sim/dex-items.ts +++ b/sim/dex-items.ts @@ -1,4 +1,4 @@ -import type { PokemonEventMethods, ConditionData } from './dex-conditions'; +import type { PokemonEventMethods, ConditionData, ModdedConditionData } from './dex-conditions'; import { assignMissingFields, BasicEffect, toID } from './dex-data'; import { Utils } from '../lib/utils'; @@ -16,6 +16,7 @@ export interface ItemData extends Partial, PokemonEventMethods { export type ModdedItemData = ItemData | Partial> & { inherit: true, onCustap?: (this: Battle, pokemon: Pokemon) => void, + condition?: ModdedConditionData, }; export interface ItemDataTable { [itemid: IDEntry]: ItemData } diff --git a/sim/dex-moves.ts b/sim/dex-moves.ts index 5b56490430..3fd3be5763 100644 --- a/sim/dex-moves.ts +++ b/sim/dex-moves.ts @@ -1,5 +1,5 @@ import { Utils } from '../lib/utils'; -import type { ConditionData } from './dex-conditions'; +import type { ConditionData, ModdedConditionData } from './dex-conditions'; import { assignMissingFields, BasicEffect, toID } from './dex-data'; /** @@ -45,6 +45,7 @@ interface MoveFlags { gravity?: 1; // Prevented from being executed or selected during Gravity's effect. heal?: 1; // Prevented from being executed or selected during Heal Block's effect. metronome?: 1; // Can be selected by Metronome. + minimize?: 1; // Deals double damage if the user is minimized. mirror?: 1; // Can be copied by Mirror Move. mustpressure?: 1; // Additional PP is deducted due to Pressure when it ordinarily would not. noassist?: 1; // Cannot be selected by Assist. @@ -278,6 +279,7 @@ export type ModdedMoveData = MoveData | Partial> & { bodyofwaterBoosted?: boolean, longWhipBoost?: boolean, gen?: number, + condition?: ModdedConditionData, }; export interface MoveDataTable { [moveid: IDEntry]: MoveData } diff --git a/sim/dex.ts b/sim/dex.ts index 50a0cc476d..1ca6287696 100644 --- a/sim/dex.ts +++ b/sim/dex.ts @@ -651,6 +651,15 @@ export class ModdedDex { // instead of overwriting entirely delete childTypedData[entryId].inherit; + // {inherit: true} can also be used to inherit parts of conditions + if (childTypedData[entryId].condition?.inherit) { + delete childTypedData[entryId].condition.inherit; + childTypedData[entryId].condition = { + ...parentTypedData[entryId].condition, + ...childTypedData[entryId].condition, + }; + } + // Merge parent and child's entry, with child overwriting parent. childTypedData[entryId] = { ...parentTypedData[entryId], ...childTypedData[entryId] }; }