Update beta branch

Don't want to be using an outdated version
This commit is contained in:
RedstonewolfX 2024-08-25 14:24:49 -04:00 committed by GitHub
commit 3826bbb3ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 3294 additions and 986 deletions

45
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,45 @@
# Order is important; the last matching pattern takes the most precedence.
# everything (whole code-base) - Junior Devs
* @pagefaultgames/junior-dev-team
# github actions/templates etc. - Dev Leads
/.github @pagefaultgames/dev-leads
# --- Translations ---
# all translations - Translation Leads
/src/locales @pagefaultgames/translation-leads
# Catalan (Spain/Spanish)
/src/locales/ca_ES @pagefaultgames/catalan-translation-team
# German
/src/locales/de @pagefaultgames/german-translation-team
# English
/src/locales/en @pagefaultgames/english-translation-team
# Spanish
/src/locales/es @pagefaultgames/spanish-translation-team
# French
/src/locales/fr @pagefaultgames/french-translation-team
# Italian
/src/locales/it @pagefaultgames/italian-translation-team
# Japenese
/src/locales/ja @pagefaultgames/japanese-translation-team
# Korean
/src/locales/ko @pagefaultgames/korean-translation-team
# Brasilian (Brasil/Portuguese)
/src/locales/pt_BR @pagefaultgames/portuguese_br-translation-team
# Chinese (simplified)
/src/locales/zh_CN @pagefaultgames/chinese_simplified-translation-team
# Chinese (traditional)
/src/locales/zh_TW @pagefaultgames/chinese_traditional-translation-team

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: patapancakes

View File

@ -1,7 +1,7 @@
name: Feature Request
description: Suggest an idea for this project
title: "[Feature] "
labels: ["enhancement"]
labels: ["Enhancement"]
body:
- type: markdown
attributes:

View File

@ -30,7 +30,7 @@
- [ ] The PR is self-contained and cannot be split into smaller PRs?
- [ ] Have I provided a clear explanation of the changes?
- [ ] Have I considered writing automated tests for the issue?
- [ ] If I have text, did I add placeholders for them in locales?
- [ ] If I have text, did I make it translatable and add a key in the English locale file(s)?
- [ ] Have I tested the changes (manually)?
- [ ] Are all unit tests still passing? (`npm run test`)
- [ ] Are the changes visual?

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 B

After

Width:  |  Height:  |  Size: 793 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,21 +1,5 @@
{
"1": {
"b0a080": "e552ec",
"f8f8e8": "ffe2ed",
"9b8259": "b021c5",
"e5e4c2": "ffb9f9",
"000000": "000000",
"bc9b4e": "900090",
"f8f8d0": "ff8ae9",
"e8e088": "ff49e7",
"d0b868": "d10cc7",
"7d673b": "510059",
"282828": "282828",
"f84040": "f84040",
"f88888": "1ae2e6",
"c81010": "00c2d2"
},
"2": {
"b0a080": "d96b23",
"f8f8e8": "ffe1b8",
"9b8259": "b43c06",
@ -30,5 +14,21 @@
"f84040": "f84040",
"f88888": "f88888",
"c81010": "c81010"
},
"2": {
"b0a080": "e552ec",
"f8f8e8": "ffe2ed",
"9b8259": "b021c5",
"e5e4c2": "ffb9f9",
"000000": "000000",
"bc9b4e": "900090",
"f8f8d0": "ff8ae9",
"e8e088": "ff49e7",
"d0b868": "d10cc7",
"7d673b": "510059",
"282828": "282828",
"f84040": "f84040",
"f88888": "1ae2e6",
"c81010": "00c2d2"
}
}

View File

@ -50,8 +50,8 @@ import CandyBar from "./ui/candy-bar";
import { Variant, variantData } from "./data/variant";
import { Localizable } from "#app/interfaces/locales";
import Overrides from "#app/overrides";
import {InputsController} from "./inputs-controller";
import {UiInputs} from "./ui-inputs";
import { InputsController } from "./inputs-controller";
import { UiInputs } from "./ui-inputs";
import { NewArenaEvent } from "./events/battle-scene";
import { ArenaFlyout } from "./ui/arena-flyout";
import { EaseType } from "#enums/ease-type";
@ -66,7 +66,7 @@ import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme";
import { TimedEventManager } from "#app/timed-event-manager.js";
import i18next from "i18next";
import {TrainerType} from "#enums/trainer-type";
import { TrainerType } from "#enums/trainer-type";
import { battleSpecDialogue } from "./data/dialogue";
import { LoadingScene } from "./loading-scene";
import * as LoggerTools from "./logger"
@ -2577,7 +2577,6 @@ export default class BattleScene extends SceneBase {
getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance, this)
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this));
});
this.updateModifiers(false).then(() => resolve());
});
}
@ -2809,7 +2808,8 @@ export default class BattleScene extends SceneBase {
wave: this.currentBattle?.waveIndex || 0,
party: this.party ? this.party.map(p => {
return { name: p.name, level: p.level };
}) : []
}) : [],
modeChain: this.ui?.getModeChain() ?? [],
};
(window as any).gameInfo = gameInfo;
}

View File

@ -2395,16 +2395,16 @@ export class PreStatChangeAbAttr extends AbAttr {
}
export class ProtectStatAbAttr extends PreStatChangeAbAttr {
private protectedStat: BattleStat | null;
private protectedStat?: BattleStat;
constructor(protectedStat?: BattleStat) {
super();
this.protectedStat = protectedStat ?? null;
this.protectedStat = protectedStat;
}
applyPreStatChange(pokemon: Pokemon, passive: boolean, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.protectedStat || stat === this.protectedStat) {
if (Utils.isNullOrUndefined(this.protectedStat) || stat === this.protectedStat) {
cancelled.value = true;
return true;
}

View File

@ -4492,7 +4492,7 @@ export class CurseAttr extends MoveEffectAttr {
const curseRecoilDamage = Math.max(1, Math.floor(user.getMaxHp() / 2));
user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true, true);
user.scene.queueMessage(
i18next.t("battle:cursedOnAdd", {
i18next.t("battlerTags:cursedOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(user),
pokemonName: getPokemonNameWithAffix(target)
})

View File

@ -1577,11 +1577,11 @@ export const trainerConfigs: TrainerConfigs = {
})),
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE, () => modifierTypes.SHINY_CHARM, () => modifierTypes.ABILITY_CHARM)
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL], TrainerSlot.TRAINER, true)),
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE, () => modifierTypes.SHINY_CHARM)
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),

View File

