Merge branch 'main' into more_music

This commit is contained in:
Madmadness65 2024-06-04 17:46:31 -05:00
commit 36910fa4f4
59 changed files with 971 additions and 336 deletions

View File

@ -146,8 +146,8 @@ body {
margin-left: 10%;
}
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn,
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_ACCESSIBILITY']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn,
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_ACCESSIBILITY']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer
{
display: none;
}

9
package-lock.json generated
View File

@ -12,6 +12,7 @@
"crypto-js": "^4.2.0",
"i18next": "^23.11.1",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-korean-postposition-processor": "^1.0.0",
"json-stable-stringify": "^1.1.0",
"phaser": "^3.70.0",
"phaser3-rex-plugins": "^1.1.84"
@ -3615,6 +3616,14 @@
"cross-fetch": "4.0.0"
}
},
"node_modules/i18next-korean-postposition-processor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/i18next-korean-postposition-processor/-/i18next-korean-postposition-processor-1.0.0.tgz",
"integrity": "sha512-ruNXjI9awsFK6Ie+F9gYaMW8ciLMuCkeRjH9QkSv2Wb8xI0mnm773v3M9eua8dtvAXudIUk4p6Ho7hNkEASXDg==",
"peerDependencies": {
"i18next": ">=8.4.0"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",

View File

@ -43,6 +43,7 @@
"crypto-js": "^4.2.0",
"i18next": "^23.11.1",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-korean-postposition-processor": "^1.0.0",
"json-stable-stringify": "^1.1.0",
"phaser": "^3.70.0",
"phaser3-rex-plugins": "^1.1.84"

Binary file not shown.

View File

@ -4065,7 +4065,7 @@
"426": [
0,
1,
2
1
],
"427": [
0,

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

View File

@ -1,4 +1,5 @@
import Move from "./data/move";
import { BerryModifier } from "./modifier/modifier";
/** Alias for all {@linkcode BattleScene} events */
export enum BattleSceneEventType {
@ -13,6 +14,12 @@ export enum BattleSceneEventType {
* @see {@linkcode MoveUsedEvent}
*/
MOVE_USED = "onMoveUsed",
/**
* Triggers when a berry gets successfully used
* @see {@linkcode BerryUsedEvent}
*/
BERRY_USED = "onBerryUsed",
/**
* Triggers on the first turn of a new battle
* @see {@linkcode TurnInitEvent}
@ -23,6 +30,7 @@ export enum BattleSceneEventType {
* @see {@linkcode TurnEndEvent}
*/
TURN_END = "onTurnEnd",
/**
* Triggers when a new {@linkcode Arena} is created during initialization
* @see {@linkcode NewArenaEvent}
@ -50,7 +58,7 @@ export class CandyUpgradeNotificationChangedEvent extends Event {
*/
export class MoveUsedEvent extends Event {
/** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */
public userId: number;
public pokemonId: number;
/** The {@linkcode Move} used */
public move: Move;
/** The amount of PP used on the {@linkcode Move} this turn */
@ -58,11 +66,25 @@ export class MoveUsedEvent extends Event {
constructor(userId: number, move: Move, ppUsed: number) {
super(BattleSceneEventType.MOVE_USED);
this.userId = userId;
this.pokemonId = userId;
this.move = move;
this.ppUsed = ppUsed;
}
}
/**
* Container class for {@linkcode BattleSceneEventType.BERRY_USED} events
* @extends Event
*/
export class BerryUsedEvent extends Event {
/** The {@linkcode BerryModifier} being used */
public berryModifier: BerryModifier;
constructor(berry: BerryModifier) {
super(BattleSceneEventType.BERRY_USED);
this.berryModifier = berry;
}
}
/**
* Container class for {@linkcode BattleSceneEventType.TURN_INIT} events
* @extends Event

View File

@ -58,6 +58,7 @@ import {InputsController} from "./inputs-controller";
import {UiInputs} from "./ui-inputs";
import { MoneyFormat } from "./enums/money-format";
import { NewArenaEvent } from "./battle-scene-events";
import ArenaFlyout from "./ui/arena-flyout";
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
@ -92,6 +93,7 @@ export default class BattleScene extends SceneBase {
public damageNumbersMode: integer = 0;
public reroll: boolean = false;
public showMovesetFlyout: boolean = true;
public showArenaFlyout: boolean = true;
public showLevelUpStats: boolean = true;
public enableTutorials: boolean = import.meta.env.VITE_BYPASS_TUTORIAL === "1";
public enableRetries: boolean = false;
@ -179,6 +181,8 @@ export default class BattleScene extends SceneBase {
private luckText: Phaser.GameObjects.Text;
private modifierBar: ModifierBar;
private enemyModifierBar: ModifierBar;
public arenaFlyout: ArenaFlyout;
private fieldOverlay: Phaser.GameObjects.Rectangle;
private modifiers: PersistentModifier[];
private enemyModifiers: PersistentModifier[];
@ -412,6 +416,10 @@ export default class BattleScene extends SceneBase {
this.luckLabelText.setVisible(false);
this.fieldUI.add(this.luckLabelText);
this.arenaFlyout = new ArenaFlyout(this);
this.fieldUI.add(this.arenaFlyout);
this.fieldUI.moveBelow<Phaser.GameObjects.GameObject>(this.arenaFlyout, this.fieldOverlay);
this.updateUIPositions();
this.damageNumberHandler = new DamageNumberHandler();
@ -1104,6 +1112,8 @@ export default class BattleScene extends SceneBase {
case Species.FLOETTE:
case Species.FLORGES:
case Species.FURFROU:
case Species.PUMPKABOO:
case Species.GOURGEIST:
case Species.ORICORIO:
case Species.MAGEARNA:
case Species.ZARUDE:
@ -1273,6 +1283,13 @@ export default class BattleScene extends SceneBase {
return sprite;
}
moveBelowOverlay<T extends Phaser.GameObjects.GameObject>(gameObject: T) {
this.fieldUI.moveBelow<any>(gameObject, this.fieldOverlay);
}
processInfoButton(pressed: boolean): void {
this.arenaFlyout.toggleFlyout(pressed);
}
showFieldOverlay(duration: integer): Promise<void> {
return new Promise(resolve => {
this.tweens.add({

View File

@ -1341,7 +1341,7 @@ export class CursedTag extends BattlerTag {
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) {
pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4));
pokemon.damageAndUpdate(Math.max(Math.floor(pokemon.getMaxHp() / 4), 1));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt by the ${this.getMoveName()}!`));
}
}

View File

@ -7,20 +7,7 @@ import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from "../plugins/i18n";
export enum BerryType {
SITRUS,
LUM,
ENIGMA,
LIECHI,
GANLON,
PETAYA,
APICOT,
SALAC,
LANSAT,
STARF,
LEPPA
}
import { BerryType } from "./enums/berry-type";
export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`);

View File

@ -0,0 +1,14 @@
export enum BerryType {
SITRUS,
LUM,
ENIGMA,
LIECHI,
GANLON,
PETAYA,
APICOT,
SALAC,
LANSAT,
STARF,
LEPPA
}

View File

@ -66,7 +66,7 @@ export enum FormChangeItem {
HARD_METEORITE,
SMOOTH_METEORITE,
ADAMANT_CRYSTAL,
LUSTROUS_ORB,
LUSTROUS_GLOBE,
GRISEOUS_CORE,
REVEAL_GLASS,
GRACIDEA,
@ -520,7 +520,7 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.DIALGA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.ADAMANT_CRYSTAL))
],
[Species.PALKIA]: [
new SpeciesFormChange(Species.PALKIA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB))
new SpeciesFormChange(Species.PALKIA, "", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_GLOBE))
],
[Species.GIRATINA]: [
new SpeciesFormChange(Species.GIRATINA, "altered", SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.GRISEOUS_CORE))

View File

@ -2010,15 +2010,15 @@ export function initSpecies() {
new PokemonSpecies(Species.TREVENANT, 6, false, false, false, "Elder Tree Pokémon", Type.GHOST, Type.GRASS, 1.5, 71, Abilities.NATURAL_CURE, Abilities.FRISK, Abilities.HARVEST, 474, 85, 110, 76, 65, 82, 56, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PUMPKABOO, 6, false, false, false, "Pumpkin Pokémon", Type.GHOST, Type.GRASS, 0.4, 5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, GrowthRate.MEDIUM_FAST, 50, false, false,
new PokemonForm("Average Size", "", Type.GHOST, Type.GRASS, 0.4, 5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 49, 66, 70, 44, 55, 51, 120, 50, 67, false, null, true),
new PokemonForm("Small Size", "small", Type.GHOST, Type.GRASS, 0.3, 3.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 44, 66, 70, 44, 55, 56, 120, 50, 67, false, null, true),
new PokemonForm("Large Size", "large", Type.GHOST, Type.GRASS, 0.5, 7.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 54, 66, 70, 44, 55, 46, 120, 50, 67, false, null, true),
new PokemonForm("Super Size", "super", Type.GHOST, Type.GRASS, 0.8, 15, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 59, 66, 70, 44, 55, 41, 120, 50, 67, false, null, true),
new PokemonForm("Small Size", "small", Type.GHOST, Type.GRASS, 0.3, 3.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 44, 66, 70, 44, 55, 56, 120, 50, 67, false, "", true),
new PokemonForm("Large Size", "large", Type.GHOST, Type.GRASS, 0.5, 7.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 54, 66, 70, 44, 55, 46, 120, 50, 67, false, "", true),
new PokemonForm("Super Size", "super", Type.GHOST, Type.GRASS, 0.8, 15, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 335, 59, 66, 70, 44, 55, 41, 120, 50, 67, false, "", true),
),
new PokemonSpecies(Species.GOURGEIST, 6, false, false, false, "Pumpkin Pokémon", Type.GHOST, Type.GRASS, 0.9, 12.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, GrowthRate.MEDIUM_FAST, 50, false, false,
new PokemonForm("Average Size", "", Type.GHOST, Type.GRASS, 0.9, 12.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 65, 90, 122, 58, 75, 84, 60, 50, 173, false, null, true),
new PokemonForm("Small Size", "small", Type.GHOST, Type.GRASS, 0.7, 9.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 55, 85, 122, 58, 75, 99, 60, 50, 173, false, null, true),
new PokemonForm("Large Size", "large", Type.GHOST, Type.GRASS, 1.1, 14, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 75, 95, 122, 58, 75, 69, 60, 50, 173, false, null, true),
new PokemonForm("Super Size", "super", Type.GHOST, Type.GRASS, 1.7, 39, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 85, 100, 122, 58, 75, 54, 60, 50, 173, false, null, true),
new PokemonForm("Small Size", "small", Type.GHOST, Type.GRASS, 0.7, 9.5, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 55, 85, 122, 58, 75, 99, 60, 50, 173, false, "", true),
new PokemonForm("Large Size", "large", Type.GHOST, Type.GRASS, 1.1, 14, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 75, 95, 122, 58, 75, 69, 60, 50, 173, false, "", true),
new PokemonForm("Super Size", "super", Type.GHOST, Type.GRASS, 1.7, 39, Abilities.PICKUP, Abilities.FRISK, Abilities.INSOMNIA, 494, 85, 100, 122, 58, 75, 54, 60, 50, 173, false, "", true),
),
new PokemonSpecies(Species.BERGMITE, 6, false, false, false, "Ice Chunk Pokémon", Type.ICE, null, 1, 99.5, Abilities.OWN_TEMPO, Abilities.ICE_BODY, Abilities.STURDY, 304, 55, 69, 85, 32, 35, 28, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.AVALUGG, 6, false, false, false, "Iceberg Pokémon", Type.ICE, null, 2, 505, Abilities.OWN_TEMPO, Abilities.ICE_BODY, Abilities.STURDY, 514, 95, 117, 184, 44, 46, 28, 55, 50, 180, GrowthRate.MEDIUM_FAST, 50, false),

View File

@ -63123,9 +63123,12 @@ export const tmSpecies: TmSpecies = {
[Moves.SNOWSCAPE]: [
Species.SLOWPOKE,
Species.SLOWBRO,
Species.SEEL,
Species.DEWGONG,
Species.SHELLDER,
Species.CLOYSTER,
Species.CHANSEY,
Species.LAPRAS,
Species.ARTICUNO,
Species.DRAGONITE,
Species.MEW,
@ -63140,6 +63143,7 @@ export const tmSpecies: TmSpecies = {
Species.PILOSWINE,
Species.DELIBIRD,
Species.BLISSEY,
Species.SUICUNE,
Species.WINGULL,
Species.PELIPPER,
Species.SPOINK,
@ -63148,11 +63152,20 @@ export const tmSpecies: TmSpecies = {
Species.SNORUNT,
Species.GLALIE,
Species.LUVDISC,
Species.REGICE,
Species.PIPLUP,
Species.PRINPLUP,
Species.EMPOLEON,
Species.SHELLOS,
Species.GASTRODON,
[
Species.SHELLOS,
"east",
"west",
],
[
Species.GASTRODON,
"east",
"west",
],
Species.MISMAGIUS,
Species.HAPPINY,
Species.SNOVER,
@ -63170,7 +63183,17 @@ export const tmSpecies: TmSpecies = {
Species.CUBCHOO,
Species.BEARTIC,
Species.CRYOGONAL,
Species.TORNADUS,
[
Species.TORNADUS,
"incarnate",
"therian",
],
[
Species.KYUREM,
"",
"black",
"white",
],
Species.FROAKIE,
Species.FROGADIER,
[
@ -63184,8 +63207,13 @@ export const tmSpecies: TmSpecies = {
Species.BERGMITE,
Species.AVALUGG,
Species.DIANCIE,
Species.PRIMARINA,
Species.CRABOMINABLE,
Species.MAGEARNA,
[
Species.MAGEARNA,
"",
"original",
],
Species.INTELEON,
Species.FROSMOTH,
Species.EISCUE,
@ -63633,12 +63661,21 @@ export const tmSpecies: TmSpecies = {
Species.WEAVILE,
Species.GLACEON,
Species.FROSLASS,
Species.PALKIA,
[
Species.PALKIA,
"",
"origin",
],
Species.ARCEUS,
Species.OSHAWOTT,
Species.DEWOTT,
Species.SAMUROTT,
Species.BASCULIN,
[
Species.BASCULIN,
"red-striped",
"blue-striped",
"white-striped",
],
Species.DUCKLETT,
Species.SWANNA,
Species.ALOMOMOLA,

View File

@ -618,7 +618,7 @@ export class TrainerConfig {
* @param isMale - Whether the Champion is Male or Female (for localization of the title).
* @returns {TrainerConfig} - The updated TrainerConfig instance.
**/
initForChampion(signatureSpecies: (Species | Species[])[],isMale: boolean): TrainerConfig {
initForChampion(signatureSpecies: (Species | Species[])[], isMale: boolean): TrainerConfig {
// Check if the internationalization (i18n) system is initialized.
if (!getIsInitialized()) {
initI18n();
@ -917,20 +917,20 @@ export const signatureSpecies: SignatureSpecies = {
AMARYS: [Species.SKARMORY, Species.EMPOLEON, Species.SCIZOR, Species.METAGROSS],
LACEY: [Species.EXCADRILL, Species.PRIMARINA, Species.ALCREMIE, Species.GALAR_SLOWBRO],
DRAYTON: [Species.DRAGONITE, Species.ARCHALUDON, Species.FLYGON, Species.SCEPTILE],
BLUE: [Species.GYARADOS, Species.MEWTWO, Species.ARCANINE, Species.ALAKAZAM, Species.PIDGEOT],
RED: [Species.CHARIZARD, [Species.LUGIA, Species.HO_OH], Species.SNORLAX, Species.RAICHU, Species.ESPEON],
LANCE_CHAMPION: [Species.DRAGONITE, Species.ZYGARDE, Species.AERODACTYL, Species.KINGDRA, Species.ALOLA_EXEGGUTOR],
STEVEN: [Species.METAGROSS, [Species.DIALGA, Species.PALKIA], Species.SKARMORY, Species.AGGRON, Species.CARBINK],
WALLACE: [Species.MILOTIC, Species.KYOGRE, Species.WHISCASH, Species.WALREIN, Species.LUDICOLO],
CYNTHIA: [Species.SPIRITOMB, Species.GIRATINA, Species.GARCHOMP, Species.MILOTIC, Species.LUCARIO, Species.TOGEKISS],
ALDER: [Species.VOLCARONA, Species.GROUDON, Species.BOUFFALANT, Species.ACCELGOR, Species.CONKELDURR],
IRIS: [Species.HAXORUS, Species.YVELTAL, Species.DRUDDIGON, Species.AGGRON, Species.LAPRAS],
DIANTHA: [Species.HAWLUCHA, Species.XERNEAS, Species.GOURGEIST, Species.GOODRA, Species.GARDEVOIR],
HAU: [Species.ALOLA_RAICHU, [Species.SOLGALEO, Species.LUNALA], Species.NOIVERN, [Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA], Species.CRABOMINABLE],
LEON: [Species.DRAGAPULT, [Species.ZACIAN, Species.ZAMAZENTA], Species.SEISMITOAD, Species.AEGISLASH, Species.CHARIZARD],
GEETA: [Species.GLIMMORA, Species.MIRAIDON, Species.ESPATHRA, Species.VELUZA, Species.KINGAMBIT],
NEMONA: [Species.LYCANROC, Species.KORAIDON, Species.KOMMO_O, Species.PAWMOT, Species.DUSKNOIR],
KIERAN: [Species.POLITOED, [Species.OGERPON, Species.TERAPAGOS], Species.HYDRAPPLE, Species.PORYGON_Z, Species.GRIMMSNARL],
BLUE: [[Species.GYARADOS, Species.EXEGGUTOR, Species.ARCANINE], Species.HO_OH, [Species.RHYPERIOR, Species.MAGNEZONE]], // Alakazam lead, Mega Pidgeot
RED: [Species.LUGIA, Species.SNORLAX, [Species.ESPEON, Species.UMBREON, Species.SYLVEON]], // GMax Pikachu lead, Mega gen 1 starter
LANCE_CHAMPION: [Species.DRAGONITE, Species.KINGDRA, Species.ALOLA_EXEGGUTOR], // Aerodactyl lead, Mega Lati@s
STEVEN: [Species.AGGRON, [Species.ARMALDO, Species.CRADILY], Species.DIALGA], // Skarmorly lead, Mega Metagross
WALLACE: [Species.MILOTIC, Species.PALKIA, Species.LUDICOLO], // Pelipper lead, Mega Swampert
CYNTHIA: [Species.GIRATINA, Species.LUCARIO, Species.TOGEKISS], // Spiritomb lead, Mega Garchomp
ALDER: [Species.VOLCARONA, Species.ZEKROM, [Species.ACCELGOR, Species.ESCAVALIER], Species.KELDEO], // Bouffalant/Braviary lead
IRIS: [Species.HAXORUS, Species.RESHIRAM, Species.ARCHEOPS], // Druddigon lead, Gmax Lapras
DIANTHA: [Species.HAWLUCHA, Species.XERNEAS, Species.GOODRA], // Gourgeist lead, Mega Gardevoir
HAU: [[Species.SOLGALEO, Species.LUNALA], Species.NOIVERN, [Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA], [Species.TAPU_BULU, Species.TAPU_FINI, Species.TAPU_KOKO, Species.TAPU_LELE]], // Alola Raichu lead
LEON: [Species.DRAGAPULT, [Species.ZACIAN, Species.ZAMAZENTA], Species.AEGISLASH], // Rillaboom/Cinderace/Inteleon lead
GEETA: [Species.MIRAIDON, [Species.ESPATHRA, Species.VELUZA], [Species.AVALUGG, Species.HISUI_AVALUGG], Species.KINGAMBIT], // Glimmora lead
NEMONA: [Species.KORAIDON, Species.PAWMOT, [Species.DUDUNSPARCE, Species.ORTHWORM], [Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL]], // Lycanroc lead
KIERAN: [[Species.GRIMMSNARL, Species.INCINEROAR, Species.PORYGON_Z], Species.OGERPON, Species.TERAPAGOS, Species.HYDRAPPLE], // Poliwrath/Politoed lead
};
export const trainerConfigs: TrainerConfigs = {
@ -1212,20 +1212,100 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.LACEY]: new TrainerConfig(++t).initForEliteFour(signatureSpecies["LACEY"],false, Type.FAIRY),
[TrainerType.DRAYTON]: new TrainerConfig(++t).initForEliteFour(signatureSpecies["DRAYTON"],true, Type.DRAGON),
[TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion(signatureSpecies["BLUE"],true).setBattleBgm("battle_kanto_champion").setHasDouble("blue_red_double").setDoubleTrainerType(TrainerType.RED).setDoubleTitle("champion_double"),
[TrainerType.RED]: new TrainerConfig(++t).initForChampion(signatureSpecies["RED"],true).setBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double"),
[TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(signatureSpecies["LANCE_CHAMPION"],true).setBattleBgm("battle_johto_champion"),
[TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double"),
[TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double"),
[TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(signatureSpecies["CYNTHIA"],false).setBattleBgm("battle_sinnoh_champion"),
[TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(signatureSpecies["ALDER"],true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder"),
[TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(signatureSpecies["IRIS"],false).setBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double"),
[TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(signatureSpecies["DIANTHA"],false),
[TrainerType.HAU]: new TrainerConfig(++t).initForChampion(signatureSpecies["HAU"],true),
[TrainerType.LEON]: new TrainerConfig(++t).initForChampion(signatureSpecies["LEON"],true),
[TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(signatureSpecies["GEETA"],false),
[TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(signatureSpecies["NEMONA"],false),
[TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(signatureSpecies["KIERAN"],true),
[TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion(signatureSpecies["BLUE"],true).setBattleBgm("battle_kanto_champion").setHasDouble("blue_red_double").setDoubleTrainerType(TrainerType.RED).setDoubleTitle("champion_double")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALAKAZAM], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.RED]: new TrainerConfig(++t).initForChampion(signatureSpecies["RED"],true).setBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PIKACHU], TrainerSlot.TRAINER, true, p => {
p.formIndex = 8;
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(signatureSpecies["LANCE_CHAMPION"],true).setBattleBgm("battle_johto_champion")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.AERODACTYL], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LATIAS, Species.LATIOS], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => {
p.abilityIndex = 1; // Drizzle
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.SWAMPERT], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(signatureSpecies["CYNTHIA"],false).setBattleBgm("battle_sinnoh_champion")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SPIRITOMB], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARCHOMP], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(signatureSpecies["ALDER"],true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BOUFFALANT, Species.BRAVIARY], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
})),
[TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(signatureSpecies["IRIS"],false).setBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double")
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DRUDDIGON], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(signatureSpecies["DIANTHA"],false)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GOURGEIST], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARDEVOIR], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1;
p.generateAndPopulateMoveset();
})),
[TrainerType.HAU]: new TrainerConfig(++t).initForChampion(signatureSpecies["HAU"],true)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALOLA_RAICHU], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
})),
[TrainerType.LEON]: new TrainerConfig(++t).initForChampion(signatureSpecies["LEON"],true)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.RILLABOOM, Species.CINDERACE, Species.INTELEON], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CHARIZARD], TrainerSlot.TRAINER, true, p => {
p.formIndex = 3;
p.generateAndPopulateMoveset();
})),
[TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(signatureSpecies["GEETA"],false)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GLIMMORA], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
})),
[TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(signatureSpecies["NEMONA"],false)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
})),
[TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(signatureSpecies["KIERAN"],true)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.POLIWRATH, Species.POLITOED], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset();
})),
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)

