Spaces:
Paused
Paused
| export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = { | |
| brn: { | |
| name: 'brn', | |
| effectType: 'Status', | |
| onStart(target) { | |
| this.add('-status', target, 'brn'); | |
| }, | |
| onAfterMoveSelfPriority: 3, | |
| onAfterMoveSelf(pokemon) { | |
| residualdmg(this, pokemon); | |
| }, | |
| onAfterSwitchInSelf(pokemon) { | |
| residualdmg(this, pokemon); | |
| }, | |
| }, | |
| par: { | |
| name: 'par', | |
| inherit: true, | |
| onBeforeMovePriority: 2, | |
| onBeforeMove(pokemon) { | |
| if (this.randomChance(1, 4)) { | |
| this.add('cant', pokemon, 'par'); | |
| return false; | |
| } | |
| }, | |
| }, | |
| slp: { | |
| name: 'slp', | |
| effectType: 'Status', | |
| onStart(target, source, sourceEffect) { | |
| if (sourceEffect && sourceEffect.effectType === 'Move') { | |
| this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`); | |
| } else { | |
| this.add('-status', target, 'slp'); | |
| } | |
| // 1-6 turns | |
| this.effectState.time = this.random(2, 8); | |
| if (target.removeVolatile('nightmare')) { | |
| this.add('-end', target, 'Nightmare', '[silent]'); | |
| } | |
| }, | |
| onBeforeMovePriority: 10, | |
| onBeforeMove(pokemon, target, move) { | |
| pokemon.statusState.time--; | |
| if (pokemon.statusState.time <= 0) { | |
| pokemon.cureStatus(); | |
| return; | |
| } | |
| this.add('cant', pokemon, 'slp'); | |
| if (move.sleepUsable) { | |
| return; | |
| } | |
| return false; | |
| }, | |
| }, | |
| frz: { | |
| name: 'frz', | |
| inherit: true, | |
| onBeforeMove(pokemon, target, move) { | |
| if (move.flags['defrost']) return; | |
| this.add('cant', pokemon, 'frz'); | |
| return false; | |
| }, | |
| onModifyMove() {}, | |
| onDamagingHit() {}, | |
| onAfterMoveSecondary(target, source, move) { | |
| if ((move.secondary && move.secondary.status === 'brn') || move.statusRoll === 'brn') { | |
| target.cureStatus(); | |
| } | |
| }, | |
| onAfterMoveSecondarySelf(pokemon, target, move) { | |
| if (move.flags['defrost']) pokemon.cureStatus(); | |
| }, | |
| onResidualOrder: 7, | |
| onResidual(pokemon) { | |
| if (this.randomChance(25, 256)) pokemon.cureStatus(); | |
| }, | |
| }, | |
| psn: { | |
| name: 'psn', | |
| effectType: 'Status', | |
| onStart(target) { | |
| this.add('-status', target, 'psn'); | |
| }, | |
| onAfterMoveSelfPriority: 3, | |
| onAfterMoveSelf(pokemon) { | |
| residualdmg(this, pokemon); | |
| }, | |
| onAfterSwitchInSelf(pokemon) { | |
| residualdmg(this, pokemon); | |
| }, | |
| }, | |
| tox: { | |
| name: 'tox', | |
| effectType: 'Status', | |
| onStart(target) { | |
| this.add('-status', target, 'tox'); | |
| if (!target.volatiles['residualdmg']) target.addVolatile('residualdmg'); | |
| target.volatiles['residualdmg'].counter = 0; | |
| }, | |
| onAfterMoveSelfPriority: 3, | |
| onAfterMoveSelf(pokemon) { | |
| const damage = this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * pokemon.volatiles['residualdmg'].counter; | |
| this.damage(damage, pokemon, pokemon); | |
| }, | |
| onSwitchIn(pokemon) { | |
| // Regular poison status and damage after a switchout -> switchin. | |
| pokemon.status = 'psn' as ID; | |
| this.add('-status', pokemon, 'psn', '[silent]'); | |
| }, | |
| onAfterSwitchInSelf(pokemon) { | |
| this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); | |
| }, | |
| }, | |
| confusion: { | |
| inherit: true, | |
| onStart(target, source, sourceEffect) { | |
| if (sourceEffect && sourceEffect.id === 'lockedmove') { | |
| this.add('-start', target, 'confusion', '[silent]'); | |
| } else { | |
| this.add('-start', target, 'confusion'); | |
| } | |
| if (sourceEffect && sourceEffect.id === 'berserkgene') { | |
| this.effectState.time = 256; | |
| } else { | |
| this.effectState.time = this.random(2, 6); | |
| } | |
| }, | |
| onBeforeMove(pokemon, target, move) { | |
| pokemon.volatiles['confusion'].time--; | |
| if (!pokemon.volatiles['confusion'].time) { | |
| pokemon.removeVolatile('confusion'); | |
| return; | |
| } | |
| this.add('-activate', pokemon, 'confusion'); | |
| if (this.randomChance(1, 2)) { | |
| return; | |
| } | |
| move = { | |
| basePower: 40, | |
| type: '???', | |
| baseMoveType: move.type, | |
| category: 'Physical', | |
| willCrit: false, | |
| isConfusionSelfHit: true, | |
| noDamageVariance: true, | |
| flags: {}, | |
| selfdestruct: move.selfdestruct, | |
| } as unknown as ActiveMove; | |
| const damage = this.actions.getDamage(pokemon, pokemon, move); | |
| if (typeof damage !== 'number') throw new Error("Confusion damage not dealt"); | |
| this.directDamage(damage); | |
| return false; | |
| }, | |
| }, | |
| partiallytrapped: { | |
| inherit: true, | |
| durationCallback(target, source) { | |
| return this.random(3, 6); | |
| }, | |
| onResidualOrder: 3, | |
| onResidualSubOrder: 1, | |
| }, | |
| lockedmove: { | |
| name: 'lockedmove', | |
| // Outrage, Thrash, Petal Dance... | |
| durationCallback() { | |
| return this.random(2, 4); | |
| }, | |
| onResidual(target) { | |
| if ((target.lastMove && target.lastMove.id === 'struggle') || target.status === 'slp') { | |
| // don't lock, and bypass confusion for calming | |
| delete target.volatiles['lockedmove']; | |
| } | |
| }, | |
| onStart(target, source, effect) { | |
| this.effectState.move = effect.id; | |
| }, | |
| onEnd(target) { | |
| // Confusion begins even if already confused | |
| delete target.volatiles['confusion']; | |
| if (!target.side.getSideCondition('safeguard')) target.addVolatile('confusion'); | |
| }, | |
| onLockMove(pokemon) { | |
| return this.effectState.move; | |
| }, | |
| onMoveAborted(pokemon) { | |
| delete pokemon.volatiles['lockedmove']; | |
| }, | |
| onBeforeTurn(pokemon) { | |
| const move = this.dex.moves.get(this.effectState.move); | |
| if (move.id) { | |
| this.debug('Forcing into ' + move.id); | |
| this.queue.changeAction(pokemon, { choice: 'move', moveid: move.id }); | |
| } | |
| }, | |
| }, | |
| futuremove: { | |
| inherit: true, | |
| onResidualOrder: 1, | |
| }, | |
| raindance: { | |
| inherit: true, | |
| onFieldResidualOrder: 2, | |
| }, | |
| sunnyday: { | |
| inherit: true, | |
| onFieldResidualOrder: 2, | |
| }, | |
| sandstorm: { | |
| inherit: true, | |
| onFieldResidualOrder: 2, | |
| onWeather(target) { | |
| this.damage(target.baseMaxhp / 8); | |
| }, | |
| }, | |
| stall: { | |
| name: 'stall', | |
| duration: 2, | |
| onStart() { | |
| this.effectState.counter = 127; | |
| }, | |
| onStallMove() { | |
| const counter = Math.floor(this.effectState.counter) || 127; | |
| this.debug(`Success chance: ${Math.round(counter * 1000 / 255) / 10}% (${counter}/255)`); | |
| return this.randomChance(counter, 255); | |
| }, | |
| onRestart() { | |
| this.effectState.counter /= 2; | |
| this.effectState.duration = 2; | |
| }, | |
| }, | |
| residualdmg: { | |
| name: 'residualdmg', | |
| onStart(target) { | |
| target.volatiles['residualdmg'].counter = 0; | |
| }, | |
| onAfterMoveSelfPriority: 100, | |
| onAfterMoveSelf(pokemon) { | |
| if (['brn', 'psn', 'tox'].includes(pokemon.status)) pokemon.volatiles['residualdmg'].counter++; | |
| }, | |
| onAfterSwitchInSelf(pokemon) { | |
| if (['brn', 'psn', 'tox'].includes(pokemon.status)) pokemon.volatiles['residualdmg'].counter++; | |
| }, | |
| }, | |
| }; | |
| function residualdmg(battle: Battle, pokemon: Pokemon) { | |
| if (pokemon.volatiles['residualdmg']) { | |
| const residualDmg = battle.clampIntRange( | |
| Math.floor(pokemon.maxhp / 16) * pokemon.volatiles['residualdmg'].counter, 1 | |
| ); | |
| battle.damage(residualDmg, pokemon); | |
| battle.hint("In Gen 2, Toxic's counter is retained through Baton Pass/Heal Bell and applies to PSN/BRN.", true); | |
| } else { | |
| battle.damage(battle.clampIntRange(Math.floor(pokemon.maxhp / 8), 1), pokemon); | |
| } | |
| } | |