Compare commits

..

No commits in common. "44d5d542213975f29c1b4cf1a60246508f2005da" and "cf065befd3fccef22c07e3ca87719f58f0f82d21" have entirely different histories.

20 changed files with 514 additions and 580 deletions

View File

@ -782,14 +782,6 @@ export default class BattleScene extends SceneBase {
return this.getPlayerField().find(p => p.isActive());
}
/**
* Finds the first {@linkcode Pokemon.isActive() | active PlayerPokemon} that isn't also currently switching out
* @returns Either the first {@linkcode PlayerPokemon} satisfying, or undefined if no player pokemon on the field satisfy
*/
getNonSwitchedPlayerPokemon(): PlayerPokemon | undefined {
return this.getPlayerField().find(p => p.isActive() && p.switchOutStatus === false);
}
/**
* Returns an array of PlayerPokemon of length 1 or 2 depending on if double battles or not
* @returns array of {@linkcode PlayerPokemon}
@ -807,14 +799,6 @@ export default class BattleScene extends SceneBase {
return this.getEnemyField().find(p => p.isActive());
}
/**
* Finds the first {@linkcode Pokemon.isActive() | active EnemyPokemon} pokemon from the enemy that isn't also currently switching out
* @returns Either the first {@linkcode EnemyPokemon} satisfying, or undefined if no player pokemon on the field satisfy
*/
getNonSwitchedEnemyPokemon(): EnemyPokemon | undefined {
return this.getEnemyField().find(p => p.isActive() && p.switchOutStatus === false);
}
/**
* Returns an array of EnemyPokemon of length 1 or 2 depending on if double battles or not
* @returns array of {@linkcode EnemyPokemon}

View File

@ -16,14 +16,6 @@ import { TrainerType } from "#enums/trainer-type";
import i18next from "#app/plugins/i18n";
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
import { CustomModifierSettings } from "#app/modifier/modifier-type";
import { ModifierTier } from "#app/modifier/modifier-tier";
export enum ClassicFixedBossWaves {
// TODO: other fixed wave battles should be added here
EVIL_BOSS_1 = 115,
EVIL_BOSS_2 = 165,
}
export enum BattleType {
WILD,
@ -427,7 +419,6 @@ export class FixedBattleConfig {
public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: number;
public customModifierRewardSettings?: CustomModifierSettings;
setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType;
@ -453,11 +444,6 @@ export class FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this;
}
setCustomModifierRewards(customModifierRewardSettings: CustomModifierSettings) {
this.customModifierRewardSettings = customModifierRewardSettings;
return this;
}
}
@ -517,13 +503,11 @@ export const classicFixedBattles: FixedBattleConfigs = {
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT ], true)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT ], true)),
[64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
@ -531,21 +515,17 @@ export const classicFixedBattles: FixedBattleConfigs = {
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA ], true)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT ], true)),
[114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA ], true, 1)),
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE ]))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
[115]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE ])),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2 ]))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[165]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2 ])),
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
@ -558,5 +538,4 @@ export const classicFixedBattles: FixedBattleConfigs = {
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false })
};

View File

@ -428,7 +428,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
moveAnim.bgSprite.setScale(1.25);
moveAnim.bgSprite.setAlpha(this.opacity / 255);
scene.field.add(moveAnim.bgSprite);
const fieldPokemon = scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon();
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
if (!isNullOrUndefined(priority)) {
scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority!);
} else if (fieldPokemon?.isOnField()) {
@ -989,7 +989,7 @@ export abstract class BattleAnim {
const setSpritePriority = (priority: integer) => {
switch (priority) {
case 0:
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption?
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getEnemyPokemon() || scene.getPlayerPokemon()!); // TODO: is this bang correct?
break;
case 1:
scene.field.moveTo(moveSprite, scene.field.getAll().length - 1);

View File

@ -5221,6 +5221,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
switchOutTarget.leaveField(false);
if (switchOutTarget.hp) {
switchOutTarget.setWildFlee(true);
user.scene.queueMessage(i18next.t("moveTriggers:fled", {pokemonName: getPokemonNameWithAffix(switchOutTarget)}), null, true, 500);
// in double battles redirect potential moves off fled pokemon

View File

@ -99,7 +99,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
public luck: integer;
public pauseEvolutions: boolean;
public pokerus: boolean;
public switchOutStatus: boolean;
public wildFlee: boolean;
public evoCounter: integer;
public fusionSpecies: PokemonSpecies | null;
@ -145,7 +145,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.species = species;
this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL;
this.level = level;
this.switchOutStatus = false;
this.wildFlee = false;
// Determine the ability index
if (abilityIndex !== undefined) {
@ -343,7 +343,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
isAllowed(): boolean {
const challengeAllowed = new Utils.BooleanHolder(true);
applyChallenges(this.scene.gameMode, ChallengeType.POKEMON_IN_BATTLE, this, challengeAllowed);
return !this.isFainted() && challengeAllowed.value;
return !this.wildFlee && challengeAllowed.value;
}
isActive(onField?: boolean): boolean {
@ -2152,11 +2152,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/**
* sets if the pokemon is switching out (if it's a enemy wild implies it's going to flee)
* sets if the pokemon has fled (implies it's a wild pokemon)
* @param status - boolean
*/
setSwitchOutStatus(status: boolean): void {
this.switchOutStatus = status;
setWildFlee(status: boolean): void {
this.wildFlee = status;
}
updateInfo(instant?: boolean): Promise<void> {
@ -3384,7 +3384,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.updateFusionPalette();
}
this.summonData = new PokemonSummonData();
this.setSwitchOutStatus(false);
if (!this.battleData) {
this.resetBattleData();
}
@ -3790,7 +3789,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.hideInfo();
}
this.scene.field.remove(this);
this.setSwitchOutStatus(true);
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
}
@ -3814,25 +3812,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const rootForm = getPokemonSpecies(this.species.getRootSpeciesId());
return rootForm.getAbility(abilityIndex) === rootForm.getAbility(currentAbilityIndex);
}
/**
* Helper function to check if the player already owns the starter data of the Pokemon's
* current ability
* @param ownedAbilityAttrs the owned abilityAttr of this Pokemon's root form
* @returns true if the player already has it, false otherwise
*/
checkIfPlayerHasAbilityOfStarter(ownedAbilityAttrs: number): boolean {
if ((ownedAbilityAttrs & 1) > 0 && this.hasSameAbilityInRootForm(0)) {
return true;
}
if ((ownedAbilityAttrs & 2) > 0 && this.hasSameAbilityInRootForm(1)) {
return true;
}
if ((ownedAbilityAttrs & 4) > 0 && this.hasSameAbilityInRootForm(2)) {
return true;
}
return false;
}
}
export default interface Pokemon {

View File

@ -268,6 +268,7 @@ export class GameMode implements GameModeConfig {
isFixedBattle(waveIndex: integer): boolean {
const dummyConfig = new FixedBattleConfig();
return this.battleConfig.hasOwnProperty(waveIndex) || applyChallenges(this, ChallengeType.FIXED_BATTLES, waveIndex, dummyConfig);
}
/**

View File

@ -1,10 +1,10 @@
{
"encounter": "又しても 時が満ちた 様 である。\nこちらへ 至る 理由は 存知するな。\n$汝は この場所へ 引かれた……\nこの何度となく 至った場所。\n$けれども 数えられぬとも 限らぬ……\n正確に宣ふのたまう 現在の 循環は {{cycleCount}}回目 である。\n$各循環に 心… 意識… 両方も 元の有様に 戻る。\nなれども 故吾の 残影は 汝の 中に 存する。\n$未だに 成功せぬ ままでも\n異なる 存在を 感ずる。\n$御座在る者は 一人。\nなれども 感ずるは… もう 他人。\n$到頭 汝から いかめしい 挑戦は 我が目にかかるか?\n千歳 万歳 相まってた挑戦……\n$始もう。",
"encounter_female": "又しても 時が満ちた 様 である。\nこちらへ 至る 理由は 存知するな。\n$汝は この場所へ 引かれた……\nこの何度となく 至った場所。\n$けれども 数えられぬとも 限らぬ……\n正確に宣ふのたまう 現在の 循環は {{cycleCount}}回目 である。\n$各循環に 心… 意識… 両方も 元の有様に 戻る。\nなれども 故吾の 残影は 汝の 中に 存する。\n$未だに 成功せぬ ままでも\n異なる 存在を 感ずる。\n$御座在る者は 一人。\nなれども 感ずるは… もう 他人。\n$到頭 汝から いかめしい 挑戦は 我が目にかかるか?\n千歳 万歳 相まってた挑戦……\n$始もう。",
"firstStageWin": "成る程。 感じた 存在は 正身(むざね) であった。\n自分を括る 必要 有らぬ 様である。\n$失望させぬが良い。",
"secondStageWin": "……お見事でございます。",
"key_ordinal_one": "",
"key_ordinal_two": "",
"key_ordinal_few": "",
"key_ordinal_other": ""
"encounter": "It appears the time has finally come once again.\nYou know why you have come here, do you not?\n$You were drawn here, because you have been here before.\nCountless times.\n$Though, perhaps it can be counted.\nTo be precise, this is in fact your {{cycleCount}} cycle.\n$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.\n$Until now you have yet to succeed, but I sense a different presence in you this time.\n\n$You are the only one here, though it is as if there is… another.\n$Will you finally prove a formidable challenge to me?\nThe challenge I have longed after for millennia?\n$We begin.",
"encounter_female": "It appears the time has finally come once again.\nYou know why you have come here, do you not?\n$You were drawn here, because you have been here before.\nCountless times.\n$Though, perhaps it can be counted.\nTo be precise, this is in fact your {{cycleCount}} cycle.\n$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.\n$Until now you have yet to succeed, but I sense a different presence in you this time.\n\n$You are the only one here, though it is as if there is… another.\n$Will you finally prove a formidable challenge to me?\nThe challenge I have longed after for millennia?\n$We begin.",
"firstStageWin": "I see. The presence I felt was indeed real.\nIt appears I no longer need to hold back.\n$Do not disappoint me.",
"secondStageWin": "…Magnificent.",
"key_ordinal_one": "st",
"key_ordinal_two": "nd",
"key_ordinal_few": "rd",
"key_ordinal_other": "th"
}

View File

@ -1,6 +1,6 @@
{
"ending": "@c{shock}帰ってきた?@d{32} それなら…@d{96} 勝った っていうこと だろう?!\n@c{smile_ehalf}絶対 やれると思う べきだったな。\n$@c{smile_eclosed}もちろん、ずっと そんな気 がしたんだな。\n@c{smile}ついに 終わった だろう? ループを 断ち切った。\n$@c{smile_ehalf}キミの夢も 叶ったよな?\n一回も 負けなかった。\n$キミの しつくした事を 覚えるのは おれだけだ。\n@c{angry_mopen}忘れない ように するが…\n$@c{smile_wave_wink}なんつって!@d{64} @c{smile}一生 忘れない。@d{32}\nキミの伝説は いつまでも みんなの 心の中に 残っているから。\n$@c{smile_wave}とにかく、@d{64} そろそろ 遅くなる……@d{96} かな?\nこの場所で よく 分からない。\n$さあ、帰ろう。\n@c{smile_wave_wink}明日、昔のよしみで バトルでも しないか?",
"ending_female": "@c{smile}えぇ? 勝ちゃった?@d{96} @c{smile_eclosed}勝てるのが 分かる べきだったね。\nやっぱり 帰ってきた…\n$@c{smile}ついに終わった。@d{64} ループを 断ち切った。\n$@c{serious_smile_fists} アナタの夢も 叶ったよね?\n一回も 負けなかった\n$@c{neutral}アタシだけが アナタが できた事 を覚えていく、ね。@d{96}\nでもね、たぶん 大丈夫なの かなぁ\n$@c{serious_smile_fists}アナタの伝説は みんなの 心の中に\nずっと 残っているからね……\n$@c{smile_eclosed}じゃあ、こんなトコは もう飽きた だろう?\n帰ろうよ。\n$@c{serious_smile_fists}ふるさとに 着いたら、 また バトルしよう?\nやる気 あればね",
"ending_endless": "現在のエンドまで やって来て おめでとう!\n更に多くの コンテンツは  近日公開予定です。",
"ending_name": "開発者"
"ending": "@c{shock}You're back?@d{32} Does that mean…@d{96} you won?!\n@c{smile_ehalf}I should have known you had it in you.\n$@c{smile_eclosed}Of course… I always had that feeling.\n@c{smile}It's over now, right? You ended the loop.\n$@c{smile_ehalf}You fulfilled your dream too, didn't you?\nYou didn't lose even once.\n$I'll be the only one to remember what you did.\n@c{angry_mopen}I'll try not to forget!\n$@c{smile_wave_wink}Just kidding!@d{64} @c{smile}I'd never forget.@d{32}\nYour legend will live on in our hearts.\n$@c{smile_wave}Anyway,@d{64} it's getting late…@d{96} I think?\nIt's hard to tell in this place.\n$Let's go home. @c{smile_wave_wink}Maybe tomorrow, we can have another battle, for old time's sake?",
"ending_female": "@c{smile}Oh? You won?@d{96} @c{smile_eclosed}I guess I should've known.\nBut, you're back now.\n$@c{smile}It's over.@d{64} You ended the loop.\n$@c{serious_smile_fists}You fulfilled your dream too, didn't you?\nYou didn't lose even once.\n$@c{neutral}I'm the only one who'll remember what you did.@d{96}\nI guess that's okay, isn't it?\n$@c{serious_smile_fists}Your legend will always live on in our hearts.\n$@c{smile_eclosed}Anyway, I've had about enough of this place, haven't you? Let's head home.\n$@c{serious_smile_fists}Maybe when we get back, we can have another battle?\nIf you're up to it.",
"ending_endless": "Congratulations on reaching the current end!\nMore content is coming soon.",
"ending_name": "Devs"
}

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
"newGame": "はじめから",
"settings": "設定",
"selectGameMode": "ゲームモードを 選んでください。",
"logInOrCreateAccount": "始めるには、ログイン、または 登録して ください。\nメールアドレスは 必要 ありません!",
"logInOrCreateAccount": "始めるには、ログイン、または 登録して ください。\nメールアドレスは 必要 ありません!",
"username": "ユーザー名",
"password": "パスワード",
"login": "ログイン",
@ -14,7 +14,7 @@
"register": "登録",
"emptyUsername": "ユーザー名を 空にする ことは できません",
"invalidLoginUsername": "入力されたユーザー名は無効です",
"invalidRegisterUsername": "ユーザー名には 英文字、 数字、 アンダースコアのみを 含くむことが 必要です",
"invalidRegisterUsername": "ユーザー名には 英文字、 数字、 アンダースコアのみを 含くむ必要が あります",
"invalidLoginPassword": "入力したパスワードは無効です",
"invalidRegisterPassword": "パスワードは 6文字以上 でなければなりません",
"usernameAlreadyUsed": "入力したユーザー名は すでに 使用されています",

View File

@ -1761,7 +1761,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),
new WeightedModifierType(modifierTypes.LOCK_CAPSULE, (party: Pokemon[]) => party[0].scene.gameMode.isClassic ? 0 : 3),
new WeightedModifierType(modifierTypes.LOCK_CAPSULE, skipInLastClassicWaveOrDefault(3)),
new WeightedModifierType(modifierTypes.SUPER_EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
new WeightedModifierType(modifierTypes.RARE_FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 6, 24),
new WeightedModifierType(modifierTypes.MEGA_BRACELET, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 9, 36),

View File

@ -40,7 +40,7 @@ export class EggLapsePhase extends Phase {
this.showSummary();
}, () => {
this.hatchEggsRegular(eggsToHatch);
this.end();
this.showSummary();
}
);
}, 100, true);

View File

@ -1,6 +1,6 @@
import BattleScene from "#app/battle-scene";
import { BattlerIndex, BattleType, ClassicFixedBossWaves } from "#app/battle";
import { CustomModifierSettings, modifierTypes } from "#app/modifier/modifier-type";
import { BattlerIndex, BattleType } from "#app/battle";
import { modifierTypes } from "#app/modifier/modifier-type";
import { BattleEndPhase } from "./battle-end-phase";
import { NewBattlePhase } from "./new-battle-phase";
import { PokemonPhase } from "./pokemon-phase";
@ -42,12 +42,8 @@ export class VictoryPhase extends PokemonPhase {
}
if (this.scene.gameMode.isEndless || !this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex)) {
this.scene.pushPhase(new EggLapsePhase(this.scene));
if (this.scene.gameMode.isClassic && this.scene.currentBattle.waveIndex === ClassicFixedBossWaves.EVIL_BOSS_2) {
// Should get Lock Capsule on 165 before shop phase so it can be used in the rewards shop
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.LOCK_CAPSULE));
}
if (this.scene.currentBattle.waveIndex % 10) {
this.scene.pushPhase(new SelectModifierPhase(this.scene, undefined, undefined, this.getFixedBattleCustomModifiers()));
this.scene.pushPhase(new SelectModifierPhase(this.scene));
} else if (this.scene.gameMode.isDaily) {
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_CHARM));
if (this.scene.currentBattle.waveIndex > 10 && !this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex)) {
@ -80,18 +76,4 @@ export class VictoryPhase extends PokemonPhase {
this.end();
}
/**
* If this wave is a fixed battle with special custom modifier rewards,
* will pass those settings to the upcoming {@linkcode SelectModifierPhase}`.
*/
getFixedBattleCustomModifiers(): CustomModifierSettings | undefined {
const gameMode = this.scene.gameMode;
const waveIndex = this.scene.currentBattle.waveIndex;
if (gameMode.isFixedBattle(waveIndex)) {
return gameMode.getFixedBattle(waveIndex).customModifierRewardSettings;
}
return undefined;
}
}

View File

@ -50,7 +50,7 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase);
const isVisible = enemyPokemon.visible;
const hasFled = enemyPokemon.switchOutStatus;
const hasFled = enemyPokemon.wildFlee;
expect(!isVisible && hasFled).toBe(true);
// simply want to test that the game makes it this far without crashing
@ -72,7 +72,7 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase);
const isVisible = enemyPokemon.visible;
const hasFled = enemyPokemon.switchOutStatus;
const hasFled = enemyPokemon.wildFlee;
expect(!isVisible && hasFled).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT
@ -97,9 +97,9 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(TurnEndPhase);
const isVisibleLead = enemyLeadPokemon.visible;
const hasFledLead = enemyLeadPokemon.switchOutStatus;
const hasFledLead = enemyLeadPokemon.wildFlee;
const isVisibleSec = enemySecPokemon.visible;
const hasFledSec = enemySecPokemon.switchOutStatus;
const hasFledSec = enemySecPokemon.wildFlee;
expect(!isVisibleLead && hasFledLead && isVisibleSec && !hasFledSec).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
@ -133,9 +133,9 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase);
const isVisibleLead = enemyLeadPokemon.visible;
const hasFledLead = enemyLeadPokemon.switchOutStatus;
const hasFledLead = enemyLeadPokemon.wildFlee;
const isVisibleSec = enemySecPokemon.visible;
const hasFledSec = enemySecPokemon.switchOutStatus;
const hasFledSec = enemySecPokemon.wildFlee;
expect(!isVisibleLead && hasFledLead && !isVisibleSec && hasFledSec).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
expect(secPokemon.hp).toBeLessThan(secPokemon.getMaxHp());