@ -938,7 +938,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* by how many learnable moves there are for the {@linkcode Pokemon}.
*/
getLearnableLevelMoves(): Moves[] {
let levelMoves = this.getLevelMoves(1, true).map(lm => lm[1]);
let levelMoves = this.getLevelMoves(1, true, false, true).map(lm => lm[1]);
if (this.metBiome === -1 && !this.scene.gameMode.isFreshStartChallenge() && !this.scene.gameMode.isDaily) {
levelMoves = this.getUnlockedEggMoves().concat(levelMoves);
}
@ -1227,11 +1227,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
*
* @param source - The Pokémon using the move.
* @param move - The move being used.
* @returns The type damage multiplier or undefined if it's a status move
* @returns The type damage multiplier or 1 if it's a status move
*/
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier | undefined {
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier {
if (move.getMove().category === MoveCategory.STATUS) {
return undefined;
return 1;
}
return this.getAttackMoveEffectiveness(source, move, !this.battleData?.abilityRevealed);

View File

@ -2573,8 +2573,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
$@c{smile}Maybe it was a bit of luck but\nWho knows you might just be able to go all the way.
$By the way, the professor asked me to give you these items. They look pretty cool.
$@c{serious_smile_fists}Good luck out there!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{serious_smile_fists}Good luck out there!`
},
},
"rival_female": {
@ -2588,8 +2587,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square I have a feeling you're going to do really well out there.
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
$@c{smile_wave}Do your best like always! I believe in you!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{smile_wave}Do your best like always! I believe in you!`
},
},
"rival_2": {
@ -2605,7 +2603,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
$@c{smile}Anyway, take care, and enjoy the event!`
$@c{smile}Anyway, take care!`
},
},
"rival_2_female": {
@ -2621,7 +2619,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
$@c{smile_wave}Keep at it, and enjoy the event!`
$@c{smile_wave}Keep at it!`
},
"defeat": {
1: "It's OK to lose sometimes…"

View File

@ -2641,8 +2641,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Vielleicht war es einfach etwas Glück, aber\nWer weiß, vielleicht schaffst du es irgendwann
$ja wirklich ganz groß raus zu kommen.
$Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Die sehen wirklich cool aus.
$@c{serious_smile_fists}Viel Glück da draußen!
$@c{smile}Oh-und genieße das Event!`
$@c{serious_smile_fists}Viel Glück da draußen!`
},
},
"rival_female": {
@ -2657,8 +2656,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Du hast gerade erst angefangen und bist schon so stark?!@d{96} @c{angry}Du hast sowas von betrogen, oder?
$@c{smile_wave_wink}Ich mach nur Spaß!@d{64} @c{smile_eclosed}Ich habe ehrlich verloren Ich habe das Gefühl, dass du es dort draußen weit bringen wirst.
$@c{smile}Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Ich hoffe sie sind hilfreich!
$@c{smile_wave}Gib wie immer dein Bestes! Ich glaube an dich!
$@c{smile}Oh-und genieße das Event!`
$@c{smile_wave}Gib wie immer dein Bestes! Ich glaube an dich!`
},
},
"rival_2": {
@ -2676,7 +2674,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Nicht, dass du wirklich Hilfe benötigen würdest, aber ich habe hier noch eins von diesen Dingern herumliegen.
$Du kannst es haben.\n
$@c{serious_smile_fists}Erwarte aber nicht, dass ich dir noch mehr gebe!\nIch kann meinen Rivalen doch keine Vorteile verschaffen.
$@c{smile}Egal, pass auf dich auf und genieße das Event!`
$@c{smile}Egal, pass auf dich auf!`
},
},
"rival_2_female": {
@ -2692,7 +2690,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Na gut. Das bedeutet ich muss noch härter tranieren!
$@c{smile_wave}Ich habe noch eins von diesen Dingern!\n@c{smile_wave_wink}Kein Grund mir zu danken~.
$@c{angry_mopen}Das ist aber das Letzte! Du bekommst ab jett keine Geschenke mehr von mir!
$@c{smile_wave}Bleib stark und genieße das Event!`
$@c{smile_wave}Bleib stark!`
},
"defeat": {
1: "Es ist Ok manchmal zu verlieren…"

View File

@ -2574,8 +2574,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
$@c{smile}Maybe it was a bit of luck but\nWho knows you might just be able to go all the way.
$By the way, the professor asked me to give you these items. They look pretty cool.
$@c{serious_smile_fists}Good luck out there!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{serious_smile_fists}Good luck out there!`
},
},
"rival_female": {
@ -2589,8 +2588,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square I have a feeling you're going to do really well out there.
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
$@c{smile_wave}Do your best like always! I believe in you!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{smile_wave}Do your best like always! I believe in you!`
},
},
"rival_2": {
@ -2604,9 +2602,9 @@ export const PGMdialogue: DialogueTranslationEntries = {
"victory": {
1: `@c{neutral_eclosed}Oh. I guess I was overconfident.
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of each of these lying around and figured you might want them.\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
$@c{smile}Anyway, take care, and enjoy the event!`
$@c{smile}Anyway, take care!`
},
},
"rival_2_female": {
@ -2620,9 +2618,9 @@ export const PGMdialogue: DialogueTranslationEntries = {
"victory": {
1: `@c{neutral}I… wasn't supposed to lose that time…
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
$@c{smile_wave}I also got you another two of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
$@c{smile_wave}Keep at it, and enjoy the event!`
$@c{smile_wave}Keep at it!`
},
"defeat": {
1: "It's OK to lose sometimes…"

View File

@ -2569,8 +2569,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
$@c{smile}Maybe it was a bit of luck but\nWho knows you might just be able to go all the way.
$By the way, the professor asked me to give you these items. They look pretty cool.
$@c{serious_smile_fists}Good luck out there!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{serious_smile_fists}Good luck out there!`
},
},
"rival_female": {
@ -2584,8 +2583,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square I have a feeling you're going to do really well out there.
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
$@c{smile_wave}Do your best like always! I believe in you!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{smile_wave}Do your best like always! I believe in you!`
},
},
"rival_2": {
@ -2601,7 +2599,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
$@c{smile}Anyway, take care, and enjoy the event!`
$@c{smile}Anyway, take care!`
},
},
"rival_2_female": {
@ -2617,7 +2615,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
$@c{smile_wave}Keep at it, and enjoy the event!`
$@c{smile_wave}Keep at it!`
},
"defeat": {
1: "It's OK to lose sometimes…"

View File

@ -2372,8 +2372,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment un débutant ?
$@c{smile}Tas peut-être eu de la chance, mais\nPeut-être que tarriveras jusquau bout du chemin.
$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.
$@c{serious_smile_fists}Bonne chance à toi !
$@c{smile}Oh, et profite bien de lévènement !`
$@c{serious_smile_fists}Bonne chance à toi !`
},
},
"rival_female": {
@ -2387,8 +2386,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !
$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles\nJai le sentiment que tu vas très bien ten sortir.
$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !
$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !
$@c{smile}Oh, et profite bien de lévènement !`
$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !`
},
},
"rival_2": {
@ -2404,7 +2402,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n
$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n
$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.
$@c{smile}Bref, prends soin de toi et profite bien de lévènement !`
$@c{smile}Bref, prends soin de toi !`
},
},
"rival_2_female": {
@ -2419,8 +2417,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{neutral}Je… Jétais pas encore supposée perdre…
$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !
$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.
$@c{angry_mopen}Cétaient les derniers, terminé les cadeaux après ceux- !
$@c{smile_wave}Allez, tiens le coup et profite bien de lévènement !`
$@c{angry_mopen}Cétait le dernier, terminé les cadeaux après celui- !
$@c{smile_wave}Allez, tiens le coup !`
},
"defeat": {
1: "Je suppose que cest parfois normal de perdre…"
@ -5053,8 +5051,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?
$@c{smile}Tas peut-être eu de la chance, mais\nPeut-être que tarriveras jusquau bout du chemin.
$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.
$@c{serious_smile_fists}Bonne chance à toi !
$@c{smile}Oh, et profite bien de lévènement !`
$@c{serious_smile_fists}Bonne chance à toi !`
},
},
"rival_female": {
@ -5068,8 +5065,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
1: `@c{shock}Tu viens de commencer et tes déjà si forte ?!@d{96}\n@c{angry}Tas triché non ? Avoue !
$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles\nJai le sentiment que tu vas très bien ten sortir.
$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !
$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !
$@c{smile}Oh, et profite bien de lévènement !`
$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !`
},
},
"rival_2": {
@ -5085,7 +5081,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n
$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n
$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.
$@c{smile}Bref, prends soin de toi et profite bien de lévènement !`
$@c{smile}Bref, prends soin de toi !`
},
},
"rival_2_female": {
@ -5101,7 +5097,7 @@ export const PGFdialogue: DialogueTranslationEntries = {
$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !
$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.
$@c{angry_mopen}Cétait le dernier, terminé les cadeaux après celui- !
$@c{smile_wave}Allez, tiens le coup et profite bien de lévènement !`
$@c{smile_wave}Allez, tiens le coup !`
},
"defeat": {
1: "Je suppose que cest parfois normal de perdre…"

View File

@ -2569,8 +2569,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
$@c{smile}Maybe it was a bit of luck but\nWho knows you might just be able to go all the way.
$By the way, the professor asked me to give you these items. They look pretty cool.
$@c{serious_smile_fists}Good luck out there!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{serious_smile_fists}Good luck out there!`
},
},
"rival_female": {
@ -2584,8 +2583,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square I have a feeling you're going to do really well out there.
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
$@c{smile_wave}Do your best like always! I believe in you!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{smile_wave}Do your best like always! I believe in you!`
},
},
"rival_2": {
@ -2601,7 +2599,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
$@c{smile}Anyway, take care, and enjoy the event!`
$@c{smile}Anyway, take care!`
},
},
"rival_2_female": {
@ -2617,7 +2615,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
$@c{smile_wave}Keep at it, and enjoy the event!`
$@c{smile_wave}Keep at it!`
},
"defeat": {
1: "It's OK to lose sometimes…"

View File

@ -2573,8 +2573,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}Wow… You cleaned me out.\nAre you actually a beginner?
$@c{smile}Maybe it was a bit of luck but\nWho knows you might just be able to go all the way.
$By the way, the professor asked me to give you these items. They look pretty cool.
$@c{serious_smile_fists}Good luck out there!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{serious_smile_fists}Good luck out there!`
},
},
"rival_female": {
@ -2588,8 +2587,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}You just started and you're already this strong?!@d{96}\n@c{angry}You totally cheated, didn't you?
$@c{smile_wave_wink}Just kidding!@d{64} @c{smile_eclosed}I lost fair and square I have a feeling you're going to do really well out there.
$@c{smile}By the way, the professor wanted me to give you some items. Hopefully they're helpful!
$@c{smile_wave}Do your best like always! I believe in you!
$@c{smile}Oh- and I hope you enjoy the event!`
$@c{smile_wave}Do your best like always! I believe in you!`
},
},
"rival_2": {
@ -2605,7 +2603,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}That's alright, though. I figured this might happen.\n@c{serious_mopen_fists}It just means I need to try harder for next time!\n
$@c{smile}Oh, not that you really need the help, but I had an extra one of these lying around and figured you might want it.\n
$@c{serious_smile_fists}Don't expect another one after this, though!\nI can't keep giving my opponent an advantage after all.
$@c{smile}Anyway, take care, and enjoy the event!`
$@c{smile}Anyway, take care!`
},
},
"rival_2_female": {
@ -2621,7 +2619,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}Aw well. That just means I'll have to train even harder for next time!
$@c{smile_wave}I also got you another one of these!\n@c{smile_wave_wink}No need to thank me~.
$@c{angry_mopen}This is the last one, though! You won't be getting anymore freebies from me after this!
$@c{smile_wave}Keep at it, and enjoy the event!`
$@c{smile_wave}Keep at it!`
},
"defeat": {
1: "It's OK to lose sometimes…"

View File

@ -2569,8 +2569,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}와… 정말 깔끔하게 당했네.\n초보자 맞아?
$@c{smile} \n그래도 .
$그나저나, .\n좋아 .
$@c{serious_smile_fists}, !
$@c{smile}- !`
$@c{serious_smile_fists}, !`
},
},
"rival_female": {
@ -2584,8 +2583,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: `@c{shock}왜 벌써 이렇게 센 건데?!@d{96}\n@c{angry}아니면 뭔가 속임수, 그런 거?
$@c{smile_wave_wink}, !@d{64} @c{smile_eclosed} \n너 .
$@c{smile} , .\n도움이 !
$@c{smile_wave} ! 믿 !
$@c{smile}- !`
$@c{smile_wave} ! 믿 !`
},
},
"rival_2": {
@ -2601,7 +2599,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}, .\n@c{serious_mopen_fists} !\n
$@c{smile} , .\n남는 .
$@c{serious_smile_fists} , ?\n공평하게 .
$@c{smile} . , !`
$@c{smile} . !`
},
},
"rival_2_female": {
@ -2617,7 +2615,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
$@c{smile}, . !
$@c{smile_wave} !\n@c{smile_wave_wink} ~.
$@c{angry_mopen}, !\n또 !
$@c{smile_wave}! !`
$@c{smile_wave}!`
},
"defeat": {
1: "가끔은 지는 것도 괜찮아…"

File diff suppressed because it is too large Load Diff

View File

@ -35,11 +35,11 @@ export const menu: SimpleTranslationEntries = {
"sessionSuccess": "Sessão carregada com sucesso.",
"failedToLoadSession": "Não foi possível carregar os dados da sua sessão.\nEles podem estar corrompidos.",
"boyOrGirl": "Você é um menino ou uma menina?",
"evolving": "Que?\n{{pokemonName}} tá evoluindo!",
"evolving": "Quê?\n{{pokemonName}} tá evoluindo!",
"stoppedEvolving": "{{pokemonName}} parou de evoluir.",
"pauseEvolutionsQuestion": "Gostaria de pausar evoluções para {{pokemonName}}?\nEvoluções podem ser religadas na tela de equipe.",
"evolutionsPaused": "Evoluções foram paradas para {{pokemonName}}.",
"evolutionDone": "Parabéns!\nSeu {{pokemonName}} evolui para {{evolvedPokemonName}}!",
"evolutionDone": "Parabéns!\nSeu {{pokemonName}} evoluiu para {{evolvedPokemonName}}!",
"dailyRankings": "Classificação Diária",
"weeklyRankings": "Classificação Semanal",
"noRankings": "Sem Classificação",

View File

@ -4,7 +4,7 @@ export const modifier: SimpleTranslationEntries = {
"surviveDamageApply": "{{pokemonNameWithAffix}} aguentou o tranco\nusando sua {{typeName}}!",
"turnHealApply": "{{pokemonNameWithAffix}} restaurou um pouco de PS usando\nsuas {{typeName}}!",
"hitHealApply": "{{pokemonNameWithAffix}} restaurou um pouco de PS usando\nsua {{typeName}}!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} foi revivido\npor sua {{typeName}}!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} foi reanimado\npor sua {{typeName}}!",
"pokemonResetNegativeStatStageApply": "Os atributos diminuídos de {{pokemonNameWithAffix}} foram\nrestaurados por seu(sua) {{typeName}}!",
"moneyInterestApply": "Você recebeu um juros de ₽{{moneyAmount}}\nde sua {{typeName}}!",
"turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} foi absorvido(a)\npelo {{typeName}} de {{pokemonName}}!",

View File

@ -26,7 +26,7 @@ export const moveTriggers: SimpleTranslationEntries = {
"soothingAromaWaftedThroughArea": "Um aroma suave se espalhou pelo ambiente!",
"sprangUp": "{{pokemonName}} se levantou!",
"choseDoomDesireAsDestiny": "{{pokemonName}} escolheu\no Desejo da Perdição como seu destino!",
"vanishedInstantly": "{{pokemonName}} desapareceu/nde repente!",
"vanishedInstantly": "{{pokemonName}} desapareceu\nde repente!",
"tookTargetIntoSky": "{{pokemonName}} levou {{targetName}}\npara o céu!",
"becameCloakedInFreezingLight": "{{pokemonName}} ficou envolto/nem uma luz congelante!",
"becameCloakedInFreezingAir": "{{pokemonName}} ficou envolto/nem ar congelante!",

View File

@ -15,7 +15,7 @@ export const partyUiHandler: SimpleTranslationEntries = {
"ALL": "Tudo",
"PASS_BATON": "Passar Bastão",
"UNPAUSE_EVOLUTION": "Ativar Evolução",
"REVIVE": "Reviver",
"REVIVE": "Reanimar",
"RENAME": "Renomear",
"choosePokemon": "Escolha um Pokémon.",

View File

@ -29,7 +29,7 @@ export const pokemonForm: SimpleTranslationEntries = {
"pikachuPartner": "Parceiro",
"eeveePartner": "Parceiro",
// 2G
"pichuSpiky": "Spiky",
"pichuSpiky": "Orelha Espetada",
"unownA": "A",
"unownB": "B",
"unownC": "C",
@ -74,8 +74,8 @@ export const pokemonForm: SimpleTranslationEntries = {
"rotomFrost": "Congelante",
"rotomFan": "Ventilador",
"rotomMow": "Corte",
"giratinaAltered": "Altered",
"shayminLand": "Land",
"giratinaAltered": "Alterado",
"shayminLand": "Terrestre",
// 5G
"basculinRedStriped": "Listras Vermelhas",
"basculinBlueStriped": "Listras Azuis",
@ -84,11 +84,11 @@ export const pokemonForm: SimpleTranslationEntries = {
"deerlingSummer": "Verão",
"deerlingAutumn": "Outono",
"deerlingWinter": "Inverno",
"tornadusIncarnate": "Incarnate",
"thundurusIncarnate": "Incarnate",
"landorusIncarnate": "Incarnate",
"keldeoOrdinary": "Ordinary",
"meloettaAria": "Aria",
"tornadusIncarnate": "Materializado",
"thundurusIncarnate": "Materializado",
"landorusIncarnate": "Materializado",
"keldeoOrdinary": "Comum",
"meloettaAria": "Ária",
// 6G
"froakieBattleBond": "Vínculo de Batalha",
"scatterbugMeadow": "Prado",
@ -165,11 +165,11 @@ export const pokemonForm: SimpleTranslationEntries = {
"eiscueNoIce": "Descongelado",
"indeedeeMale": "Macho",
"indeedeeFemale": "Fêmea",
"morpekoFullBelly": "Full Belly",
"zacianHeroOfManyBattles": "Hero Of Many Battles",
"zamazentaHeroOfManyBattles": "Hero Of Many Battles",
"morpekoFullBelly": "Saciado",
"zacianHeroOfManyBattles": "Herói Veterano",
"zamazentaHeroOfManyBattles": "Herói Veterano",
"zarudeDada": "Papa",
"enamorusIncarnate": "Incarnate",
"enamorusIncarnate": "Materializado",
// 9G
"squawkabillyGreenPlumage": "Plumas Verdes",
"squawkabillyBluePlumage": "Plumas Azuis",

View File

@ -2463,7 +2463,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile}嘿,我在找你呢!我知道你急着上路,\n但至少说个再见吧…$@c{smile_eclosed}所以你终于要开始追逐梦想了?\n我几乎不敢相信。$@c{serious_smile_fists}来都来了,来一场对战怎么样?\n毕竟我想看看你是不是准备周全了。$@c{serious_mopen_fists}不要手下留情,我想让你全力以赴!",
},
"victory": {
1: "@c{shock}哇…你彻底击败了我。\n你是真初学者吗$@c{smile}也许是靠点运气,但是…\n谁知道你可能真的能一路走下去。$顺便说一下,博士让我给你这些东西。它们看起来可牛了。$@c{serious_smile_fists}祝你好运!$@c{smile}哦!我希望你能喜欢这次的活动! ",
1: "@c{shock}哇…你彻底击败了我。\n你是真初学者吗$@c{smile}也许是靠点运气,但是…\n谁知道你可能真的能一路走下去。$顺便说一下,博士让我给你这些东西。它们看起来可牛了。$@c{serious_smile_fists}祝你好运!",
},
},
"rival_female": {
@ -2471,7 +2471,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile_wave}你在这儿啊!我到处找你呢!$@c{angry_mopen}你忘了和你最好的朋友说再见了吗?$@c{smile_ehalf}你要去追逐梦想了,对吧?\n从今天开始是不是…$@c{smile}不管怎样,忘了我的事就原谅你吧,\n但有个条件。@c{smile_wave_wink}你必须和我对战!$@c{angry_mopen}全力以赴!\n你也不想让你的冒险在开始之前就结束了对吧",
},
"victory": {
1: "@c{shock}你刚开始就已经这么强了?!@d{96}$@c{angry}你是不是开了?$@c{smile_wave_wink}只是开个玩笑啦!@d{64} @c{smile_eclosed}我输地心服口服了…\n我感觉你出去挺有天赋的。$@c{smile}顺便说一下,博士想让我给你一些东西。\n希望它们能帮上忙$@c{smile_wave}像往常一样尽力而为!\n我相信你$@c{smile}哦!我希望你能喜欢这次的活动! ",
1: "@c{shock}你刚开始就已经这么强了?!@d{96}$@c{angry}你是不是开了?$@c{smile_wave_wink}只是开个玩笑啦!@d{64} @c{smile_eclosed}我输地心服口服了…\n我感觉你出去挺有天赋的。$@c{smile}顺便说一下,博士想让我给你一些东西。\n希望它们能帮上忙$@c{smile_wave}像往常一样尽力而为!\n我相信你",
},
},
"rival_2": {
@ -2479,7 +2479,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile}嘿,你也在这里吗?$@c{smile_eclosed}一路过关斩将,是吧?$@c{serious_mopen_fists}我知道看起来好像我尾随着你来到这里,\n怎么可能啦。$@c{serious_smile_fists}说真的,自从你在老家打败我后,\n我就一直很渴望再比一场。$我自己也进行了很多训练,\n所以这次我肯定会好好打一场。$@c{serious_mopen_fists}不要手下留情,就像以前一样!$让我们开始吧!",
},
"victory": {
1: "@c{neutral_eclosed}哦。我过于自信了。$@c{smile}不过没关系。我猜到可能会这样。$@c{serious_mopen_fists}这只意味着我下次需要更努力!$$@c{smile}呃,不是特意帮你,我正好有多余的这个,\n我觉得你可能想要。$$@c{serious_smile_fists}不过这次之后别指望再有了!$我不能一直给我的对手优势。$@c{smile}反正,保重,要享受活动哦",
1: "@c{neutral_eclosed}哦。我过于自信了。$@c{smile}不过没关系。我猜到可能会这样。$@c{serious_mopen_fists}这只意味着我下次需要更努力!$$@c{smile}呃,不是特意帮你,我正好有多余的这个,\n我觉得你可能想要。$$@c{serious_smile_fists}不过这次之后别指望再有了!$我不能一直给我的对手优势。$@c{smile}反正,保重",
},
},
"rival_2_female": {
@ -2487,7 +2487,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile_wave}哦,真巧,在这里遇见你。\n看来你还没输过嘛。@c{angry_mopen}哈……好家伙!$@c{angry_mopen}我知道你在想什么,\n不我才不会跟踪你什么呢。 @c{smile_eclosed}我只是碰巧在附近。$@c{smile_ehalf}我为你感到高兴,但我只想让你知道\n有时输了是可以接受的。$@c{smile}我们从错误中学到的东西\n往往比我们一直成功时学到的还要多。$@c{angry_mopen}无论如何,我为了我们的复赛已经努力训练了\n所以你最好全力以赴",
},
"victory": {
1: "@c{neutral}我……没打算会输来着……$@c{smile}嗷……好吧。看来我要再更加努力训练了!$@c{smile_wave}我还给你带了个这个$@c{smile_wave_wink}不用谢我哦~.$@c{angry_mopen}不过,这是最后一个啦!\n你可别想再从我这赚小便宜了~$@c{smile_wave}要保重哦,要享受活动哦",
1: "@c{neutral}我……没打算会输来着……$@c{smile}嗷……好吧。看来我要再更加努力训练了!$@c{smile_wave}我还给你带了个这个$@c{smile_wave_wink}不用谢我哦~.$@c{angry_mopen}不过,这是最后一个啦!\n你可别想再从我这赚小便宜了~$@c{smile_wave}要保重哦",
},
"defeat": {
1: "输了有时候也不要紧的…",

View File

@ -2463,7 +2463,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile}嘿,我在找你呢!我知道你急著上路,\n但至少說個再見吧…$@c{smile_eclosed}所以你終於要開始追逐夢想了?\n我幾乎不敢相信。$@c{serious_smile_fists}來都來了,來一場對戰怎麼樣?\n畢竟我想看看你是不是準備周全了。$@c{serious_mopen_fists}不要手下留情,我想讓你全力以赴!",
},
"victory": {
1: "@c{shock}哇…你徹底擊敗了我。\n你是真初學者嗎$@c{smile}也許是靠點運氣,但是…\n誰知道你可能真的能一路走下去。$順便說一下,博士讓我給你這些東西。它們看起來可牛了。$@c{serious_smile_fists}祝你好运!$@c{smile}哦!我希望你能喜歡這次的活動!",
1: "@c{shock}哇…你徹底擊敗了我。\n你是真初學者嗎$@c{smile}也許是靠點運氣,但是…\n誰知道你可能真的能一路走下去。$順便說一下,博士讓我給你這些東西。它們看起來可牛了。$@c{serious_smile_fists}祝你好运!",
},
},
"rival_female": {
@ -2471,7 +2471,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile_wave}你在這兒啊!我到處找你呢!$@c{angry_mopen}你忘了和你最好的朋友說再見了嗎?$@c{smile_ehalf}你要去追逐夢想了,對吧?\n從今天開始是不是…$@c{smile}不管怎樣,忘了我的事就原諒你吧,\n但有個條件。@c{smile_wave_wink}你必須和我對戰!$@c{angry_mopen}全力以赴!\n你也不想讓你的冒險在開始之前就結束了對吧",
},
"victory": {
1: "@c{shock}你剛開始就已經這麼強了?!@d{96}$@c{angry}你是不是開了?$@c{smile_wave_wink}只是開個玩笑啦!@d{64} @c{smile_eclosed}我輸地心服口服了…\n我感覺你出去挺有天賦的。$@c{smile}順便說一下,博士想讓我給你一些東西。\n希望它們能幫上忙$@c{smile_wave}像往常一樣盡力而為!\n我相信你$@c{smile}哦!我希望你能喜歡這次的活動!",
1: "@c{shock}你剛開始就已經這麼強了?!@d{96}$@c{angry}你是不是開了?$@c{smile_wave_wink}只是開個玩笑啦!@d{64} @c{smile_eclosed}我輸地心服口服了…\n我感覺你出去挺有天賦的。$@c{smile}順便說一下,博士想讓我給你一些東西。\n希望它們能幫上忙$@c{smile_wave}像往常一樣盡力而為!\n我相信你",
},
},
"rival_2": {
@ -2479,7 +2479,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile}嘿,你也在這裡嗎?$@c{smile_eclosed}一路過關斬將,是吧?$@c{serious_mopen_fists}我知道看起來好像我尾隨著你來到這裡,\n怎麼可能啦。$@c{serious_smile_fists}說真的,自從你在老家打敗我後,\n我就一直很渴望再比一場。$我自己也進行了很多訓練,\n所以這次我肯定會好好打一場。$@c{serious_mopen_fists}不要手下留情,就像以前一樣!$讓我們開始吧!",
},
"victory": {
1: "@c{neutral_eclosed}哦。我過於自信了。$@c{smile}不過沒關係。我猜到可能會這樣。$@c{serious_mopen_fists}這只意味著我下次需要更努力!$$@c{smile}呃,不是特意幫你,我正好有多餘的這個,\n我覺得你可能想要。$$@c{serious_smile_fists}不過這次之後別指望再有了!$我不能一直給我的對手優勢。$@c{smile}反正,保重, 要享受活動哦",
1: "@c{neutral_eclosed}哦。我過於自信了。$@c{smile}不過沒關係。我猜到可能會這樣。$@c{serious_mopen_fists}這只意味著我下次需要更努力!$$@c{smile}呃,不是特意幫你,我正好有多餘的這個,\n我覺得你可能想要。$$@c{serious_smile_fists}不過這次之後別指望再有了!$我不能一直給我的對手優勢。$@c{smile}反正,保重",
},
},
"rival_2_female": {
@ -2487,7 +2487,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "@c{smile_wave}哦,真巧,在這裡遇見你。\n看來你還沒輸過嘛。@c{angry_mopen}哈……好傢伙!$@c{angry_mopen}我知道你在想什麼,\n不我才不會跟蹤你什麼呢。 @c{smile_eclosed}我只是碰巧在附近。$@c{smile_ehalf}我為你感到高興,但我只想讓你知道\n有時輸了是可以接受的。$@c{smile}我們從錯誤中學到的東西\n往往比我們一直成功時學到的還要多。$@c{angry_mopen}無論如何,我為了我們的複賽已經努力訓練了\n所以你最好全力以赴",
},
"victory": {
1: "@c{neutral}我……沒打算會輸來著……$@c{smile}嗷……好吧。看來我要再更加努力訓練了!$@c{smile_wave}我還給你帶了個這個$@c{smile_wave_wink}不用謝我哦~.$@c{angry_mopen}不過,這是最後一個啦!\n 你可別想再從我這賺小便宜了~$@c{smile_wave}要保重哦,要享受活動哦",
1: "@c{neutral}我……沒打算會輸來著……$@c{smile}嗷……好吧。看來我要再更加努力訓練了!$@c{smile_wave}我還給你帶了個這個$@c{smile_wave_wink}不用謝我哦~.$@c{angry_mopen}不過,這是最後一個啦!\n 你可別想再從我這賺小便宜了~$@c{smile_wave}要保重哦",
},
"defeat": {
1: "輸了有時候也不要緊的…",

View File

@ -1026,6 +1026,8 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
return new AttackTypeBoosterModifierType(pregenArgs[0] as Type, 20);
}
console.log("Generating item: Attack Type Booster")
const attackMoveTypes = party.map(p => p.getMoveset().map(m => m?.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
if (!attackMoveTypes.length) {
return null;
@ -1055,6 +1057,13 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
const randInt = Utils.randSeedInt(totalWeight);
let weight = 0;
var fullweights: integer[] = []
attackMoveTypeWeights.forEach((v, idx) => {
for (var i = 0; i < v; i++) {
fullweights.push(idx)
}
})
for (const t of attackMoveTypeWeights.keys()) {
const typeWeight = attackMoveTypeWeights.get(t)!; // guranteed to be defined
if (randInt <= weight + typeWeight) {
@ -1064,6 +1073,8 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
weight += typeWeight;
}
//console.log(fullweights.map((v, i) => i == randInt ? `> ${Utils.getEnumKeys(Type)[v]} <` : `${Utils.getEnumKeys(Type)[v]}`))
return new AttackTypeBoosterModifierType(type!, 20);
});
}
@ -1091,6 +1102,8 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
return new SpeciesStatBoosterModifierType(pregenArgs[0] as SpeciesStatBoosterItem);
}
console.log("Generating item: Species Booster")
const values = Object.values(items);
const keys = Object.keys(items);
const weights = keys.map(() => 0);
@ -1129,6 +1142,15 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
const randInt = Utils.randSeedInt(totalWeight, 1);
let weight = 0;
var fullweights: integer[] = []
weights.forEach((v, idx) => {
for (var i = 0; i < v; i++) {
fullweights.push(idx)
}
})
//console.log(fullweights.map((v, i) => i == randInt ? `> ${keys[v]} <` : `${keys[v]}`))
for (const i in weights) {
if (weights[i] !== 0) {
const curWeight = weight + weights[i];
@ -1151,12 +1173,16 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator {
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Moves)) {
return new TmModifierType(pregenArgs[0] as Moves, tier);
}
console.log("Generating item: TM (Tier: " + Utils.getEnumKeys(ModifierTier)[tier].toLowerCase() + ")")
const partyMemberCompatibleTms = party.map(p => (p as PlayerPokemon).compatibleTms.filter(tm => !p.moveset.find(m => m?.moveId === tm)));
const tierUniqueCompatibleTms = partyMemberCompatibleTms.flat().filter(tm => tmPoolTiers[tm] === tier).filter(tm => !allMoves[tm].name.endsWith(" (N)")).filter((tm, i, array) => array.indexOf(tm) === i);
if (!tierUniqueCompatibleTms.length) {
return null;
}
const randTmIndex = Utils.randSeedInt(tierUniqueCompatibleTms.length);
//console.log(tierUniqueCompatibleTms.map((v, i) => i == randTmIndex ? `> ${Utils.getEnumKeys(Moves)[v].toUpperCase() + Utils.getEnumKeys(Moves)[v].substring(1).toLowerCase()} <` : `${Utils.getEnumKeys(Moves)[v].toUpperCase() + Utils.getEnumKeys(Moves)[v].substring(1).toLowerCase()}`))
return new TmModifierType(tierUniqueCompatibleTms[randTmIndex], tier);
});
}
@ -1169,6 +1195,8 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem);
}
console.log("Generating item: Evolution Item")
const evolutionItemPool = [
party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
const evolutions = pokemonEvolutions[p.species.speciesId];
@ -1184,7 +1212,9 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
return null;
}
return new EvolutionItemModifierType(evolutionItemPool[Utils.randSeedInt(evolutionItemPool.length)]!); // TODO: is the bang correct?
const idx = Utils.randSeedInt(evolutionItemPool.length)
// console.log(evolutionItemPool.map((v, i) => i == idx ? `> ${Utils.getEnumKeys(EvolutionItem)[v!]} <` : Utils.getEnumKeys(EvolutionItem)[v!]))
return new EvolutionItemModifierType(evolutionItemPool[idx]!); // TODO: is the bang correct?
});
}
}
@ -1196,6 +1226,8 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
}
console.log("Generating item: Form Change Item")
const formChangeItemPool = [...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChanges = pokemonFormChanges[p.species.speciesId];
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length)
@ -1236,7 +1268,9 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
return null;
}
return new FormChangeItemModifierType(formChangeItemPool[Utils.randSeedInt(formChangeItemPool.length)]);
const idx = Utils.randSeedInt(formChangeItemPool.length)
// console.log(formChangeItemPool.map((v, i) => i == idx ? `> ${Utils.getEnumKeys(FormChangeItem)[v!]} <` : Utils.getEnumKeys(FormChangeItem)[v!]))
return new FormChangeItemModifierType(formChangeItemPool[idx]!);
});
}
}
@ -1642,6 +1676,368 @@ function hasMaximumBalls(party: Pokemon[], ballType: PokeballType): boolean {
return (party[0].scene.gameMode.isClassic && party[0].scene.pokeballCounts[ballType] >= MAX_PER_TYPE_POKEBALLS);
}
var evioliteOverride = "";
export function setEvioliteOverride(v: string) {
evioliteOverride = v;
}
export function calculateItemConditions(party: Pokemon[], log?: boolean, showAll?: boolean) {
let total_common = 0
let total_great = 0
let total_ultra = 0
let total_rogue = 0
let total_master = 0
let items: string[][] = [[], [], [], [], []]
if (!hasMaximumBalls(party, PokeballType.POKEBALL)) {
items[0].push(`Poké Ball (6)`)
total_common += 6
}
items[0].push(`Rare Candy (2)`)
total_common += 2
var potion = Math.min(party.filter(p => (p.getInverseHp() >= 10 || p.getHpRatio() <= 0.875) && !p.isFainted()).length, 3)
if (potion > 0) {
items[0].push(`Potion (${potion * 3})`)
total_common += potion * 3
}
var superpotion = Math.min(party.filter(p => (p.getInverseHp() >= 25 || p.getHpRatio() <= 0.75) && !p.isFainted()).length, 3)
if (superpotion > 0) {
items[0].push(`Super Potion (${superpotion})`)
total_common += superpotion
}
var ether = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3)
if (ether > 0) {
items[0].push(`Ether (${ether * 3})`)
items[0].push(`Max Ether (${ether})`)
total_common += ether * 4
}
let lure = skipInLastClassicWaveOrDefault(2)(party)
if (lure > 0) {
items[0].push(`Lure (${lure})`)
total_common += lure;
}
if (showAll) {
items[0].push(`X Attack (0.66)`)
items[0].push(`X Defense (0.66)`)
items[0].push(`X Sp. Atk (0.66)`)
items[0].push(`X Sp. Def (0.66)`)
items[0].push(`X Speed (0.66)`)
items[0].push(`X Accuracy (0.66)`)
} else {
items[0].push(`Any X Item (4, 6 kinds)`)
}
items[0].push(`Berry (2)`)
items[0].push(`Common TM (2)`)
total_common += 8 // X item = 4, berry = 2, common TM = 2
if (!hasMaximumBalls(party, PokeballType.GREAT_BALL)) {
items[1].push(`Great Ball (6)`)
total_great += 6
}
items[1].push(`PP Up (2)`)
total_great += 2
let statusPartyCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => {
if (i instanceof Modifiers.TurnStatusEffectModifier) {
return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status?.effect;
}
return false;
})).length, 3)
if (statusPartyCount > 0) {
items[1].push(`Full Heal (${statusPartyCount * 3})`)
total_great += statusPartyCount * 3
}
let reviveCount = Math.min(party.filter(p => p.isFainted()).length, 3);
if (reviveCount > 0) {
items[1].push(`Revive (${reviveCount * 9})`)
items[1].push(`Max Revive (${reviveCount * 3})`)
total_great += reviveCount * 12
}
if (party.filter(p => p.isFainted()).length >= Math.ceil(party.length / 2)) {
items[1].push(`Sacred Ash (1)`)
total_great++
}
let hyperpotion = Math.min(party.filter(p => (p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625) && !p.isFainted()).length, 3)
if (hyperpotion > 0) {
items[1].push(`Hyper Potion (${hyperpotion * 3})`)
total_great += hyperpotion * 3
}
let maxpotion = Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3)
if (maxpotion > 0) {
items[1].push(`Max Potion (${maxpotion})`)
total_great += maxpotion
}
let fullrestore = Math.floor((Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3) + statusPartyCount) / 2)
if (fullrestore > 0) {
items[1].push(`Full Restore (${fullrestore})`)
total_great += fullrestore
}
let elexir = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3)
if (elexir) {
items[1].push(`Elexir (${elexir * 3})`)
items[1].push(`Max Elexir (${elexir})`)
total_great += elexir * 4
}
items[1].push("Dire Hit (4)")
total_great += 4
let superlure = skipInLastClassicWaveOrDefault(4)(party)
if (superlure > 0) {
items[1].push(`Super Lure (4)`)
items[1].push(`Nugget (5)`)
total_great += 9
}
let evo = Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8)
if (evo > 0) {
items[1].push(`Evolution Item (${evo})`)
total_great += evo
}
if (party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180) {
if (!party[0].scene.getModifiers(Modifiers.MapModifier).length) {
console.log(`Map (1)`)
} else {
console.log(`Map (1, results in a retry as it's already owned)`)
}
total_great++
}
items[1].push(`Rare TM (2)`)
total_great += 3
if (party.find(p => p.getLearnableLevelMoves().length)) {
// Memory Mushroom
let highestLev = party.map(p => p.level).reduce((highestLevel: integer, level: integer) => Math.max(highestLevel, level), 1)
let memoryshroom = Math.min(Math.ceil(highestLev / 20), 4)
if (memoryshroom > 0) {
items[1].push(`Memory Mushroom (${memoryshroom})`)
total_great += memoryshroom
}
}
if (showAll) {
items[1].push(`${getBaseStatBoosterItemName(Stat.HP)} (0.5)`)
items[1].push(`${getBaseStatBoosterItemName(Stat.ATK)} (0.5)`)
items[1].push(`${getBaseStatBoosterItemName(Stat.DEF)} (0.5)`)
items[1].push(`${getBaseStatBoosterItemName(Stat.SPATK)} (0.5)`)
items[1].push(`${getBaseStatBoosterItemName(Stat.SPDEF)} (0.5)`)
items[1].push(`${getBaseStatBoosterItemName(Stat.SPD)} (0.5)`)
} else {
items[1].push(`Any Vitamin (3, 6 kinds)`)
}
total_great += 3
if (party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length) {
if (showAll) {
const teratypes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
const randomchance1 = 1/3 * 1/64
const randomchance2 = 1/3 * 63/64 * 1/18
const teamTypes = party.map(p => p.getTypes(false, false, true)).flat()
teratypes.forEach((v, i) => {
if (i == Type.STELLAR) {
teratypes[i] += randomchance1
} else {
teratypes[i] += randomchance2
}
})
teamTypes.forEach(v => {
teratypes[v] += 2/3 * 1/teamTypes.length
})
items[1].push(`Any Tera Shard (1, 19 kinds)`)
teratypes.forEach((v, i) => {
items[1].push(` ${i18next.t(`pokemonInfo:Type.${Type[i]}`)}: ${Math.round(v*1000)/10}%`)
})
} else {
items[1].push(`Any Tera Shard (1, 19 kinds)`)
}
total_great++;
}
if (party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1) {
items[1].push(`DNA Splicer (4)`)
total_great += 4
}
if (!party[0].scene.gameMode.isDaily ) {
items[1].push("Voucher (1, or 0 if reroll)")
total_great += 1
}
if (!hasMaximumBalls(party, PokeballType.ULTRA_BALL)) {
items[2].push(`Ultra Ball (15)`)
total_ultra += 15
}
if (superlure) {
items[2].push(`Max Lure (4)`)
items[2].push(`Big Nugget (12)`)
total_ultra += 16
}
items[2].push(`PP Max (3)`)
items[2].push(`Mint (4)`)
total_ultra += 7
let evoRare = Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * 4, 32)
if (evoRare) {
items[2].push(`Rare Evolution Item (${evoRare})`)
total_ultra += evoRare
}
if (superlure) {
items[2].push(`Amulet Coin (3)`)
total_ultra += 3
}
if (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.EVIOLITE]) {
if (party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))) && !p.getHeldItems().some(i => i instanceof Modifiers.EvolutionStatBoosterModifier))) {
items[2].push(`Eviolite (10)`)
total_ultra += 10
}
}
items[2].push(`Species Stat Booster (12, retries if incompatible)`)
total_ultra += 12
const checkedSpecies = [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ]
const checkedAbilitiesT = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD];
const checkedAbilitiesF = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD];
const checkedAbilitiesW = [Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT];
const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
const weightMultiplier = party.filter(
p => !p.getHeldItems().some(i => i instanceof Modifiers.PokemonResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) &&
(checkedAbilitiesW.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && selfStatLowerMoves.includes(m.moveId)))).length;
if (party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.SpeciesCritBoosterModifier) && (checkedSpecies.includes(p.getSpeciesForm(true).speciesId) || (p.isFusion() && checkedSpecies.includes(p.getFusionSpeciesForm(true).speciesId))))) {
items[2].push(`Leek (12)`)
total_ultra += 12
}
if (party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier) && (checkedAbilitiesT.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId))))) {
items[2].push(`Toxic Orb (10)`)
total_ultra += 10
}
if (party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier) && (checkedAbilitiesF.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId))))) {
items[2].push(`Flame Orb (10)`)
total_ultra += 10
}
let whiteherb = 0 * (weightMultiplier ? 2 : 1) + (weightMultiplier ? weightMultiplier * 0 : 0)
if (whiteherb) {
items[2].push(`White Herb (${whiteherb})`)
total_ultra += whiteherb
}
if (superlure) {
items[2].push(`Wide Lens (5)`)
total_ultra += 5
}
items[2].push(`Reviver Seed (4)`)
items[2].push(`Attack Type Booster (9)`)
items[2].push(`Epic TM (11)`)
items[2].push(`Rarer Candy (4)`)
if (superlure) {
items[2].push(`Golden Punch (2)`)
items[2].push(`IV Scanner (4)`)
items[2].push(`EXP Charm (8)`)
items[2].push(`EXP Share (10)`)
items[2].push(`EXP Balance (3)`)
total_ultra += 27
}
let teraorb = Math.min(Math.max(Math.floor(party[0].scene.currentBattle.waveIndex / 50) * 2, 1), 4)
if (teraorb) {
items[2].push(`Tera Orb (${teraorb})`)
total_ultra += teraorb
}
items[2].push(`Quick Claw (3)`)
items[2].push(`Wide Lens (4)`)
total_ultra += 35
if (!hasMaximumBalls(party, PokeballType.ROGUE_BALL)) {
items[3].push(`Rogue Ball (16)`)
total_rogue += 16
}
if (superlure) {
items[3].push(`Relic Gold (2)`)
total_rogue += 2
}
items[3].push(`Leftovers (3)`)
items[3].push(`Shell Bell (3)`)
items[3].push(`Berry Pouch (4)`)
items[3].push(`Grip Claw (5)`)
items[3].push(`Scope Lens (4)`)
items[3].push(`Baton (2)`)
items[3].push(`Soul Dew (7)`)
items[3].push(`Soothe Bell (4)`)
let abilitycharm = skipInClassicAfterWave(189, 6)(party);
if (abilitycharm) {
items[3].push(`Ability Charm (${abilitycharm})`)
total_rogue += abilitycharm
}
items[3].push(`Focus Band (5)`)
items[3].push(`King's Rock (3)`)
total_rogue += 40
if (superlure) {
items[3].push(`Lock Capsule (3)`)
items[3].push(`Super EXP Charm (8)`)
total_rogue += 11
}
let formchanger = Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 6
let megabraclet = Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 9
let dynamaxband = Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 9
if (formchanger) {
items[3].push(`Form Change Item (${formchanger}, retries if incompatible)`)
total_rogue += formchanger
}
if (megabraclet) {
items[3].push(`Mega Bracelet (${megabraclet}, retries if already owned)`)
total_rogue += megabraclet
}
if (dynamaxband) {
items[3].push(`Dynamax Band (${dynamaxband}, retries if already owned)`)
total_rogue += dynamaxband
}
if (!party[0].scene.gameMode.isDaily) {
items[3].push(`Voucher Plus (3 - number of rerolls)`)
total_rogue += 3
}
if (!hasMaximumBalls(party, PokeballType.MASTER_BALL)) {
items[4].push(`Master Ball (24)`)
total_master += 24
}
items[4].push(`Shiny Charm (14)`)
total_master += 14
items[4].push(`Healing Charm (18)`)
total_master += 18
items[4].push(`Multi Lens (18)`)
total_master += 18
if (!party[0].scene.gameMode.isDaily && !party[0].scene.gameMode.isEndless && !party[0].scene.gameMode.isSplicedOnly) {
items[4].push(`Voucher Premium (5, -2 per reroll)`)
total_master += 3
}
if (!party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1) {
items[4].push(`DNA Splicer (24)`)
total_master += 24
}
if ((!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE])) {
items[4].push(`Mini Black Hole (1)`)
total_master += 1
}
items[0].sort()
items[1].sort()
items[2].sort()
items[3].sort()
items[4].sort()
if (!log)
return items;
let itemlabels = [
`Poké (${items[0].length}, weight ${total_common})`,
`Great (${items[1].length}, weight ${total_great})`,
`Ultra (${items[2].length}, weight ${total_ultra})`,
`Rogue (${items[3].length}, weight ${total_rogue})`,
`Master (${items[4].length}, weight ${total_master})`
]
items.forEach((mi, idx) => {
console.log(itemlabels[idx])
mi.forEach(m => {
console.log(" " + mi)
})
})
return items;
}
const modifierPool: ModifierPool = {
[ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.POKEBALL, (party: Pokemon[]) => (hasMaximumBalls(party, PokeballType.POKEBALL)) ? 0 : 6, 6),
@ -1749,7 +2145,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.RARE_EVOLUTION_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15) * 4, 32), 32),
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
if (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.EVIOLITE]) {
if (evioliteOverride == "on" || (evioliteOverride != "off" && (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.EVIOLITE]))) {
return party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))) && !p.getHeldItems().some(i => i instanceof Modifiers.EvolutionStatBoosterModifier)) ? 10 : 0;
}
return 0;
@ -1986,6 +2382,7 @@ export function getModifierType(modifierTypeFunc: ModifierTypeFunc): ModifierTyp
let modifierPoolThresholds = {};
let ignoredPoolIndexes = {};
let ignoredPoolNames: string[][] = [];
let dailyStarterModifierPoolThresholds = {};
let ignoredDailyStarterPoolIndexes = {}; // eslint-disable-line @typescript-eslint/no-unused-vars
@ -2021,22 +2418,44 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool
const tierWeights = [ 768 / 1024, 195 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ];
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) {
console.log("Regenerating item pool")
const pool = getModifierPoolForType(poolType);
const ignoredIndexes = {};
const ignoredNames: string[][] = [];
const modifierTableData = {};
const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => {
ignoredIndexes[t] = [];
ignoredNames[t] = []
const thresholds = new Map();
const tierModifierIds: string[] = [];
let tierMaxWeight = 0;
let i = 0;
console.log("Summing pool weights")
pool[t].reduce((total: integer, modifierType: WeightedModifierType) => {
//console.warn(` ${modifierType.modifierType.name} (Running total: ${total})`)
const weightedModifierType = modifierType as WeightedModifierType;
const existingModifiers = party[0].scene.findModifiers(m => m.type.id === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER);
if (weightedModifierType.modifierType instanceof ModifierTypeGenerator) {
//console.warn(" Generating modifier type based on party contents")
}
const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator
? weightedModifierType.modifierType.generateType(party)
: weightedModifierType.modifierType;
if (weightedModifierType.modifierType instanceof ModifierTypeGenerator) {
//console.warn(" --> " + itemModifierType?.name)
}
if (!existingModifiers.length) {
//console.warn (" No existing modifiers that match type '" + weightedModifierType.modifierType.id + "'")
} else if (itemModifierType instanceof PokemonHeldItemModifierType) {
//console.warn(" Modifier is a Held Item")
} else if (itemModifierType instanceof FormChangeItemModifierType) {
//console.warn(" Modifier is a Form Change item")
} else if (existingModifiers.find(m => m.stackCount < m.getMaxStackCount(party[0].scene, true))) {
//console.warn(" Modifier exists, but the player can hold more")
} else {
//console.warn(" All conditions failed - ignoring this modifier")
}
const weight = !existingModifiers.length
|| itemModifierType instanceof PokemonHeldItemModifierType
|| itemModifierType instanceof FormChangeItemModifierType
@ -2050,12 +2469,20 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
tierModifierIds.push(modifierId);
const outputWeight = useMaxWeightForOutput ? weightedModifierType.maxWeight : weight;
modifierTableData[modifierId] = { weight: outputWeight, tier: parseInt(t), tierPercent: 0, totalPercent: 0 };
//console.warn(" Added '" + modifierId + "' to modifier IDs list")
//console.warn(" Incremented tierMaxWeight: " + tierMaxWeight + " --> " + (tierMaxWeight + outputWeight))
if (weight) {
//console.warn(" Incremented total: " + total + " --> " + (total + weight))
}
tierMaxWeight += outputWeight;
}
if (weight) {
total += weight;
//console.warn("Added " + weightedModifierType.modifierType.id)
} else {
ignoredIndexes[t].push(i++);
ignoredNames[t].push(weightedModifierType.modifierType.name)
//console.warn("Ignored " + weightedModifierType.modifierType.id)
return total;
}
thresholds.set(total, i++);
@ -2092,6 +2519,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
ignoredDailyStarterPoolIndexes = ignoredIndexes;
break;
}
ignoredPoolNames = ignoredNames;
}
export function getModifierTypeFuncById(id: string): ModifierTypeFunc {
@ -2102,12 +2530,22 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo
const options: ModifierTypeOption[] = [];
const retryCount = Math.min(count * 5, 50);
new Array(count).fill(0).map((_, i) => {
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, modifierTiers && modifierTiers.length > i ? modifierTiers[i] : undefined);
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, modifierTiers && modifierTiers.length > i ? modifierTiers[i] : undefined, undefined, undefined, scene, shutUpBro, generateAltTiers, advanced);
let r = 0;
const aT = candidate?.alternates
const aT2 = candidate?.advancedAlternates
while (options.length && ++r < retryCount && options.filter(o => o.type?.name === candidate?.type?.name || o.type?.group === candidate?.type?.group).length) {
//if (options.filter(o => o.type?.name === candidate?.type?.name))
//console.error(options.filter(o => o.type?.name === candidate?.type?.name).map((v, q) => v.type.name + " (" + v.type.group + ") - conflicting name").join("\n"))
//if (options.filter(o => o.type?.group === candidate?.type?.group))
//console.error(options.filter(o => o.type?.group === candidate?.type?.group).map((v, q) => v.type.name + " (" + v.type.group + ") - conflicting group").join("\n"))
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate?.type?.tier, candidate?.upgradeCount, undefined, scene, shutUpBro, generateAltTiers, advanced);
//console.log(" Retrying - attempt " + r, candidate?.type.name)
}
if (options.length && options.filter(o => o.type?.name === candidate?.type?.name || o.type?.group === candidate?.type?.group).length) {
//console.log(" Item " + (i+1) + "/" + count + " (+" + r + ")", candidate?.type.name, "(Out of retries)")
} else {
//console.log(" Item " + (i+1) + "/" + count + " (+" + r + ")", candidate?.type.name)
}
if (candidate && candidate.alternates == undefined) {
candidate.alternates = aT
@ -2411,7 +2849,12 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
}
if (player) {
if (!shutUpBro) console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier]);
if (!shutUpBro) {
console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier].filter(i => i <= index).length)
//console.log("Index ", index);
//console.log("# of ignored items for this tier", ignoredPoolIndexes[tier].filter(i => i <= index).length)
//console.log("Ignored items for this tier", ignoredPoolIndexes[tier].map((v, i) => [ignoredPoolNames[i], v]).flat())
}
}
let modifierType: ModifierType = (pool[tier][index]).modifierType;
if (modifierType instanceof ModifierTypeGenerator) {
@ -2420,7 +2863,10 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
if (player) {
if (!shutUpBro) console.log(ModifierTier[tier], upgradeCount);
}
console.error("Null Modifier - regenerating")
return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount, scene, shutUpBro, generateAltTiers);
} else {
console.log("Generated type", modifierType)
}
}
@ -2490,9 +2936,11 @@ export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType
export class ModifierTypeOption {
public type: ModifierType;
public eviolite: ModifierType;
public upgradeCount: integer;
public cost: integer;
public alternates?: integer[];
public netprice: integer;
public advancedAlternates?: string[];
constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) {

View File

@ -2420,7 +2420,7 @@ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModif
}
getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string {
return i18next.t("modifier:contactHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.name, typeName: this.type.name });
return i18next.t("modifier:contactHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: getPokemonNameWithAffix(pokemon), typeName: this.type.name });
}
getMaxHeldItemCount(pokemon: Pokemon): integer {

View File

@ -18,7 +18,7 @@ import { Phase } from "./phase";
import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "./data/battle-stat";
import { biomeLinks, getBiomeName } from "./data/biomes";
import { ModifierTier } from "./modifier/modifier-tier";
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getLuckString, getModifierType, getPartyLuckValue, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, calculateItemConditions, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getLuckString, getModifierType, getPartyLuckValue, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds, setEvioliteOverride } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, CenterOfAttentionTag, EncoreTag, ProtectedTag, SemiInvulnerableTag, TrappedTag } from "./data/battler-tags";
import { getPokemonNameWithAffix } from "./messages";
@ -1653,6 +1653,10 @@ export class EncounterPhase extends BattlePhase {
} else if (!(battle.waveIndex % 1000)) {
enemyPokemon.formIndex = 1;
enemyPokemon.updateScale();
const bossMBH = this.scene.findModifier(m => m instanceof TurnHeldItemTransferModifier && m.pokemonId === enemyPokemon.id, false) as TurnHeldItemTransferModifier;
this.scene.removeModifier(bossMBH!);
bossMBH?.setTransferrableFalse();
this.scene.addEnemyModifier(bossMBH!);
}
}
@ -1802,7 +1806,7 @@ export class EncounterPhase extends BattlePhase {
}
LoggerTools.resetWaveActions(this.scene, undefined, true)
this.scene.doShinyCheck()
//this.scene.doShinyCheck()
if (LoggerTools.autoCheckpoints.includes(this.scene.currentBattle.waveIndex)) {
//this.scene.gameData.saveGameToAuto(this.scene)
@ -1875,7 +1879,6 @@ export class EncounterPhase extends BattlePhase {
const enemyField = this.scene.getEnemyField();
enemyField.forEach((enemyPokemon, e) => {
enemyPokemon.flyout.revealMoves()
if (enemyPokemon.isShiny()) {
this.scene.unshiftPhase(new ShinySparklePhase(this.scene, BattlerIndex.ENEMY + e));
}
@ -5468,13 +5471,24 @@ export class FaintPhase extends PokemonPhase {
}
if (this.player) {
const nonFaintedLegalPartyMembers = this.scene.getParty().filter(p => p.isAllowedInBattle());
const nonFaintedPartyMemberCount = nonFaintedLegalPartyMembers.length;
if (!nonFaintedPartyMemberCount) {
/** The total number of Pokemon in the player's party that can legally fight */
const legalPlayerPokemon = this.scene.getParty().filter(p => p.isAllowedInBattle());
/** The total number of legal player Pokemon that aren't currently on the field */
const legalPlayerPartyPokemon = legalPlayerPokemon.filter(p => !p.isActive(true));
if (!legalPlayerPokemon.length) {
/** If the player doesn't have any legal Pokemon, end the game */
this.scene.unshiftPhase(new GameOverPhase(this.scene));
} else if (nonFaintedPartyMemberCount === 1 && this.scene.currentBattle.double) {
} else if (this.scene.currentBattle.double && legalPlayerPokemon.length === 1 && legalPlayerPartyPokemon.length === 0) {
/**
* If the player has exactly one Pokemon in total at this point in a double battle, and that Pokemon
* is already on the field, unshift a phase that moves that Pokemon to center position.
*/
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
} else if (nonFaintedPartyMemberCount >= this.scene.currentBattle.getBattlerCount()) {
} else if (legalPlayerPartyPokemon.length > 0) {
/**
* If previous conditions weren't met, and the player has at least 1 legal Pokemon off the field,
* push a phase that prompts the player to summon a Pokemon from their party.
*/
LoggerTools.isFaintSwitch.value = true;
this.scene.pushPhase(new SwitchPhase(this.scene, this.fieldIndex, true, false));
}
@ -7089,9 +7103,10 @@ export function runShinyCheck(scene: BattleScene, mode: integer, wv?: integer) {
}
export class SelectModifierPhase extends BattlePhase {
private rerollCount: integer;
private modifierTiers: ModifierTier[];
private modifierTiers: ModifierTier[] = [];
private modifierPredictions: ModifierTypeOption[][] = []
private predictionCost: integer;
private predictionCost: integer = 0;
private costTiers: integer[] = [];
constructor(scene: BattleScene, rerollCount: integer = 0, modifierTiers?: ModifierTier[], predictionCost?: integer, modifierPredictions?: ModifierTypeOption[][]) {
super(scene);
@ -7103,13 +7118,19 @@ export class SelectModifierPhase extends BattlePhase {
this.modifierPredictions = modifierPredictions;
}
this.predictionCost = 0
this.costTiers = []
}
generateSelection(rerollOverride: integer, modifierOverride?: integer) {
generateSelection(rerollOverride: integer, modifierOverride?: integer, eviolite?: boolean) {
//const STATE = Phaser.Math.RND.state() // Store RNG state
//console.log("====================")
//console.log(" Reroll Prediction: " + rerollOverride)
const party = this.scene.getParty();
if (eviolite) {
setEvioliteOverride("on")
} else {
setEvioliteOverride("off")
}
regenerateModifierPoolThresholds(party, this.getPoolType(), rerollOverride);
const modifierCount = new Utils.IntegerHolder(3);
if (this.isPlayer()) {
@ -7119,11 +7140,31 @@ export class SelectModifierPhase extends BattlePhase {
//modifierCount.value = modifierOverride
}
const typeOptions: ModifierTypeOption[] = this.getModifierTypeOptions(modifierCount.value, true, true);
setEvioliteOverride("")
typeOptions.forEach((option, idx) => {
option.netprice = this.predictionCost
if (option.type.name == "Nugget") {
option.netprice -= this.scene.getWaveMoneyAmount(1)
}
if (option.type.name == "Big Nugget") {
option.netprice -= this.scene.getWaveMoneyAmount(2.5)
}
if (option.type.name == "Relic Gold") {
option.netprice -= this.scene.getWaveMoneyAmount(10)
}
//console.log(option.type.name)
})
//console.log("====================")
this.modifierPredictions.push(typeOptions)
if (eviolite) {
this.modifierPredictions[rerollOverride].forEach((m, i) => {
if (m.type.name != typeOptions[i].type.name) {
m.eviolite = typeOptions[i].type
}
})
} else {
this.modifierPredictions[rerollOverride] = typeOptions
}
this.costTiers.push(this.predictionCost)
this.predictionCost += this.getRerollCost(typeOptions, false, rerollOverride)
//Phaser.Math.RND.state(STATE) // Restore RNG state like nothing happened
}
@ -7133,10 +7174,19 @@ export class SelectModifierPhase extends BattlePhase {
if (!this.rerollCount) {
this.updateSeed();
console.log("\n\nPerforming reroll prediction\n\n\n")
console.log(calculateItemConditions(this.scene.getParty(), false, true))
console.log("\n\nPerforming reroll prediction (Eviolite OFF)\n\n\n")
this.predictionCost = 0
this.costTiers = []
for (var idx = 0; idx < 10 && this.predictionCost < this.scene.money; idx++) {
this.generateSelection(idx)
this.generateSelection(idx, undefined, false)
}
this.updateSeed();
console.log("\n\nPerforming reroll prediction (Eviolite ON)\n\n\n")
this.predictionCost = 0
this.costTiers = []
for (var idx = 0; idx < 10 && this.predictionCost < this.scene.money; idx++) {
this.generateSelection(idx, undefined, true)
}
this.updateSeed();
} else {
@ -7362,35 +7412,83 @@ export class SelectModifierPhase extends BattlePhase {
return !cost!;// TODO: is the bang correct?
};
if (this.rerollCount == 0) {
this.modifierPredictions.forEach((mp, r) => {
console.log("Rerolls: " + r)
mp.forEach((m, i) => {
console.log(" " + m.type!.name)
if (m.alternates) {
let showedLuckFlag = false
for (var j = 0, currentTier = m.type!.tier; j < m.alternates.length; j++) {
if (m.alternates[j] > currentTier) {
currentTier = m.alternates[j]
if (m.advancedAlternates) {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
if (true) {
this.modifierPredictions.forEach((mp, r) => {
// costTiers
console.log("Rerolls: " + r + (this.costTiers[r] != 0 ? " - ₽" + this.costTiers[r] : ""))
mp.forEach((m, i) => {
console.log(" " + m.type!.name + (m.netprice != this.costTiers[r] ? " - ₽" + m.netprice : ""))
if (m.eviolite) {
console.log(" With Eviolite unlocked: " + m.eviolite.name)
}
if (m.alternates) {
//console.log(m.alternates)
let showedLuckFlag = false
for (var j = 0, currentTier = m.type!.tier; j < m.alternates.length; j++) {
if (m.alternates[j] > currentTier) {
currentTier = m.alternates[j]
if (m.advancedAlternates) {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + m.advancedAlternates[j])
} else {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + tierNames[currentTier] + "-tier item (failed to generate item)")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + m.advancedAlternates[j])
} else {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + tierNames[currentTier] + "-tier item (failed to generate item)")
}
}
} else {
//console.log(" No alt-luck data")
}
} else {
console.log(" No alt-luck data")
}
})
})
})
} else {
let modifierList: string[] = []
this.modifierPredictions.forEach((mp, r) => {
//console.log("Rerolls: " + r)
mp.forEach((m, i) => {
modifierList.push(m.type!.name + (r > 0 ? " (x" + r + ")" : ""))
//console.log(" " + m.type!.name)
if (m.eviolite) {
modifierList.push(m.type!.name + (r > 0 ? " (x" + r + " with eviolite unlocked)" : " (With eviolite unlocked)"))
//console.log(" With Eviolite unlocked: " + m.eviolite.name)
}
if (m.alternates) {
//console.log(m.alternates)
let showedLuckFlag = false
for (var j = 0, currentTier = m.type!.tier; j < m.alternates.length; j++) {
if (m.alternates[j] > currentTier) {
currentTier = m.alternates[j]
if (m.advancedAlternates) {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + m.advancedAlternates[j])
} else {
if (!showedLuckFlag) {
showedLuckFlag = true
console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")")
}
console.log(" At " + j + " luck (" + getLuckString(j) + "): " + tierNames[currentTier] + "-tier item (failed to generate item)")
}
}
}
} else {
//console.log(" No alt-luck data")
}
})
})
modifierList.sort()
modifierList.forEach(v => {
console.log(v)
})
}
}
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
}

View File

@ -0,0 +1,58 @@
import { BattleStat } from "#app/data/battle-stat";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import { getMovePosition } from "#test/utils/gameManagerUtils";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Abilities - Hyper Cutter", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.battleType("single")
.moveset([Moves.SAND_ATTACK, Moves.NOBLE_ROAR, Moves.DEFOG, Moves.OCTOLOCK])
.ability(Abilities.BALL_FETCH)
.enemySpecies(Species.SHUCKLE)
.enemyAbility(Abilities.HYPER_CUTTER)
.enemyMoveset(SPLASH_ONLY);
});
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Hyper_Cutter_(Ability)
it("only prevents ATK drops", async () => {
await game.startBattle();
const enemy = game.scene.getEnemyPokemon()!;
game.doAttack(getMovePosition(game.scene, 0, Moves.OCTOLOCK));
await game.toNextTurn();
game.doAttack(getMovePosition(game.scene, 0, Moves.DEFOG));
await game.toNextTurn();
game.doAttack(getMovePosition(game.scene, 0, Moves.NOBLE_ROAR));
await game.toNextTurn();
game.doAttack(getMovePosition(game.scene, 0, Moves.SAND_ATTACK));
await game.toNextTurn();
game.override.moveset([Moves.STRING_SHOT]);
game.doAttack(getMovePosition(game.scene, 0, Moves.STRING_SHOT));
await game.toNextTurn();
expect(enemy.summonData.battleStats[BattleStat.ATK]).toEqual(0);
[BattleStat.ACC, BattleStat.DEF, BattleStat.EVA, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD].forEach((stat: number) => expect(enemy.summonData.battleStats[stat]).toBeLessThan(0));
});
});

View File

@ -12,6 +12,7 @@ import { SPLASH_ONLY } from "#test/utils/testUtils";
describe("Moves - Rollout", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => {
phaserGame = new Phaser.Game({
@ -77,5 +78,5 @@ describe("Moves - Rollout", () => {
// reset
expect(turn6Dmg).toBeGreaterThanOrEqual(turn1Dmg - variance);
expect(turn6Dmg).toBeLessThanOrEqual(turn1Dmg + variance);
});
}, TIMEOUT);
});

View File

@ -87,7 +87,6 @@ describe("UI - Transfer Items", () => {
handler.processInput(Button.ACTION); // select Pokemon
expect(handler.optionsContainer.list.some((option) => (option as BBCodeText).text?.includes("Transfer"))).toBe(true);
game.phaseInterceptor.unlock();
});

View File

@ -0,0 +1,89 @@
import { Button } from "#app/enums/buttons.js";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
import { CommandPhase } from "#app/phases";
import FightUiHandler from "#app/ui/fight-ui-handler.js";
import { Mode } from "#app/ui/ui.js";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import MockText from "../utils/mocks/mocksContainer/mockText";
import { SPLASH_ONLY } from "../utils/testUtils";
describe("UI - Type Hints", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(async () => {
game = new GameManager(phaserGame);
game.settings.typeHints(true); //activate type hints
game.override.battleType("single").startingLevel(100).startingWave(1).enemyMoveset(SPLASH_ONLY);
});
it("check immunity color", async () => {
game.override
.battleType("single")
.startingLevel(100)
.startingWave(1)
.enemySpecies(Species.FLORGES)
.enemyMoveset(SPLASH_ONLY)
.moveset([Moves.DRAGON_CLAW]);
game.settings.typeHints(true); //activate type hints
await game.startBattle([Species.RAYQUAZA]);
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
const { ui } = game.scene;
const handler = ui.getHandler<FightUiHandler>();
handler.processInput(Button.ACTION); // select "Fight"
game.phaseInterceptor.unlock();
});
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
const { ui } = game.scene;
const movesContainer = ui.getByName<Phaser.GameObjects.Container>(FightUiHandler.MOVES_CONTAINER_NAME);
const dragonClawText = movesContainer
.getAll<Phaser.GameObjects.Text>()
.find((text) => text.text === "Dragon Claw")! as unknown as MockText;
expect.soft(dragonClawText.color).toBe("#929292");
ui.getHandler().processInput(Button.ACTION);
});
await game.phaseInterceptor.to(CommandPhase);
});
it("check status move color", async () => {
game.override.enemySpecies(Species.FLORGES).moveset([Moves.GROWL]);
await game.startBattle([Species.RAYQUAZA]);
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
const { ui } = game.scene;
const handler = ui.getHandler<FightUiHandler>();
handler.processInput(Button.ACTION); // select "Fight"
game.phaseInterceptor.unlock();
});
game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
const { ui } = game.scene;
const movesContainer = ui.getByName<Phaser.GameObjects.Container>(FightUiHandler.MOVES_CONTAINER_NAME);
const growlText = movesContainer
.getAll<Phaser.GameObjects.Text>()
.find((text) => text.text === "Growl")! as unknown as MockText;
expect.soft(growlText.color).toBe(undefined);
ui.getHandler().processInput(Button.ACTION);
});
await game.phaseInterceptor.to(CommandPhase);
});
});