View File

@ -10,8 +10,10 @@ export enum ArenaEventType {
/** Triggers when a {@linkcode TerrainType} is added, overlapped, or removed */
TERRAIN_CHANGED = "onTerrainChanged",
/** Triggers when a {@linkcode ArenaTagType} is added or removed */
TAG_CHANGED = "onTagChanged",
/** Triggers when a {@linkcode ArenaTagType} is added */
TAG_ADDED = "onTagAdded",
/** Triggers when a {@linkcode ArenaTagType} is removed */
TAG_REMOVED = "onTagRemoved",
}
/**
@ -59,17 +61,34 @@ export class TerrainChangedEvent extends ArenaEvent {
this.newTerrainType = newTerrainType;
}
}
/**
* Container class for {@linkcode ArenaEventType.TAG_CHANGED} events
* Container class for {@linkcode ArenaEventType.TAG_ADDED} events
* @extends ArenaEvent
*/
export class TagChangedEvent extends ArenaEvent {
/** The {@linkcode ArenaTagType} being set */
export class TagAddedEvent extends ArenaEvent {
/** The {@linkcode ArenaTagType} being added */
public arenaTagType: ArenaTagType;
/** The {@linkcode ArenaTagSide} the tag is being placed on */
public arenaTagSide: ArenaTagSide;
constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number) {
super(ArenaEventType.TAG_CHANGED, duration);
super(ArenaEventType.TAG_ADDED, duration);
this.arenaTagType = arenaTagType;
this.arenaTagSide = arenaTagSide;
}
}
/**
* Container class for {@linkcode ArenaEventType.TAG_REMOVED} events
* @extends ArenaEvent
*/
export class TagRemovedEvent extends ArenaEvent {
/** The {@linkcode ArenaTagType} being removed */
public arenaTagType: ArenaTagType;
/** The {@linkcode ArenaTagSide} the tag was being placed on */
public arenaTagSide: ArenaTagSide;
constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number) {
super(ArenaEventType.TAG_REMOVED, duration);
this.arenaTagType = arenaTagType;
this.arenaTagSide = arenaTagSide;

View File

@ -19,7 +19,7 @@ import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
import Pokemon from "./pokemon";
import * as Overrides from "../overrides";
import { WeatherChangedEvent, TerrainChangedEvent, TagChangedEvent } from "./arena-events";
import { WeatherChangedEvent, TerrainChangedEvent, TagAddedEvent, TagRemovedEvent } from "./arena-events";
export class Arena {
public scene: BattleScene;
@ -550,7 +550,7 @@ export class Arena {
this.tags.push(newTag);
newTag.onAdd(this);
this.eventTarget.dispatchEvent(new TagChangedEvent(newTag.tagType, newTag.side, newTag.turnCount));
this.eventTarget.dispatchEvent(new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount));
return true;
}
@ -577,6 +577,8 @@ export class Arena {
this.tags.filter(t => !(t.lapse(this))).forEach(t => {
t.onRemove(this);
this.tags.splice(this.tags.indexOf(t), 1);
this.eventTarget.dispatchEvent(new TagRemovedEvent(t.tagType, t.side, t.turnCount));
});
}
@ -586,6 +588,8 @@ export class Arena {
if (tag) {
tag.onRemove(this);
tags.splice(tags.indexOf(tag), 1);
this.eventTarget.dispatchEvent(new TagRemovedEvent(tag.tagType, tag.side, tag.turnCount));
}
return !!tag;
}
@ -595,6 +599,8 @@ export class Arena {
if (tag) {
tag.onRemove(this);
this.tags.splice(this.tags.indexOf(tag), 1);
this.eventTarget.dispatchEvent(new TagRemovedEvent(tag.tagType, tag.side, tag.turnCount));
}
return !!tag;
}
@ -603,6 +609,8 @@ export class Arena {
removeAllTags(): void {
while (this.tags.length) {
this.tags[0].onRemove(this);
this.eventTarget.dispatchEvent(new TagRemovedEvent(this.tags[0].tagType, this.tags[0].side, this.tags[0].turnCount));
this.tags.splice(0, 1);
}
}

View File

@ -44,7 +44,7 @@ import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMov
import { TerrainType } from "../data/terrain";
import { TrainerSlot } from "../data/trainer-config";
import * as Overrides from "../overrides";
import { BerryType } from "../data/berry";
import { BerryType } from "../data/enums/berry-type";
import i18next from "../plugins/i18n";
import { speciesEggMoves } from "../data/egg-moves";
import { ModifierTier } from "../modifier/modifier-tier";

View File

@ -95,6 +95,11 @@ export class LoadingScene extends SceneBase {
this.loadImage("type_tera", "ui");
this.loadAtlas("type_bgs", "ui");
this.loadImage("dawn_icon", "ui");
this.loadImage("day_icon", "ui");
this.loadImage("dusk_icon", "ui");
this.loadImage("night_icon", "ui");
this.loadImage("pb_tray_overlay_player", "ui");
this.loadImage("pb_tray_overlay_enemy", "ui");
this.loadAtlas("pb_tray_ball", "ui");
@ -208,7 +213,7 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("types", "");
// Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang>
const lang = i18next.language;
const lang = i18next.resolvedLanguage;
if (lang !== "en") {
if (Utils.verifyLang(lang)) {
this.loadAtlas(`types_${lang}`, "");

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" },
"ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" },
"ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" },
"ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 10%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 2,5%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" },
"ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" },
"ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" },
@ -366,7 +364,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Harter Meteorit",
"SMOOTH_METEORITE": "Glatter Meteorit",
"ADAMANT_CRYSTAL": "Adamantkristall",
"LUSTROUS_ORB": "Weiß-Orb",
"LUSTROUS_GLOBE": "Weißkristall",
"GRISEOUS_CORE": "Platinumkristall",
"REVEAL_GLASS": "Wahrspiegel",
"GRACIDEA": "Gracidea",

