Merge branch 'main' of github.com:Greenlamp2/pokerogue into feat/inputs_management_rework

 Conflicts:
	src/ui/summary-ui-handler.ts
pull/429/head
Greenlamp 2024-05-05 01:02:29 +02:00
commit 8e3bf1ce15
22 changed files with 274 additions and 89 deletions

View File

@ -19,7 +19,7 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
### ❔ FAQ ### ❔ FAQ
**How do I test a new _______?** **How do I test a new _______?**
- In the `battle-scene.ts` file there are overrides for most values you'll need to change for testing - In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing
## 🪧 To Do ## 🪧 To Do

BIN
public/images/ui/candy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
@ -827,13 +827,16 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
} }
export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
constructor() { private ability: Abilities;
constructor(ability: Abilities) {
super(); super();
this.ability = ability;
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) {
attacker.summonData.ability = pokemon.getAbility().id; attacker.summonData.ability = this.ability;
return true; return true;
} }
@ -1785,6 +1788,53 @@ function getAnticipationCondition(): AbAttrCondition {
}; };
} }
export class ForewarnAbAttr extends PostSummonAbAttr {
constructor() {
super(true);
}
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let maxPowerSeen = 0;
let maxMove = "";
let movePower = 0;
for (let opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) {
if (move.getMove() instanceof StatusMove) {
movePower = 1;
} else if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) {
movePower = 150;
} else if (move.getMove().id === Moves.COUNTER || move.getMove().id === Moves.MIRROR_COAT || move.getMove().id === Moves.METAL_BURST) {
movePower = 120;
} else if (move.getMove().power === -1) {
movePower = 80;
} else {
movePower = move.getMove().power;
}
if (movePower > maxPowerSeen) {
maxPowerSeen = movePower;
maxMove = move.getName();
}
}
}
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " was forewarned about " + maxMove + "!"));
return true;
}
}
export class FriskAbAttr extends PostSummonAbAttr {
constructor() {
super(true);
}
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
for (let opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "\'s " + opponent.getAbility().name + "!"));
}
return true;
}
}
export class PostWeatherChangeAbAttr extends AbAttr { export class PostWeatherChangeAbAttr extends AbAttr {
applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean { applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean {
return false; return false;
@ -1935,13 +1985,19 @@ export class MoodyAbAttr extends PostTurnAbAttr {
} }
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
// TODO: Edge case of not choosing to buff or debuff a stat that's already maxed
let selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD]; let selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD];
let increaseStat = selectableStats[Utils.randInt(selectableStats.length)]; let increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6);
selectableStats = selectableStats.filter(s => s !== increaseStat); let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6);
let decreaseStat = selectableStats[Utils.randInt(selectableStats.length)];
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2)); if (increaseStatArray.length > 0) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1)); let increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)];
decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2));
}
if (decreaseStatArray.length > 0) {
let decreaseStat = selectableStats[Utils.randInt(selectableStats.length)];
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1));
}
return true; return true;
} }
} }
@ -2854,7 +2910,7 @@ export function initAbilities() {
new Ability(Abilities.ANTICIPATION, 4) new Ability(Abilities.ANTICIPATION, 4)
.conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' shuddered!')), .conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' shuddered!')),
new Ability(Abilities.FOREWARN, 4) new Ability(Abilities.FOREWARN, 4)
.unimplemented(), .attr(ForewarnAbAttr),
new Ability(Abilities.UNAWARE, 4) new Ability(Abilities.UNAWARE, 4)
.attr(IgnoreOpponentStatChangesAbAttr) .attr(IgnoreOpponentStatChangesAbAttr)
.ignorable(), .ignorable(),
@ -2883,7 +2939,7 @@ export function initAbilities() {
new Ability(Abilities.HONEY_GATHER, 4) new Ability(Abilities.HONEY_GATHER, 4)
.unimplemented(), .unimplemented(),
new Ability(Abilities.FRISK, 4) new Ability(Abilities.FRISK, 4)
.unimplemented(), .attr(FriskAbAttr),
new Ability(Abilities.RECKLESS, 4) new Ability(Abilities.RECKLESS, 4)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.getAttrs(RecoilAttr).length && move.id !== Moves.STRUGGLE, 1.2), .attr(MovePowerBoostAbAttr, (user, target, move) => move.getAttrs(RecoilAttr).length && move.id !== Moves.STRUGGLE, 1.2),
new Ability(Abilities.MULTITYPE, 4) new Ability(Abilities.MULTITYPE, 4)
@ -2976,7 +3032,7 @@ export function initAbilities() {
new Ability(Abilities.INFILTRATOR, 5) new Ability(Abilities.INFILTRATOR, 5)
.unimplemented(), .unimplemented(),
new Ability(Abilities.MUMMY, 5) new Ability(Abilities.MUMMY, 5)
.attr(PostDefendAbilityGiveAbAttr) .attr(PostDefendAbilityGiveAbAttr, Abilities.MUMMY)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.MOXIE, 5) new Ability(Abilities.MOXIE, 5)
.attr(PostVictoryStatChangeAbAttr, BattleStat.ATK, 1), .attr(PostVictoryStatChangeAbAttr, BattleStat.ATK, 1),
@ -3309,6 +3365,7 @@ export function initAbilities() {
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr) .attr(NoTransformAbilityAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, '\'s Neutralizing Gas filled the area!'))
.partial(), .partial(),
new Ability(Abilities.PASTEL_VEIL, 8) new Ability(Abilities.PASTEL_VEIL, 8)
.attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
@ -3347,7 +3404,7 @@ export function initAbilities() {
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr), .attr(UnsuppressableAbilityAbAttr),
new Ability(Abilities.LINGERING_AROMA, 9) new Ability(Abilities.LINGERING_AROMA, 9)
.attr(PostDefendAbilityGiveAbAttr) .attr(PostDefendAbilityGiveAbAttr, Abilities.LINGERING_AROMA)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.SEED_SOWER, 9) new Ability(Abilities.SEED_SOWER, 9)
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY), .attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY),

View File

@ -984,6 +984,19 @@ export class HideSpriteTag extends BattlerTag {
} }
} }
export class TypeImmuneTag extends BattlerTag {
public immuneType: Type;
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
}
}
export class MagnetRisenTag extends TypeImmuneTag {
constructor(tagType: BattlerTagType, sourceMove: Moves) {
super(tagType, sourceMove, Type.GROUND, 5);
}
}
export class TypeBoostTag extends BattlerTag { export class TypeBoostTag extends BattlerTag {
public boostedType: Type; public boostedType: Type;
public boostValue: number; public boostValue: number;
@ -1211,6 +1224,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new CursedTag(sourceId); return new CursedTag(sourceId);
case BattlerTagType.CHARGED: case BattlerTagType.CHARGED:
return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true);
case BattlerTagType.MAGNET_RISEN:
return new MagnetRisenTag(tagType, sourceMove);
case BattlerTagType.NONE: case BattlerTagType.NONE:
default: default:
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);

View File

@ -4391,8 +4391,8 @@ export const biomeTrainerPools: BiomeTrainerPools = {
] ]
], ],
[ Species.SHAYMIN, Type.GRASS, -1, [ [ Species.SHAYMIN, Type.GRASS, -1, [
[ Biome.MEADOW, BiomePoolTier.BOSS_ULTRA_RARE ] [ Biome.MEADOW, BiomePoolTier.BOSS_ULTRA_RARE ]
] ]
], ],
[ Species.ARCEUS, Type.NORMAL, -1, [ ] [ Species.ARCEUS, Type.NORMAL, -1, [ ]
], ],

View File