View File

@ -30,6 +30,7 @@ import { MoveHelper } from "./helpers/moveHelper";
import { vi } from "vitest";
import { ClassicModeHelper } from "./helpers/classicModeHelper";
import { DailyModeHelper } from "./helpers/dailyModeHelper";
import { SettingsHelper } from "./helpers/settingsHelper";
/**
* Class to manage the game state and transitions between phases.
@ -44,6 +45,7 @@ export default class GameManager {
public readonly move: MoveHelper;
public readonly classicMode: ClassicModeHelper;
public readonly dailyMode: DailyModeHelper;
public readonly settings: SettingsHelper;
/**
* Creates an instance of GameManager.
@ -63,6 +65,7 @@ export default class GameManager {
this.move = new MoveHelper(this);
this.classicMode = new ClassicModeHelper(this);
this.dailyMode = new DailyModeHelper(this);
this.settings = new SettingsHelper(this);
}
/**

View File

@ -0,0 +1,15 @@
import { GameManagerHelper } from "./gameManagerHelper";
/**
* Helper to handle settings for tests
*/
export class SettingsHelper extends GameManagerHelper {
/**
* Disable/Enable type hints settings
* @param enable true to enabled, false to disabled
*/
typeHints(enable: boolean) {
this.game.scene.typeHints = enable;
}
}

View File

@ -1,4 +1,5 @@
import MockTextureManager from "#test/utils/mocks/mockTextureManager";
import { vi } from "vitest";
import { MockGameObject } from "../mockGameObject";
export default class MockContainer implements MockGameObject {
@ -13,6 +14,7 @@ export default class MockContainer implements MockGameObject {
public frame;
protected textureManager;
public list: MockGameObject[] = [];
private name?: string;
constructor(textureManager: MockTextureManager, x, y) {
this.x = x;
@ -159,9 +161,10 @@ export default class MockContainer implements MockGameObject {
// Moves this Game Object to be below the given Game Object in the display list.
}
setName(name) {
setName = vi.fn((name: string) => {
this.name = name;
// return this.phaserSprite.setName(name);
}
});
bringToTop(obj) {
// Brings this Game Object to the top of its parents display list.

View File

@ -1,4 +1,5 @@
import UI from "#app/ui/ui";
import { vi } from "vitest";
import { MockGameObject } from "../mockGameObject";
export default class MockText implements MockGameObject {
@ -10,6 +11,8 @@ export default class MockText implements MockGameObject {
public list: MockGameObject[] = [];
public style;
public text = "";
private name?: string;
public color?: string;
constructor(textureManager, x, y, content, styleOptions) {
this.scene = textureManager.scene;
@ -190,10 +193,9 @@ export default class MockText implements MockGameObject {
};
}
setColor(color) {
// Sets the tint of this Game Object.
// return this.phaserText.setColor(color);
}
setColor = vi.fn((color: string) => {
this.color = color;
});
setShadowColor(color) {
// Sets the shadow color.
@ -219,9 +221,9 @@ export default class MockText implements MockGameObject {
// return this.phaserText.setAlpha(alpha);
}
setName(name) {
// return this.phaserText.setName(name);
}
setName = vi.fn((name: string) => {
this.name = name;
});
setAlign(align) {
// return this.phaserText.setAlign(align);

View File

@ -200,6 +200,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
this.shinyCharmIcon = this.scene.add.sprite(this.flyoutWidth - 8, 8, "items", "shiny_charm")
this.shinyCharmIcon.setScale(0.4)
this.shinyCharmIcon.setInteractive(new Phaser.Geom.Rectangle(2, 2, 26, 27), Phaser.Geom.Rectangle.Contains);
this.shinyCharmIcon.setVisible(false)
this.flyoutContainer.add(this.shinyCharmIcon)
this.shinyCharmLuckCount = addTextObject(this.scene, this.flyoutWidth - 9, 5, "?", TextStyle.BATTLE_INFO);
@ -211,7 +212,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
}
doShinyCharmTooltip() {
if ((this.scene as BattleScene).currentBattle.waveIndex % 10 == 0) {
if (true || (this.scene as BattleScene).currentBattle.waveIndex % 10 == 0) {
this.shinyCharmIcon.setVisible(false)
this.shinyCharmLuckCount.setVisible(false)
return;
@ -227,11 +228,11 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
//this.shinyCharmIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(null, `???`));
} else if ((this.scene as BattleScene).waveShinyFlag) {
this.shinyCharmIcon.clearTint()
this.shinyCharmIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(null, `Shinies are OK`));
this.shinyCharmIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip("", `Shinies are OK`));
this.shinyCharmLuckCount.setVisible(false)
} else {
this.shinyCharmIcon.setTintFill(0x000000)
this.shinyCharmIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(null, `Shinies change shop with luck ${(this.scene as BattleScene).waveShinyMinToBreak} or higher`));
this.shinyCharmIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip("", `Shinies change shop with luck ${(this.scene as BattleScene).waveShinyMinToBreak} or higher`));
this.shinyCharmLuckCount.text = getLuckString((this.scene as BattleScene).waveShinyMinToBreak)
}
this.shinyCharmIcon.on("pointerout", () => (this.scene as BattleScene).ui.hideTooltip());
@ -270,7 +271,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
this.flyoutTextHeader.text = "Game Logs"
this.flyoutTextPlayer.setPosition(6, 4)
this.flyoutTextPlayer.setFontSize(30);
var instructions = []
var instructions: string[] = []
var drpd = LoggerTools.getDRPD(this.scene as BattleScene);
var doWaveInstructions = true;
for (var i = 0; i < drpd.waves.length && drpd.waves[i] != undefined && doWaveInstructions; i++) {

View File

@ -161,7 +161,7 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
if (foundInfo) {
foundInfo.ppUsed = moveUsedEvent.ppUsed;
} else {
var idx = this.pokemon.moveset.indexOf(this.pokemon.moveset.find((v) => (v.getMove().id == moveUsedEvent.move.id)))
var idx = this.pokemon.moveset.indexOf(this.pokemon.moveset.find((v) => (v!.getMove().id == moveUsedEvent.move.id))!)
if (idx == -1) {
this.moveInfo.push({move: moveUsedEvent.move, maxPp: moveUsedEvent.move.pp, ppUsed: moveUsedEvent.ppUsed});
} else {
@ -189,15 +189,6 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
this.setText();
}
public revealMoves() {
return;
this.moveInfo = new Array<MoveInfo>(4);
this.pokemon.moveset.forEach((mv, idx) => {
this.moveInfo[idx] = {move: mv.getMove(), maxPp: mv.getMovePp(), ppUsed: mv.ppUsed}
})
this.setText()
}
/** Animates the flyout to either show or hide it by applying a fade and translation */
toggleFlyout(visible: boolean): void {
this.flyoutVisible = visible;

View File

@ -555,6 +555,27 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
}
}
}
updateBossSegmentDividers_override(pokemon: Pokemon, bars: integer, index: integer): void {
while (this.hpBarSegmentDividers.length) {
this.hpBarSegmentDividers.pop()?.destroy();
}
if (bars > 1) {
const uiTheme = (this.scene as BattleScene).uiTheme;
const maxHp = pokemon.getMaxHp();
for (let s = 1; s < bars; s++) {
const dividerX = (Math.round((maxHp / bars) * s) / maxHp) * this.hpBar.width;
const divider = this.scene.add.rectangle(0, 0, 1, this.hpBar.height - (uiTheme ? 0 : 1), index >= s ? 0xFFFFFF : 0x404040);
divider.setOrigin(0.5, 0);
divider.setName("hpBar_divider_" + s.toString());
this.add(divider);
this.moveBelow(divider as Phaser.GameObjects.GameObject, this.statsContainer);
divider.setPositionRelative(this.hpBar, dividerX, uiTheme ? 0 : 1);
this.hpBarSegmentDividers.push(divider);
}
}
}
displayParty(overwriteparty?: Pokemon[], useparty?: EnemyPokemon[]): void {
// Floor 8: 2 pokemon

View File

@ -226,7 +226,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
highestIv = ivs[s];
}
});
if (shownStat) {
if (shownStat !== null && shownStat !== undefined) {
shownStats.push(shownStat);
statsPool.splice(statsPool.indexOf(shownStat), 1);
}

View File

@ -28,6 +28,8 @@ import { BattleStat } from "#app/data/battle-stat.js";
import { PokemonMultiHitModifierType } from "#app/modifier/modifier-type.js";
export default class FightUiHandler extends UiHandler {
public static readonly MOVES_CONTAINER_NAME = "moves";
private movesContainer: Phaser.GameObjects.Container;
private moveInfoContainer: Phaser.GameObjects.Container;
private typeIcon: Phaser.GameObjects.Sprite;
@ -51,7 +53,7 @@ export default class FightUiHandler extends UiHandler {
const ui = this.getUi();
this.movesContainer = this.scene.add.container(18, -38.7);
this.movesContainer.setName("moves");
this.movesContainer.setName(FightUiHandler.MOVES_CONTAINER_NAME);
ui.add(this.movesContainer);
this.moveInfoContainer = this.scene.add.container(1, 0);
@ -841,11 +843,10 @@ export default class FightUiHandler extends UiHandler {
return undefined;
}
const moveColors = opponents.map((opponent) => {
return opponent.getMoveEffectiveness(pokemon, pokemonMove);
}).filter((eff) => !!eff).sort((a, b) => b - a).map((effectiveness) => {
return getTypeDamageMultiplierColor(effectiveness, "offense");
});
const moveColors = opponents
.map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove))
.sort((a, b) => b - a)
.map((effectiveness) => getTypeDamageMultiplierColor(effectiveness ?? 0, "offense"));
return moveColors[0];
}

View File

@ -8,7 +8,7 @@ import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui
import { Tutorial, handleTutorial } from "../tutorial";
import { loggedInUser, updateUserInfo } from "../account";
import i18next from "i18next";
import {Button} from "#enums/buttons";
import { Button } from "#enums/buttons";
import { GameDataType } from "#enums/game-data-type";
import BgmBar from "#app/ui/bgm-bar";
@ -113,7 +113,6 @@ export default class MenuUiHandler extends MessageUiHandler {
render() {
const ui = this.getUi();
console.log(ui.getModeChain());
this.excludedMenus = () => [
{ condition: ![Mode.COMMAND, Mode.TITLE].includes(ui.getModeChain()[0]), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] }

View File

@ -2916,14 +2916,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
const isCaught = this.scene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
const isVariant3Caught = !!(isCaught & DexAttr.VARIANT_3);
const isVariant2Caught = !!(isCaught & DexAttr.VARIANT_2);
const isDefaultVariantCaught = !!(isCaught & DexAttr.DEFAULT_VARIANT);
const isVariantCaught = !!(isCaught & DexAttr.SHINY);
const isMaleCaught = !!(isCaught & DexAttr.MALE);
const isFemaleCaught = !!(isCaught & DexAttr.FEMALE);
const starterAttributes = this.starterPreferences[species.speciesId];
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
if (!dexEntry.caughtAttr) {
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
if (shiny === undefined || shiny !== props.shiny) {
shiny = props.shiny;
}
@ -2942,6 +2946,83 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
if (natureIndex === undefined || natureIndex !== defaultNature) {
natureIndex = defaultNature;
}
} else {
// compare current shiny, formIndex, female, variant, abilityIndex, natureIndex with the caught ones
// if the current ones are not caught, we need to find the next caught ones
if (shiny) {
if (!(isVariantCaught || isVariant2Caught || isVariant3Caught)) {
shiny = false;
starterAttributes.shiny = false;
variant = 0;
starterAttributes.variant = 0;
} else {
shiny = true;
starterAttributes.shiny = true;
if (variant === 0 && !isDefaultVariantCaught) {
if (isVariant2Caught) {
variant = 1;
starterAttributes.variant = 1;
} else if (isVariant3Caught) {
variant = 2;
starterAttributes.variant = 2;
} else {
variant = 0;
starterAttributes.variant = 0;
}
} else if (variant === 1 && !isVariant2Caught) {
if (isVariantCaught) {
variant = 0;
starterAttributes.variant = 0;
} else if (isVariant3Caught) {
variant = 2;
starterAttributes.variant = 2;
} else {
variant = 0;
starterAttributes.variant = 0;
}
} else if (variant === 2 && !isVariant3Caught) {
if (isVariantCaught) {
variant = 0;
starterAttributes.variant = 0;
} else if (isVariant2Caught) {
variant = 1;
starterAttributes.variant = 1;
} else {
variant = 0;
starterAttributes.variant = 0;
}
}
}
}
if (female) {
if (!isFemaleCaught) {
female = false;
starterAttributes.female = false;
}
} else {
if (!isMaleCaught) {
female = true;
starterAttributes.female = true;
}
}
if (species.forms) {
const formCount = species.forms.length;
let newFormIndex = formIndex??0;
if (species.forms[newFormIndex]) {
const isValidForm = species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex);
if (!isValidForm) {
do {
newFormIndex = (newFormIndex + 1) % formCount;
if (species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex)) {
break;
}
} while (newFormIndex !== props.formIndex);
formIndex = newFormIndex;
starterAttributes.form = formIndex;
}
}
}
}
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
@ -2993,12 +3074,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
}
if (dexEntry.caughtAttr && species.malePercent !== null) {
let gender: Gender;
if ((female && isFemaleCaught) || (!female && !isMaleCaught)) {
gender = Gender.FEMALE;
} else {
gender = Gender.MALE;
}
const gender = !female ? Gender.MALE : Gender.FEMALE;
this.pokemonGenderText.setText(getGenderSymbol(gender));
this.pokemonGenderText.setColor(getGenderColor(gender));
this.pokemonGenderText.setShadowColor(getGenderColor(gender, true));
@ -3479,7 +3555,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
checkIconId(icon: Phaser.GameObjects.Sprite, species: PokemonSpecies, female: boolean, formIndex: number, shiny: boolean, variant: number) {
if (icon.frame.name !== species.getIconId(female, formIndex, shiny, variant)) {
console.log(`${species.name}'s variant icon does not exist. Replacing with default.`);
console.log(`${species.name}'s icon ${icon.frame.name} does not match getIconId with female: ${female}, formIndex: ${formIndex}, shiny: ${shiny}, variant: ${variant}`);
icon.setTexture(species.getIconAtlasKey(formIndex, false, variant));
icon.setFrame(species.getIconId(female, formIndex, false, variant));
}

View File

@ -1,4 +1,4 @@
import {default as BattleScene} from "../battle-scene";
import { default as BattleScene } from "../battle-scene";
import UiHandler from "./ui-handler";
import BattleMessageUiHandler from "./battle-message-ui-handler";
import CommandUiHandler from "./command-ui-handler";
@ -37,8 +37,8 @@ import SavingIconHandler from "./saving-icon-handler";
import UnavailableModalUiHandler from "./unavailable-modal-ui-handler";
import OutdatedModalUiHandler from "./outdated-modal-ui-handler";
import SessionReloadModalUiHandler from "./session-reload-modal-ui-handler";
import {Button} from "#enums/buttons";
import i18next, {ParseKeys} from "i18next";
import { Button } from "#enums/buttons";
import i18next, { ParseKeys } from "i18next";
import GamepadBindingUiHandler from "./settings/gamepad-binding-ui-handler";
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
import KeyboardBindingUiHandler from "#app/ui/settings/keyboard-binding-ui-handler";
@ -461,6 +461,7 @@ export default class UI extends Phaser.GameObjects.Container {
}
if (chainMode && this.mode && !clear) {
this.modeChain.push(this.mode);
(this.scene as BattleScene).updateGameInfo();
}
this.mode = mode;
const touchControls = document?.getElementById("touchControls");
@ -508,6 +509,7 @@ export default class UI extends Phaser.GameObjects.Container {
resetModeChain(): void {
this.modeChain = [];
(this.scene as BattleScene).updateGameInfo();
}
revertMode(): Promise<boolean> {
@ -521,6 +523,7 @@ export default class UI extends Phaser.GameObjects.Container {
const doRevertMode = () => {
this.getHandler().clear();
this.mode = this.modeChain.pop()!; // TODO: is this bang correct?
(this.scene as BattleScene).updateGameInfo();
const touchControls = document.getElementById("touchControls");
if (touchControls) {
touchControls.dataset.uiMode = Mode[this.mode];

View File

@ -567,3 +567,11 @@ export function capitalizeString(str: string, sep: string, lowerFirstChar: boole
}
return null;
}
/**
* Returns if an object is null or undefined
* @param object
*/
export function isNullOrUndefined(object: any): boolean {
return null === object || undefined === object;
}