View File

@ -1578,7 +1578,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
"encounter": {
1: `Know what? I really look forward to having serious battles with strong Trainers!
$I mean, come on! The Trainers who make it here are Trainers who desire victory with every fiber of their being!
#And they are battling alongside Pokémon that have been through countless difficult battles!
$And they are battling alongside Pokémon that have been through countless difficult battles!
$If I battle with people like that, not only will I get stronger, my Pokémon will, too!
$And we'll get to know each other even better! OK! Brace yourself!
$I'm Iris, the Pokémon League Champion, and I'm going to defeat you!`,

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Recovery Token", description: "Heals 2% of max HP every turn" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 10% chance every turn to heal a status condition" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 2.5% chance every turn to heal a status condition" },
"ENEMY_ENDURE_CHANCE": { name: "Endure Token" },
"ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Adds a 1% chance that a wild Pokémon will be a fusion" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Hard Meteorite",
"SMOOTH_METEORITE": "Smooth Meteorite",
"ADAMANT_CRYSTAL": "Adamant Crystal",
"LUSTROUS_ORB": "Lustrous Orb",
"LUSTROUS_GLOBE": "Lustrous Globe",
"GRISEOUS_CORE": "Griseous Core",
"REVEAL_GLASS": "Reveal Glass",
"GRACIDEA": "Gracidea",

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Recovery Token", description: "Cura el 2% de los PS máximo en cada turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 10% de probabilidad cada turno de curar un problema de estado" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 2.5% de probabilidad cada turno de curar un problema de estado" },
"ENEMY_ENDURE_CHANCE": { name: "Endure Token" },
"ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Meteorito Duro",
"SMOOTH_METEORITE": "Meteorito Suave",
"ADAMANT_CRYSTAL": "Gran Diamansfera",
"LUSTROUS_ORB": "Gran Lustresfera",
"LUSTROUS_GLOBE": "Gran Lustresfera",
"GRISEOUS_CORE": "Gran Griseosfera",
"REVEAL_GLASS": "Espejo Veraz",
"GRACIDEA": "Gracídea",

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Jeton Soin", description: "Soigne 2% des PV max à chaque tour" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Jeton Poison" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Jeton Paralysie" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Jeton Sommeil" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Jeton Gel" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Jeton Brulure" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 10% de chances à chaque tour de se soigner dun problème de statut." },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 2.5% de chances à chaque tour de se soigner dun problème de statut." },
"ENEMY_ENDURE_CHANCE": { name: "Jeton Ténacité" },
"ENEMY_FUSED_CHANCE": { name: "Jeton Fusion", description: "Ajoute 1% de chances quun Pokémon sauvage soit une fusion." },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Méteorite Solide",
"SMOOTH_METEORITE": "Méteorite Lisse",
"ADAMANT_CRYSTAL": "Globe Adamant",
"LUSTROUS_ORB": "Orbe Perlé",
"LUSTROUS_GLOBE": "Globe Perlé",
"GRISEOUS_CORE": "Globe Platiné",
"REVEAL_GLASS": "Miroir Sacré",
"GRACIDEA": "Gracidée",

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Gettone del Recupero", description: "Cura il 2% dei PS massimi ogni turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del Veleno" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della Paralisi" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Gettone del Sonno" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Gettone del Congelamento" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della Bruciatura" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 10% a ogni turno di curare una condizione di stato" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 2.5% a ogni turno di curare una condizione di stato" },
"ENEMY_ENDURE_CHANCE": { name: "Gettone di Resistenza" },
"ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Meteorite Dura",
"SMOOTH_METEORITE": "Meteorite Liscia",
"ADAMANT_CRYSTAL": "Adamasferoide",
"LUSTROUS_ORB": "Splendisfera",
"LUSTROUS_GLOBE": "Splendisferoide",
"GRISEOUS_CORE": "Grigiosferoide",
"REVEAL_GLASS": "Verispecchio",
"GRACIDEA": "Gracidea",

View File

@ -1,6 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{pokemonName}}(는)은 {{abilityName}} 때문에\n반동 데미지를 받지 않는다!",
"badDreams": "{{pokemonName}}(는)은\n나이트메어 때문에 시달리고 있다!",
"blockRecoilDamage" : "{{pokemonName}}[[는]] {{abilityName}} 때문에\n반동 데미지를 받지 않는다!",
"badDreams": "{{pokemonName}}[[는]]\n나이트메어 때문에 시달리고 있다!",
} as const;

View File