View File

@ -381,8 +381,17 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
const ownedAbilityAttrs = pokemon.scene.gameData.starterData[pokemon.species.getRootSpeciesId()].abilityAttr;
let playerOwnsThisAbility = false;
// Check if the player owns ability for the root form
const playerOwnsThisAbility = pokemon.checkIfPlayerHasAbilityOfStarter(ownedAbilityAttrs);
if ((ownedAbilityAttrs & 1) > 0 && pokemon.hasSameAbilityInRootForm(0)) {
playerOwnsThisAbility = true;
}
if ((ownedAbilityAttrs & 2) > 0 && pokemon.hasSameAbilityInRootForm(1)) {
playerOwnsThisAbility = true;
}
if ((ownedAbilityAttrs & 4) > 0 && pokemon.hasSameAbilityInRootForm(2)) {
playerOwnsThisAbility = true;
}
if (missingDexAttrs || !playerOwnsThisAbility) {
this.ownedIcon.setTint(0x808080);

View File

@ -267,13 +267,18 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
this.pokemonAbilityText.setColor(getTextColor(abilityTextStyle, false, this.scene.uiTheme));
this.pokemonAbilityText.setShadowColor(getTextColor(abilityTextStyle, true, this.scene.uiTheme));
/**
* If the opposing Pokemon only has 1 normal ability and is using the hidden ability it should have the same behavior
* if it had 2 normal abilities. This code checks if that is the case and uses the correct opponent Pokemon abilityIndex (2)
* for calculations so it aligns with where the hidden ability is stored in the starter data's abilityAttr (4)
*/
const opponentPokemonOneNormalAbility = (pokemon.species.getAbilityCount() === 2);
const opponentPokemonAbilityIndex = (opponentPokemonOneNormalAbility && pokemon.abilityIndex === 1) ? 2 : pokemon.abilityIndex;
const opponentPokemonAbilityAttr = 1 << opponentPokemonAbilityIndex;
const ownedAbilityAttrs = pokemon.scene.gameData.starterData[pokemon.species.getRootSpeciesId()].abilityAttr;
const rootFormHasHiddenAbility = starterEntry.abilityAttr & opponentPokemonAbilityAttr;
// Check if the player owns ability for the root form
const playerOwnsThisAbility = pokemon.checkIfPlayerHasAbilityOfStarter(ownedAbilityAttrs);
if (!playerOwnsThisAbility) {
if (!rootFormHasHiddenAbility) {
this.pokemonAbilityLabelText.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme));
this.pokemonAbilityLabelText.setShadowColor(getTextColor(TextStyle.SUMMARY_BLUE, true, this.scene.uiTheme));
} else {

View File

@ -13,7 +13,7 @@ import { RunEntry } from "../system/game-data";
import { PlayerGender } from "#enums/player-gender";
import { TrainerVariant } from "../field/trainer";
export type RunSelectCallback = (cursor: number) => void;
export type RunSelectCallback = (cursor: integer) => void;
export const RUN_HISTORY_LIMIT: number = 25;
@ -25,15 +25,15 @@ export const RUN_HISTORY_LIMIT: number = 25;
*/
export default class RunHistoryUiHandler extends MessageUiHandler {
private readonly maxRows = 3;
private runSelectContainer: Phaser.GameObjects.Container;
private runsContainer: Phaser.GameObjects.Container;
private runSelectMessageBox: Phaser.GameObjects.NineSlice;
private runSelectMessageBoxContainer: Phaser.GameObjects.Container;
private runs: RunEntryContainer[];
private runSelectCallback: RunSelectCallback | null;
private scrollCursor: number = 0;
private scrollCursor: integer = 0;
private cursorObj: Phaser.GameObjects.NineSlice | null;
@ -74,15 +74,15 @@ export default class RunHistoryUiHandler extends MessageUiHandler {
this.getUi().bringToTop(this.runSelectContainer);
this.runSelectContainer.setVisible(true);
this.populateRuns(this.scene).then(() => {
this.setScrollCursor(0);
this.setCursor(0);
this.populateRuns(this.scene);
//Destroys the cursor if there are no runs saved so far.
if (this.runs.length === 0) {
this.clearCursor();
}
});
this.setScrollCursor(0);
this.setCursor(0);
//Destroys the cursor if there are no runs saved so far.
if (this.runs.length === 0) {
this.clearCursor();
}
return true;
}
@ -122,21 +122,13 @@ export default class RunHistoryUiHandler extends MessageUiHandler {
success = this.setCursor(this.cursor - 1);
} else if (this.scrollCursor) {
success = this.setScrollCursor(this.scrollCursor - 1);
} else if (this.runs.length > 1) {
// wrap around to the bottom
success = this.setCursor(Math.min(this.runs.length - 1, this.maxRows - 1));
success = this.setScrollCursor(Math.max(0, this.runs.length - this.maxRows)) || success;
}
break;
case Button.DOWN:
if (this.cursor < Math.min(this.maxRows - 1, this.runs.length - this.scrollCursor - 1)) {
if (this.cursor < 2) {
success = this.setCursor(this.cursor + 1);
} else if (this.scrollCursor < this.runs.length - this.maxRows) {
} else if (this.scrollCursor < this.runs.length - 3) {
success = this.setScrollCursor(this.scrollCursor + 1);
} else if (this.runs.length > 1) {
// wrap around to the top
success = this.setCursor(0);
success = this.setScrollCursor(0) || success;
}
break;
}
@ -226,7 +218,6 @@ export default class RunHistoryUiHandler extends MessageUiHandler {
override clear() {
super.clear();
this.runSelectContainer.setVisible(false);
this.setScrollCursor(0);
this.clearCursor();
this.runSelectCallback = null;
this.clearRuns();
@ -369,7 +360,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container {
// The code here does not account for icon weirdness.
const pokemonIconsContainer = this.scene.add.container(140, 17);
data.party.forEach((p: PokemonData, i: number) => {
data.party.forEach((p: PokemonData, i: integer) => {
const iconContainer = this.scene.add.container(26 * i, 0);
iconContainer.setScale(0.75);
const pokemon = p.toPokemon(this.scene);

View File

@ -49,11 +49,15 @@ export default class RunInfoUiHandler extends UiHandler {
private runResultContainer: Phaser.GameObjects.Container;
private runInfoContainer: Phaser.GameObjects.Container;
private partyContainer: Phaser.GameObjects.Container;
private partyHeldItemsContainer: Phaser.GameObjects.Container;
private statsBgWidth: integer;
private partyContainerHeight: integer;
private partyContainerWidth: integer;
private hallofFameContainer: Phaser.GameObjects.Container;
private endCardContainer: Phaser.GameObjects.Container;
private partyInfo: Phaser.GameObjects.Container[];
private partyVisibility: Boolean;
private modifiersModule: any;
@ -859,7 +863,7 @@ export default class RunInfoUiHandler extends UiHandler {
private buttonCycleOption(button: Button) {
switch (button) {
case Button.CYCLE_FORM:
if (this.isVictory && this.pageMode !== RunInfoUiMode.HALL_OF_FAME) {
if (this.isVictory) {
if (!this.endCardContainer || !this.endCardContainer.visible) {
this.createVictorySplash();
this.endCardContainer.setVisible(true);
@ -873,7 +877,7 @@ export default class RunInfoUiHandler extends UiHandler {
}
break;
case Button.CYCLE_SHINY:
if (this.isVictory && this.pageMode !== RunInfoUiMode.ENDING_ART) {
if (this.isVictory) {
if (!this.hallofFameContainer.visible) {
this.hallofFameContainer.setVisible(true);
this.pageMode = RunInfoUiMode.HALL_OF_FAME;
@ -884,7 +888,7 @@ export default class RunInfoUiHandler extends UiHandler {
}
break;
case Button.CYCLE_ABILITY:
if (this.runInfo.modifiers.length !== 0 && this.pageMode === RunInfoUiMode.MAIN) {
if (this.runInfo.modifiers.length !== 0) {
if (this.partyVisibility) {
this.showParty(false);
} else {

View File

@ -76,7 +76,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
.then(stats => {
this.playerCountLabel.setText(`${stats.playerCount} ${i18next.t("menu:playersOnline")}`);
if (this.splashMessage === "splashMessages:battlesWon") {
this.splashMessageText.setText(i18next.t(this.splashMessage, { count: stats.battleCount }));
this.splashMessageText.setText(i18next.t(this.splashMessage, { count: stats.battlesWon }));
}
})
.catch(err => {

View File

@ -139,8 +139,7 @@ const noTransitionModes = [
Mode.TEST_DIALOGUE,
Mode.AUTO_COMPLETE,
Mode.ADMIN,
Mode.MYSTERY_ENCOUNTER,
Mode.RUN_INFO
Mode.MYSTERY_ENCOUNTER
];
export default class UI extends Phaser.GameObjects.Container {