diff --git a/src/data/move.ts b/src/data/move.ts index dab737f7208..13d4c701525 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -77,6 +77,7 @@ export enum MoveFlags { WIND_MOVE = 1 << 14, TRIAGE_MOVE = 1 << 15, IGNORE_ABILITIES = 1 << 16, + SCREEN_MOVE = 1 << 17, } type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean; @@ -312,6 +313,11 @@ export default class Move implements Localizable { return this; } + screenMove(screenMove?: boolean): this { + this.setFlag(MoveFlags.SCREEN_MOVE, screenMove); + return this; + } + ignoresAbilities(ignoresAbilities?: boolean): this { this.setFlag(MoveFlags.IGNORE_ABILITIES, ignoresAbilities); return this; @@ -3037,7 +3043,7 @@ export class AddArenaTagAttr extends MoveEffectAttr { const turnCountHolder = new Utils.IntegerHolder(this.turnCount); - if ([ArenaTagType.REFLECT, ArenaTagType.LIGHT_SCREEN, ArenaTagType.AURORA_VEIL].includes(this.tagType)) + if (move.hasFlag(MoveFlags.SCREEN_MOVE)) user.scene.applyModifiers(ExtendScreenModifier, user.isPlayer(), user, turnCountHolder); if (move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) { @@ -4406,6 +4412,7 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.DEF, 2, true), new StatusMove(Moves.LIGHT_SCREEN, Type.PSYCHIC, -1, 30, -1, 0, 1) .attr(AddArenaTagAttr, ArenaTagType.LIGHT_SCREEN, 5, true) + .screenMove() .target(MoveTarget.USER_SIDE), new StatusMove(Moves.HAZE, Type.ICE, -1, 30, -1, 0, 1) .target(MoveTarget.BOTH_SIDES) @@ -6033,6 +6040,7 @@ export function initMoves() { new StatusMove(Moves.AURORA_VEIL, Type.ICE, -1, 20, -1, 0, 7) .condition((user, target, move) => (user.scene.arena.weather?.weatherType === WeatherType.HAIL || user.scene.arena.weather?.weatherType === WeatherType.SNOW) && !user.scene.arena.weather?.isEffectSuppressed(user.scene)) .attr(AddArenaTagAttr, ArenaTagType.AURORA_VEIL, 5, true) + .screenMove() .target(MoveTarget.USER_SIDE), /* Unused */ new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) @@ -6157,8 +6165,10 @@ export function initMoves() { new AttackMove(Moves.SIZZLY_SLIDE, Type.FIRE, MoveCategory.PHYSICAL, 60, 100, 20, 100, 0, 7) .attr(StatusEffectAttr, StatusEffect.BURN), new AttackMove(Moves.GLITZY_GLOW, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 95, 15, -1, 0, 7) + .screenMove() .attr(AddArenaTagAttr, ArenaTagType.LIGHT_SCREEN, 5, false, true), new AttackMove(Moves.BADDY_BAD, Type.DARK, MoveCategory.SPECIAL, 80, 95, 15, -1, 0, 7) + .screenMove() .attr(AddArenaTagAttr, ArenaTagType.REFLECT, 5, false, true), new AttackMove(Moves.SAPPY_SEED, Type.GRASS, MoveCategory.PHYSICAL, 100, 90, 10, 100, 0, 7) .attr(AddBattlerTagAttr, BattlerTagType.SEEDED), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8afff1b2724..6b1f97dd194 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant'; import { variantData } from '#app/data/variant'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import { Moves } from "../data/enums/moves"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, IgnoreWeatherTypeDebuffAttr } from "../data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, IgnoreWeatherTypeDebuffAttr, MoveFlags } from "../data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species'; import * as Utils from '../utils'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; @@ -1705,6 +1705,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.summonData.moveQueue; } + /** Checks if a pokemon has a move with a certain flag in its moveset. + * @param {MoveFlags} moveFlag Move flag to check for + */ + hasMoveWithFlag(moveFlag: MoveFlags): boolean { + for (let move of this.moveset) { + if (move.getMove().hasFlag(moveFlag)) { + return true; + } + } + return false; + } + changeForm(formChange: SpeciesFormChange): Promise { return new Promise(resolve => { this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index cb2f88b07b5..004539ce8f7 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1,5 +1,5 @@ import * as Modifiers from './modifier'; -import { AttackMove, allMoves } from '../data/move'; +import { AttackMove, MoveFlags, allMoves } from '../data/move'; import { Moves } from "../data/enums/moves"; import { PokeballType, getPokeballCatchMultiplier, getPokeballName } from '../data/pokeball'; import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from '../field/pokemon'; @@ -1074,6 +1074,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.EXP_SHARE, 12), new WeightedModifierType(modifierTypes.EXP_BALANCE, 4), new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(party[0].scene.currentBattle.waveIndex / 50) * 2, 1), 4), 4), + new WeightedModifierType(modifierTypes.LIGHT_CLAY, (party: Pokemon[]) => party.filter(p => p.hasMoveWithFlag(MoveFlags.SCREEN_MOVE)).length > 1 ? 10 : 0), new WeightedModifierType(modifierTypes.VOUCHER, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily ? Math.max(3 - rerollCount, 0) : 0, 3), ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), [ModifierTier.ROGUE]: [