@ -77,8 +77,6 @@ export function getEggHatchWavesMessage(hatchWaves: integer): string {
} }
export function getEggGachaTypeDescriptor(scene: BattleScene, egg: Egg): string { export function getEggGachaTypeDescriptor(scene: BattleScene, egg: Egg): string {
if (egg.isManaphyEgg())
return '';
switch (egg.gachaType) { switch (egg.gachaType) {
case GachaType.LEGENDARY: case GachaType.LEGENDARY:
return `Legendary Rate Up (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, egg.timestamp)).getName()})`; return `Legendary Rate Up (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, egg.timestamp)).getName()})`;

View File

@ -54,5 +54,6 @@ export enum BattlerTagType {
SALT_CURED = "SALT_CURED", SALT_CURED = "SALT_CURED",
CURSED = "CURSED", CURSED = "CURSED",
CHARGED = "CHARGED", CHARGED = "CHARGED",
GROUNDED = "GROUNDED" GROUNDED = "GROUNDED",
MAGNET_RISEN = "MAGNET_RISEN"
} }

View File

@ -1496,6 +1496,23 @@ export class StatChangeAttr extends MoveEffectAttr {
} }
} }
export class AcupressureStatChangeAttr extends MoveEffectAttr {
constructor() {
super();
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise<boolean> {
let randStats = [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD, BattleStat.ACC, BattleStat.EVA ];
randStats = randStats.filter(s => target.summonData.battleStats[s] < 6);
if (randStats.length > 0) {
let boostStat = [randStats[Utils.randInt(randStats.length)]];
user.scene.unshiftPhase(new StatChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2));
return true;
}
return false;
}
}
export class GrowthStatChangeAttr extends StatChangeAttr { export class GrowthStatChangeAttr extends StatChangeAttr {
constructor() { constructor() {
super([ BattleStat.ATK, BattleStat.SPATK ], 1, true); super([ BattleStat.ATK, BattleStat.SPATK ], 1, true);
@ -3690,6 +3707,22 @@ export class LastResortAttr extends MoveAttr {
} }
} }
export class VariableTargetAttr extends MoveAttr {
private targetChangeFunc: (user: Pokemon, target: Pokemon, move: Move) => number;
constructor(targetChange: (user: Pokemon, target: Pokemon, move: Move) => number) {
super();
this.targetChangeFunc = targetChange;
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const targetVal = args[0] as Utils.NumberHolder;
targetVal.value = this.targetChangeFunc(user, target, move);
return true;
}
}
const failOnGravityCondition: MoveConditionFunc = (user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY); const failOnGravityCondition: MoveConditionFunc = (user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY);
const failOnBossCondition: MoveConditionFunc = (user, target, move) => !target.isBossImmune(); const failOnBossCondition: MoveConditionFunc = (user, target, move) => !target.isBossImmune();
@ -3770,7 +3803,10 @@ export type MoveTargetSet = {
} }
export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet { export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet {
const moveTarget = move ? allMoves[move].moveTarget : move === undefined ? MoveTarget.NEAR_ENEMY : []; const variableTarget = new Utils.NumberHolder(0);
user.getOpponents().forEach(p => applyMoveAttrs(VariableTargetAttr, user, p, allMoves[move], variableTarget));
const moveTarget = allMoves[move].getAttrs(VariableTargetAttr).length ? variableTarget.value : move ? allMoves[move].moveTarget : move === undefined ? MoveTarget.NEAR_ENEMY : [];
const opponents = user.getOpponents(); const opponents = user.getOpponents();
let set: Pokemon[] = []; let set: Pokemon[] = [];
@ -4700,8 +4736,7 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.SLEEP) .attr(StatusEffectAttr, StatusEffect.SLEEP)
.soundBased(), .soundBased(),
new StatusMove(Moves.TICKLE, Type.NORMAL, 100, 20, -1, 0, 3) new StatusMove(Moves.TICKLE, Type.NORMAL, 100, 20, -1, 0, 3)
.attr(StatChangeAttr, BattleStat.ATK, -1) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF ], -1),
.attr(StatChangeAttr, BattleStat.DEF, -1),
new SelfStatusMove(Moves.COSMIC_POWER, Type.PSYCHIC, -1, 20, -1, 0, 3) new SelfStatusMove(Moves.COSMIC_POWER, Type.PSYCHIC, -1, 20, -1, 0, 3)
.attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], 1, true), .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], 1, true),
new AttackMove(Moves.WATER_SPOUT, Type.WATER, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 3) new AttackMove(Moves.WATER_SPOUT, Type.WATER, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 3)
@ -4823,7 +4858,7 @@ export function initMoves() {
.attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true) .attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true)
.target(MoveTarget.USER_SIDE), .target(MoveTarget.USER_SIDE),
new StatusMove(Moves.ACUPRESSURE, Type.NORMAL, -1, 30, -1, 0, 4) new StatusMove(Moves.ACUPRESSURE, Type.NORMAL, -1, 30, -1, 0, 4)
.attr(StatChangeAttr, BattleStat.RAND, 2) .attr(AcupressureStatChangeAttr)
.target(MoveTarget.USER_OR_NEAR_ALLY), .target(MoveTarget.USER_OR_NEAR_ALLY),
new AttackMove(Moves.METAL_BURST, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 4) new AttackMove(Moves.METAL_BURST, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 4)
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5) .attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
@ -4895,6 +4930,10 @@ export function initMoves() {
new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4) new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4)
.attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true), .attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true),
new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4) new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4)
.attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true)
.condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) &&
!user.getTag(BattlerTagType.IGNORE_FLYING) && !user.getTag(BattlerTagType.INGRAIN) &&
!user.getTag(BattlerTagType.MAGNET_RISEN))
.unimplemented(), .unimplemented(),
new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4) new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4)
.attr(RecoilAttr, false, 0.33) .attr(RecoilAttr, false, 0.33)
@ -5737,8 +5776,7 @@ export function initMoves() {
.ignoresAbilities() .ignoresAbilities()
.partial(), .partial(),
new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, 100, 0, 7) new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, 100, 0, 7)
.attr(StatChangeAttr, BattleStat.ATK, -1) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPATK ], -1),
.attr(StatChangeAttr, BattleStat.SPATK, -1),
new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7) new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7)
.attr(FlinchAttr), .attr(FlinchAttr),
new AttackMove(Moves.NATURES_MADNESS, Type.FAIRY, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 7) new AttackMove(Moves.NATURES_MADNESS, Type.FAIRY, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 7)
@ -5917,8 +5955,7 @@ export function initMoves() {
new AttackMove(Moves.BODY_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8) new AttackMove(Moves.BODY_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8)
.attr(DefAtkAttr), .attr(DefAtkAttr),
new StatusMove(Moves.DECORATE, Type.FAIRY, -1, 15, 100, 0, 8) new StatusMove(Moves.DECORATE, Type.FAIRY, -1, 15, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.ATK, 2) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPATK ], 2),
.attr(StatChangeAttr, BattleStat.SPATK, 2),
new AttackMove(Moves.DRUM_BEATING, Type.GRASS, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 8) new AttackMove(Moves.DRUM_BEATING, Type.GRASS, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.SPD, -1) .attr(StatChangeAttr, BattleStat.SPD, -1)
.makesContact(false), .makesContact(false),
@ -5968,7 +6005,8 @@ export function initMoves() {
new AttackMove(Moves.STEEL_BEAM, Type.STEEL, MoveCategory.SPECIAL, 140, 95, 5, -1, 0, 8) new AttackMove(Moves.STEEL_BEAM, Type.STEEL, MoveCategory.SPECIAL, 140, 95, 5, -1, 0, 8)
.attr(HalfSacrificialAttr), .attr(HalfSacrificialAttr),
new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8) new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8)
.partial(), .attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 1.5 : 1)
.attr(VariableTargetAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 6 : 3),
new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8) new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8)
.attr(ClearTerrainAttr) .attr(ClearTerrainAttr)
.condition((user, target, move) => !!user.scene.arena.terrain), .condition((user, target, move) => !!user.scene.arena.terrain),

View File

