Merge remote-tracking branch 'upstream/main' into move-power-trick

This commit is contained in:
cadi 2024-06-28 16:10:07 +09:00
commit 86d3a4179c
35 changed files with 206 additions and 60 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1875,6 +1875,8 @@ export default class BattleScene extends SceneBase {
return 0.175; return 0.175;
case "battle_legendary_ruinous": //SV Treasures of Ruin Battle case "battle_legendary_ruinous": //SV Treasures of Ruin Battle
return 6.333; return 6.333;
case "battle_legendary_kor_mir": //SV Depths of Area Zero Battle
return 6.442;
case "battle_legendary_loyal_three": //SV Loyal Three Battle case "battle_legendary_loyal_three": //SV Loyal Three Battle
return 6.500; return 6.500;
case "battle_legendary_ogerpon": //SV Ogerpon Battle case "battle_legendary_ogerpon": //SV Ogerpon Battle

View File

@ -311,6 +311,9 @@ export default class Battle {
if (pokemon.species.speciesId === Species.WO_CHIEN || pokemon.species.speciesId === Species.CHIEN_PAO || pokemon.species.speciesId === Species.TING_LU || pokemon.species.speciesId === Species.CHI_YU) { if (pokemon.species.speciesId === Species.WO_CHIEN || pokemon.species.speciesId === Species.CHIEN_PAO || pokemon.species.speciesId === Species.TING_LU || pokemon.species.speciesId === Species.CHI_YU) {
return "battle_legendary_ruinous"; return "battle_legendary_ruinous";
} }
if (pokemon.species.speciesId === Species.KORAIDON || pokemon.species.speciesId === Species.MIRAIDON) {
return "battle_legendary_kor_mir";
}
if (pokemon.species.speciesId === Species.OKIDOGI || pokemon.species.speciesId === Species.MUNKIDORI || pokemon.species.speciesId === Species.FEZANDIPITI) { if (pokemon.species.speciesId === Species.OKIDOGI || pokemon.species.speciesId === Species.MUNKIDORI || pokemon.species.speciesId === Species.FEZANDIPITI) {
return "battle_legendary_loyal_three"; return "battle_legendary_loyal_three";
} }

View File

@ -1,5 +1,5 @@
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
import { BattleEndPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
import { BattleStat, getBattleStatName } from "./battle-stat"; import { BattleStat, getBattleStatName } from "./battle-stat";
import { EncoreTag, PowerTrickTag, SemiInvulnerableTag } from "./battler-tags"; import { EncoreTag, PowerTrickTag, SemiInvulnerableTag } from "./battler-tags";
import { getPokemonMessage, getPokemonNameWithAffix } from "../messages"; import { getPokemonMessage, getPokemonNameWithAffix } from "../messages";
@ -3872,7 +3872,7 @@ export class DisableMoveAttr extends MoveEffectAttr {
export class FrenzyAttr extends MoveEffectAttr { export class FrenzyAttr extends MoveEffectAttr {
constructor() { constructor() {
super(true, MoveEffectTrigger.HIT); super(true, MoveEffectTrigger.HIT, false, true);
} }
canApply(user: Pokemon, target: Pokemon, move: Move, args: any[]) { canApply(user: Pokemon, target: Pokemon, move: Move, args: any[]) {
@ -5549,6 +5549,25 @@ const userSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target:
const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(Abilities.COMATOSE); const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(Abilities.COMATOSE);
/**
* Condition to apply effects only upon applying the move to its last target.
* Currently only used for Make It Rain.
* @param {Pokemon} user The user of the move.
* @param {Pokemon} target The current target of the move.
* @param {Move} move The move to which this condition applies.
* @returns true if the target is the last target to which the move applies.
*/
const lastTargetOnlyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => {
const effectPhase = user.scene.getCurrentPhase();
const targetIndex = target.getFieldIndex() + (target.isPlayer() ? 0 : BattlerIndex.ENEMY);
if (effectPhase instanceof MoveEffectPhase) {
const activeTargets = effectPhase.getTargets();
return (activeTargets.length === 0 || targetIndex >= activeTargets.at(-1).getBattlerIndex());
}
return false;
};
export type MoveAttrFilter = (attr: MoveAttr) => boolean; export type MoveAttrFilter = (attr: MoveAttr) => boolean;
function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<void> { function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<void> {
@ -8052,6 +8071,7 @@ export function initMoves() {
new AttackMove(Moves.MYSTICAL_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 70, 90, 10, 100, 0, 8) new AttackMove(Moves.MYSTICAL_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 70, 90, 10, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.SPATK, 1, true), .attr(StatChangeAttr, BattleStat.SPATK, 1, true),
new AttackMove(Moves.RAGING_FURY, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8) new AttackMove(Moves.RAGING_FURY, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8)
.makesContact(false)
.attr(FrenzyAttr) .attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc) .attr(MissEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY), .target(MoveTarget.RANDOM_NEAR_ENEMY),
@ -8070,6 +8090,7 @@ export function initMoves() {
.attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true) .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true)
.punchingMove(), .punchingMove(),
new AttackMove(Moves.BARB_BARRAGE, Type.POISON, MoveCategory.PHYSICAL, 60, 100, 10, 50, 0, 8) new AttackMove(Moves.BARB_BARRAGE, Type.POISON, MoveCategory.PHYSICAL, 60, 100, 10, 50, 0, 8)
.makesContact(false)
.attr(MovePowerMultiplierAttr, (user, target, move) => target.status && (target.status.effect === StatusEffect.POISON || target.status.effect === StatusEffect.TOXIC) ? 2 : 1) .attr(MovePowerMultiplierAttr, (user, target, move) => target.status && (target.status.effect === StatusEffect.POISON || target.status.effect === StatusEffect.TOXIC) ? 2 : 1)
.attr(StatusEffectAttr, StatusEffect.POISON), .attr(StatusEffectAttr, StatusEffect.POISON),
new AttackMove(Moves.ESPER_WING, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, 100, 0, 8) new AttackMove(Moves.ESPER_WING, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, 100, 0, 8)
@ -8080,6 +8101,7 @@ export function initMoves() {
new SelfStatusMove(Moves.SHELTER, Type.STEEL, -1, 10, 100, 0, 8) new SelfStatusMove(Moves.SHELTER, Type.STEEL, -1, 10, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.DEF, 2, true), .attr(StatChangeAttr, BattleStat.DEF, 2, true),
new AttackMove(Moves.TRIPLE_ARROWS, Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 10, 30, 0, 8) new AttackMove(Moves.TRIPLE_ARROWS, Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 10, 30, 0, 8)
.makesContact(false)
.attr(HighCritAttr) .attr(HighCritAttr)
.attr(StatChangeAttr, BattleStat.DEF, -1) .attr(StatChangeAttr, BattleStat.DEF, -1)
.attr(FlinchAttr) .attr(FlinchAttr)
@ -8293,7 +8315,7 @@ export function initMoves() {
.attr(RemoveScreensAttr), .attr(RemoveScreensAttr),
new AttackMove(Moves.MAKE_IT_RAIN, Type.STEEL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) new AttackMove(Moves.MAKE_IT_RAIN, Type.STEEL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9)
.attr(MoneyAttr) .attr(MoneyAttr)
.attr(StatChangeAttr, BattleStat.SPATK, -1, true, null, true, false) .attr(StatChangeAttr, BattleStat.SPATK, -1, true, lastTargetOnlyCondition, true, false)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.PSYBLADE, Type.PSYCHIC, MoveCategory.PHYSICAL, 80, 100, 15, -1, 0, 9) new AttackMove(Moves.PSYBLADE, Type.PSYCHIC, MoveCategory.PHYSICAL, 80, 100, 15, -1, 0, 9)
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && user.isGrounded() ? 1.5 : 1) .attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && user.isGrounded() ? 1.5 : 1)
@ -8316,8 +8338,7 @@ export function initMoves() {
.target(MoveTarget.BOTH_SIDES), .target(MoveTarget.BOTH_SIDES),
new SelfStatusMove(Moves.TIDY_UP, Type.NORMAL, -1, 10, -1, 0, 9) new SelfStatusMove(Moves.TIDY_UP, Type.NORMAL, -1, 10, -1, 0, 9)
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPD ], 1, true, null, true, true) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPD ], 1, true, null, true, true)
.attr(RemoveArenaTrapAttr) .attr(RemoveArenaTrapAttr, true),
.target(MoveTarget.BOTH_SIDES),
new StatusMove(Moves.SNOWSCAPE, Type.ICE, -1, 10, -1, 0, 9) new StatusMove(Moves.SNOWSCAPE, Type.ICE, -1, 10, -1, 0, 9)
.attr(WeatherChangeAttr, WeatherType.SNOW) .attr(WeatherChangeAttr, WeatherType.SNOW)
.target(MoveTarget.BOTH_SIDES), .target(MoveTarget.BOTH_SIDES),

View File

@ -639,6 +639,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.AEGISLASH, "shield", "blade", new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))), new SpeciesFormChange(Species.AEGISLASH, "shield", "blade", new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))),
new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true) new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true)
], ],
[Species.XERNEAS]: [
new SpeciesFormChange(Species.XERNEAS, "neutral", "active", new SpeciesFormChangeActiveTrigger(true), true),
new SpeciesFormChange(Species.XERNEAS, "active", "neutral", new SpeciesFormChangeActiveTrigger(false), true)
],
[Species.ZYGARDE]: [ [Species.ZYGARDE]: [
new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true),

View File

@ -3406,12 +3406,15 @@ export class EnemyPokemon extends Pokemon {
public aiType: AiType; public aiType: AiType;
public bossSegments: integer; public bossSegments: integer;
public bossSegmentIndex: integer; public bossSegmentIndex: integer;
/** To indicate of the instance was populated with a dataSource -> e.g. loaded & populated from session data */
public readonly isPopulatedFromDataSource: boolean;
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean, dataSource: PokemonData) { constructor(scene: BattleScene, species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean, dataSource: PokemonData) {
super(scene, 236, 84, species, level, dataSource?.abilityIndex, dataSource?.formIndex, super(scene, 236, 84, species, level, dataSource?.abilityIndex, dataSource?.formIndex,
dataSource?.gender, dataSource ? dataSource.shiny : false, dataSource ? dataSource.variant : undefined, null, dataSource ? dataSource.nature : undefined, dataSource); dataSource?.gender, dataSource ? dataSource.shiny : false, dataSource ? dataSource.variant : undefined, null, dataSource ? dataSource.nature : undefined, dataSource);
this.trainerSlot = trainerSlot; this.trainerSlot = trainerSlot;
this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource
if (boss) { if (boss) {
this.setBoss(boss, dataSource?.bossSegments); this.setBoss(boss, dataSource?.bossSegments);
} }
@ -3461,6 +3464,13 @@ export class EnemyPokemon extends Pokemon {
} }
} }
/**
* Sets the pokemons boss status. If true initializes the boss segments either from the arguments
* or through the the Scene.getEncounterBossSegments function
*
* @param boss if the pokemon is a boss
* @param bossSegments amount of boss segments (health-bar segments)
*/
setBoss(boss: boolean = true, bossSegments: integer = 0): void { setBoss(boss: boolean = true, bossSegments: integer = 0): void {
if (boss) { if (boss) {
this.bossSegments = bossSegments || this.scene.getEncounterBossSegments(this.scene.currentBattle.waveIndex, this.level, this.species, true); this.bossSegments = bossSegments || this.scene.getEncounterBossSegments(this.scene.currentBattle.waveIndex, this.level, this.species, true);

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH Vs. Coronospa", "battle_legendary_calyrex": "SWSH Vs. Coronospa",
"battle_legendary_birds_galar": "SWSH Vs. Legendäre Galar-Vögel", "battle_legendary_birds_galar": "SWSH Vs. Legendäre Galar-Vögel",
"battle_legendary_ruinous": "KAPU Vs. Schätze des Unheils", "battle_legendary_ruinous": "KAPU Vs. Schätze des Unheils",
"battle_legendary_kor_mir": "KAPU Die Tiefen von Zone Null",
"battle_legendary_loyal_three": "KAPU Drei Gefährten", "battle_legendary_loyal_three": "KAPU Drei Gefährten",
"battle_legendary_ogerpon": "KAPU Vs. Ogerpon", "battle_legendary_ogerpon": "KAPU Vs. Ogerpon",
"battle_legendary_terapagos": "KAPU Vs. Terapagos", "battle_legendary_terapagos": "KAPU Vs. Terapagos",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "HAFTUNGSAUSSCHLUSS", "disclaimer": "HAFTUNGSAUSSCHLUSS",
"disclaimerDescription": "Dieses Spiel ist ein unfertiges Produkt. Es kann spielbeinträchtigende Fehler (bis hin zum Verlust des Speicherstandes)\n aufweisen, sich ohne Vorankündigung ändern und es gibt keine Garantie dass es weiterentwickelt oder fertiggestellt wird.", "disclaimerDescription": "Dieses Spiel ist ein unfertiges Produkt. Es kann spielbeinträchtigende Fehler (bis hin zum Verlust des Speicherstandes)\n aufweisen, sich ohne Vorankündigung ändern und es gibt keine Garantie dass es weiterentwickelt oder fertiggestellt wird.",
"choosePokemon": "Choose a Pokémon.", "choosePokemon": "Choose a Pokémon.",
"errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH Calyrex Battle", "battle_legendary_calyrex": "SWSH Calyrex Battle",
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle", "battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
"battle_legendary_ruinous": "SV Treasures of Ruin Battle", "battle_legendary_ruinous": "SV Treasures of Ruin Battle",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV Loyal Three Battle", "battle_legendary_loyal_three": "SV Loyal Three Battle",
"battle_legendary_ogerpon": "SV Ogerpon Battle", "battle_legendary_ogerpon": "SV Ogerpon Battle",
"battle_legendary_terapagos": "SV Terapagos Battle", "battle_legendary_terapagos": "SV Terapagos Battle",
@ -91,7 +92,7 @@ export const bgmName: SimpleTranslationEntries = {
"cave": "PMD EoS Sky Peak Cave", "cave": "PMD EoS Sky Peak Cave",
"construction_site": "PMD EoS Boulder Quarry", "construction_site": "PMD EoS Boulder Quarry",
"desert": "PMD EoS Northern Desert", "desert": "PMD EoS Northern Desert",
"dojo": "PMD EoS Marowa Dojo", "dojo": "PMD EoS Marowak Dojo",
"end": "PMD RTDX Sky Tower", "end": "PMD RTDX Sky Tower",
"factory": "PMD EoS Concealed Ruins", "factory": "PMD EoS Concealed Ruins",
"fairy_cave": "PMD EoS Star Cave", "fairy_cave": "PMD EoS Star Cave",

View File

@ -447,7 +447,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "My old associates need me... Are you going to get in my way?" 1: "My old associates need me... Are you going to get in my way?"
}, },
"victory": { "victory": {
1: "How is this possible...?\nThe precious dream of Team Rocket has become little more than an illusion..." 1: "How is this possible...? The precious dream of Team Rocket has become little more than an illusion..."
}, },
"defeat": { "defeat": {
1: "Team Rocket will be reborn again, and I will rule the world!" 1: "Team Rocket will be reborn again, and I will rule the world!"
@ -466,7 +466,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"magma_boss_maxie_2": { "magma_boss_maxie_2": {
"encounter": { "encounter": {
1: "You are the final obstacle remaining between me and my goals.\nBrace yourself for my ultimate attack! Fuhahaha!" 1: `You are the final obstacle remaining between me and my goals.
$Brace yourself for my ultimate attack! Fuhahaha!`
}, },
"victory": { "victory": {
1: "This... This is not.. Ngh..." 1: "This... This is not.. Ngh..."
@ -499,7 +500,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_1": { "galactic_boss_cyrus_1": {
"encounter": { "encounter": {
1: "You were compelled to come here by such vacuous sentimentality.\nI will make you regret paying heed to your heart!" 1: `You were compelled to come here by such vacuous sentimentality.
$I will make you regret paying heed to your heart!`
}, },
"victory": { "victory": {
1: "Interesting. And quite curious." 1: "Interesting. And quite curious."
@ -510,7 +512,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_2": { "galactic_boss_cyrus_2": {
"encounter": { "encounter": {
1: "So we meet again. It seems our fates have become intertwined.\nBut here and now, I will finally break that bond!" 1: `So we meet again. It seems our fates have become intertwined.
$But here and now, I will finally break that bond!`
}, },
"victory": { "victory": {
1: "How? How? HOW?!" 1: "How? How? HOW?!"

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "DISCLAIMER", "disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed.", "disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed.",
"choosePokemon": "Choose a Pokémon.", "choosePokemon": "Choose a Pokémon.",
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH - ¡Vs Calyrex!", "battle_legendary_calyrex": "SWSH - ¡Vs Calyrex!",
"battle_legendary_birds_galar": "SWSH - ¡Vs Aves Legendarias de Galar!", "battle_legendary_birds_galar": "SWSH - ¡Vs Aves Legendarias de Galar!",
"battle_legendary_ruinous": "SV - ¡Vs Tesoros Funestos!", "battle_legendary_ruinous": "SV - ¡Vs Tesoros Funestos!",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV - ¡Vs Compatrones!", "battle_legendary_loyal_three": "SV - ¡Vs Compatrones!",
"battle_legendary_ogerpon": "SV - ¡Vs Ogerpon!", "battle_legendary_ogerpon": "SV - ¡Vs Ogerpon!",
"battle_legendary_terapagos": "SV - ¡Vs Terapagos!", "battle_legendary_terapagos": "SV - ¡Vs Terapagos!",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "AVISO", "disclaimer": "AVISO",
"disclaimerDescription": "Este juego es un producto inacabado; puede tener problemas de jugabilidad (incluyendo la posible pérdida\n de datos de guardado),cambiar sin avisar, y puede o no puede ser actualizado hasta ser completado.", "disclaimerDescription": "Este juego es un producto inacabado; puede tener problemas de jugabilidad (incluyendo la posible pérdida\n de datos de guardado),cambiar sin avisar, y puede o no puede ser actualizado hasta ser completado.",
"choosePokemon": "Choose a Pokémon.", "choosePokemon": "Choose a Pokémon.",
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta,\nel juego se reconectará automáticamente.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "ÉB - Vs. Sylveroy", "battle_legendary_calyrex": "ÉB - Vs. Sylveroy",
"battle_legendary_birds_galar": "ÉB - Vs. Oiseaux Légendaires de Galar", "battle_legendary_birds_galar": "ÉB - Vs. Oiseaux Légendaires de Galar",
"battle_legendary_ruinous": "ÉV - Vs. Trésors du fléau", "battle_legendary_ruinous": "ÉV - Vs. Trésors du fléau",
"battle_legendary_kor_mir": "ÉV - Profondeurs de la Zone Zéro (Combat)",
"battle_legendary_loyal_three": "ÉV - Vs. Adoramis", "battle_legendary_loyal_three": "ÉV - Vs. Adoramis",
"battle_legendary_ogerpon": "ÉV - Vs. Ogerpon", "battle_legendary_ogerpon": "ÉV - Vs. Ogerpon",
"battle_legendary_terapagos": "ÉV - Vs. Terapagos", "battle_legendary_terapagos": "ÉV - Vs. Terapagos",

View File

@ -447,7 +447,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "Mes anciens collaborateurs mattendent.\nComptes-tu men empêcher ?" 1: "Mes anciens collaborateurs mattendent.\nComptes-tu men empêcher ?"
}, },
"victory": { "victory": {
1: "Comment c'est possible… ?\nLe grand dessein de la Team Rocket nest plus quune illusion…" 1: "Comment c'est possible… ? Le grand dessein de la Team Rocket nest plus quune illusion…"
}, },
"defeat": { "defeat": {
1: "La Team Rocket renaitra, et je dominerai le monde !" 1: "La Team Rocket renaitra, et je dominerai le monde !"
@ -499,7 +499,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_1": { "galactic_boss_cyrus_1": {
"encounter": { "encounter": {
1: "Tu tes senti obligé de venir ici dans un acte vide de sens.\nJe vais te le faire regretter." 1: "Tu tes senti obligé de venir ici dans un acte vide de sens. Je vais te le faire regretter."
}, },
"victory": { "victory": {
1: "Intéressant. Et plutôt curieux." 1: "Intéressant. Et plutôt curieux."
@ -510,7 +510,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_2": { "galactic_boss_cyrus_2": {
"encounter": { "encounter": {
1: "Nous y revoilà. Il semblerait que nos destinées soient entremêlées.\nIl est lheure dy mettre un terme." 1: "Nous y revoilà. Il semblerait que nos destinées soient entremêlées. Il est lheure dy mettre un terme."
}, },
"victory": { "victory": {
1: "Comment. Comment ?\nCOMMENT ?!" 1: "Comment. Comment ?\nCOMMENT ?!"
@ -2954,7 +2954,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
1: "Mes anciens collaborateurs mattendent.\nComptes-tu men empêcher ?" 1: "Mes anciens collaborateurs mattendent.\nComptes-tu men empêcher ?"
}, },
"victory": { "victory": {
1: "Comment c'est possible… ?\nLe grand dessein de la Team Rocket nest plus quune illusion…" 1: "Comment c'est possible… ? Le grand dessein de la Team Rocket nest plus quune illusion…"
}, },
"defeat": { "defeat": {
1: "La Team Rocket renaitra, et je dominerai le monde !" 1: "La Team Rocket renaitra, et je dominerai le monde !"
@ -3006,7 +3006,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_1": { "galactic_boss_cyrus_1": {
"encounter": { "encounter": {
1: "Tu tes sentie obligée de venir ici dans un acte vide de sens.\nJe vais te le faire regretter." 1: "Tu tes sentie obligée de venir ici dans un acte vide de sens. Je vais te le faire regretter."
}, },
"victory": { "victory": {
1: "Intéressant. Et plutôt curieux." 1: "Intéressant. Et plutôt curieux."
@ -3017,7 +3017,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
}, },
"galactic_boss_cyrus_2": { "galactic_boss_cyrus_2": {
"encounter": { "encounter": {
1: "Nous y revoilà. Il semblerait que nos destinées soient entremêlées.\nIl est lheure dy mettre un terme." 1: "Nous y revoilà. Il semblerait que nos destinées soient entremêlées. Il est lheure dy mettre un terme."
}, },
"victory": { "victory": {
1: "Comment. Comment ?\nCOMMENT ?!" 1: "Comment. Comment ?\nCOMMENT ?!"

View File

@ -49,4 +49,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "AVERTISSEMENT", "disclaimer": "AVERTISSEMENT",
"disclaimerDescription": "Ce jeu nest pas un produit fini et peut contenir des problèmes de jouabilité, dont de possibles pertes de sauvegardes,\ndes modifications sans avertissement et pourrait ou non encore être mis à jour ou terminé.", "disclaimerDescription": "Ce jeu nest pas un produit fini et peut contenir des problèmes de jouabilité, dont de possibles pertes de sauvegardes,\ndes modifications sans avertissement et pourrait ou non encore être mis à jour ou terminé.",
"choosePokemon": "Sélectionnez un Pokémon.", "choosePokemon": "Sélectionnez un Pokémon.",
"errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH Calyrex Battle", "battle_legendary_calyrex": "SWSH Calyrex Battle",
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle", "battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
"battle_legendary_ruinous": "SV Treasures of Ruin Battle", "battle_legendary_ruinous": "SV Treasures of Ruin Battle",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV Loyal Three Battle", "battle_legendary_loyal_three": "SV Loyal Three Battle",
"battle_legendary_ogerpon": "SV Ogerpon Battle", "battle_legendary_ogerpon": "SV Ogerpon Battle",
"battle_legendary_terapagos": "SV Terapagos Battle", "battle_legendary_terapagos": "SV Terapagos Battle",
@ -91,7 +92,7 @@ export const bgmName: SimpleTranslationEntries = {
"cave": "PMD EoS Sky Peak Cave", "cave": "PMD EoS Sky Peak Cave",
"construction_site": "PMD EoS Boulder Quarry", "construction_site": "PMD EoS Boulder Quarry",
"desert": "PMD EoS Northern Desert", "desert": "PMD EoS Northern Desert",
"dojo": "PMD EoS Marowa Dojo", "dojo": "PMD EoS Marowak Dojo",
"end": "PMD RTDX Sky Tower", "end": "PMD RTDX Sky Tower",
"factory": "PMD EoS Concealed Ruins", "factory": "PMD EoS Concealed Ruins",
"fairy_cave": "PMD EoS Star Cave", "fairy_cave": "PMD EoS Star Cave",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "DISCLAIMER", "disclaimer": "DISCLAIMER",
"disclaimerDescription": "Questo gioco è un prodotto incompleto; si potrebbero riscontrare errori (inclusa la perdita dei dati di salvataggio),\ncambiamenti impercettibili, e non è detto che venga aggiornato nel tempo o mai completato del tutto.", "disclaimerDescription": "Questo gioco è un prodotto incompleto; si potrebbero riscontrare errori (inclusa la perdita dei dati di salvataggio),\ncambiamenti impercettibili, e non è detto che venga aggiornato nel tempo o mai completato del tutto.",
"choosePokemon": "Choose a Pokémon.", "choosePokemon": "Choose a Pokémon.",
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
} as const; } as const;

View File

@ -9,5 +9,5 @@ export const abilityTriggers: SimpleTranslationEntries = {
"poisonHeal": "{{pokemonName}}[[는]] {{abilityName}}[[로]]인해\n조금 회복했다.", "poisonHeal": "{{pokemonName}}[[는]] {{abilityName}}[[로]]인해\n조금 회복했다.",
"trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!", "trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!",
"windPowerCharged": "{{pokemonName}}[[는]]\n{{moveName}}에 맞아 충전되었다!", "windPowerCharged": "{{pokemonName}}[[는]]\n{{moveName}}에 맞아 충전되었다!",
"quickDraw": "{{pokemonName}} can act faster than normal, thanks to its Quick Draw!", "quickDraw": "{{pokemonName}}[[는]]\n퀵드로에 의해 행동이 빨라졌다!",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH 버드렉스 배틀", "battle_legendary_calyrex": "SWSH 버드렉스 배틀",
"battle_legendary_birds_galar": "SWSH 가라르 전설의 새 배틀", "battle_legendary_birds_galar": "SWSH 가라르 전설의 새 배틀",
"battle_legendary_ruinous": "SV 재앙의 보물 배틀", "battle_legendary_ruinous": "SV 재앙의 보물 배틀",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV 세벗들 배틀", "battle_legendary_loyal_three": "SV 세벗들 배틀",
"battle_legendary_ogerpon": "SV 오거폰 배틀", "battle_legendary_ogerpon": "SV 오거폰 배틀",
"battle_legendary_terapagos": "SV 테라파고스 배틀", "battle_legendary_terapagos": "SV 테라파고스 배틀",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "면책 조항", "disclaimer": "면책 조항",
"disclaimerDescription": "이 게임은 완전히 개발되지 않았습니다- (세이브 데이터 소실을 포함) 플레이에 지장을 주는 문제가 생길 수 있으며,\n공지 없이 업데이트가 진행 혹은 중지될 수 있습니다.", "disclaimerDescription": "이 게임은 완전히 개발되지 않았습니다- (세이브 데이터 소실을 포함) 플레이에 지장을 주는 문제가 생길 수 있으며,\n공지 없이 업데이트가 진행 혹은 중지될 수 있습니다.",
"choosePokemon": "포켓몬을 선택하세요.", "choosePokemon": "포켓몬을 선택하세요.",
"errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH Calyrex Battle", "battle_legendary_calyrex": "SWSH Calyrex Battle",
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle", "battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
"battle_legendary_ruinous": "SV Treasures of Ruin Battle", "battle_legendary_ruinous": "SV Treasures of Ruin Battle",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV Loyal Three Battle", "battle_legendary_loyal_three": "SV Loyal Three Battle",
"battle_legendary_ogerpon": "SV Ogerpon Battle", "battle_legendary_ogerpon": "SV Ogerpon Battle",
"battle_legendary_terapagos": "SV Terapagos Battle", "battle_legendary_terapagos": "SV Terapagos Battle",
@ -91,7 +92,7 @@ export const bgmName: SimpleTranslationEntries = {
"cave": "PMD EoS Sky Peak Cave", "cave": "PMD EoS Sky Peak Cave",
"construction_site": "PMD EoS Boulder Quarry", "construction_site": "PMD EoS Boulder Quarry",
"desert": "PMD EoS Northern Desert", "desert": "PMD EoS Northern Desert",
"dojo": "PMD EoS Marowa Dojo", "dojo": "PMD EoS Marowak Dojo",
"end": "PMD RTDX Sky Tower", "end": "PMD RTDX Sky Tower",
"factory": "PMD EoS Concealed Ruins", "factory": "PMD EoS Concealed Ruins",
"fairy_cave": "PMD EoS Star Cave", "fairy_cave": "PMD EoS Star Cave",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "AVISO", "disclaimer": "AVISO",
"disclaimerDescription": "Este jogo é um produto inacabado; ele pode ter problemas de jogabilidade (incluindo possíveis\n perdas de dados salvos), sofrer alterações sem aviso prévio e pode ou não ser atualizado ou concluído.", "disclaimerDescription": "Este jogo é um produto inacabado; ele pode ter problemas de jogabilidade (incluindo possíveis\n perdas de dados salvos), sofrer alterações sem aviso prévio e pode ou não ser atualizado ou concluído.",
"choosePokemon": "Escolha um Pokémon.", "choosePokemon": "Escolha um Pokémon.",
"errorServerDown": "Opa! Não foi possível conectar-se ao servidor.\n\nVocê pode deixar essa janela aberta,\npois o jogo irá se reconectar automaticamente.",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "剑盾「战斗!蕾冠王」", "battle_legendary_calyrex": "剑盾「战斗!蕾冠王」",
"battle_legendary_birds_galar": "剑盾「战斗!传说的鸟宝可梦」", "battle_legendary_birds_galar": "剑盾「战斗!传说的鸟宝可梦」",
"battle_legendary_ruinous": "朱紫「战斗!灾厄宝可梦」", "battle_legendary_ruinous": "朱紫「战斗!灾厄宝可梦」",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "朱紫「战斗!宝伴」", "battle_legendary_loyal_three": "朱紫「战斗!宝伴」",
"battle_legendary_ogerpon": "朱紫「战斗!厄鬼椪」", "battle_legendary_ogerpon": "朱紫「战斗!厄鬼椪」",
"battle_legendary_terapagos": "朱紫「战斗!太乐巴戈斯」", "battle_legendary_terapagos": "朱紫「战斗!太乐巴戈斯」",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "免责声明", "disclaimer": "免责声明",
"disclaimerDescription": "这个游戏尚未完成; 可能存在游戏性问题(包括潜在的丢档风险)、\n 不经通知的调整、 未来可能会更新或完成更多内容", "disclaimerDescription": "这个游戏尚未完成; 可能存在游戏性问题(包括潜在的丢档风险)、\n 不经通知的调整、 未来可能会更新或完成更多内容",
"choosePokemon": "选择一只宝可梦。", "choosePokemon": "选择一只宝可梦。",
"errorServerDown": "糟糕!访问服务器时发生了错误。\n\n你可以保持页面开启\n游戏会自动重新连接。",
} as const; } as const;

View File

@ -96,12 +96,12 @@ export const modifierType: ModifierTypeTranslationEntries = {
description: "攻击以40/25/12.5%的伤害造成2/3/4次伤害", description: "攻击以40/25/12.5%的伤害造成2/3/4次伤害",
}, },
"TmModifierType": { "TmModifierType": {
name: "招式学习器 {{moveId}} - {{moveName}}", name: "招式学习器\n{{moveId}} - {{moveName}}",
description: "教会一只宝可梦{{moveName}}。", description: "教会一只宝可梦{{moveName}}。",
}, },
"TmModifierTypeWithInfo": { "TmModifierTypeWithInfo": {
name: "招式学习器 {{moveId}} - {{moveName}}", name: "招式学习器\n{{moveId}} - {{moveName}}",
description: "教会一只宝可梦{{moveName}}\n(Hold C or Shift for more info)。", description: "教会一只宝可梦{{moveName}}\n(按住C或者Shift查看更多信息)。",
}, },
"EvolutionItemModifierType": { "EvolutionItemModifierType": {
description: "使某些宝可梦进化。", description: "使某些宝可梦进化。",

View File

@ -1,37 +1,37 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const splashMessages: SimpleTranslationEntries = { export const splashMessages: SimpleTranslationEntries = {
"battlesWon": "Battles Won!", "battlesWon": "胜利场数!",
"joinTheDiscord": "Join the Discord!", "joinTheDiscord": "加入Discord!",
"infiniteLevels": "Infinite Levels!", "infiniteLevels": "无限等级!",
"everythingStacks": "Everything Stacks!", "everythingStacks": "叠加一切!",
"optionalSaveScumming": "Optional Save Scumming!", "optionalSaveScumming": "可选SL!",
"biomes": "35 Biomes!", "biomes": "35种生态!",
"openSource": "Open Source!", "openSource": "开源!",
"playWithSpeed": "Play with 5x Speed!", "playWithSpeed": "五倍速游玩!",
"liveBugTesting": "Live Bug Testing!", "liveBugTesting": "即时漏洞测试!",
"heavyInfluence": "Heavy RoR2 Influence!", "heavyInfluence": "深受雨中冒险2影响!",
"pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!", "pokemonRiskAndPokemonRain": "宝可梦雨中冒险!",
"nowWithMoreSalt": "Now with 33% More Salt!", "nowWithMoreSalt": "增加33%的盐!",
"infiniteFusionAtHome": "Infinite Fusion at Home!", "infiniteFusionAtHome": "家庭版无限融合!",
"brokenEggMoves": "Broken Egg Moves!", "brokenEggMoves": "超模的蛋招式!",
"magnificent": "Magnificent!", "magnificent": "华丽!",
"mubstitute": "Mubstitute!", "mubstitute": "替身!",
"thatsCrazy": "That\'s Crazy!", "thatsCrazy": "疯狂!",
"oranceJuice": "Orance Juice!", "oranceJuice": "橙汁!",
"questionableBalancing": "Questionable Balancing!", "questionableBalancing": "值得质疑的平衡性!",
"coolShaders": "Cool Shaders!", "coolShaders": "炫酷的着色器!",
"aiFree": "AI-Free!", "aiFree": "不含AI!",
"suddenDifficultySpikes": "Sudden Difficulty Spikes!", "suddenDifficultySpikes": "突然上升的难度曲线!",
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!", "basedOnAnUnfinishedFlashGame": "基于未完成的flash游戏!",
"moreAddictiveThanIntended": "More Addictive than Intended!", "moreAddictiveThanIntended": "比预期的更上瘾!",
"mostlyConsistentSeeds": "Mostly Consistent Seeds!", "mostlyConsistentSeeds": "多数情况下一致的种子!",
"achievementPointsDontDoAnything": "Achievement Points Don\'t Do Anything!", "achievementPointsDontDoAnything": "成就点没有任何用处!",
"youDoNotStartAtLevel": "You Do Not Start at Level 2000!", "youDoNotStartAtLevel": "你不能从2000级开始!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!", "dontTalkAboutTheManaphyEggIncident": "禁止谈论玛纳霏蛋事件!",
"alsoTryPokengine": "Also Try Pokéngine!", "alsoTryPokengine": "也试试Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!", "alsoTryEmeraldRogue": "也试试绿宝石肉鸽!",
"alsoTryRadicalRed": "Also Try Radical Red!", "alsoTryRadicalRed": "也试试激进红!",
"eeveeExpo": "Eevee Expo!", "eeveeExpo": "伊布博览会!",
"ynoproject": "YNOproject!", "ynoproject": "YNOproject!",
} as const; } as const;

View File

@ -62,6 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH Calyrex Battle", "battle_legendary_calyrex": "SWSH Calyrex Battle",
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle", "battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
"battle_legendary_ruinous": "SV Treasures of Ruin Battle", "battle_legendary_ruinous": "SV Treasures of Ruin Battle",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
"battle_legendary_loyal_three": "SV Loyal Three Battle", "battle_legendary_loyal_three": "SV Loyal Three Battle",
"battle_legendary_ogerpon": "SV Ogerpon Battle", "battle_legendary_ogerpon": "SV Ogerpon Battle",
"battle_legendary_terapagos": "SV Terapagos Battle", "battle_legendary_terapagos": "SV Terapagos Battle",
@ -91,7 +92,7 @@ export const bgmName: SimpleTranslationEntries = {
"cave": "PMD EoS Sky Peak Cave", "cave": "PMD EoS Sky Peak Cave",
"construction_site": "PMD EoS Boulder Quarry", "construction_site": "PMD EoS Boulder Quarry",
"desert": "PMD EoS Northern Desert", "desert": "PMD EoS Northern Desert",
"dojo": "PMD EoS Marowa Dojo", "dojo": "PMD EoS Marowak Dojo",
"end": "PMD RTDX Sky Tower", "end": "PMD RTDX Sky Tower",
"factory": "PMD EoS Concealed Ruins", "factory": "PMD EoS Concealed Ruins",
"fairy_cave": "PMD EoS Star Cave", "fairy_cave": "PMD EoS Star Cave",

View File

@ -54,4 +54,5 @@ export const menu: SimpleTranslationEntries = {
"disclaimer": "DISCLAIMER", "disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed.", "disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed.",
"choosePokemon": "Choose a Pokémon.", "choosePokemon": "Choose a Pokémon.",
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
} as const; } as const;

View File

@ -868,9 +868,11 @@ export class EncounterPhase extends BattlePhase {
if (battle.battleType === BattleType.TRAINER) { if (battle.battleType === BattleType.TRAINER) {
loadEnemyAssets.push(battle.trainer.loadAssets().then(() => battle.trainer.initSprite())); loadEnemyAssets.push(battle.trainer.loadAssets().then(() => battle.trainer.initSprite()));
} else { } else {
// This block only applies for double battles to init the boss segments (idk why it's split up like this)
if (battle.enemyParty.filter(p => p.isBoss()).length > 1) { if (battle.enemyParty.filter(p => p.isBoss()).length > 1) {
for (const enemyPokemon of battle.enemyParty) { for (const enemyPokemon of battle.enemyParty) {
if (enemyPokemon.isBoss()) { // If the enemy pokemon is a boss and wasn't populated from data source, then set it up
if (enemyPokemon.isBoss() && !enemyPokemon.isPopulatedFromDataSource) {
enemyPokemon.setBoss(true, Math.ceil(enemyPokemon.bossSegments * (enemyPokemon.getSpeciesForm().baseTotal / totalBst))); enemyPokemon.setBoss(true, Math.ceil(enemyPokemon.bossSegments * (enemyPokemon.getSpeciesForm().baseTotal / totalBst)));
enemyPokemon.initBattleInfo(); enemyPokemon.initBattleInfo();
} }

View File

@ -28,7 +28,7 @@ describe("Abilities - Dry Skin", () => {
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DRY_SKIN); vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DRY_SKIN);
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHARMANDER); vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHARMANDER);
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE);
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHANDELURE); vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHANDELURE);
}); });

View File

@ -382,7 +382,7 @@ describe("Abilities - Parental Bond", () => {
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(MoveEndPhase, false);
expect(enemyPokemon.hp).toBe(Math.ceil(enemyStartingHp * 0.25)); expect(enemyPokemon.hp).toBe(Math.ceil(enemyStartingHp * 0.25));
}, TIMEOUT }, TIMEOUT
@ -413,7 +413,7 @@ describe("Abilities - Parental Bond", () => {
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(MoveEndPhase, false);
expect(enemyPokemon.hp).toBe(enemyStartingHp - 200); expect(enemyPokemon.hp).toBe(enemyStartingHp - 200);
}, TIMEOUT }, TIMEOUT

View File

@ -0,0 +1,82 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import Phaser from "phaser";
import GameManager from "#app/test/utils/gameManager";
import * as overrides from "#app/overrides";
import { Species } from "#enums/species";
import {
CommandPhase,
MoveEndPhase,
StatChangePhase,
} from "#app/phases";
import { Moves } from "#enums/moves";
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
import { Abilities } from "#enums/abilities";
import { BattleStat } from "#app/data/battle-stat.js";
describe("Moves - Make It Rain", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.MAKE_IT_RAIN, Moves.SPLASH]);
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX);
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA);
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100);
vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100);
});
it("should only reduce Sp. Atk. once in a double battle", async () => {
await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]);
const playerPokemon = game.scene.getPlayerField();
expect(playerPokemon.length).toBe(2);
playerPokemon.forEach(p => expect(p).toBeDefined());
const enemyPokemon = game.scene.getEnemyField();
expect(enemyPokemon.length).toBe(2);
enemyPokemon.forEach(p => expect(p).toBeDefined());
game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN));
await game.phaseInterceptor.to(CommandPhase);
game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH));
await game.phaseInterceptor.to(MoveEndPhase);
expect(playerPokemon[0].summonData.battleStats[BattleStat.SPATK]).toBe(-1);
});
it("should apply effects even if the target faints", async () => {
vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); // ensures the enemy will faint
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(false);
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
await game.startBattle([Species.CHARIZARD]);
const playerPokemon = game.scene.getPlayerPokemon();
expect(playerPokemon).toBeDefined();
const enemyPokemon = game.scene.getEnemyPokemon();
expect(enemyPokemon).toBeDefined();
game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN));
await game.phaseInterceptor.to(StatChangePhase);
expect(enemyPokemon.isFainted()).toBe(true);
expect(playerPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(-1);
});
});

View File

@ -4,6 +4,7 @@ import { addTextObject, TextStyle } from "./text";
import { Mode } from "./ui"; import { Mode } from "./ui";
import { updateUserInfo } from "#app/account"; import { updateUserInfo } from "#app/account";
import * as Utils from "#app/utils"; import * as Utils from "#app/utils";
import i18next from "i18next";
export default class UnavailableModalUiHandler extends ModalUiHandler { export default class UnavailableModalUiHandler extends ModalUiHandler {
private reconnectTimer: NodeJS.Timeout; private reconnectTimer: NodeJS.Timeout;
@ -43,7 +44,7 @@ export default class UnavailableModalUiHandler extends ModalUiHandler {
setup(): void { setup(): void {
super.setup(); super.setup();
const label = addTextObject(this.scene, this.getWidth() / 2, this.getHeight() / 2, "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.", TextStyle.WINDOW, { fontSize: "48px", align: "center" }); const label = addTextObject(this.scene, this.getWidth() / 2, this.getHeight() / 2, i18next.t("menu:errorServerDown"), TextStyle.WINDOW, { fontSize: "48px", align: "center" });
label.setOrigin(0.5, 0.5); label.setOrigin(0.5, 0.5);
this.modalContainer.add(label); this.modalContainer.add(label);