@ -1,21 +1,21 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "{{bossName}}(이)가 나타났다.",
"trainerAppeared": "{{trainerName}}(이)가\n승부를 걸어왔다!",
"trainerAppearedDouble": "{{trainerName}}(이)가\n승부를 걸어왔다!",
"trainerSendOut": "{{trainerName}}(는)은\n{{pokemonName}}(를)을 내보냈다!",
"singleWildAppeared": "앗! 야생 {{pokemonName}}(이)가\n튀어나왔다!",
"multiWildAppeared": "야생 {{pokemonName1}}(과)와\n{{pokemonName2}}(이)가 튀어나왔다!",
"bossAppeared": "{{bossName}}[[가]] 나타났다.",
"trainerAppeared": "{{trainerName}}[[가]]\n승부를 걸어왔다!",
"trainerAppearedDouble": "{{trainerName}}[[가]]\n승부를 걸어왔다!",
"trainerSendOut": "{{trainerName}}[[는]]\n{{pokemonName}}[[를]] 내보냈다!",
"singleWildAppeared": "앗! 야생 {{pokemonName}}[[가]]\n튀어나왔다!",
"multiWildAppeared": "야생 {{pokemonName1}}[[와]]\n{{pokemonName2}}[[가]] 튀어나왔다!",
"playerComeBack": "돌아와, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}}(는)은 {{pokemonName}}를(을) 넣어버렸다!",
"trainerComeBack": "{{trainerName}}[[는]] {{pokemonName}}[[를]] 넣어버렸다!",
"playerGo": "가랏! {{pokemonName}}!",
"trainerGo": "{{trainerName}}(는)은 {{pokemonName}}를(을) 내보냈다!",
"switchQuestion": "{{pokemonName}}를(을)\n교체하시겠습니까?",
"trainerDefeated": "{{trainerName}}과(와)의\n승부에서 이겼다!",
"trainerGo": "{{trainerName}}[[는]] {{pokemonName}}[[를]] 내보냈다!",
"switchQuestion": "{{pokemonName}}[[를]]\n교체하시겠습니까?",
"trainerDefeated": "{{trainerName}}[[와]]의\n승부에서 이겼다!",
"moneyWon": "상금으로\n₽{{moneyAmount}}을 손에 넣었다!",
"pokemonCaught": "신난다-!\n{{pokemonName}}(를)을 잡았다!",
"partyFull": "지닌 포켓몬이 가득 찼습니다. {{pokemonName}}를(을)\n대신해 포켓몬을 놓아주시겠습니까?",
"pokemonCaught": "신난다-!\n{{pokemonName}}[[를]] 잡았다!",
"partyFull": "지닌 포켓몬이 가득 찼습니다. {{pokemonName}}[[를]]\n대신해 포켓몬을 놓아주시겠습니까?",
"pokemon": "포켓몬",
"sendOutPokemon": "가랏! {{pokemonName}}!",
"hitResultCriticalHit": "급소에 맞았다!",
@ -25,22 +25,22 @@ export const battle: SimpleTranslationEntries = {
"hitResultOneHitKO": "일격필살!",
"attackFailed": "하지만 실패했다!",
"attackHitsCount": "{{count}}번 맞았다!",
"expGain": "{{pokemonName}}(는)은\n{{exp}} 경험치를 얻었다!",
"levelUp": "{{pokemonName}}(는)은\n레벨 {{level}}(으)로 올랐다!",
"learnMove": "{{pokemonName}}(는)은 새로\n{{moveName}}를(을) 배웠다!",
"learnMovePrompt": "{{pokemonName}}(는)은 새로\n{{moveName}}를(을) 배우고 싶다!…",
"learnMoveLimitReached": "그러나 {{pokemonName}}(는)은 기술을 4개\n알고 있으므로 더 이상 배울 수 없다!",
"expGain": "{{pokemonName}}[[는]]\n{{exp}} 경험치를 얻었다!",
"levelUp": "{{pokemonName}}[[는]]\n레벨 {{level}}[[로]] 올랐다!",
"learnMove": "{{pokemonName}}[[는]] 새로\n{{moveName}}[[를]] 배웠다!",
"learnMovePrompt": "{{pokemonName}}[[는]] 새로\n{{moveName}}[[를]] 배우고 싶다!…",
"learnMoveLimitReached": "그러나 {{pokemonName}}[[는]] 기술을 4개\n알고 있으므로 더 이상 배울 수 없다!",
"learnMoveReplaceQuestion": "{{moveName}} 대신 다른 기술을 잊게 하겠습니까?",
"learnMoveStopTeaching": "그럼… {{moveName}}를(을)\n배우는 것을 포기하겠습니까?",
"learnMoveNotLearned": "{{pokemonName}}(는)은 {{moveName}}를(을)\n결국 배우지 않았다!",
"learnMoveStopTeaching": "그럼… {{moveName}}[[를]]\n배우는 것을 포기하겠습니까?",
"learnMoveNotLearned": "{{pokemonName}}[[는]] {{moveName}}[[를]]\n결국 배우지 않았다!",
"learnMoveForgetQuestion": "어느 기술을 잊게 하고싶은가?",
"learnMoveForgetSuccess": "{{pokemonName}}(는)은 {{moveName}}를(을) 깨끗이 잊었다!",
"learnMoveForgetSuccess": "{{pokemonName}}[[는]] {{moveName}}[[를]] 깨끗이 잊었다!",
"countdownPoof": "@d{32}1, @d{15}2, @d{15}… @d{15}… @d{30}@s{pb_bounce_1}짠!",
"learnMoveAnd": "그리고…",
"levelCapUp": "레벨의 최대치가\n{{levelCap}}까지 상승했다!",
"moveNotImplemented": "{{moveName}}(는)은 아직 구현되지 않아 사용할 수 없다…",
"moveNotImplemented": "{{moveName}}[[는]] 아직 구현되지 않아 사용할 수 없다…",
"moveNoPP": "기술의 남은 포인트가 없다!",
"moveDisabled": "{{moveName}}를(을) 쓸 수 없다!",
"moveDisabled": "{{moveName}}[[를]] 쓸 수 없다!",
"noPokeballForce": "본 적 없는 힘이\n볼을 사용하지 못하게 한다.",
"noPokeballTrainer": "다른 트레이너의 포켓몬은 잡을 수 없다!",
"noPokeballMulti": "안돼! 2마리 있어서\n목표를 정할 수가 없어…!",

View File

@ -5,5 +5,5 @@ export const commandUiHandler: SimpleTranslationEntries = {
"ball": "볼",
"pokemon": "포켓몬",
"run": "도망간다",
"actionMessage": "{{pokemonName}}(는)은 무엇을 할까?",
"actionMessage": "{{pokemonName}}[[는]] 무엇을 할까?",
} as const;

View File

@ -1,4 +1,4 @@
import {DialogueTranslationEntries, SimpleTranslationEntries} from "#app/plugins/i18n";
import { DialogueTranslationEntries, SimpleTranslationEntries } from "#app/plugins/i18n";
// Dialogue of the NPCs in the game when the player character is male (or unset)
export const PGMdialogue: DialogueTranslationEntries = {
@ -285,7 +285,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"worker_female": {
"encounter": {
1: `It bothers me that people always misunderstand me.
1: `It bothers me that people always misunderstand me.
$I'm a lot more pure than everyone thinks.`
},
"victory": {
@ -788,7 +788,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
"cheren": {
"encounter": {
1: "You remind me of an old friend. That makes me excited about this Pokémon battle!",
2: `Pokémon battles have no meaning if you don't think why you battle.
2: `Pokémon battles have no meaning if you don't think why you battle.
$Or better said, it makes battling together with Pokémon meaningless.`,
3: "My name's Cheren! I'm a Gym Leader and a teacher! Pleasure to meet you."
},
@ -829,13 +829,13 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"victory": {
1: "Er… Is it over now?",
2: `…What a surprise. You are very strong, aren't you?
2: `…What a surprise. You are very strong, aren't you?
$I guess my brothers wouldn't have been able to defeat you either`,
3: "…Huh. Looks like my timing was, um, off?"
},
"defeat": {
1: "Huh? Did I win?",
2: `I guess…
2: `I guess…
$I suppose I won, because I've been competing with my brothers Chili and Cress, and we all were able to get tougher.`,
3: "It…it was quite a thrilling experience…"
}
@ -864,9 +864,9 @@ export const PGMdialogue: DialogueTranslationEntries = {
"encounter": {
1: `With a little more, I could see a future in which I meet the legendary Pokémon.
$You're going to help me reach that level!`,
2: `It's said that a rainbow-hued Pokémon will come down to appear before a truly powerful Trainer.
$I believed that tale, so I have secretly trained here all my life. As a result, I can now see what others cannot.
$I see a shadow of the person who will make the Pokémon appear.
2: `It's said that a rainbow-hued Pokémon will come down to appear before a truly powerful Trainer.
$I believed that tale, so I have secretly trained here all my life. As a result, I can now see what others cannot.
$I see a shadow of the person who will make the Pokémon appear.
$I believe that person is me! You're going to help me reach that level!`,
3: "Whether you choose to believe or not, mystic power does exist.",
4: "You can bear witness to the fruits of my training.",
@ -931,7 +931,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"drayton": {
"encounter": {
1: `Man, I love chairs. Don't you love chairs? What lifesavers.
1: `Man, I love chairs. Don't you love chairs? What lifesavers.
$I don't get why everyone doesn't just sit all the time. Standing up's tiring work!`,
},
"victory": {
@ -956,7 +956,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
"viola": {
"encounter": {
1: `Whether it's the tears of frustration that follow a loss or the blossoming of joy that comes with victory…
$They're both great subjects for my camera! Fantastic! This'll be just fantastic!
$They're both great subjects for my camera! Fantastic! This'll be just fantastic!
$Now come at me!`,
2: "My lens is always focused on victory--I won't let anything ruin this shot!"
},
@ -972,14 +972,14 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"candice": {
"encounter": {
1: `You want to challenge Candice? Sure thing! I was waiting for someone tough!
1: `You want to challenge Candice? Sure thing! I was waiting for someone tough!
$But I should tell you, I'm tough because I know how to focus.`,
2: `Pokémon, fashion, romance… It's all about focus!
2: `Pokémon, fashion, romance… It's all about focus!
$I'll show you just what I mean. Get ready to lose!`
},
"victory": {
1: "I must say, I'm warmed up to you! I might even admire you a little.",
2: `Wow! You're great! You've earned my respect!
2: `Wow! You're great! You've earned my respect!
$I think your focus and will bowled us over totally. `
},
"defeat": {
@ -1040,7 +1040,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "Man oh man… It feels good to go all out and still be defeated!"
},
"defeat": {
1: `What's important is how ya react to losin'.
1: `What's important is how ya react to losin'.
$That's why folks who use losin' as fuel to get better are tough.`,
}
},
@ -1081,8 +1081,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"phoebe": {
"encounter": {
1: `While I trained, I gained the ability to commune with Ghost-type Pokémon.
$Yes, the bond I developed with Pokémon is extremely tight.
1: `While I trained, I gained the ability to commune with Ghost-type Pokémon.
$Yes, the bond I developed with Pokémon is extremely tight.
$So, come on, just try and see if you can even inflict damage on my Pokémon!`,
},
"victory": {
@ -1094,12 +1094,12 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"glacia": {
"encounter": {
1: `All I have seen are challenges by weak Trainers and their Pokémon.
1: `All I have seen are challenges by weak Trainers and their Pokémon.
$What about you? It would please me to no end if I could go all out against you!`,
},
"victory": {
1: `You and your Pokémon… How hot your spirits burn!
$The all-consuming heat overwhelms.
$The all-consuming heat overwhelms.
$It's no surprise that my icy skills failed to harm you.`,
},
"defeat": {
@ -1108,7 +1108,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"drake": {
"encounter": {
1: `For us to battle with Pokémon as partners, do you know what it takes? Do you know what is needed?
1: `For us to battle with Pokémon as partners, do you know what it takes? Do you know what is needed?
$If you don't, then you will never prevail over me!`,
},
"victory": {
@ -1120,12 +1120,12 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"wallace": {
"encounter": {
1: `There's something about you… A difference in your demeanor.
$I think I sense that in you. Now, show me. Show me the power you wield with your Pokémon.
1: `There's something about you… A difference in your demeanor.
$I think I sense that in you. Now, show me. Show me the power you wield with your Pokémon.
$And I, in turn, shall present you with a performance of illusions in water by me and my Pokémon!`,
},
"victory": {
1: `Bravo. I realize now your authenticity and magnificence as a Pokémon Trainer.
1: `Bravo. I realize now your authenticity and magnificence as a Pokémon Trainer.
$I find much joy in having met you and your Pokémon. You have proven yourself worthy.`,
},
"defeat": {
@ -1158,7 +1158,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"malva": {
"encounter": {
1: `I feel like my heart might just burst into flames.
1: `I feel like my heart might just burst into flames.
$I'm burning up with my hatred for you, runt!`,
},
"victory": {
@ -1181,7 +1181,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"molayne": {
"encounter": {
1: `I gave the captain position to my cousin Sophocles, but I'm confident in my ability.
1: `I gave the captain position to my cousin Sophocles, but I'm confident in my ability.
$My strength is like that of a supernova!`,
},
"victory": {
@ -1240,8 +1240,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "Well, would you show this old lady how much you've learned?"
},
"victory": {
1: `Well! Dear child, I must say, that was most impressive.
$Your Pokémon believed in you and did their best to earn you the win.
1: `Well! Dear child, I must say, that was most impressive.
$Your Pokémon believed in you and did their best to earn you the win.
$Even though I've lost, I find myself with this silly grin!`,
},
"defeat": {
@ -1267,7 +1267,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "I shall store my memory of you and your Pokémon forever away within my heart."
},
"defeat": {
1: `Our Pokémon battle was like food for my soul. It shall keep me going.
1: `Our Pokémon battle was like food for my soul. It shall keep me going.
$That is how I will pay my respects to you for giving your all in battle!`,
}
},
@ -1301,7 +1301,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "Uagh?! Mmmuuuggghhh…"
},
"defeat": {
1: `Yaaay! I did it! I de-feet-ed you! You can come for… For… An avenge match?
1: `Yaaay! I did it! I de-feet-ed you! You can come for… For… An avenge match?
$Come for an avenge match anytime you want!`,
}
},
@ -1341,8 +1341,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
"caitlin": {
"encounter": {
1: `It's me who appeared when the flower opened up. You who have been waiting…
$You look like a Pokémon Trainer with refined strength and deepened kindness.
$What I look for in my opponent is superb strength
$You look like a Pokémon Trainer with refined strength and deepened kindness.
$What I look for in my opponent is superb strength
$Please unleash your power to the fullest!`,
},
"victory": {
@ -1354,7 +1354,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"diantha": {
"encounter": {
1: `Battling against you and your Pokémon, all of you brimming with hope for the future…
1: `Battling against you and your Pokémon, all of you brimming with hope for the future…
$Honestly, it just fills me up with energy I need to keep facing each new day! It does!`,
},
"victory": {
@ -1366,14 +1366,14 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"wikstrom": {
"encounter": {
1: `Well met, young challenger! Verily am I the famed blade of hardened steel, Duke Wikstrom!
1: `Well met, young challenger! Verily am I the famed blade of hardened steel, Duke Wikstrom!
$Let the battle begin! En garde!`,
},
"victory": {
1: "Glorious! The trust that you share with your honorable Pokémon surpasses even mine!"
},
"defeat": {
1: `What manner of magic is this? My heart, it doth hammer ceaselessly in my breast!
1: `What manner of magic is this? My heart, it doth hammer ceaselessly in my breast!
$Winning against such a worthy opponent doth give my soul wings--thus do I soar!`,
}
},
@ -1433,8 +1433,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"milo": {
"encounter": {
1: `Sure seems like you understand Pokémon real well.
$This is gonna be a doozy of a battle!
1: `Sure seems like you understand Pokémon real well.
$This is gonna be a doozy of a battle!
$I'll have to Dynamax my Pokémon if I want to win!`,
},
"victory": {
@ -1446,9 +1446,9 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"lucian": {
"encounter": {
1: `Just a moment, please. The book I'm reading has nearly reached its thrilling climax…
$The hero has obtained a mystic sword and is about to face their final trial Ah, never mind.
$Since you've made it this far, I'll put that aside and battle you.
1: `Just a moment, please. The book I'm reading has nearly reached its thrilling climax…
$The hero has obtained a mystic sword and is about to face their final trial Ah, never mind.
$Since you've made it this far, I'll put that aside and battle you.
$Let me see if you'll achieve as much glory as the hero of my book!,`
},
"victory": {
@ -1486,7 +1486,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "Prepare to learn firsthand how the fiery breath of ferocious battle feels!"
},
"victory": {
1: `Fortune smiled on me this time, but…
1: `Fortune smiled on me this time, but…
$Judging from how the match went, who knows if I will be so lucky next time.`,
},
"defeat": {
@ -1550,10 +1550,10 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"steven": {
"encounter": {
1: `Tell me… What have you seen on your journey with your Pokémon?
$What have you felt, meeting so many other Trainers out there?
$Traveling this rich land Has it awoken something inside you?
$I want you to come at me with all that you've learned.
1: `Tell me… What have you seen on your journey with your Pokémon?
$What have you felt, meeting so many other Trainers out there?
$Traveling this rich land Has it awoken something inside you?
$I want you to come at me with all that you've learned.
$My Pokémon and I will respond in turn with all that we know!`,
},
"victory": {
@ -1576,11 +1576,11 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"iris": {
"encounter": {
1: `Know what? I really look forward to having serious battles with strong Trainers!
$I mean, come on! The Trainers who make it here are Trainers who desire victory with every fiber of their being!
#And they are battling alongside Pokémon that have been through countless difficult battles!
$If I battle with people like that, not only will I get stronger, my Pokémon will, too!
$And we'll get to know each other even better! OK! Brace yourself!
1: `Know what? I really look forward to having serious battles with strong Trainers!
$I mean, come on! The Trainers who make it here are Trainers who desire victory with every fiber of their being!
#And they are battling alongside Pokémon that have been through countless difficult battles!
$If I battle with people like that, not only will I get stronger, my Pokémon will, too!
$And we'll get to know each other even better! OK! Brace yourself!
$I'm Iris, the Pokémon League Champion, and I'm going to defeat you!`,
},
"victory": {
@ -1604,7 +1604,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"geeta": {
"encounter": {
1: `I decided to throw my hat in the ring once more.
1: `I decided to throw my hat in the ring once more.
$Come now Show me the fruits of your training.`,
},
"victory": {
@ -1630,8 +1630,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "We're gonna have an absolutely champion time!"
},
"victory": {
1: `My time as Champion is over…
$But what a champion time it's been!
1: `My time as Champion is over…
$But what a champion time it's been!
$Thank you for the greatest battle I've ever had!`,
},
"defeat": {
@ -1695,7 +1695,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"maylene": {
"encounter": {
1: `I've come to challenge you now, and I won't hold anything back.
1: `I've come to challenge you now, and I won't hold anything back.
$Please prepare yourself for battle!`,
},
"victory": {
@ -1707,7 +1707,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"fantina": {
"encounter": {
1: `You shall challenge me, yes? But I shall win.
1: `You shall challenge me, yes? But I shall win.
$That is what the Gym Leader of Hearthome does, non?`,
},
"victory": {
@ -1719,8 +1719,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"byron": {
"encounter": {
1: `Trainer! You're young, just like my son, Roark.
$With more young Trainers taking charge, the future of Pokémon is bright!
1: `Trainer! You're young, just like my son, Roark.
$With more young Trainers taking charge, the future of Pokémon is bright!
$So, as a wall for young people, I'll take your challenge!`,
},
"victory": {
@ -1748,19 +1748,19 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"victory": {
1: `You've got me beat…
$Your desire and the noble way your Pokémon battled for you
$Your desire and the noble way your Pokémon battled for you
$I even felt thrilled during our match. That was a very good battle.`,
},
"defeat": {
1: `It was not shocking at all…
1: `It was not shocking at all…
$That is not what I wanted!`,
}
},
"burgh": {
"encounter": {
1: `M'hm… If I win this battle, I feel like I can draw a picture unlike any before it.
1: `M'hm… If I win this battle, I feel like I can draw a picture unlike any before it.
$OK! I can hear my battle muse loud and clear. Let's get straight to it!`,
2: `Of course, I'm really proud of all of my Pokémon!
2: `Of course, I'm really proud of all of my Pokémon!
$Well now Let's get right to it!`
},
"victory": {
@ -1769,13 +1769,13 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"defeat": {
1: "Wow… It's beautiful somehow, isn't it…",
2: `Sometimes I hear people say something was an ugly win.
2: `Sometimes I hear people say something was an ugly win.
$I think if you're trying your best, any win is beautiful.`
}
},
"elesa": {
"encounter": {
1: `C'est fini! When I'm certain of that, I feel an electric jolt run through my body!
1: `C'est fini! When I'm certain of that, I feel an electric jolt run through my body!
$I want to feel the sensation, so now my beloved Pokémon are going to make your head spin!`,
},
"victory": {
@ -1787,8 +1787,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"skyla": {
"encounter": {
1: `It's finally time for a showdown! That means the Pokémon battle that decides who's at the top, right?
$I love being on the summit! 'Cause you can see forever and ever from high places!
1: `It's finally time for a showdown! That means the Pokémon battle that decides who's at the top, right?
$I love being on the summit! 'Cause you can see forever and ever from high places!
$So, how about you and I have some fun?`,
},
"victory": {
@ -1800,7 +1800,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"brycen": {
"encounter": {
1: `There is also strength in being with other people and Pokémon.
1: `There is also strength in being with other people and Pokémon.
$Receiving their support makes you stronger. I'll show you this power!`,
},
"victory": {
@ -1812,7 +1812,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"drayden": {
"encounter": {
1: `What I want to find is a young Trainer who can show me a bright future.
1: `What I want to find is a young Trainer who can show me a bright future.
$Let's battle with everything we have: your skill, my experience, and the love we've raised our Pokémon with!`,
},
"victory": {
@ -1824,15 +1824,15 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"grant": {
"encounter": {
1: `There is only one thing I wish for.
1: `There is only one thing I wish for.
$That by surpassing one another, we find a way to even greater heights.`,
},
"victory": {
1: "You are a wall that I am unable to surmount!"
},
"defeat": {
1: `Do not give up.
$That is all there really is to it.
1: `Do not give up.
$That is all there really is to it.
$The most important lessons in life are simple.`,
}
},
@ -1860,8 +1860,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"valerie": {
"encounter": {
1: `Oh, if it isn't a young Trainer… It is lovely to get to meet you like this.
$Then I suppose you have earned yourself the right to a battle, as a reward for your efforts.
1: `Oh, if it isn't a young Trainer… It is lovely to get to meet you like this.
$Then I suppose you have earned yourself the right to a battle, as a reward for your efforts.
$The elusive Fairy may appear frail as the breeze and delicate as a bloom, but it is strong.`,
},
"victory": {
@ -1874,7 +1874,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
"wulfric": {
"encounter": {
1: `You know what? We all talk big about what you learn from battling and bonds and all that…
$But really, I just do it 'cause it's fun.
$But really, I just do it 'cause it's fun.
$Who cares about the grandstanding? Let's get to battling!`,
},
"victory": {
@ -1886,8 +1886,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"kabu": {
"encounter": {
1: `Every Trainer and Pokémon trains hard in pursuit of victory.
$But that means your opponent is also working hard to win.
1: `Every Trainer and Pokémon trains hard in pursuit of victory.
$But that means your opponent is also working hard to win.
$In the end, the match is decided by which side is able to unleash their true potential.`,
},
"victory": {
@ -1899,7 +1899,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"bea": {
"encounter": {
1: `Do you have an unshakable spirit that won't be moved, no matter how you are attacked?
1: `Do you have an unshakable spirit that won't be moved, no matter how you are attacked?
$I think I'll just test that out, shall I?`,
},
"victory": {
@ -1944,7 +1944,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"marnie": {
"encounter": {
1: `The truth is, when all's said and done… I really just wanna become Champion for myself!
1: `The truth is, when all's said and done… I really just wanna become Champion for myself!
$So don't take it personal when I kick your butt!`,
},
"victory": {
@ -1959,8 +1959,8 @@ export const PGMdialogue: DialogueTranslationEntries = {
1: "I'm going to defeat the Champion, win the whole tournament, and prove to the world just how strong the great Raihan really is!"
},
"victory": {
1: `I look this good even when I lose.
$It's a real curse.
1: `I look this good even when I lose.
$It's a real curse.
$Guess it's time for another selfie!`,
},
"defeat": {
@ -1982,7 +1982,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
"encounter": {
1: `How're ya feelin' about this battle?
$...
$Let's get this show on the road! How strong is our challenger?
$Let's get this show on the road! How strong is our challenger?
$I 'unno! Let's find out together!`,
},
"victory": {
@ -2335,113 +2335,113 @@ export const PGFmiscDialogue: SimpleTranslationEntries = PGMmiscDialogue;
export const PGMdoubleBattleDialogue: DialogueTranslationEntries = {
"blue_red_double": {
"encounter": {
1: `Blue: Hey Red, let's show them what we're made of!
$Red: ...
$Blue: This is Pallet Town Power!`,
1: `그린: 어이 레드! 우리가 누군지 보여주자고!
$레드: ...
$그린: 태초마을의 !`,
},
"victory": {
1: `Blue: That was a great battle!
$Red: ...`,
1: `그린: 훌륭한 승부였어!
$레드: ...`,
},
},
"red_blue_double": {
"encounter": {
1: `Red: ...!
$Blue: He never talks much.
$Blue: But dont let that fool you! He is a champ after all!`,
1: `레드: ...!
$그린: .
$그린: 그렇지만 ! !`,
},
"victory": {
1: `Red: ...!
$Blue: Next time we will beat you!`,
1: `레드: ...!
$그린: 다음에는 !`,
},
},
"tate_liza_double": {
"encounter": {
1: `Tate: Are you suprised?
$Liza: We are two gym leaders at once!
$Tate: We are twins!
$Liza: We dont need to talk to understand each other!
$Tate: Twice the power...
$Liza: Can you handle it?`,
1: `풍: 에헤헤... 체육관 관장이
$란: ?
$풍: 우리는 !
$란: 굳이
$풍: 자동으로 릿
$란: 호흡을 !`,
},
"victory": {
1: `Tate: What? Our combination was perfect!
$Liza: Looks like we need to train more...`,
1: `풍: 우, 우리들의
$란: 팀워크가...!`,
},
},
"liza_tate_double": {
"encounter": {
1: `Liza: Hihihi... Are you suprised?
$Tate: Yes, we are really two gym leaders at once!
$Liza: This is my twin brother Tate!
$Tate: And this is my twin sister Liza!
$Liza: Don't you think we are a perfect combination?`
1: `란: 우후후... 체육관 관장이
$풍: ?
$란: 우리는 !
$풍: 완벽한
$란: 과연 ?`
},
"victory": {
1: `Liza: Are we...
$Tate: ...not as strong as we thought?`,
1: `란: 우리들이 생각한 만큼
$풍: 우리가 ?`,
},
},
"wallace_steven_double": {
"encounter": {
1: `Steven: Wallace, let's show them the power of the champions!
$Wallace: We will show you the power of Hoenn!
$Steven: Let's go!`,
1: `성호: 윤진! 우리 챔피언의 힘을 보여주자!
$윤진: 호연의 !
$성호: 간다!`,
},
"victory": {
1: `Steven: That was a great battle!
$Wallace: We will win next time!`,
1: `성호: 훌륭한 승부였어!
$윤진: 다음엔 !`,
},
},
"steven_wallace_double": {
"encounter": {
1: `Steven: Do you have any rare pokémon?
$Wallace: Steven... We are here for a battle, not to show off our pokémon.
$Steven: Oh... I see... Let's go then!`,
1: `성호: 너 혹시 희귀한 포켓몬 가지고 있니?
$윤진: 성호야... .
$성호: 오... ... !`,
},
"victory": {
1: `Steven: Now that we are done with the battle, let's show off our pokémon!
$Wallace: Steven...`,
1: `성호: 이제 승부는 끝났으니 포켓몬을 자랑해 볼까!
$윤진: 성호야...`,
},
},
"alder_iris_double": {
"encounter": {
1: `Alder: We are the strongest trainers in Unova!
$Iris: Fights against strong trainers are the best!`,
1: `노간주: 우리는 하나 지방 최강의 트레이너들이란다!
$아이리스: 이렇게 ~!!`,
},
"victory": {
1: `Alder: Wow! You are super strong!
$Iris: We will win next time!`,
1: `노간주: 장하구나! 실로 견줄 자가 천하에 없도다!
$아이리스: 다음 ~!`,
},
},
"iris_alder_double": {
"encounter": {
1: `Iris: Welcome Challenger! I am THE Unova Champion!
$Alder: Iris, aren't you a bit too excited?`,
1: `아이리스: 어서 와, 도전자! 내가 바로 하나 지방 챔피언이야~!
$노간주: 아이리스야, ?`,
},
"victory": {
1: `Iris: A loss like this is not easy to take...
$Alder: But we will only get stronger with every loss!`,
1: `아이리스: 후와아아아아... 최선을 다했는데도... 우리가 져버렸네!
$노간주: 하지만 !`,
},
},
"piers_marnie_double": {
"encounter": {
1: `Marnie: Brother, let's show them the power of Spikemuth!
$Piers: We bring darkness!`,
1: `마리: 오빠, 스파이크마을의 힘을 보여주자!
$두송: 우리가 !`,
},
"victory": {
1: `Marnie: You brought light to our darkness!
$Piers: Its too bright...`,
1: `마리: 네가 우리의 어둠에 빛을 불러왔구나!
$두송: 여긴 ...`,
},
},
"marnie_piers_double": {
"encounter": {
1: `Piers: Ready for a concert?
$Marnie: Brother... They are here to fight, not to sing...`,
1: `두송: 큰서트 즐길 준비 됐어?
$마리: 오빠... ...`,
},
"victory": {
1: `Piers: Now that was a great concert!
$Marnie: Brother...`,
1: `두송: 훌륭한 콘서트였다!
$마리: 오빠...`,
},
},
};

View File

@ -38,9 +38,9 @@ export const menu: SimpleTranslationEntries = {
"girl": "여자",
"evolving": "…오잉!?\n{{pokemonName}}의 모습이…!",
"stoppedEvolving": "얼라리…?\n{{pokemonName}}의 변화가 멈췄다!",
"pauseEvolutionsQuestion": "{{pokemonName}}를(을) 진화하지 않게 만드시겠습니까?\n포켓몬 화면에서 다시 활성화시킬 수 있습니다.",
"pauseEvolutionsQuestion": "{{pokemonName}}[[를]] 진화하지 않게 만드시겠습니까?\n포켓몬 화면에서 다시 활성화시킬 수 있습니다.",
"evolutionsPaused": "{{pokemonName}}의 진화가 비활성화되었다.",
"evolutionDone": "축하합니다! {{pokemonName}}(는)은\n{{evolvedPokemonName}}(으)로 진화했습니다!",
"evolutionDone": "축하합니다! {{pokemonName}}[[는]]\n{{evolvedPokemonName}}[[로]] 진화했습니다!",
"dailyRankings": "일간 랭킹",
"weeklyRankings": "주간 랭킹",
"noRankings": "랭킹 정보 없음",

View File

@ -12,8 +12,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
},
"PokemonHeldItemModifierType": {
extra: {
"inoperable": "{{pokemonName}}(는)은\n이 아이템을 얻을 수 없다!",
"tooMany": "{{pokemonName}}(는)은\n이 아이템을 너무 많이 갖고 있다!",
"inoperable": "{{pokemonName}}[[는]]\n이 아이템을 얻을 수 없다!",
"tooMany": "{{pokemonName}}[[는]]\n이 아이템을 너무 많이 갖고 있다!",
}
},
"PokemonHpRestoreModifierType": {
@ -46,13 +46,13 @@ export const modifierType: ModifierTypeTranslationEntries = {
},
"PokemonNatureChangeModifierType": {
name: "{{natureName}}민트",
description: "포켓몬의 성격을 {{natureName}}(으)로 바꾸고 스타팅에도 등록한다.",
description: "포켓몬의 성격을 {{natureName}}[[로]] 바꾸고 스타팅에도 등록한다.",
},
"DoubleBattleChanceBoosterModifierType": {
description: "{{battleCount}}번의 배틀 동안 더블 배틀이 등장할 확률 두 배",
},
"TempBattleStatBoosterModifierType": {
description: "자신의 모든 포켓몬이 5번의 배틀 동안 {{tempBattleStatName}}(이)가 한 단계 증가"
description: "자신의 모든 포켓몬이 5번의 배틀 동안 {{tempBattleStatName}}[[가]] 한 단계 증가"
},
"AttackTypeBoosterModifierType": {
description: "지니게 하면 {{moveType}}타입 기술의 위력이 20% 상승",
@ -97,7 +97,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
},
"TmModifierType": {
name: "No.{{moveId}} {{moveName}}",
description: "포켓몬에게 {{moveName}}를(을) 가르침",
description: "포켓몬에게 {{moveName}}[[를]] 가르침",
},
"EvolutionItemModifierType": {
description: "어느 특정 포켓몬을 진화",
@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "회복 토큰", description: "매 턴 최대 체력의 2%를 회복" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "독 토큰" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "마비 토큰" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "잠듦 토큰" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "얼음 토큰" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "화상 토큰" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 10% 추가" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 2.5% 추가" },
"ENEMY_ENDURE_CHANCE": { name: "버티기 토큰" },
"ENEMY_FUSED_CHANCE": { name: "합체 토큰", description: "야생 포켓몬이 합체할 확률 1% 추가" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "단단한운석",
"SMOOTH_METEORITE": "부드러운운석",
"ADAMANT_CRYSTAL": "큰금강옥",
"LUSTROUS_ORB": "큰백옥",
"LUSTROUS_GLOBE": "큰백옥",
"GRISEOUS_CORE": "큰백금옥",
"REVEAL_GLASS": "비추는거울",
"GRACIDEA": "그라시데아꽃",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "모래바람이 불기 시작했다!",
"sandstormLapseMessage": "모래바람이 세차게 분다",
"sandstormClearMessage": "모래바람이 가라앉았다!",
"sandstormDamageMessage": "모래바람이\n{{pokemonPrefix}}{{pokemonName}}를(을) 덮쳤다!",
"sandstormDamageMessage": "모래바람이\n{{pokemonPrefix}}{{pokemonName}}[[를]] 덮쳤다!",
"hailStartMessage": "싸라기눈이 내리기 시작했다!",
"hailLapseMessage": "싸라기눈이 계속 내리고 있다",
"hailClearMessage": "싸라기눈이 그쳤다!",
"hailDamageMessage": "싸라기눈이\n{{pokemonPrefix}}{{pokemonName}}를(을) 덮쳤다!",
"hailDamageMessage": "싸라기눈이\n{{pokemonPrefix}}{{pokemonName}}[[를]] 덮쳤다!",
"snowStartMessage": "눈이 내리기 시작했다!",
"snowLapseMessage": "눈이 계속 내리고 있다",

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Token de Recuperação", description: "Cura 2% dos PS máximos a cada turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Token de Veneno" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Token de Paralisia" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Token de Sono" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Token de Congelamento" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Token de Queimadura" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 10% a cada turno de curar uma condição de status" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 2.5% a cada turno de curar uma condição de status" },
"ENEMY_ENDURE_CHANCE": { name: "Token de Persistência" },
"ENEMY_FUSED_CHANCE": { name: "Token de Fusão", description: "Adiciona uma chance de 1% de que um Pokémon selvagem seja uma fusão" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "Meteorito Duro",
"SMOOTH_METEORITE": " Meteorito Liso",
"ADAMANT_CRYSTAL": "Cristal Adamante",
"LUSTROUS_ORB": "Orbe Pérola",
"LUSTROUS_GLOBE": "Globo Brilhante",
"GRISEOUS_CORE": "Núcleo Platinado",
"REVEAL_GLASS": "Espelho da Verdade",
"GRACIDEA": "Gracídea",

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "回复硬币", description: "每回合回复2%最大HP" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "剧毒硬币" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "麻痹硬币" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "睡眠硬币" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "冰冻硬币" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "灼烧硬币" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加10%每回合治愈异常状态的概率" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加2.5%每回合治愈异常状态的概率" },
"ENEMY_ENDURE_CHANCE": { name: "忍受硬币" },
"ENEMY_FUSED_CHANCE": { name: "融合硬币", description: "增加1%野生融合宝可梦出现概率" },
},
@ -365,7 +363,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"HARD_METEORITE": "坚硬陨石",
"SMOOTH_METEORITE": "光滑陨石",
"ADAMANT_CRYSTAL": "大金刚宝玉",
"LUSTROUS_ORB": "白玉宝珠",
"LUSTROUS_GLOBE": "大白宝玉",
"GRISEOUS_CORE": "大白金宝玉",
"REVEAL_GLASS": "现形镜",
"GRACIDEA": "葛拉西蒂亚花",

View File

@ -282,12 +282,10 @@ export const modifierType: ModifierTypeTranslationEntries = {
ENEMY_HEAL: { name: "恢復硬幣", description: "每回合恢復2%最大HP" },
ENEMY_ATTACK_POISON_CHANCE: { name: "劇毒硬幣" },
ENEMY_ATTACK_PARALYZE_CHANCE: { name: "麻痹硬幣" },
ENEMY_ATTACK_SLEEP_CHANCE: { name: "睡眠硬幣" },
ENEMY_ATTACK_FREEZE_CHANCE: { name: "冰凍硬幣" },
ENEMY_ATTACK_BURN_CHANCE: { name: "灼燒硬幣" },
ENEMY_STATUS_EFFECT_HEAL_CHANCE: {
name: "萬靈藥硬幣",
description: "增加10%每回合治癒異常狀態的概率",
description: "增加2.5%每回合治癒異常狀態的概率",
},
ENEMY_ENDURE_CHANCE: { name: "忍受硬幣" },
ENEMY_FUSED_CHANCE: {
@ -419,7 +417,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
HARD_METEORITE: "堅硬隕石",
SMOOTH_METEORITE: "光滑隕石",
ADAMANT_CRYSTAL: "大金剛寶玉",
LUSTROUS_ORB: "白玉寶珠",
LUSTROUS_GLOBE: "大白寶玉",
GRISEOUS_CORE: "大白金寶玉",
REVEAL_GLASS: "現形鏡",
GRACIDEA: "葛拉西蒂亞花",

View File

@ -11,7 +11,8 @@ import { Type } from "../data/type";
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "../ui/party-ui-handler";
import * as Utils from "../utils";
import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from "../data/temp-battle-stat";
import { BerryType, getBerryEffectDescription, getBerryName } from "../data/berry";
import { getBerryEffectDescription, getBerryName } from "../data/berry";
import { BerryType } from "../data/enums/berry-type";
import { Unlockables } from "../system/unlockables";
import { StatusEffect, getStatusEffectDescriptor } from "../data/status-effect";
import { SpeciesFormKey } from "../data/pokemon-species";
@ -977,8 +978,8 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType {
private chancePercent: integer;
private effect: StatusEffect;
constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect) {
super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent), "enemy_status_chance");
constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect, stackCount?: integer) {
super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance");
this.chancePercent = chancePercent;
this.effect = effect;
@ -1215,14 +1216,12 @@ export const modifierTypes = {
ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2)),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 10, StatusEffect.POISON),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 10, StatusEffect.PARALYSIS),
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_SLEEP_CHANCE", "wl_awakening", 10, StatusEffect.SLEEP),
ENEMY_ATTACK_FREEZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_FREEZE_CHANCE", "wl_ice_heal", 10, StatusEffect.FREEZE),
ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 10, StatusEffect.BURN),
ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 10)),
ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2.5),
ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2, 10)),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 5, StatusEffect.POISON, 10),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 2.5, StatusEffect.PARALYSIS, 10),
ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 5, StatusEffect.BURN, 10),
ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)),
ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2),
ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)),
};
@ -1465,15 +1464,13 @@ const trainerModifierPool: ModifierPool = {
const enemyBuffModifierPool: ModifierPool = {
[ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_SLEEP_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10),
new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 9),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 9),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 9),
new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 4),
new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1)
].map(m => {
m.setTier(ModifierTier.COMMON); return m;

View File

@ -12,7 +12,8 @@ import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } fr
import { getPokemonMessage } from "../messages";
import * as Utils from "../utils";
import { TempBattleStat } from "../data/temp-battle-stat";
import { BerryType, getBerryEffectFunc, getBerryPredicate } from "../data/berry";
import { getBerryEffectFunc, getBerryPredicate } from "../data/berry";
import { BerryType } from "../data/enums/berry-type";
import { StatusEffect, getStatusEffectHealText } from "../data/status-effect";
import { achvs } from "../system/achv";
import { VoucherType } from "../system/voucher";
@ -775,6 +776,9 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) {
bypassSpeed.value = true;
if (this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW") {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " used its quick claw to move faster!"));
}
return true;
}
@ -2140,7 +2144,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier {
}
export class EnemyTurnHealModifier extends EnemyPersistentModifier {
private healPercent: number;
public healPercent: number;
constructor(type: ModifierType, healPercent: number, stackCount?: integer) {
super(type, stackCount);
@ -2175,23 +2179,23 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
}
getMaxStackCount(scene: BattleScene): integer {
return 15;
return 10;
}
}
export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier {
public effect: StatusEffect;
private chance: number;
public chance: number;
constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
this.effect = effect;
this.chance = (chancePercent || 10) / 100;
this.chance = (chancePercent || 5) / 100;
}
match(modifier: Modifier): boolean {
return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect && modifier.chance === this.chance;
return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect;
}
clone(): EnemyAttackStatusEffectChanceModifier {
@ -2210,19 +2214,23 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi
return false;
}
getMaxStackCount(scene: BattleScene): integer {
return 10;
}
}
export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier {
private chance: number;
public chance: number;
constructor(type: ModifierType, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
this.chance = (chancePercent || 10) / 100;
this.chance = (chancePercent || 2.5) / 100;
}
match(modifier: Modifier): boolean {
return modifier instanceof EnemyStatusEffectHealChanceModifier && modifier.chance === this.chance;
return modifier instanceof EnemyStatusEffectHealChanceModifier;
}
clone(): EnemyStatusEffectHealChanceModifier {
@ -2244,19 +2252,23 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier
return false;
}
getMaxStackCount(scene: BattleScene): integer {
return 10;
}
}
export class EnemyEndureChanceModifier extends EnemyPersistentModifier {
private chance: number;
public chance: number;
constructor(type: ModifierType, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
constructor(type: ModifierType, chancePercent?: number, stackCount?: integer) {
super(type, stackCount || 10);
this.chance = (chancePercent || 2.5) / 100;
this.chance = (chancePercent || 2) / 100;
}
match(modifier: Modifier) {
return modifier instanceof EnemyEndureChanceModifier && modifier.chance === this.chance;
return modifier instanceof EnemyEndureChanceModifier;
}
clone() {

View File

@ -4,7 +4,7 @@ import { Biome } from "./data/enums/biome";
import { Moves } from "./data/enums/moves";
import { WeatherType } from "./data/weather";
import { Variant } from "./data/variant";
import { BerryType } from "./data/berry";
import { BerryType } from "./data/enums/berry-type";
import { TempBattleStat } from "./data/temp-battle-stat";
import { Nature } from "./data/nature";
import { Type } from "./data/type";

View File

@ -61,7 +61,7 @@ import { Abilities } from "./data/enums/abilities";
import * as Overrides from "./overrides";
import { TextStyle, addTextObject } from "./ui/text";
import { Type } from "./data/type";
import { MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events";
import { BerryUsedEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events";
export class LoginPhase extends Phase {
@ -2244,6 +2244,7 @@ export class BerryPhase extends FieldPhase {
berryModifier.consumed = false;
}
}
this.scene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used
}
this.scene.updateModifiers(pokemon.isPlayer());

View File

@ -1,5 +1,6 @@
import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import processor, { KoreanPostpositionProcessor } from "i18next-korean-postposition-processor";
import { deConfig } from "#app/locales/de/config.js";
import { enConfig } from "#app/locales/en/config.js";
@ -148,7 +149,7 @@ export function initI18n(): void {
* A: In src/system/settings.ts, add a new case to the Setting.Language switch statement.
*/
i18next.use(LanguageDetector).init({
i18next.use(LanguageDetector).use(processor).use(new KoreanPostpositionProcessor()).init({
lng: lang,
nonExplicitSupportedLngs: true,
fallbackLng: "en",
@ -186,6 +187,7 @@ export function initI18n(): void {
...koConfig
},
},
postProcess: ["korean-postposition"],
});
}

View File

@ -34,6 +34,8 @@ import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./setti
import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard";
import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js";
import { Device } from "#app/enums/devices.js";
import { EnemyAttackStatusEffectChanceModifier } from "../modifier/modifier";
import { StatusEffect } from "#app/data/status-effect.js";
const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary
@ -1078,6 +1080,9 @@ export class GameData {
if (md?.className === "ExpBalanceModifier") { // Temporarily limit EXP Balance until it gets reworked
md.stackCount = Math.min(md.stackCount, 4);
}
if (md instanceof EnemyAttackStatusEffectChanceModifier && md.effect === StatusEffect.FREEZE || md.effect === StatusEffect.SLEEP) {
continue;
}
ret.push(new PersistentModifierData(md, player));
}
return ret;

View File

@ -53,6 +53,7 @@ export const SettingKeys = {
Music_Preference: "MUSIC_PREFERENCE",
Move_Animations: "MOVE_ANIMATIONS",
Show_Moveset_Flyout: "SHOW_MOVESET_FLYOUT",
Show_Arena_Flyout: "SHOW_ARENA_FLYOUT",
Show_Stats_on_Level_Up: "SHOW_LEVEL_UP_STATS",
EXP_Gains_Speed: "EXP_GAINS_SPEED",
EXP_Party_Display: "EXP_PARTY_DISPLAY",
@ -198,6 +199,13 @@ export const Setting: Array<Setting> = [
default: 1,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Show_Arena_Flyout,
label: "Show Battle Effects Flyout",
options: OFF_ON,
default: 1,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Show_Stats_on_Level_Up,
label: "Show Stats on Level Up",
@ -355,6 +363,9 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
case SettingKeys.Show_Moveset_Flyout:
scene.showMovesetFlyout = Setting[index].options[value] === "On";
break;
case SettingKeys.Show_Arena_Flyout:
scene.showArenaFlyout = Setting[index].options[value] === "On";
break;
case SettingKeys.Show_Stats_on_Level_Up:
scene.showLevelUpStats = Setting[index].options[value] === "On";
break;

View File

@ -69,7 +69,7 @@ export class UiInputs {
[Button.CYCLE_GENDER]: () => this.buttonCycleOption(Button.CYCLE_GENDER),
[Button.CYCLE_ABILITY]: () => this.buttonCycleOption(Button.CYCLE_ABILITY),
[Button.CYCLE_NATURE]: () => this.buttonCycleOption(Button.CYCLE_NATURE),
[Button.V]: () => this.buttonCycleOption(Button.V),
[Button.V]: () => this.buttonCycleOption(Button.V),
[Button.SPEED_UP]: () => this.buttonSpeedChange(),
[Button.SLOW_DOWN]: () => this.buttonSpeedChange(false),
};
@ -119,12 +119,14 @@ export class UiInputs {
}
}
buttonInfo(pressed: boolean = true): void {
if (!this.scene.showMovesetFlyout) {
return;
if (this.scene.showMovesetFlyout ) {
for (const p of this.scene.getField().filter(p => p?.isActive(true))) {
p.toggleFlyout(pressed);
}
}
for (const p of this.scene.getField().filter(p => p?.isActive(true))) {
p.toggleFlyout(pressed);
if (this.scene.showArenaFlyout) {
this.scene.ui.processInfoButton(pressed);
}
}

384
src/ui/arena-flyout.ts Normal file
View File

@ -0,0 +1,384 @@
import * as Utils from "../utils";
import { addTextObject, TextStyle } from "./text";
import BattleScene from "#app/battle-scene.js";
import { ArenaTagSide } from "#app/data/arena-tag.js";
import { WeatherType } from "#app/data/weather.js";
import { TerrainType } from "#app/data/terrain.js";
import { addWindow, WindowVariant } from "./ui-theme";
import { ArenaEvent, ArenaEventType, TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js";
import { BattleSceneEventType, TurnEndEvent } from "#app/battle-scene-events.js";
import { ArenaTagType } from "#app/data/enums/arena-tag-type.js";
import { TimeOfDay } from "#app/data/enums/time-of-day.js";
/** Enum used to differentiate {@linkcode Arena} effects */
enum ArenaEffectType {
PLAYER,
WEATHER,
TERRAIN,
FIELD,
ENEMY,
}
/** Container for info about an {@linkcode Arena}'s effects */
interface ArenaEffectInfo {
/** The enum string representation of the effect */
name: string;
/** {@linkcode ArenaEffectType} type of effect */
type: ArenaEffectType,
/** The maximum duration set by the effect */
maxDuration: number;
/** The current duration left on the effect */
duration: number;
}
export default class ArenaFlyout extends Phaser.GameObjects.Container {
/** An alias for the scene typecast to a {@linkcode BattleScene} */
private battleScene: BattleScene;
/** The restricted width of the flyout which should be drawn to */
private flyoutWidth = 170;
/** The restricted height of the flyout which should be drawn to */
private flyoutHeight = 51;
/** The amount of translation animation on the x-axis */
private translationX: number;
/** The x-axis point where the flyout should sit when activated */
private anchorX: number;
/** The y-axis point where the flyout should sit when activated */
private anchorY: number;
/** The initial container which defines where the flyout should be attached */
private flyoutParent: Phaser.GameObjects.Container;
/** The container which defines the drawable dimensions of the flyout */
private flyoutContainer: Phaser.GameObjects.Container;
/** The background {@linkcode Phaser.GameObjects.NineSlice} window for the flyout */
private flyoutWindow: Phaser.GameObjects.NineSlice;
/** The header {@linkcode Phaser.GameObjects.NineSlice} window for the flyout */
private flyoutWindowHeader: Phaser.GameObjects.NineSlice;
/** The {@linkcode Phaser.GameObjects.Text} that goes inside of the header */
private flyoutTextHeader: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Sprite} that represents the current time of day */
private timeOfDayIcon: Phaser.GameObjects.Sprite;
/** The {@linkcode Phaser.GameObjects.Text} header used to indicate the player's effects */
private flyoutTextHeaderPlayer: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Text} header used to indicate the enemy's effects */
private flyoutTextHeaderEnemy: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Text} header used to indicate neutral effects */
private flyoutTextHeaderField: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Text} used to indicate the player's effects */
private flyoutTextPlayer: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Text} used to indicate the enemy's effects */
private flyoutTextEnemy: Phaser.GameObjects.Text;
/** The {@linkcode Phaser.GameObjects.Text} used to indicate neutral effects */
private flyoutTextField: Phaser.GameObjects.Text;
/** Container for all field effects observed by this object */
private readonly fieldEffectInfo: ArenaEffectInfo[] = [];
// Stores callbacks in a variable so they can be unsubscribed from when destroyed
private readonly onNewArenaEvent = (event: Event) => this.onNewArena(event);
private readonly onTurnInitEvent = (event: Event) => this.onTurnInit(event);
private readonly onTurnEndEvent = (event: Event) => this.onTurnEnd(event);
private readonly onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event);
constructor(scene: Phaser.Scene) {
super(scene, 0, 0);
this.battleScene = this.scene as BattleScene;
this.translationX = this.flyoutWidth;
this.anchorX = 0;
this.anchorY = -98;
this.flyoutParent = this.scene.add.container(this.anchorX - this.translationX, this.anchorY);
this.flyoutParent.setAlpha(0);
this.add(this.flyoutParent);
this.flyoutContainer = this.scene.add.container(0, 0);
this.flyoutParent.add(this.flyoutContainer);
this.flyoutWindow = addWindow(this.scene as BattleScene, 0, 0, this.flyoutWidth, this.flyoutHeight, false, false, 0, 0, WindowVariant.THIN);
this.flyoutContainer.add(this.flyoutWindow);
this.flyoutWindowHeader = addWindow(this.scene as BattleScene, this.flyoutWidth / 2, 0, this.flyoutWidth / 2, 14, false, false, 0, 0, WindowVariant.XTHIN);
this.flyoutWindowHeader.setOrigin();
this.flyoutContainer.add(this.flyoutWindowHeader);
this.flyoutTextHeader = addTextObject(this.scene, this.flyoutWidth / 2, 0, "Active Battle Effects", TextStyle.BATTLE_INFO);
this.flyoutTextHeader.setFontSize(54);
this.flyoutTextHeader.setAlign("center");
this.flyoutTextHeader.setOrigin();
this.flyoutContainer.add(this.flyoutTextHeader);
this.timeOfDayIcon = this.scene.add.sprite((this.flyoutWidth / 2) + (this.flyoutWindowHeader.displayWidth / 2), 0, "dawn_icon").setOrigin();
this.timeOfDayIcon.setVisible(false);
this.flyoutContainer.add(this.timeOfDayIcon);
this.flyoutTextHeaderPlayer = addTextObject(this.scene, 6, 5, "Player", TextStyle.SUMMARY_BLUE);
this.flyoutTextHeaderPlayer.setFontSize(54);
this.flyoutTextHeaderPlayer.setAlign("left");
this.flyoutTextHeaderPlayer.setOrigin(0, 0);
this.flyoutContainer.add(this.flyoutTextHeaderPlayer);
this.flyoutTextHeaderField = addTextObject(this.scene, this.flyoutWidth / 2, 5, "Neutral", TextStyle.SUMMARY_GREEN);
this.flyoutTextHeaderField.setFontSize(54);
this.flyoutTextHeaderField.setAlign("center");
this.flyoutTextHeaderField.setOrigin(0.5, 0);
this.flyoutContainer.add(this.flyoutTextHeaderField);
this.flyoutTextHeaderEnemy = addTextObject(this.scene, this.flyoutWidth - 6, 5, "Enemy", TextStyle.SUMMARY_RED);
this.flyoutTextHeaderEnemy.setFontSize(54);
this.flyoutTextHeaderEnemy.setAlign("right");
this.flyoutTextHeaderEnemy.setOrigin(1, 0);
this.flyoutContainer.add(this.flyoutTextHeaderEnemy);
this.flyoutTextPlayer = addTextObject(this.scene, 6, 13, "", TextStyle.BATTLE_INFO);
this.flyoutTextPlayer.setLineSpacing(-1);
this.flyoutTextPlayer.setFontSize(48);
this.flyoutTextPlayer.setAlign("left");
this.flyoutTextPlayer.setOrigin(0, 0);
this.flyoutContainer.add(this.flyoutTextPlayer);
this.flyoutTextField = addTextObject(this.scene, this.flyoutWidth / 2, 13, "", TextStyle.BATTLE_INFO);
this.flyoutTextField.setLineSpacing(-1);
this.flyoutTextField.setFontSize(48);
this.flyoutTextField.setAlign("center");
this.flyoutTextField.setOrigin(0.5, 0);
this.flyoutContainer.add(this.flyoutTextField);
this.flyoutTextEnemy = addTextObject(this.scene, this.flyoutWidth - 6, 13, "", TextStyle.BATTLE_INFO);
this.flyoutTextEnemy.setLineSpacing(-1);
this.flyoutTextEnemy.setFontSize(48);
this.flyoutTextEnemy.setAlign("right");
this.flyoutTextEnemy.setOrigin(1, 0);
this.flyoutContainer.add(this.flyoutTextEnemy);
this.name = "Fight Flyout";
this.flyoutParent.name = "Fight Flyout Parent";
// Subscribes to required events available on game start
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.NEW_ARENA, this.onNewArenaEvent);
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.TURN_INIT, this.onTurnInitEvent);
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.TURN_END, this.onTurnEndEvent);
}
private setTimeOfDayIcon() {
this.timeOfDayIcon.setTexture(TimeOfDay[this.battleScene.arena.getTimeOfDay()].toLowerCase() + "_icon");
}
private onTurnInit(event: Event) {
this.setTimeOfDayIcon();
}
private onNewArena(event: Event) {
this.fieldEffectInfo.length = 0;
// Subscribes to required events available on battle start
this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.WEATHER_CHANGED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TERRAIN_CHANGED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.addEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent);
this.setTimeOfDayIcon();
}
/**
* Formats a string to title case
* @param unformattedText Text to be formatted
* @returns the formatted string
*/
private formatText(unformattedText: string): string {
const text = unformattedText.split("_");
for (let i = 0; i < text.length; i++) {
text[i] = text[i].charAt(0).toUpperCase() + text[i].substring(1).toLowerCase();
}
return text.join(" ");
}
/** Clears out the current string stored in all arena effect texts */
private clearText() {
this.flyoutTextPlayer.text = "";
this.flyoutTextField.text = "";
this.flyoutTextEnemy.text = "";
}
/** Parses through all set Arena Effects and puts them into the proper {@linkcode Phaser.GameObjects.Text} object */
private updateFieldText() {
this.clearText();
this.fieldEffectInfo.sort((infoA, infoB) => infoA.duration - infoB.duration);
for (let i = 0; i < this.fieldEffectInfo.length; i++) {
const fieldEffectInfo = this.fieldEffectInfo[i];
// Creates a proxy object to decide which text object needs to be updated
let textObject: Phaser.GameObjects.Text;
switch (fieldEffectInfo.type) {
case ArenaEffectType.PLAYER:
textObject = this.flyoutTextPlayer;
break;
case ArenaEffectType.WEATHER:
case ArenaEffectType.TERRAIN:
case ArenaEffectType.FIELD:
textObject = this.flyoutTextField;
break;
case ArenaEffectType.ENEMY:
textObject = this.flyoutTextEnemy;
break;
}
textObject.text += this.formatText(fieldEffectInfo.name);
if (fieldEffectInfo.type === ArenaEffectType.TERRAIN) {
textObject.text += " Terrain"; // Adds 'Terrain' since the enum does not contain it
}
if (fieldEffectInfo.maxDuration !== 0) {
textObject.text += " " + fieldEffectInfo.duration + "/" + fieldEffectInfo.maxDuration;
}
textObject.text += "\n";
}
}
/**
* Parses the {@linkcode Event} being passed and updates the state of the fieldEffectInfo array
* @param event {@linkcode Event} being sent
*/
private onFieldEffectChanged(event: Event) {
const arenaEffectChangedEvent = event as ArenaEvent;
if (!arenaEffectChangedEvent) {
return;
}
let foundIndex: number;
switch (arenaEffectChangedEvent.constructor) {
case TagAddedEvent:
const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent;
this.fieldEffectInfo.push({
name: ArenaTagType[tagAddedEvent.arenaTagType],
type: tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH
? ArenaEffectType.FIELD
: tagAddedEvent.arenaTagSide === ArenaTagSide.PLAYER
? ArenaEffectType.PLAYER
: ArenaEffectType.ENEMY,
maxDuration: tagAddedEvent.duration,
duration: tagAddedEvent.duration});
break;
case TagRemovedEvent:
const tagRemovedEvent = arenaEffectChangedEvent as TagRemovedEvent;
foundIndex = this.fieldEffectInfo.findIndex(info => info.name === ArenaTagType[tagRemovedEvent.arenaTagType]);
if (foundIndex !== -1) { // If the tag was being tracked, remove it
this.fieldEffectInfo.splice(foundIndex, 1);
}
break;
case WeatherChangedEvent:
case TerrainChangedEvent:
const fieldEffectChangedEvent = arenaEffectChangedEvent as WeatherChangedEvent | TerrainChangedEvent;
// Stores the old Weather/Terrain name in case it's in the array already
const oldName =
fieldEffectChangedEvent instanceof WeatherChangedEvent
? WeatherType[fieldEffectChangedEvent.oldWeatherType]
: TerrainType[fieldEffectChangedEvent.oldTerrainType];
// Stores the new Weather/Terrain info
const newInfo = {
name:
fieldEffectChangedEvent instanceof WeatherChangedEvent
? WeatherType[fieldEffectChangedEvent.newWeatherType]
: TerrainType[fieldEffectChangedEvent.newTerrainType],
type: fieldEffectChangedEvent instanceof WeatherChangedEvent
? ArenaEffectType.WEATHER
: ArenaEffectType.TERRAIN,
maxDuration: fieldEffectChangedEvent.duration,
duration: fieldEffectChangedEvent.duration};
foundIndex = this.fieldEffectInfo.findIndex(info => [newInfo.name, oldName].includes(info.name));
if (foundIndex === -1) {
if (newInfo.name !== undefined) {
this.fieldEffectInfo.push(newInfo); // Adds the info to the array if it doesn't already exist and is defined
}
} else if (!newInfo.name) {
this.fieldEffectInfo.splice(foundIndex, 1); // Removes the old info if the new one is undefined
} else {
this.fieldEffectInfo[foundIndex] = newInfo; // Otherwise, replace the old info
}
break;
}
this.updateFieldText();
}
/**
* Iterates through the fieldEffectInfo array and decrements the duration of each item
* @param event {@linkcode Event} being sent
*/
private onTurnEnd(event: Event) {
const turnEndEvent = event as TurnEndEvent;
if (!turnEndEvent) {
return;
}
const fieldEffectInfo: ArenaEffectInfo[] = [];
this.fieldEffectInfo.forEach(i => fieldEffectInfo.push(i));
for (let i = 0; i < fieldEffectInfo.length; i++) {
const info = fieldEffectInfo[i];
if (info.maxDuration === 0) {
continue;
}
--info.duration;
if (info.duration <= 0) { // Removes the item if the duration has expired
this.fieldEffectInfo.splice(this.fieldEffectInfo.indexOf(info), 1);
}
}
this.updateFieldText();
}
/**
* Animates the flyout to either show or hide it by applying a fade and translation
* @param visible Should the flyout be shown?
*/
toggleFlyout(visible: boolean): void {
this.scene.tweens.add({
targets: this.flyoutParent,
x: visible ? this.anchorX : this.anchorX - this.translationX,
duration: Utils.fixedInt(125),
ease: "Sine.easeInOut",
alpha: visible ? 1 : 0,
});
}
destroy(fromScene?: boolean): void {
this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.NEW_ARENA, this.onNewArenaEvent);
this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.TURN_END, this.onTurnEndEvent);
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.WEATHER_CHANGED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TERRAIN_CHANGED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent);
super.destroy(fromScene);
}
}

View File

@ -4,7 +4,9 @@ import * as Utils from "../utils";
import BattleScene from "#app/battle-scene.js";
import { UiTheme } from "#app/enums/ui-theme.js";
import Move from "#app/data/move.js";
import { BattleSceneEventType, MoveUsedEvent } from "#app/battle-scene-events.js";
import { BattleSceneEventType, BerryUsedEvent, MoveUsedEvent } from "#app/battle-scene-events.js";
import { BerryType } from "#app/data/enums/berry-type.js";
import { Moves } from "#app/data/enums/moves.js";
/** Container for info about a {@linkcode Move} */
interface MoveInfo {
@ -53,7 +55,9 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
/** The array of {@linkcode MoveInfo} used to track moves for the {@linkcode Pokemon} linked to the flyout */
private moveInfo: MoveInfo[] = new Array();
private readonly onMoveUsed = (event) => this.updateInfo(event);
// Stores callbacks in a variable so they can be unsubscribed from when destroyed
private readonly onMoveUsedEvent = (event: Event) => this.onMoveUsed(event);
private readonly onBerryUsedEvent = (event: Event) => this.onBerryUsed(event);
constructor(scene: Phaser.Scene, player: boolean) {
super(scene, 0, 0);
@ -109,11 +113,12 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
this.name = `Flyout ${this.pokemon.name}`;
this.flyoutParent.name = `Flyout Parent ${this.pokemon.name}`;
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsed);
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsedEvent);
this.battleScene.eventTarget.addEventListener(BattleSceneEventType.BERRY_USED, this.onBerryUsedEvent);
}
/** Sets and formats the text property for all {@linkcode Phaser.GameObjects.Text} in the flyoutText array */
setText() {
private setText() {
for (let i = 0; i < this.flyoutText.length; i++) {
const flyoutText = this.flyoutText[i];
const moveInfo = this.moveInfo[i];
@ -122,21 +127,23 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
continue;
}
const currentPp = Math.max(moveInfo.maxPp - moveInfo.ppUsed, 0);
const currentPp = moveInfo.maxPp - moveInfo.ppUsed;
flyoutText.text = `${moveInfo.move.name} ${currentPp}/${moveInfo.maxPp}`;
}
}
/** Updates all of the {@linkcode MoveInfo} objects in the moveInfo array */
updateInfo(event: Event) {
private onMoveUsed(event: Event) {
const moveUsedEvent = event as MoveUsedEvent;
if (!moveUsedEvent || moveUsedEvent.userId !== this.pokemon?.id) {
if (!moveUsedEvent
|| moveUsedEvent.pokemonId !== this.pokemon?.id
|| moveUsedEvent.move.id === Moves.STRUGGLE) { // Ignore Struggle
return;
}
const foundInfo = this.moveInfo.find(x => x?.move.id === moveUsedEvent.move.id);
if (foundInfo) {
foundInfo.ppUsed += moveUsedEvent.ppUsed;
foundInfo.ppUsed = Math.min(foundInfo.ppUsed + moveUsedEvent.ppUsed, foundInfo.maxPp);
} else {
this.moveInfo.push({move: moveUsedEvent.move, maxPp: moveUsedEvent.move.pp, ppUsed: moveUsedEvent.ppUsed});
}
@ -144,6 +151,23 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
this.setText();
}
private onBerryUsed(event: Event) {
const berryUsedEvent = event as BerryUsedEvent;
if (!berryUsedEvent
|| berryUsedEvent.berryModifier.pokemonId !== this.pokemon?.id
|| berryUsedEvent.berryModifier.berryType !== BerryType.LEPPA) { // We only care about Leppa berries
return;
}
const foundInfo = this.moveInfo.find(info => info.ppUsed === info.maxPp);
if (!foundInfo) { // This will only happen on a de-sync of PP tracking
return;
}
foundInfo.ppUsed = Math.max(foundInfo.ppUsed - 10, 0);
this.setText();
}
/** Animates the flyout to either show or hide it by applying a fade and translation */
toggleFlyout(visible: boolean): void {
this.scene.tweens.add({
@ -156,8 +180,9 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
}
destroy(fromScene?: boolean): void {
this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsed);
this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsedEvent);
this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.BERRY_USED, this.onBerryUsedEvent);
super.destroy();
super.destroy(fromScene);
}
}

View File

@ -35,7 +35,7 @@ export default class FightUiHandler extends UiHandler {
this.movesContainer = this.scene.add.container(18, -38.7);
ui.add(this.movesContainer);
this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36,`types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}` , "unknown");
this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36,`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}` , "unknown");
this.typeIcon.setVisible(false);
ui.add(this.typeIcon);
@ -168,7 +168,7 @@ export default class FightUiHandler extends UiHandler {
if (hasMove) {
const pokemonMove = moveset[cursor];
this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8);
this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8);
this.moveCategoryIcon.setTexture("categories", MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0);
const power = pokemonMove.getMove().power;

View File

@ -73,7 +73,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
}
setup(): void {
const currentLanguage = i18next.language;
const currentLanguage = i18next.resolvedLanguage;
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang));
const textSettings = languageSettings[langSettingKey];
const infoBg = addWindow(this.scene, 0, 0, this.infoWindowWidth, 132);

View File

@ -251,7 +251,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
setup() {
const ui = this.getUi();
const currentLanguage = i18next.language;
const currentLanguage = i18next.resolvedLanguage;
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang));
const textSettings = languageSettings[langSettingKey];
@ -518,11 +518,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
this.starterSelectContainer.add(this.pokemonSprite);
this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`); this.type1Icon.setScale(0.5);
this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type1Icon.setScale(0.5);
this.type1Icon.setOrigin(0, 0);
this.starterSelectContainer.add(this.type1Icon);
this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`); this.type2Icon.setScale(0.5);
this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type2Icon.setScale(0.5);
this.type2Icon.setOrigin(0, 0);
this.starterSelectContainer.add(this.type2Icon);

View File

@ -695,7 +695,7 @@ export default class SummaryUiHandler extends UiHandler {
const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => {
const xCoord = 39 + 34 * index;
const typeIcon = !tera
? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera");
? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera");
if (tera) {
typeIcon.setScale(0.5);
const typeRgb = getTypeRgb(type);
@ -897,7 +897,7 @@ export default class SummaryUiHandler extends UiHandler {
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
this.extraMoveRowContainer.setVisible(true);
const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[this.newMove.type].toLowerCase());
const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[this.newMove.type].toLowerCase());
newMoveTypeIcon.setOrigin(0, 1);
this.extraMoveRowContainer.add(newMoveTypeIcon);
@ -920,7 +920,7 @@ export default class SummaryUiHandler extends UiHandler {
this.moveRowsContainer.add(moveRowContainer);
if (move) {
const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1);
const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1);
moveRowContainer.add(typeIcon);
}

View File

@ -98,7 +98,7 @@ export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, wi
}
function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, number, number ] {
const lang = i18next.language;
const lang = i18next.resolvedLanguage;
let shadowXpos = 4;
let shadowYpos = 5;

View File

@ -222,6 +222,21 @@ export default class UI extends Phaser.GameObjects.Container {
return this.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
}
processInfoButton(pressed: boolean) {
if (this.overlayActive) {
return false;
}
const battleScene = this.scene as BattleScene;
if ([Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE].includes(this.mode)) {
battleScene?.processInfoButton(pressed);
return true;
}
battleScene?.processInfoButton(false);
return true;
}
processInput(button: Button): boolean {
if (this.overlayActive) {
return false;

View File

@ -396,7 +396,7 @@ English itself counts as not available
export function verifyLang(lang?: string): boolean {
//IMPORTANT - ONLY ADD YOUR LANG HERE IF YOU'VE ALREADY ADDED ALL THE NECESSARY IMAGES
if (!lang) {
lang = i18next.language;
lang = i18next.resolvedLanguage;
}
switch (lang) {