@ -30,7 +30,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 24, Moves.SWEET_SCENT ], [ 24, Moves.SWEET_SCENT ],
[ 27, Moves.SYNTHESIS ], [ 27, Moves.SYNTHESIS ],
[ 30, Moves.WORRY_SEED ], [ 30, Moves.WORRY_SEED ],
[ 33, Moves.DOUBLE_EDGE ], [ 33, Moves.POWER_WHIP ],
[ 36, Moves.SOLAR_BEAM ], [ 36, Moves.SOLAR_BEAM ],
], ],
[Species.IVYSAUR]: [ [Species.IVYSAUR]: [
@ -47,16 +47,16 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 30, Moves.SWEET_SCENT ], [ 30, Moves.SWEET_SCENT ],
[ 35, Moves.SYNTHESIS ], [ 35, Moves.SYNTHESIS ],
[ 40, Moves.WORRY_SEED ], [ 40, Moves.WORRY_SEED ],
[ 45, Moves.DOUBLE_EDGE ], [ 45, Moves.POWER_WHIP ],
[ 50, Moves.SOLAR_BEAM ], [ 50, Moves.SOLAR_BEAM ],
], ],
[Species.VENUSAUR]: [ [Species.VENUSAUR]: [
[ 0, Moves.PETAL_BLIZZARD ], [ 0, Moves.PETAL_BLIZZARD ],
[ 1, Moves.GROWTH ],
[ 1, Moves.PETAL_DANCE ],
[ 1, Moves.VINE_WHIP ], [ 1, Moves.VINE_WHIP ],
[ 1, Moves.TACKLE ], [ 1, Moves.TACKLE ],
[ 1, Moves.GROWL ], [ 1, Moves.GROWL ],
[ 1, Moves.GROWTH ],
[ 1, Moves.PETAL_DANCE ],
[ 9, Moves.LEECH_SEED ], [ 9, Moves.LEECH_SEED ],
[ 12, Moves.RAZOR_LEAF ], [ 12, Moves.RAZOR_LEAF ],
[ 15, Moves.POISON_POWDER ], [ 15, Moves.POISON_POWDER ],
@ -66,7 +66,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 30, Moves.SWEET_SCENT ], [ 30, Moves.SWEET_SCENT ],
[ 37, Moves.SYNTHESIS ], [ 37, Moves.SYNTHESIS ],
[ 44, Moves.WORRY_SEED ], [ 44, Moves.WORRY_SEED ],
[ 51, Moves.DOUBLE_EDGE ], [ 51, Moves.POWER_WHIP ],
[ 58, Moves.SOLAR_BEAM ], [ 58, Moves.SOLAR_BEAM ],
], ],
[Species.CHARMANDER]: [ [Species.CHARMANDER]: [
@ -127,7 +127,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 27, Moves.SHELL_SMASH ], [ 27, Moves.SHELL_SMASH ],
[ 30, Moves.IRON_DEFENSE ], [ 30, Moves.IRON_DEFENSE ],
[ 33, Moves.HYDRO_PUMP ], [ 33, Moves.HYDRO_PUMP ],
[ 36, Moves.SKULL_BASH ], [ 36, Moves.WAVE_CRASH ],
], ],
[Species.WARTORTLE]: [ [Species.WARTORTLE]: [
[ 1, Moves.TACKLE ], [ 1, Moves.TACKLE ],
@ -143,7 +143,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 35, Moves.SHELL_SMASH ], [ 35, Moves.SHELL_SMASH ],
[ 40, Moves.IRON_DEFENSE ], [ 40, Moves.IRON_DEFENSE ],
[ 45, Moves.HYDRO_PUMP ], [ 45, Moves.HYDRO_PUMP ],
[ 50, Moves.SKULL_BASH ], [ 50, Moves.WAVE_CRASH ],
], ],
[Species.BLASTOISE]: [ [Species.BLASTOISE]: [
[ 0, Moves.FLASH_CANNON ], [ 0, Moves.FLASH_CANNON ],
@ -160,7 +160,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 35, Moves.SHELL_SMASH ], [ 35, Moves.SHELL_SMASH ],
[ 42, Moves.IRON_DEFENSE ], [ 42, Moves.IRON_DEFENSE ],
[ 49, Moves.HYDRO_PUMP ], [ 49, Moves.HYDRO_PUMP ],
[ 56, Moves.SKULL_BASH ], [ 56, Moves.WAVE_CRASH ],
], ],
[Species.CATERPIE]: [ [Species.CATERPIE]: [
[ 1, Moves.TACKLE ], [ 1, Moves.TACKLE ],
@ -341,9 +341,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 12, Moves.GLARE ], [ 12, Moves.GLARE ],
[ 17, Moves.SCREECH ], [ 17, Moves.SCREECH ],
[ 20, Moves.ACID ], [ 20, Moves.ACID ],
[ 25, Moves.SWALLOW ],
[ 25, Moves.STOCKPILE ], [ 25, Moves.STOCKPILE ],
[ 25, Moves.SPIT_UP ], [ 25, Moves.SPIT_UP ],
[ 25, Moves.SWALLOW ],
[ 28, Moves.ACID_SPRAY ], [ 28, Moves.ACID_SPRAY ],
[ 33, Moves.SLUDGE_BOMB ], [ 33, Moves.SLUDGE_BOMB ],
[ 36, Moves.GASTRO_ACID ], [ 36, Moves.GASTRO_ACID ],
@ -1780,14 +1780,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 4, Moves.DOUBLE_KICK ], [ 4, Moves.DOUBLE_KICK ],
[ 8, Moves.LOW_KICK ], [ 8, Moves.LOW_KICK ],
[ 12, Moves.ENDURE ], [ 12, Moves.ENDURE ],
[ 16, Moves.REVENGE ], [ 16, Moves.SUCKER_PUNCH ],
[ 21, Moves.WIDE_GUARD ], [ 21, Moves.WIDE_GUARD ],
[ 24, Moves.BLAZE_KICK ], [ 24, Moves.BLAZE_KICK ],
[ 28, Moves.MIND_READER ], [ 28, Moves.FEINT ],
[ 32, Moves.MEGA_KICK ], [ 32, Moves.MEGA_KICK ],
[ 36, Moves.CLOSE_COMBAT ], [ 36, Moves.CLOSE_COMBAT ],
[ 40, Moves.REVERSAL ], [ 40, Moves.REVERSAL ],
[ 44, Moves.HIGH_JUMP_KICK ], [ 44, Moves.HIGH_JUMP_KICK ],
[ 50, Moves.AXE_KICK ],
], ],
[Species.HITMONCHAN]: [ [Species.HITMONCHAN]: [
[ 0, Moves.DRAIN_PUNCH ], [ 0, Moves.DRAIN_PUNCH ],
@ -1796,16 +1797,14 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.FAKE_OUT ], [ 1, Moves.FAKE_OUT ],
[ 1, Moves.HELPING_HAND ], [ 1, Moves.HELPING_HAND ],
[ 1, Moves.FEINT ], [ 1, Moves.FEINT ],
[ 1, Moves.VACUUM_WAVE ],
[ 1, Moves.BULLET_PUNCH ],
[ 4, Moves.MACH_PUNCH ], [ 4, Moves.MACH_PUNCH ],
[ 8, Moves.POWER_UP_PUNCH ], [ 8, Moves.VACUUM_WAVE ],
[ 12, Moves.DETECT ], [ 12, Moves.DETECT ],
[ 16, Moves.REVENGE ], [ 16, Moves.BULLET_PUNCH ],
[ 21, Moves.QUICK_GUARD ], [ 21, Moves.QUICK_GUARD ],
[ 24, Moves.FIRE_PUNCH ],
[ 24, Moves.ICE_PUNCH ],
[ 24, Moves.THUNDER_PUNCH ], [ 24, Moves.THUNDER_PUNCH ],
[ 24, Moves.ICE_PUNCH ],
[ 24, Moves.FIRE_PUNCH ],
[ 28, Moves.AGILITY ], [ 28, Moves.AGILITY ],
[ 32, Moves.MEGA_PUNCH ], [ 32, Moves.MEGA_PUNCH ],
[ 36, Moves.CLOSE_COMBAT ], [ 36, Moves.CLOSE_COMBAT ],

View File

@ -3209,7 +3209,7 @@ export const starterPassiveAbilities = {
[Species.BELLSPROUT]: Abilities.CORROSION, [Species.BELLSPROUT]: Abilities.CORROSION,
[Species.TENTACOOL]: Abilities.INNARDS_OUT, [Species.TENTACOOL]: Abilities.INNARDS_OUT,
[Species.GEODUDE]: Abilities.ROCKY_PAYLOAD, [Species.GEODUDE]: Abilities.ROCKY_PAYLOAD,
[Species.PONYTA]: Abilities.PIXILATE, [Species.PONYTA]: Abilities.MAGIC_GUARD,
[Species.SLOWPOKE]: Abilities.UNAWARE, [Species.SLOWPOKE]: Abilities.UNAWARE,
[Species.MAGNEMITE]: Abilities.MOTOR_DRIVE, [Species.MAGNEMITE]: Abilities.MOTOR_DRIVE,
[Species.FARFETCHD]: Abilities.PURE_POWER, [Species.FARFETCHD]: Abilities.PURE_POWER,
@ -3235,7 +3235,7 @@ export const starterPassiveAbilities = {
[Species.SCYTHER]: Abilities.SPEED_BOOST, [Species.SCYTHER]: Abilities.SPEED_BOOST,
[Species.PINSIR]: Abilities.SAP_SIPPER, [Species.PINSIR]: Abilities.SAP_SIPPER,
[Species.TAUROS]: Abilities.ROCK_HEAD, [Species.TAUROS]: Abilities.ROCK_HEAD,
[Species.MAGIKARP]: Abilities.BERSERK, [Species.MAGIKARP]: Abilities.MULTISCALE,
[Species.LAPRAS]: Abilities.LIQUID_VOICE, [Species.LAPRAS]: Abilities.LIQUID_VOICE,
[Species.DITTO]: Abilities.GOOEY, [Species.DITTO]: Abilities.GOOEY,
[Species.EEVEE]: Abilities.PROTEAN, [Species.EEVEE]: Abilities.PROTEAN,
@ -3249,16 +3249,16 @@ export const starterPassiveAbilities = {
[Species.DRATINI]: Abilities.DELTA_STREAM, [Species.DRATINI]: Abilities.DELTA_STREAM,
[Species.MEWTWO]: Abilities.NEUROFORCE, [Species.MEWTWO]: Abilities.NEUROFORCE,
[Species.MEW]: Abilities.PROTEAN, [Species.MEW]: Abilities.PROTEAN,
[Species.CHIKORITA]: Abilities.RIPEN, [Species.CHIKORITA]: Abilities.THICK_FAT,
[Species.CYNDAQUIL]: Abilities.TURBOBLAZE, [Species.CYNDAQUIL]: Abilities.TURBOBLAZE,
[Species.TOTODILE]: Abilities.TOUGH_CLAWS, [Species.TOTODILE]: Abilities.TOUGH_CLAWS,
[Species.SENTRET]: Abilities.FLUFFY, [Species.SENTRET]: Abilities.FLUFFY,
[Species.HOOTHOOT]: Abilities.CURSED_BODY, [Species.HOOTHOOT]: Abilities.CURSED_BODY,
[Species.LEDYBA]: Abilities.SCREEN_CLEANER, [Species.LEDYBA]: Abilities.PRANKSTER,
[Species.SPINARAK]: Abilities.PRANKSTER, [Species.SPINARAK]: Abilities.PRANKSTER,
[Species.CHINCHOU]: Abilities.REGENERATOR, [Species.CHINCHOU]: Abilities.REGENERATOR,
[Species.PICHU]: Abilities.TRANSISTOR, [Species.PICHU]: Abilities.TRANSISTOR,
[Species.CLEFFA]: Abilities.MISTY_SURGE, [Species.CLEFFA]: Abilities.MAGIC_BOUNCE,
[Species.IGGLYBUFF]: Abilities.SERENE_GRACE, [Species.IGGLYBUFF]: Abilities.SERENE_GRACE,
[Species.TOGEPI]: Abilities.OPPORTUNIST, [Species.TOGEPI]: Abilities.OPPORTUNIST,
[Species.NATU]: Abilities.TINTED_LENS, [Species.NATU]: Abilities.TINTED_LENS,
@ -3276,7 +3276,7 @@ export const starterPassiveAbilities = {
[Species.DUNSPARCE]: Abilities.MARVEL_SCALE, [Species.DUNSPARCE]: Abilities.MARVEL_SCALE,
[Species.GLIGAR]: Abilities.MERCILESS, [Species.GLIGAR]: Abilities.MERCILESS,
[Species.SNUBBULL]: Abilities.BALL_FETCH, [Species.SNUBBULL]: Abilities.BALL_FETCH,
[Species.QWILFISH]: Abilities.LIQUID_OOZE, [Species.QWILFISH]: Abilities.TOXIC_DEBRIS,
[Species.SHUCKLE]: Abilities.WELL_BAKED_BODY, [Species.SHUCKLE]: Abilities.WELL_BAKED_BODY,
[Species.HERACROSS]: Abilities.QUICK_FEET, [Species.HERACROSS]: Abilities.QUICK_FEET,
[Species.SNEASEL]: Abilities.MOXIE, [Species.SNEASEL]: Abilities.MOXIE,
@ -3292,7 +3292,7 @@ export const starterPassiveAbilities = {
[Species.STANTLER]: Abilities.MAGIC_GUARD, [Species.STANTLER]: Abilities.MAGIC_GUARD,
[Species.SMEARGLE]: Abilities.QUICK_DRAW, [Species.SMEARGLE]: Abilities.QUICK_DRAW,
[Species.TYROGUE]: Abilities.STAMINA, [Species.TYROGUE]: Abilities.STAMINA,
[Species.SMOOCHUM]: Abilities.CUTE_CHARM, [Species.SMOOCHUM]: Abilities.DAZZLING,
[Species.ELEKID]: Abilities.IRON_FIST, [Species.ELEKID]: Abilities.IRON_FIST,
[Species.MAGBY]: Abilities.CONTRARY, [Species.MAGBY]: Abilities.CONTRARY,
[Species.MILTANK]: Abilities.GLUTTONY, [Species.MILTANK]: Abilities.GLUTTONY,
@ -3303,7 +3303,7 @@ export const starterPassiveAbilities = {
[Species.LUGIA]: Abilities.DELTA_STREAM, [Species.LUGIA]: Abilities.DELTA_STREAM,
[Species.HO_OH]: Abilities.MAGIC_GUARD, [Species.HO_OH]: Abilities.MAGIC_GUARD,
[Species.CELEBI]: Abilities.GRASSY_SURGE, [Species.CELEBI]: Abilities.GRASSY_SURGE,
[Species.TREECKO]: Abilities.GRASSY_SURGE, [Species.TREECKO]: Abilities.TINTED_LENS,
[Species.TORCHIC]: Abilities.RECKLESS, [Species.TORCHIC]: Abilities.RECKLESS,
[Species.MUDKIP]: Abilities.REGENERATOR, [Species.MUDKIP]: Abilities.REGENERATOR,
[Species.POOCHYENA]: Abilities.STRONG_JAW, [Species.POOCHYENA]: Abilities.STRONG_JAW,
@ -3320,7 +3320,7 @@ export const starterPassiveAbilities = {
[Species.NINCADA]: Abilities.OVERCOAT, [Species.NINCADA]: Abilities.OVERCOAT,
[Species.WHISMUR]: Abilities.PUNK_ROCK, [Species.WHISMUR]: Abilities.PUNK_ROCK,
[Species.MAKUHITA]: Abilities.STAMINA, [Species.MAKUHITA]: Abilities.STAMINA,
[Species.AZURILL]: Abilities.UNNERVE, [Species.AZURILL]: Abilities.MISTY_SURGE,
[Species.NOSEPASS]: Abilities.LEVITATE, [Species.NOSEPASS]: Abilities.LEVITATE,
[Species.SKITTY]: Abilities.SCRAPPY, [Species.SKITTY]: Abilities.SCRAPPY,
[Species.SABLEYE]: Abilities.UNNERVE, [Species.SABLEYE]: Abilities.UNNERVE,
@ -3351,7 +3351,7 @@ export const starterPassiveAbilities = {
[Species.BALTOY]: Abilities.OWN_TEMPO, [Species.BALTOY]: Abilities.OWN_TEMPO,
[Species.LILEEP]: Abilities.WATER_ABSORB, [Species.LILEEP]: Abilities.WATER_ABSORB,
[Species.ANORITH]: Abilities.WATER_ABSORB, [Species.ANORITH]: Abilities.WATER_ABSORB,
[Species.FEEBAS]: Abilities.PASTEL_VEIL, [Species.FEEBAS]: Abilities.MAGIC_GUARD,
[Species.CASTFORM]: Abilities.ADAPTABILITY, [Species.CASTFORM]: Abilities.ADAPTABILITY,
[Species.KECLEON]: Abilities.ADAPTABILITY, [Species.KECLEON]: Abilities.ADAPTABILITY,
[Species.SHUPPET]: Abilities.MUMMY, [Species.SHUPPET]: Abilities.MUMMY,
@ -3372,7 +3372,7 @@ export const starterPassiveAbilities = {
[Species.LATIAS]: Abilities.SOUL_HEART, [Species.LATIAS]: Abilities.SOUL_HEART,
[Species.LATIOS]: Abilities.TINTED_LENS, [Species.LATIOS]: Abilities.TINTED_LENS,
[Species.KYOGRE]: Abilities.HYDRATION, [Species.KYOGRE]: Abilities.HYDRATION,
[Species.GROUDON]: Abilities.FLAME_BODY, [Species.GROUDON]: Abilities.PROTOSYNTHESIS,
[Species.RAYQUAZA]: Abilities.UNNERVE, [Species.RAYQUAZA]: Abilities.UNNERVE,
[Species.JIRACHI]: Abilities.COMATOSE, [Species.JIRACHI]: Abilities.COMATOSE,
[Species.DEOXYS]: Abilities.PROTEAN, [Species.DEOXYS]: Abilities.PROTEAN,
@ -3431,7 +3431,7 @@ export const starterPassiveAbilities = {
[Species.VICTINI]: Abilities.SUPER_LUCK, [Species.VICTINI]: Abilities.SUPER_LUCK,
[Species.SNIVY]: Abilities.MULTISCALE, [Species.SNIVY]: Abilities.MULTISCALE,
[Species.TEPIG]: Abilities.ROCK_HEAD, [Species.TEPIG]: Abilities.ROCK_HEAD,
[Species.OSHAWOTT]: Abilities.MOLD_BREAKER, [Species.OSHAWOTT]: Abilities.QUICK_DRAW,
[Species.PATRAT]: Abilities.STAKEOUT, [Species.PATRAT]: Abilities.STAKEOUT,
[Species.LILLIPUP]: Abilities.BALL_FETCH, [Species.LILLIPUP]: Abilities.BALL_FETCH,
[Species.PURRLOIN]: Abilities.DEFIANT, [Species.PURRLOIN]: Abilities.DEFIANT,
@ -3444,14 +3444,14 @@ export const starterPassiveAbilities = {
[Species.ROGGENROLA]: Abilities.SOLID_ROCK, [Species.ROGGENROLA]: Abilities.SOLID_ROCK,
[Species.WOOBAT]: Abilities.SOUL_HEART, [Species.WOOBAT]: Abilities.SOUL_HEART,
[Species.DRILBUR]: Abilities.SAND_STREAM, [Species.DRILBUR]: Abilities.SAND_STREAM,
[Species.AUDINO]: Abilities.SERENE_GRACE, [Species.AUDINO]: Abilities.FRIEND_GUARD,
[Species.TIMBURR]: Abilities.STAMINA, [Species.TIMBURR]: Abilities.STAMINA,
[Species.TYMPOLE]: Abilities.MOODY, [Species.TYMPOLE]: Abilities.MOODY,
[Species.THROH]: Abilities.SIMPLE, [Species.THROH]: Abilities.SIMPLE,
[Species.SAWK]: Abilities.DEFIANT, [Species.SAWK]: Abilities.DEFIANT,
[Species.SEWADDLE]: Abilities.SHARPNESS, [Species.SEWADDLE]: Abilities.SHARPNESS,
[Species.VENIPEDE]: Abilities.INTIMIDATE, [Species.VENIPEDE]: Abilities.INTIMIDATE,
[Species.COTTONEE]: Abilities.MISTY_SURGE, [Species.COTTONEE]: Abilities.FLUFFY,
[Species.PETILIL]: Abilities.DANCER, [Species.PETILIL]: Abilities.DANCER,
[Species.BASCULIN]: Abilities.OPPORTUNIST, [Species.BASCULIN]: Abilities.OPPORTUNIST,
[Species.SANDILE]: Abilities.STRONG_JAW, [Species.SANDILE]: Abilities.STRONG_JAW,
@ -3460,7 +3460,7 @@ export const starterPassiveAbilities = {
[Species.DWEBBLE]: Abilities.STAMINA, [Species.DWEBBLE]: Abilities.STAMINA,
[Species.SCRAGGY]: Abilities.ROCK_HEAD, [Species.SCRAGGY]: Abilities.ROCK_HEAD,
[Species.SIGILYPH]: Abilities.MAGICIAN, [Species.SIGILYPH]: Abilities.MAGICIAN,
[Species.YAMASK]: Abilities.GOOD_AS_GOLD, [Species.YAMASK]: Abilities.PURIFYING_SALT,
[Species.TIRTOUGA]: Abilities.SHELL_ARMOR, [Species.TIRTOUGA]: Abilities.SHELL_ARMOR,
[Species.ARCHEN]: Abilities.ROCKY_PAYLOAD, [Species.ARCHEN]: Abilities.ROCKY_PAYLOAD,
[Species.TRUBBISH]: Abilities.GOOEY, [Species.TRUBBISH]: Abilities.GOOEY,
@ -3521,7 +3521,7 @@ export const starterPassiveAbilities = {
[Species.SKIDDO]: Abilities.GRASSY_SURGE, [Species.SKIDDO]: Abilities.GRASSY_SURGE,
[Species.PANCHAM]: Abilities.FLUFFY, [Species.PANCHAM]: Abilities.FLUFFY,
[Species.FURFROU]: Abilities.BALL_FETCH, [Species.FURFROU]: Abilities.BALL_FETCH,
[Species.ESPURR]: Abilities.PSYCHIC_SURGE, [Species.ESPURR]: Abilities.FUR_COAT,
[Species.HONEDGE]: Abilities.SHARPNESS, [Species.HONEDGE]: Abilities.SHARPNESS,
[Species.SPRITZEE]: Abilities.MISTY_SURGE, [Species.SPRITZEE]: Abilities.MISTY_SURGE,
[Species.SWIRLIX]: Abilities.WELL_BAKED_BODY, [Species.SWIRLIX]: Abilities.WELL_BAKED_BODY,
@ -3548,7 +3548,7 @@ export const starterPassiveAbilities = {
[Species.HOOPA]: Abilities.OPPORTUNIST, [Species.HOOPA]: Abilities.OPPORTUNIST,
[Species.VOLCANION]: Abilities.FILTER, [Species.VOLCANION]: Abilities.FILTER,
[Species.ROWLET]: Abilities.SNIPER, [Species.ROWLET]: Abilities.SNIPER,
[Species.LITTEN]: Abilities.PRANKSTER, [Species.LITTEN]: Abilities.FLAME_BODY,
[Species.POPPLIO]: Abilities.PUNK_ROCK, [Species.POPPLIO]: Abilities.PUNK_ROCK,
[Species.PIKIPEK]: Abilities.ANGER_POINT, [Species.PIKIPEK]: Abilities.ANGER_POINT,
[Species.YUNGOOS]: Abilities.HUGE_POWER, [Species.YUNGOOS]: Abilities.HUGE_POWER,
@ -3577,7 +3577,7 @@ export const starterPassiveAbilities = {
[Species.KOMALA]: Abilities.GUTS, [Species.KOMALA]: Abilities.GUTS,
[Species.TURTONATOR]: Abilities.ANGER_SHELL, [Species.TURTONATOR]: Abilities.ANGER_SHELL,
[Species.TOGEDEMARU]: Abilities.STATIC, [Species.TOGEDEMARU]: Abilities.STATIC,
[Species.MIMIKYU]: Abilities.CURSED_BODY, [Species.MIMIKYU]: Abilities.TOUGH_CLAWS,
[Species.BRUXISH]: Abilities.MULTISCALE, [Species.BRUXISH]: Abilities.MULTISCALE,
[Species.DRAMPA]: Abilities.FLASH_FIRE, [Species.DRAMPA]: Abilities.FLASH_FIRE,
[Species.DHELMISE]: Abilities.INFILTRATOR, [Species.DHELMISE]: Abilities.INFILTRATOR,
@ -3607,9 +3607,9 @@ export const starterPassiveAbilities = {
[Species.SOBBLE]: Abilities.SUPER_LUCK, [Species.SOBBLE]: Abilities.SUPER_LUCK,
[Species.SKWOVET]: Abilities.HONEY_GATHER, [Species.SKWOVET]: Abilities.HONEY_GATHER,
[Species.ROOKIDEE]: Abilities.IRON_BARBS, [Species.ROOKIDEE]: Abilities.IRON_BARBS,
[Species.BLIPBUG]: Abilities.TINTED_LENS, [Species.BLIPBUG]: Abilities.PSYCHIC_SURGE,
[Species.NICKIT]: Abilities.INTIMIDATE, [Species.NICKIT]: Abilities.INTIMIDATE,
[Species.GOSSIFLEUR]: Abilities.STORM_DRAIN, [Species.GOSSIFLEUR]: Abilities.GRASSY_SURGE,
[Species.WOOLOO]: Abilities.ROCK_HEAD, [Species.WOOLOO]: Abilities.ROCK_HEAD,
[Species.CHEWTLE]: Abilities.ROCK_HEAD, [Species.CHEWTLE]: Abilities.ROCK_HEAD,
[Species.YAMPER]: Abilities.STAKEOUT, [Species.YAMPER]: Abilities.STAKEOUT,
@ -3624,7 +3624,7 @@ export const starterPassiveAbilities = {
[Species.SINISTEA]: Abilities.WATER_ABSORB, [Species.SINISTEA]: Abilities.WATER_ABSORB,
[Species.HATENNA]: Abilities.MAGIC_GUARD, [Species.HATENNA]: Abilities.MAGIC_GUARD,
[Species.IMPIDIMP]: Abilities.TANGLING_HAIR, [Species.IMPIDIMP]: Abilities.TANGLING_HAIR,
[Species.MILCERY]: Abilities.WELL_BAKED_BODY, [Species.MILCERY]: Abilities.MISTY_SURGE,
[Species.FALINKS]: Abilities.MOXIE, [Species.FALINKS]: Abilities.MOXIE,
[Species.PINCURCHIN]: Abilities.IRON_BARBS, [Species.PINCURCHIN]: Abilities.IRON_BARBS,
[Species.SNOM]: Abilities.SNOW_WARNING, [Species.SNOM]: Abilities.SNOW_WARNING,
@ -3674,9 +3674,9 @@ export const starterPassiveAbilities = {
[Species.RELLOR]: Abilities.MAGIC_GUARD, [Species.RELLOR]: Abilities.MAGIC_GUARD,
[Species.FLITTLE]: Abilities.COMPETITIVE, [Species.FLITTLE]: Abilities.COMPETITIVE,
[Species.TINKATINK]: Abilities.HUGE_POWER, [Species.TINKATINK]: Abilities.HUGE_POWER,
[Species.WIGLETT]: Abilities.STORM_DRAIN, [Species.WIGLETT]: Abilities.STURDY,
[Species.BOMBIRDIER]: Abilities.UNAWARE, [Species.BOMBIRDIER]: Abilities.UNAWARE,
[Species.FINIZEN]: Abilities.LIQUID_VOICE, [Species.FINIZEN]: Abilities.IRON_FIST,
[Species.VAROOM]: Abilities.SPEED_BOOST, [Species.VAROOM]: Abilities.SPEED_BOOST,
[Species.CYCLIZAR]: Abilities.PROTEAN, [Species.CYCLIZAR]: Abilities.PROTEAN,
[Species.ORTHWORM]: Abilities.HEATPROOF, [Species.ORTHWORM]: Abilities.HEATPROOF,
@ -3725,13 +3725,13 @@ export const starterPassiveAbilities = {
[Species.ALOLA_RATTATA]: Abilities.CHEEK_POUCH, [Species.ALOLA_RATTATA]: Abilities.CHEEK_POUCH,
[Species.ALOLA_SANDSHREW]: Abilities.ICE_BODY, [Species.ALOLA_SANDSHREW]: Abilities.ICE_BODY,
[Species.ALOLA_VULPIX]: Abilities.ICE_BODY, [Species.ALOLA_VULPIX]: Abilities.ICE_BODY,
[Species.ALOLA_DIGLETT]: Abilities.CUTE_CHARM, [Species.ALOLA_DIGLETT]: Abilities.STURDY,
[Species.ALOLA_MEOWTH]: Abilities.UNNERVE, [Species.ALOLA_MEOWTH]: Abilities.UNNERVE,
[Species.ALOLA_GEODUDE]: Abilities.ELECTROMORPHOSIS, [Species.ALOLA_GEODUDE]: Abilities.ELECTROMORPHOSIS,
[Species.ALOLA_GRIMER]: Abilities.MERCILESS, [Species.ALOLA_GRIMER]: Abilities.MERCILESS,
[Species.ETERNAL_FLOETTE]: Abilities.MAGIC_GUARD, [Species.ETERNAL_FLOETTE]: Abilities.MAGIC_GUARD,
[Species.GALAR_MEOWTH]: Abilities.SUPER_LUCK, [Species.GALAR_MEOWTH]: Abilities.SUPER_LUCK,
[Species.GALAR_PONYTA]: Abilities.MAGIC_GUARD, [Species.GALAR_PONYTA]: Abilities.PIXILATE,
[Species.GALAR_SLOWPOKE]: Abilities.POISON_TOUCH, [Species.GALAR_SLOWPOKE]: Abilities.POISON_TOUCH,
[Species.GALAR_FARFETCHD]: Abilities.SUPER_LUCK, [Species.GALAR_FARFETCHD]: Abilities.SUPER_LUCK,
[Species.GALAR_ARTICUNO]: Abilities.SERENE_GRACE, [Species.GALAR_ARTICUNO]: Abilities.SERENE_GRACE,

View File

@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant';
import { variantData } from '#app/data/variant'; import { variantData } from '#app/data/variant';
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
import { Moves } from "../data/enums/moves"; 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 } 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 } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species'; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species';
import * as Utils from '../utils'; import * as Utils from '../utils';
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
@ -43,8 +43,8 @@ import { Nature, getNatureStatMultiplier } from '../data/nature';
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms'; import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms';
import { TerrainType } from '../data/terrain'; import { TerrainType } from '../data/terrain';
import { TrainerSlot } from '../data/trainer-config'; import { TrainerSlot } from '../data/trainer-config';
import { ABILITY_OVERRIDE, MOVE_OVERRIDE, MOVE_OVERRIDE_2, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE, OPP_MOVE_OVERRIDE_2, OPP_SHINY_OVERRIDE, OPP_VARIANT_OVERRIDE } from '../overrides';
import { BerryType } from '../data/berry'; import { BerryType } from '../data/berry';
import { ABILITY_OVERRIDE, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE, OPP_SHINY_OVERRIDE, OPP_VARIANT_OVERRIDE } from '../overrides';
import i18next from '../plugins/i18n'; import i18next from '../plugins/i18n';
export enum FieldPosition { export enum FieldPosition {
@ -725,6 +725,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.moveset[0] = new PokemonMove(MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[MOVE_OVERRIDE].pp)); this.moveset[0] = new PokemonMove(MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[MOVE_OVERRIDE].pp));
else if (OPP_MOVE_OVERRIDE && !this.isPlayer()) else if (OPP_MOVE_OVERRIDE && !this.isPlayer())
this.moveset[0] = new PokemonMove(OPP_MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[OPP_MOVE_OVERRIDE].pp)); this.moveset[0] = new PokemonMove(OPP_MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[OPP_MOVE_OVERRIDE].pp));
if (MOVE_OVERRIDE_2 && this.isPlayer())
this.moveset[1] = new PokemonMove(MOVE_OVERRIDE_2, Math.min(this.moveset[1].ppUsed, allMoves[MOVE_OVERRIDE_2].pp));
else if (OPP_MOVE_OVERRIDE_2 && !this.isPlayer())
this.moveset[1] = new PokemonMove(OPP_MOVE_OVERRIDE_2, Math.min(this.moveset[1].ppUsed, allMoves[OPP_MOVE_OVERRIDE_2].pp));
return ret; return ret;
} }
@ -2474,9 +2479,10 @@ export class PlayerPokemon extends Pokemon {
if (newEvolution.condition.predicate(this)) { if (newEvolution.condition.predicate(this)) {
const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, undefined, this.shiny, this.variant, this.ivs, this.nature); const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, undefined, this.shiny, this.variant, this.ivs, this.nature);
newPokemon.natureOverride = this.natureOverride; newPokemon.natureOverride = this.natureOverride;
newPokemon.passive = this.passive;
newPokemon.moveset = this.moveset.slice();
newPokemon.moveset = this.copyMoveset(); newPokemon.moveset = this.copyMoveset();
newPokemon.luck = this.luck; newPokemon.luck = this.luck;
newPokemon.fusionSpecies = this.fusionSpecies; newPokemon.fusionSpecies = this.fusionSpecies;
newPokemon.fusionFormIndex = this.fusionFormIndex; newPokemon.fusionFormIndex = this.fusionFormIndex;
newPokemon.fusionAbilityIndex = this.fusionAbilityIndex; newPokemon.fusionAbilityIndex = this.fusionAbilityIndex;
@ -2731,6 +2737,10 @@ export class EnemyPokemon extends Pokemon {
let targetScores: integer[] = []; let targetScores: integer[] = [];
for (let mt of moveTargets[move.id]) { for (let mt of moveTargets[move.id]) {
// Prevent a target score from being calculated when the target is whoever attacks the user
if (mt === BattlerIndex.ATTACKER)
break;
const target = this.scene.getField()[mt]; const target = this.scene.getField()[mt];
let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1); let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1);
if (move.name.endsWith(' (N)') || !move.applyConditions(this, target, move)) if (move.name.endsWith(' (N)') || !move.applyConditions(this, target, move))
@ -2801,8 +2811,14 @@ export class EnemyPokemon extends Pokemon {
return scoreA < scoreB ? 1 : scoreA > scoreB ? -1 : 0; return scoreA < scoreB ? 1 : scoreA > scoreB ? -1 : 0;
}); });
if (!sortedBenefitScores.length) if (!sortedBenefitScores.length) {
// Set target to BattlerIndex.ATTACKER when using a counter move
// This is the same as when the player does so
if (!!move.findAttr(attr => attr instanceof CounterDamageAttr))
return [BattlerIndex.ATTACKER];
return []; return [];
}
let targetWeights = sortedBenefitScores.map(s => s[1]); let targetWeights = sortedBenefitScores.map(s => s[1]);
const lowestWeight = targetWeights[targetWeights.length - 1]; const lowestWeight = targetWeights[targetWeights.length - 1];

View File

@ -31,6 +31,8 @@ export class LoadingScene extends SceneBase {
this.loadAtlas('bg', 'ui'); this.loadAtlas('bg', 'ui');
this.loadImage('command_fight_labels', 'ui'); this.loadImage('command_fight_labels', 'ui');
this.loadAtlas('prompt', 'ui'); this.loadAtlas('prompt', 'ui');
this.loadImage('candy', 'ui');
this.loadImage('candy_overlay', 'ui');
this.loadImage('cursor', 'ui'); this.loadImage('cursor', 'ui');
this.loadImage('cursor_reverse', 'ui'); this.loadImage('cursor_reverse', 'ui');
for (let wv of Utils.getEnumValues(WindowVariant)) { for (let wv of Utils.getEnumValues(WindowVariant)) {

View File

@ -9,7 +9,7 @@ export const battle: SimpleTranslationEntries = {
"trainerComeBack": "{{trainerName}} retire {{pokemonName}} !", "trainerComeBack": "{{trainerName}} retire {{pokemonName}} !",
"playerGo": "{{pokemonName}} ! Go !", "playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !", "trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?", "switchQuestion": "Voulez-vous changer\nvotre {{pokemonName}} ?",
"trainerDefeated": `Vous avez battu\n{{trainerName}} !`, "trainerDefeated": `Vous avez battu\n{{trainerName}} !`,
"pokemonCaught": "Vous avez attrapé {{pokemonName}} !", "pokemonCaught": "Vous avez attrapé {{pokemonName}} !",
"pokemon": "Pokémon", "pokemon": "Pokémon",

View File

@ -1151,7 +1151,7 @@ const enemyBuffModifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10), new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10),
new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 10000), new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1)
].map(m => { m.setTier(ModifierTier.COMMON); return m; }), ].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
[ModifierTier.GREAT]: [ [ModifierTier.GREAT]: [
@ -1162,12 +1162,12 @@ const enemyBuffModifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1)
].map(m => { m.setTier(ModifierTier.GREAT); return m; }), ].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [ [ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 5), new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 5), new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10),
new WeightedModifierType(modifierTypes.ENEMY_HEAL, 5), new WeightedModifierType(modifierTypes.ENEMY_HEAL, 10),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 5), new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10),
new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5), new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 10),
new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 300) new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 5)
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.ROGUE]: [ ].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), [ModifierTier.ROGUE]: [ ].map(m => { m.setTier(ModifierTier.ROGUE); return m; }),
[ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) [ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; })

View File

@ -15,9 +15,11 @@ export const WEATHER_OVERRIDE = WeatherType.NONE;
export const ABILITY_OVERRIDE = Abilities.NONE; export const ABILITY_OVERRIDE = Abilities.NONE;
export const MOVE_OVERRIDE = Moves.NONE; export const MOVE_OVERRIDE = Moves.NONE;
export const MOVE_OVERRIDE_2 = Moves.NONE;
export const OPP_SPECIES_OVERRIDE = 0; export const OPP_SPECIES_OVERRIDE = 0;
export const OPP_ABILITY_OVERRIDE = Abilities.NONE; export const OPP_ABILITY_OVERRIDE = Abilities.NONE;
export const OPP_MOVE_OVERRIDE = Moves.NONE; export const OPP_MOVE_OVERRIDE = Moves.NONE;
export const OPP_MOVE_OVERRIDE_2 = Moves.NONE;
export const OPP_SHINY_OVERRIDE = false; export const OPP_SHINY_OVERRIDE = false;
export const OPP_VARIANT_OVERRIDE = 0; export const OPP_VARIANT_OVERRIDE = 0;

View File

@ -2,7 +2,7 @@ import BattleScene, { bypassLogin, startingWave } from "./battle-scene";
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon"; import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
import * as Utils from './utils'; import * as Utils from './utils';
import { Moves } from "./data/enums/moves"; import { Moves } from "./data/enums/moves";
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr } from "./data/move"; import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } from "./data/move";
import { Mode } from './ui/ui'; import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler"; import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat"; import { Stat } from "./data/pokemon-stat";
@ -57,6 +57,7 @@ import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run";
import { GameModes, gameModes } from "./game-mode"; import { GameModes, gameModes } from "./game-mode";
import { getPokemonSpecies, speciesStarters } from "./data/pokemon-species"; import { getPokemonSpecies, speciesStarters } from "./data/pokemon-species";
import i18next from './plugins/i18n'; import i18next from './plugins/i18n';
import { Abilities } from "./data/enums/abilities";
import { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE } from './overrides'; import { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE } from './overrides';
export class LoginPhase extends Phase { export class LoginPhase extends Phase {
@ -1729,7 +1730,7 @@ export class CommandPhase extends FieldPhase {
}, null, true); }, null, true);
} else if (cursor < 5) { } else if (cursor < 5) {
const targetPokemon = this.scene.getEnemyField().find(p => p.isActive(true)); const targetPokemon = this.scene.getEnemyField().find(p => p.isActive(true));
if (targetPokemon.isBoss() && targetPokemon.bossSegmentIndex >= 1 && cursor < PokeballType.MASTER_BALL) { if (targetPokemon.isBoss() && targetPokemon.bossSegmentIndex >= 1 && !targetPokemon.hasAbility(Abilities.WONDER_GUARD, false, true) && cursor < PokeballType.MASTER_BALL) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('battle:noPokeballStrong'), null, () => { this.scene.ui.showText(i18next.t('battle:noPokeballStrong'), null, () => {
@ -2399,7 +2400,7 @@ export class MoveEffectPhase extends PokemonPhase {
const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ])); const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ]));
const activeTargets = targets.map(t => t.isActive(true)); const activeTargets = targets.map(t => t.isActive(true));
if (!activeTargets.length || (!this.move.getMove().isMultiTarget() && !targetHitChecks[this.targets[0]])) { if (!activeTargets.length || (!this.move.getMove().getAttrs(VariableTargetAttr).length && !this.move.getMove().isMultiTarget() && !targetHitChecks[this.targets[0]])) {
user.turnData.hitCount = 1; user.turnData.hitCount = 1;
user.turnData.hitsLeft = 1; user.turnData.hitsLeft = 1;
if (activeTargets.length) { if (activeTargets.length) {
@ -3219,19 +3220,22 @@ export class VictoryPhase extends PokemonPhase {
const expShareModifier = this.scene.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier; const expShareModifier = this.scene.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier;
const expBalanceModifier = this.scene.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier; const expBalanceModifier = this.scene.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
const multipleParticipantExpBonusModifier = this.scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier; const multipleParticipantExpBonusModifier = this.scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
const expPartyMembers = party.filter(p => p.hp && p.level < this.scene.getMaxExpLevel()); const nonFaintedPartyMembers = party.filter(p => p.hp);
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < this.scene.getMaxExpLevel());
const partyMemberExp = []; const partyMemberExp = [];
if (participantIds.size) { if (participantIds.size) {
let expValue = this.getPokemon().getExpValue(); let expValue = this.getPokemon().getExpValue();
if (this.scene.currentBattle.battleType === BattleType.TRAINER) if (this.scene.currentBattle.battleType === BattleType.TRAINER)
expValue = Math.floor(expValue * 1.5); expValue = Math.floor(expValue * 1.5);
for (let partyMember of expPartyMembers) { for (let partyMember of nonFaintedPartyMembers) {
const pId = partyMember.id; const pId = partyMember.id;
const participated = participantIds.has(pId); const participated = participantIds.has(pId);
if (participated) if (participated)
partyMember.addFriendship(2); partyMember.addFriendship(2);
else if (!expShareModifier) { if (!expPartyMembers.includes(partyMember))
continue;
if (!participated && !expShareModifier) {
partyMemberExp.push(0); partyMemberExp.push(0);
continue; continue;
} }

View File

@ -129,6 +129,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
private starterSelectMessageBox: Phaser.GameObjects.NineSlice; private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container; private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
private statsContainer: StatsContainer; private statsContainer: StatsContainer;
private pokemonFormText: Phaser.GameObjects.Text;
private genMode: boolean; private genMode: boolean;
private statsMode: boolean; private statsMode: boolean;
@ -435,6 +436,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonCandyIcon.setOrigin(0, 0); this.pokemonCandyIcon.setOrigin(0, 0);
this.starterSelectContainer.add(this.pokemonCandyIcon); this.starterSelectContainer.add(this.pokemonCandyIcon);
this.pokemonFormText = addTextObject(this.scene, 6, 42, 'Form', TextStyle.WINDOW_ALT, { fontSize: '42px' });
this.pokemonFormText.setOrigin(0, 0);
this.starterSelectContainer.add(this.pokemonFormText);
this.pokemonCandyOverlayIcon = this.scene.add.sprite(1, 12, 'items', 'candy_overlay'); this.pokemonCandyOverlayIcon = this.scene.add.sprite(1, 12, 'items', 'candy_overlay');
this.pokemonCandyOverlayIcon.setScale(0.5); this.pokemonCandyOverlayIcon.setScale(0.5);
this.pokemonCandyOverlayIcon.setOrigin(0, 0); this.pokemonCandyOverlayIcon.setOrigin(0, 0);
@ -1289,6 +1294,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonCandyOverlayIcon.setVisible(true); this.pokemonCandyOverlayIcon.setVisible(true);
this.pokemonCandyCountText.setText(`x${this.scene.gameData.starterData[species.speciesId].candyCount}`); this.pokemonCandyCountText.setText(`x${this.scene.gameData.starterData[species.speciesId].candyCount}`);
this.pokemonCandyCountText.setVisible(true); this.pokemonCandyCountText.setVisible(true);
this.pokemonFormText.setVisible(true);
} }
this.iconAnimHandler.addOrUpdate(this.starterSelectGenIconContainers[species.generation - 1].getAt(this.genSpecies[species.generation - 1].indexOf(species)) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.PASSIVE); this.iconAnimHandler.addOrUpdate(this.starterSelectGenIconContainers[species.generation - 1].getAt(this.genSpecies[species.generation - 1].indexOf(species)) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.PASSIVE);
@ -1338,6 +1344,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonCandyIcon.setVisible(false); this.pokemonCandyIcon.setVisible(false);
this.pokemonCandyOverlayIcon.setVisible(false); this.pokemonCandyOverlayIcon.setVisible(false);
this.pokemonCandyCountText.setVisible(false); this.pokemonCandyCountText.setVisible(false);
this.pokemonFormText.setVisible(false);
const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, true, true); const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, true, true);
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
@ -1364,6 +1371,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonCandyIcon.setVisible(false); this.pokemonCandyIcon.setVisible(false);
this.pokemonCandyOverlayIcon.setVisible(false); this.pokemonCandyOverlayIcon.setVisible(false);
this.pokemonCandyCountText.setVisible(false); this.pokemonCandyCountText.setVisible(false);
this.pokemonFormText.setVisible(false);
this.setSpeciesDetails(species, false, 0, false, 0, 0, 0); this.setSpeciesDetails(species, false, 0, false, 0, 0, 0);
this.pokemonSprite.clearTint(); this.pokemonSprite.clearTint();
@ -1523,6 +1531,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.starterMoveset.push(...availableStarterMoves.filter(sm => this.starterMoveset.indexOf(sm) === -1).slice(0, 4 - this.starterMoveset.length)); this.starterMoveset.push(...availableStarterMoves.filter(sm => this.starterMoveset.indexOf(sm) === -1).slice(0, 4 - this.starterMoveset.length));
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex); const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex);
const formText = species?.forms[formIndex]?.formKey.split('-');
for (let i = 0; i < formText?.length; i++)
formText[i] = formText[i].charAt(0).toUpperCase() + formText[i].substring(1);
this.pokemonFormText.setText(formText?.join(' '));
this.setTypeIcons(speciesForm.type1, speciesForm.type2); this.setTypeIcons(speciesForm.type1, speciesForm.type2);
} else { } else {
this.pokemonAbilityText.setText(''); this.pokemonAbilityText.setText('');

View File

@ -1,8 +1,10 @@
import BattleScene from "../battle-scene"; import BattleScene, { starterColors } from "../battle-scene";
import { Mode } from "./ui"; import { Mode } from "./ui";
import UiHandler from "./ui-handler"; import UiHandler from "./ui-handler";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { PlayerPokemon } from "../field/pokemon"; import { PlayerPokemon } from "../field/pokemon";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species';
import { argbFromRgba } from "@material/material-color-utilities";
import { Type, getTypeRgb } from "../data/type"; import { Type, getTypeRgb } from "../data/type";
import { TextStyle, addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "./text"; import { TextStyle, addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "./text";
import Move, { MoveCategory } from "../data/move"; import Move, { MoveCategory } from "../data/move";
@ -45,6 +47,9 @@ export default class SummaryUiHandler extends UiHandler {
private genderText: Phaser.GameObjects.Text; private genderText: Phaser.GameObjects.Text;
private shinyIcon: Phaser.GameObjects.Image; private shinyIcon: Phaser.GameObjects.Image;
private fusionShinyIcon: Phaser.GameObjects.Image; private fusionShinyIcon: Phaser.GameObjects.Image;
private candyShadow: Phaser.GameObjects.Sprite;
private candyIcon: Phaser.GameObjects.Sprite;
private candyOverlay: Phaser.GameObjects.Sprite;
private statusContainer: Phaser.GameObjects.Container; private statusContainer: Phaser.GameObjects.Container;
private status: Phaser.GameObjects.Image; private status: Phaser.GameObjects.Image;
private summaryPageContainer: Phaser.GameObjects.Container; private summaryPageContainer: Phaser.GameObjects.Container;
@ -137,6 +142,20 @@ export default class SummaryUiHandler extends UiHandler {
this.pokeball.setOrigin(0, 1); this.pokeball.setOrigin(0, 1);
this.summaryContainer.add(this.pokeball); this.summaryContainer.add(this.pokeball);
this.candyShadow = this.scene.add.sprite(13, -140, 'candy');
this.candyShadow.setTint(0x141414)
this.candyShadow.setScale(0.8);
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
this.summaryContainer.add(this.candyShadow);
this.candyIcon = this.scene.add.sprite(13, -140, 'candy');
this.candyIcon.setScale(0.8);
this.summaryContainer.add(this.candyIcon);
this.candyOverlay = this.scene.add.sprite(13, -140, 'candy_overlay');
this.candyOverlay.setScale(0.8);
this.summaryContainer.add(this.candyOverlay);
this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT); this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT);
this.levelText.setOrigin(0, 1); this.levelText.setOrigin(0, 1);
this.summaryContainer.add(this.levelText); this.summaryContainer.add(this.levelText);
@ -223,6 +242,10 @@ export default class SummaryUiHandler extends UiHandler {
this.shinyOverlay.setVisible(this.pokemon.isShiny()); this.shinyOverlay.setVisible(this.pokemon.isShiny());
const colorScheme = starterColors[this.pokemon.species.getRootSpeciesId()];
this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0])));
this.candyOverlay.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1])));
this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4)); this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4));
this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD)); this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD));
this.numberText.setShadowColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true)); this.numberText.setShadowColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true));
@ -252,6 +275,21 @@ export default class SummaryUiHandler extends UiHandler {
this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
} }
var currentFriendship = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].friendship;
if (!currentFriendship || currentFriendship === undefined)
currentFriendship = 0;
const friendshipCap = getStarterValueFriendshipCap(speciesStarters[this.pokemon.species.getRootSpeciesId()]);
const candyCropY = 16 - (16 * (currentFriendship / friendshipCap));
if (this.candyShadow.visible) {
this.candyShadow.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `${currentFriendship}/${friendshipCap}`, true));
this.candyShadow.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
}
this.candyIcon.setCrop(0,candyCropY,16, 16);
this.candyOverlay.setCrop(0,candyCropY,16, 16);
const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny; const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny;
const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant; const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant;