Compare commits

...

16 Commits

Author SHA1 Message Date
SnowCharm
2a6ef08cff
[Localization] Improve zh_CN Localization Content (#2075)
* fix zh_CN modifier-type locales

* update zh_CN/achv.ts
2024-06-11 01:32:56 -04:00
40chyan
f45ad124b2
[Localization] translation of zh_cn dialogues (#1903)
* Update dialogue.ts

* Update text.ts

* Update dialogue.ts

* Update dialogue.ts

* ignore linting in zh_cn

* try renaming the .eslintrc

* ignoring lint did not work

* lint fix by replacing ` with "

* change eternaus dialogue string back to ` to prevent error

* indentation fixed

---------

Co-authored-by: Temps Ray <temps.ray@gmail.com>
2024-06-11 01:06:39 -04:00
snnh
40e342d806
[Localization] Improve Simplified Chinese Localization Content ( achv.ts ) (#2071)
* Update achv.ts

* Update achv.ts
2024-06-11 00:49:55 -04:00
40chyan
689ec47bde
[Localization] fixing typo in zh_cn challenge.ts (#2070)
* Update challenges.ts fixing typo

* another typo
2024-06-11 00:45:00 -04:00
Matthew Olker
8c596c6f33 update zh font to unicode to fit both 2024-06-10 23:21:19 -04:00
Matthew Olker
073c8aaf01 censor glitch hotfix 2024-06-10 22:51:54 -04:00
Greenlamp2
725df33600
[Bug] Restrict Menu Access to Specific Game Modes + Gamepad Start Button in Select-Starter Menu (#2064)
* fix softlock + start run on button menu for gamepad on starter_select

* chop chop even more mode to the menu whitelist
2024-06-10 21:18:07 -05:00
Matthew
8d75670a81
[UI] egg and starter formatting (#2043)
* egg and starter formatting

* localization update

* localization update

* fix local voucher test

* pr comments

* pr comments

* account for new font
2024-06-10 21:58:01 -04:00
snnh
f6a6c2da1b
[Localization] Improve Simplified Chinese Localization Content (#2067)
* Update modifier-type.ts

* Update save-slot-select-ui-handler.ts

* Update party-ui-handler.ts

* Update party-ui-handler.ts
2024-06-10 21:55:03 -04:00
Greenlamp2
8af02ff2dc
deleted palete unused in masterlist to fix tests (#2065) 2024-06-11 03:36:21 +02:00
Matthew
5248160112
add zh localization font (#2066) 2024-06-10 21:36:09 -04:00
returntoice
b9e809b685
[Localization][ko] Some localization updates for Korean (#2046)
* localization

* localization2

* local3
2024-06-10 21:32:57 -04:00
Adrian T
5d358fc57f
[Enhancement] Refactor egg counter (#1996)
* refactor egg counter

* add documentation
2024-06-10 20:20:00 -05:00
Adrian T
65ddd49d64
[Enhancement] Move event files to a central directory (#1918)
* Move events to a central directory

* Update modifier import

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* remove old battle-scene-events

* Move to field events

* Update battle-scene.ts

---------

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-06-10 20:19:07 -05:00
Zach Day
5762409b17
[Move] Implement Core Enforcer (#2024)
* [Move] Implement Core Enforcer

* Documentation

* Documentation
2024-06-10 21:17:28 -04:00
Xavion3
dc6c8f22ac
Make speed ties seed based on current turn (#2044) 2024-06-11 09:42:39 +10:00
58 changed files with 1615 additions and 1797 deletions

View File

@ -19,6 +19,11 @@
font-family: 'emerald'; font-family: 'emerald';
src: url('./fonts/pokemon-emerald-pro.ttf') format('truetype'); src: url('./fonts/pokemon-emerald-pro.ttf') format('truetype');
} }
@font-face {
font-family: 'unifont';
src: url('./fonts/unifont-15.1.05.otf') format('opentype');
size-adjust: 70%;
}
@font-face { @font-face {
font-family: 'pkmnems'; font-family: 'pkmnems';

Binary file not shown.

View File

@ -1,18 +0,0 @@
{
"0": {
"737373": "737373",
"ffffff": "ffffff",
"101010": "101010",
"b5b5bd": "b5b5bd",
"8442ad": "282828",
"5a3173": "121212",
"294a31": "294a31",
"4a9c42": "5fd054",
"422152": "000000",
"ffc500": "ffc500",
"42733a": "317c25",
"6b4229": "6b4229",
"ad7b4a": "ad7b4a",
"deb56b": "deb56b"
}
}

View File

@ -1,18 +0,0 @@
{
"0": {
"5a3a73": "121212",
"8442ad": "282828",
"101010": "101010",
"422152": "000000",
"737373": "737373",
"ffffff": "ffffff",
"b5b5bd": "b5b5bd",
"294a31": "294a31",
"4a9c42": "5fd054",
"deb56b": "ffc500",
"42733a": "317c25",
"ad7b4a": "ad7b4a",
"6b4229": "6b4229",
"de3a29": "deb56b"
}
}

View File

@ -1,19 +0,0 @@
{
"0": {
"737373": "737373",
"101010": "101010",
"b5b5bd": "878787",
"ffffff": "ffffff",
"102152": "521010",
"5a42ad": "992828",
"29426b": "6b2929",
"5284a5": "952f2f",
"63c5ff": "ff6363",
"313131": "313131",
"31317b": "3a1111",
"4a4a4a": "4a4a4a",
"212121": "212121",
"ffc55a": "ffc55a",
"d69431": "d69431"
}
}

View File

@ -1,18 +0,0 @@
{
"0": {
"192952": "521010",
"737373": "6a0d0d",
"ffffff": "ffffff",
"101010": "101010",
"5a4aad": "952f2f",
"b5b5bd": "a49696",
"3a3a84": "3a1111",
"5284a5": "7c0b0b",
"29426b": "6b2929",
"63c5ff": "c83f3f",
"d69431": "ffc55a",
"ffc55a": "d69431",
"313131": "313131",
"212121": "212121"
}
}

View File

@ -1,18 +0,0 @@
{
"0": {
"b5b5bd": "999999",
"737373": "737373",
"101010": "101010",
"ffffff": "d0d0d0",
"6b213a": "838383",
"bd4a52": "380d5f",
"a55a3a": "451c6a",
"f77b42": "69418e",
"633110": "2c2c2c",
"ffce63": "9386ff",
"4a2919": "191919",
"634231": "2c143a",
"84634a": "311e42",
"943142": "0b0b0b"
}
}

View File

@ -1,18 +0,0 @@
{
"0": {
"634231": "2c143a",
"101010": "101010",
"bd4a52": "380d5f",
"84634a": "311e42",
"4a2919": "191919",
"737373": "737373",
"ffffff": "d0d0d0",
"b5b5bd": "999999",
"73313a": "838383",
"633110": "2c2c2c",
"f77b42": "69418e",
"a55a3a": "451c6a",
"943142": "0b0b0b",
"ffce63": "9386ff"
}
}

View File

@ -1770,7 +1770,7 @@
0 0
], ],
"645-therian": [ "645-therian": [
1, 0,
0, 0,
0 0
], ],

View File

@ -1,17 +0,0 @@
{
"0": {
"737373": "737373",
"101010": "101010",
"ffffff": "ffffff",
"b5b5bd": "b5b5bd",
"6b4229": "6b4229",
"deb56b": "deb56b",
"ad7b4a": "ad7b4a",
"5a3173": "121212",
"8442ad": "282828",
"4a9c42": "5fd054",
"294a31": "294a31",
"42733a": "317c25",
"422152": "000000"
}
}

View File

@ -1,17 +0,0 @@
{
"0": {
"422152": "000000",
"5a3a73": "121212",
"8442ad": "282828",
"101010": "101010",
"ffffff": "ffffff",
"b5b5bd": "b5b5bd",
"737373": "737373",
"294a31": "294a31",
"42733a": "317c25",
"4a9c42": "5fd054",
"ad7b4a": "ad7b4a",
"deb56b": "deb56b",
"6b4229": "6b4229"
}
}

View File

@ -1,17 +0,0 @@
{
"0": {
"737373": "737373",
"b5b5bd": "878787",
"ffffff": "ffffff",
"101010": "101010",
"31317b": "3a1111",
"5a42ad": "992828",
"102152": "521010",
"5284a5": "952f2f",
"63c5ff": "ff6363",
"313131": "313131",
"4a4a4a": "4a4a4a",
"212121": "212121",
"29426b": "6b2929"
}
}

View File

@ -1,18 +0,0 @@
{
"0": {
"737373": "6a0d0d",
"ffffff": "ffffff",
"101010": "101010",
"192952": "521010",
"5a4aad": "952f2f",
"3a3a84": "3a1111",
"b5b5bd": "a49696",
"29426b": "6b2929",
"63c5ff": "c83f3f",
"5284a5": "7c0b0b",
"ffc55a": "d69431",
"d69431": "ffc55a",
"313131": "313131",
"212121": "212121"
}
}

View File

@ -1,17 +0,0 @@
{
"0": {
"101010": "101010",
"ffffff": "d0d0d0",
"737373": "737373",
"4a2919": "191919",
"bd4a52": "380d5f",
"943142": "0b0b0b",
"b5b5bd": "999999",
"84634a": "311e42",
"634231": "2c143a",
"6b213a": "838383",
"a55a3a": "451c6a",
"633110": "2c2c2c",
"f77b42": "69418e"
}
}

View File

@ -1,19 +0,0 @@
{
"0": {
"101010": "101010",
"634231": "531975",
"84634a": "311e42",
"4a2919": "191919",
"bd4a52": "380d5f",
"737373": "737373",
"b5b5bd": "999999",
"ffffff": "d0d0d0",
"73313a": "2c143a",
"943142": "311e42",
"633110": "2c2c2c",
"a55a3a": "451c6a",
"ad8c3a": "380d5f",
"f77b42": "69418e",
"ffce63": "9386ff"
}
}

View File

@ -58,7 +58,7 @@ import * as Overrides from "./overrides";
import {InputsController} from "./inputs-controller"; import {InputsController} from "./inputs-controller";
import {UiInputs} from "./ui-inputs"; import {UiInputs} from "./ui-inputs";
import { MoneyFormat } from "./enums/money-format"; import { MoneyFormat } from "./enums/money-format";
import { NewArenaEvent } from "./battle-scene-events"; import { NewArenaEvent } from "./events/battle-scene";
import { Abilities } from "./data/enums/abilities"; import { Abilities } from "./data/enums/abilities";
import ArenaFlyout from "./ui/arena-flyout"; import ArenaFlyout from "./ui/arena-flyout";
import { EaseType } from "./ui/enums/ease-type"; import { EaseType } from "./ui/enums/ease-type";

View File

@ -5117,7 +5117,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
target.summonData.abilitySuppressed = true; target.summonData.abilitySuppressed = true;
target.scene.queueMessage(getPokemonMessage(target, " ability\nwas suppressed!")); target.scene.queueMessage(getPokemonMessage(target, "'s ability\nwas suppressed!"));
return true; return true;
} }
@ -5127,6 +5127,35 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
} }
} }
/**
* Applies the effects of {@linkcode SuppressAbilitiesAttr} if the target has already moved this turn.
* @extends MoveEffectAttr
* @see {@linkcode Moves.CORE_ENFORCER} (the move which uses this effect)
*/
export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr {
/**
* If the target has already acted this turn, apply a {@linkcode SuppressAbilitiesAttr} effect unless the
* abillity cannot be suppressed. This is a secondary effect and has no bearing on the success or failure of the move.
*
* @returns True if the move occurred, otherwise false. Note that true will be returned even if the target has not
* yet moved or if the target's abiilty is un-suppressable.
*/
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args)) {
return false;
}
if (target.turnData.acted) {
const suppressAttr = new SuppressAbilitiesAttr();
if (suppressAttr.getCondition()(user, target, move)) {
suppressAttr.apply(user, target, move, args);
}
}
return true;
}
}
export class TransformAttr extends MoveEffectAttr { export class TransformAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
@ -7311,7 +7340,7 @@ export function initMoves() {
.attr(MatchUserTypeAttr), .attr(MatchUserTypeAttr),
new AttackMove(Moves.CORE_ENFORCER, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 7) new AttackMove(Moves.CORE_ENFORCER, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 7)
.target(MoveTarget.ALL_NEAR_ENEMIES) .target(MoveTarget.ALL_NEAR_ENEMIES)
.partial(), .attr(SuppressAbilitiesIfActedAttr),
new AttackMove(Moves.TROP_KICK, Type.GRASS, MoveCategory.PHYSICAL, 70, 100, 15, 100, 0, 7) new AttackMove(Moves.TROP_KICK, Type.GRASS, MoveCategory.PHYSICAL, 70, 100, 15, 100, 0, 7)
.attr(StatChangeAttr, BattleStat.ATK, -1), .attr(StatChangeAttr, BattleStat.ATK, -1),
new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7) new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7)

View File

@ -538,7 +538,6 @@ export class TrainerConfig {
initI18n(); initI18n();
} }
this.setPartyTemplates(trainerPartyTemplates.RIVAL_5); this.setPartyTemplates(trainerPartyTemplates.RIVAL_5);
console.log(signatureSpecies);
signatureSpecies.forEach((speciesPool, s) => { signatureSpecies.forEach((speciesPool, s) => {
if (!Array.isArray(speciesPool)) { if (!Array.isArray(speciesPool)) {
speciesPool = [speciesPool]; speciesPool = [speciesPool];

View File

@ -12,7 +12,8 @@ import { achvs } from "./system/achv";
import { pokemonPrevolutions } from "./data/pokemon-evolutions"; import { pokemonPrevolutions } from "./data/pokemon-evolutions";
import { EggTier } from "./data/enums/egg-type"; import { EggTier } from "./data/enums/egg-type";
import PokemonInfoContainer from "./ui/pokemon-info-container"; import PokemonInfoContainer from "./ui/pokemon-info-container";
import EggsToHatchCountContainer from "./ui/eggs-to-hatch-count-container"; import EggCounterContainer from "./ui/egg-counter-container";
import { EggCountChangedEvent } from "./events/egg";
/** /**
* Class that represents egg hatching * Class that represents egg hatching
@ -24,7 +25,7 @@ export class EggHatchPhase extends Phase {
/** The number of eggs that are hatching */ /** The number of eggs that are hatching */
private eggsToHatchCount: integer; private eggsToHatchCount: integer;
/** The container that lists how many eggs are hatching */ /** The container that lists how many eggs are hatching */
private eggsToHatchCountContainer: EggsToHatchCountContainer; private eggCounterContainer: EggCounterContainer;
/** The scene handler for egg hatching */ /** The scene handler for egg hatching */
private eggHatchHandler: EggHatchSceneHandler; private eggHatchHandler: EggHatchSceneHandler;
@ -110,10 +111,8 @@ export class EggHatchPhase extends Phase {
this.eggContainer.add(this.eggLightraysOverlay); this.eggContainer.add(this.eggLightraysOverlay);
this.eggHatchContainer.add(this.eggContainer); this.eggHatchContainer.add(this.eggContainer);
this.eggsToHatchCountContainer = new EggsToHatchCountContainer(this.scene, this.eggsToHatchCount); this.eggCounterContainer = new EggCounterContainer(this.scene, this.eggsToHatchCount);
this.eggsToHatchCountContainer.setup(); this.eggHatchContainer.add(this.eggCounterContainer);
this.eggHatchContainer.add(this.eggsToHatchCountContainer);
const getPokemonSprite = () => { const getPokemonSprite = () => {
const ret = this.scene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, "pkmn__sub"); const ret = this.scene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, "pkmn__sub");
@ -308,13 +307,6 @@ export class EggHatchPhase extends Phase {
* Function to do the logic and animation of completing a hatch and revealing the Pokemon * Function to do the logic and animation of completing a hatch and revealing the Pokemon
*/ */
doReveal(): void { doReveal(): void {
// Update/reduce count of hatching eggs when revealed if count is at least 1
// If count is 0, hide eggsToHatchCountContainer instead
if (this.eggsToHatchCount > 1) {
this.eggsToHatchCount -= 1;
} else {
this.eggsToHatchCountContainer.setVisible(false);
}
const isShiny = this.pokemon.isShiny(); const isShiny = this.pokemon.isShiny();
if (this.pokemon.species.subLegendary) { if (this.pokemon.species.subLegendary) {
this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY); this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
@ -336,10 +328,8 @@ export class EggHatchPhase extends Phase {
this.pokemonSprite.setPipelineData("variant", this.pokemon.variant); this.pokemonSprite.setPipelineData("variant", this.pokemon.variant);
this.pokemonSprite.setVisible(true); this.pokemonSprite.setVisible(true);
this.scene.time.delayedCall(Utils.fixedInt(250), () => { this.scene.time.delayedCall(Utils.fixedInt(250), () => {
if (this.eggsToHatchCount < 10) { this.eggsToHatchCount--;
this.eggsToHatchCountContainer.setWindowToDefaultSize(); this.eggHatchHandler.eventTarget.dispatchEvent(new EggCountChangedEvent(this.eggsToHatchCount));
}
this.eggsToHatchCountContainer.eggCountText.setText(`${this.eggsToHatchCount}`);
this.pokemon.cry(); this.pokemon.cry();
if (isShiny) { if (isShiny) {
this.scene.time.delayedCall(Utils.fixedInt(500), () => { this.scene.time.delayedCall(Utils.fixedInt(500), () => {

View File

@ -1,5 +1,5 @@
import Move from "./data/move"; import Move from "../data/move";
import { BerryModifier } from "./modifier/modifier"; import { BerryModifier } from "../modifier/modifier";
/** Alias for all {@linkcode BattleScene} events */ /** Alias for all {@linkcode BattleScene} events */
export enum BattleSceneEventType { export enum BattleSceneEventType {
@ -7,7 +7,7 @@ export enum BattleSceneEventType {
* Triggers when the corresponding setting is changed * Triggers when the corresponding setting is changed
* @see {@linkcode CandyUpgradeNotificationChangedEvent} * @see {@linkcode CandyUpgradeNotificationChangedEvent}
*/ */
CANDY_UPGRADE_NOTIFICATION_CHANGED = "onCandyUpgradeDisplayChanged", CANDY_UPGRADE_NOTIFICATION_CHANGED = "onCandyUpgradeNotificationChanged",
/** /**
* Triggers when a move is successfully used * Triggers when a move is successfully used

21
src/events/egg.ts Normal file
View File

@ -0,0 +1,21 @@
export enum EggEventType {
/**
* Triggers when egg count is changed.
* @see {@linkcode MoveUsedEvent}
*/
EGG_COUNT_CHANGED = "onEggCountChanged"
}
/**
* Container class for {@linkcode EggEventType.EGG_COUNT_CHANGED} events
* @extends Event
*/
export class EggCountChangedEvent extends Event {
/** The updated egg count. */
public eggCount: integer;
constructor(eggCount: number) {
super(EggEventType.EGG_COUNT_CHANGED);
this.eggCount = eggCount;
}
}

View File

@ -19,7 +19,7 @@ import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability"; import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
import Pokemon from "./pokemon"; import Pokemon from "./pokemon";
import * as Overrides from "../overrides"; import * as Overrides from "../overrides";
import { WeatherChangedEvent, TerrainChangedEvent, TagAddedEvent, TagRemovedEvent } from "./arena-events"; import { WeatherChangedEvent, TerrainChangedEvent, TagAddedEvent, TagRemovedEvent } from "./events/arena";
export class Arena { export class Arena {
public scene: BattleScene; public scene: BattleScene;

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "Wähle die gewünschte Attacke.", "selectMoveSwapWith": "Wähle die gewünschte Attacke.",
"unlockPassive": "Passiv-Skill freischalten", "unlockPassive": "Passiv-Skill freischalten",
"reduceCost": "Preis reduzieren", "reduceCost": "Preis reduzieren",
"cycleShiny": "R: Schillernd Ja/Nein", "cycleShiny": ": Schillernd",
"cycleForm": "F: Form ändern", "cycleForm": ": Form",
"cycleGender": "G: Geschlecht ändern", "cycleGender": ": Geschlecht",
"cycleAbility": "E: Fähigkeit ändern", "cycleAbility": ": Fähigkeit",
"cycleNature": "N: Wesen Ändern", "cycleNature": ": Wesen",
"cycleVariant": "V: Seltenheit ändern", "cycleVariant": ": Seltenheit",
"enablePassive": "Passiv-Skill aktivieren", "enablePassive": "Passiv-Skill aktivieren",
"disablePassive": "Passiv-Skill deaktivieren", "disablePassive": "Passiv-Skill deaktivieren",
"locked": "Gesperrt", "locked": "Gesperrt",

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "Select a move to swap with", "selectMoveSwapWith": "Select a move to swap with",
"unlockPassive": "Unlock Passive", "unlockPassive": "Unlock Passive",
"reduceCost": "Reduce Cost", "reduceCost": "Reduce Cost",
"cycleShiny": ": Cycle Shiny", "cycleShiny": ": Shiny",
"cycleForm": ": Cycle Form", "cycleForm": ": Form",
"cycleGender": ": Cycle Gender", "cycleGender": ": Gender",
"cycleAbility": ": Cycle Ability", "cycleAbility": ": Ability",
"cycleNature": ": Cycle Nature", "cycleNature": ": Nature",
"cycleVariant": ": Cycle Variant", "cycleVariant": ": Variant",
"enablePassive": "Enable Passive", "enablePassive": "Enable Passive",
"disablePassive": "Disable Passive", "disablePassive": "Disable Passive",
"locked": "Locked", "locked": "Locked",

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "Elige el movimiento que sustituirá a", "selectMoveSwapWith": "Elige el movimiento que sustituirá a",
"unlockPassive": "Añadir Pasiva", "unlockPassive": "Añadir Pasiva",
"reduceCost": "Reducir Coste", "reduceCost": "Reducir Coste",
"cycleShiny": ": Cambiar Shiny", "cycleShiny": ": Shiny",
"cycleForm": ": Cambiar Forma", "cycleForm": ": Forma",
"cycleGender": ": Cambiar Género", "cycleGender": ": Género",
"cycleAbility": ": Cambiar Habilidad", "cycleAbility": ": Habilidad",
"cycleNature": ": Cambiar Naturaleza", "cycleNature": ": Naturaleza",
"cycleVariant": ": Cambiar Variante", "cycleVariant": ": Variante",
"enablePassive": "Activar Pasiva", "enablePassive": "Activar Pasiva",
"disablePassive": "Desactivar Pasiva", "disablePassive": "Desactivar Pasiva",
"locked": "Bloqueado", "locked": "Bloqueado",

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "Seleziona una mossa da scambiare con", "selectMoveSwapWith": "Seleziona una mossa da scambiare con",
"unlockPassive": "Sblocca Passiva", "unlockPassive": "Sblocca Passiva",
"reduceCost": "Riduci Costo", "reduceCost": "Riduci Costo",
"cycleShiny": ": Alterna Shiny", "cycleShiny": ": Shiny",
"cycleForm": ": Alterna Forma", "cycleForm": ": Forma",
"cycleGender": ": Alterna Sesso", "cycleGender": ": Sesso",
"cycleAbility": ": Alterna Abilità", "cycleAbility": ": Abilità",
"cycleNature": ": Alterna Natura", "cycleNature": ": Natura",
"cycleVariant": ": Alterna Variante", "cycleVariant": ": Variante",
"enablePassive": "Attiva Passiva", "enablePassive": "Attiva Passiva",
"disablePassive": "Disattiva Passiva", "disablePassive": "Disattiva Passiva",
"locked": "Bloccato", "locked": "Bloccato",

View File

@ -171,98 +171,98 @@ export const PGMachv: AchievementTranslationEntries = {
}, },
"MONO_GEN_ONE": { "MONO_GEN_ONE": {
name: "The Original Rival", name: "근본 라이벌",
description: "Complete the generation one only challenge.", description: "1세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_TWO": { "MONO_GEN_TWO": {
name: "Generation 1.5", name: "이거 1.5세대죠?",
description: "Complete the generation two only challenge.", description: "2세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_THREE": { "MONO_GEN_THREE": {
name: "Too much water?", name: "Too much water?",
description: "Complete the generation three only challenge.", description: "3세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_FOUR": { "MONO_GEN_FOUR": {
name: "Is she really the hardest?", name: "난천이 진짜 최강인가요?",
description: "Complete the generation four only challenge.", description: "4세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_FIVE": { "MONO_GEN_FIVE": {
name: "All Original", name: "100% 오리지널!",
description: "Complete the generation five only challenge.", description: "5세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_SIX": { "MONO_GEN_SIX": {
name: "Almost Royalty", name: "크루아상 안에 뭐 들었나요?",
description: "Complete the generation six only challenge.", description: "6세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_SEVEN": { "MONO_GEN_SEVEN": {
name: "Only Technically", name: "기술적으로는…",
description: "Complete the generation seven only challenge.", description: "7세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_EIGHT": { "MONO_GEN_EIGHT": {
name: "A Champion Time!", name: "챔피언 타임!",
description: "Complete the generation eight only challenge.", description: "8세대 챌린지 모드 클리어.",
}, },
"MONO_GEN_NINE": { "MONO_GEN_NINE": {
name: "She was going easy on you", name: "걔, 봐 준 거야",
description: "Complete the generation nine only challenge.", description: "9세대 챌린지 모드 클리어.",
}, },
"MonoType": { "MonoType": {
description: "Complete the {{type}} monotype challenge.", description: "{{type}} 타입 챌린지 모드 클리어.",
}, },
"MONO_NORMAL": { "MONO_NORMAL": {
name: "Mono NORMAL", name: "심플한 것이 가장 강한 것",
}, },
"MONO_FIGHTING": { "MONO_FIGHTING": {
name: "I Know Kung Fu", name: "태권도 할 줄 알아요",
}, },
"MONO_FLYING": { "MONO_FLYING": {
name: "Mono FLYING", name: "추락하는 것은 날개가 있다",
}, },
"MONO_POISON": { "MONO_POISON": {
name: "Kanto's Favourite", name: "관동 지방 최애 타입",
}, },
"MONO_GROUND": { "MONO_GROUND": {
name: "Mono GROUND", name: "전기 안 통해요",
}, },
"MONO_ROCK": { "MONO_ROCK": {
name: "Brock Hard", name: "웅골참",
}, },
"MONO_BUG": { "MONO_BUG": {
name: "Sting Like A Beedrill", name: "독침붕처럼 쏴라",
}, },
"MONO_GHOST": { "MONO_GHOST": {
name: "Who you gonna call?", name: "누굴 부를 거야?",
}, },
"MONO_STEEL": { "MONO_STEEL": {
name: "Mono STEEL", name: "강철 심장",
}, },
"MONO_FIRE": { "MONO_FIRE": {
name: "Mono FIRE", name: "불타오르네",
}, },
"MONO_WATER": { "MONO_WATER": {
name: "When It Rains, It Pours", name: "물 들어올 때 노 젓기",
}, },
"MONO_GRASS": { "MONO_GRASS": {
name: "Mono GRASS", name: "초록은 동색",
}, },
"MONO_ELECTRIC": { "MONO_ELECTRIC": {
name: "Mono ELECTRIC", name: "찌릿찌릿",
}, },
"MONO_PSYCHIC": { "MONO_PSYCHIC": {
name: "Mono PSYCHIC", name: "1세대 최강",
}, },
"MONO_ICE": { "MONO_ICE": {
name: "Mono ICE", name: "얼음땡",
}, },
"MONO_DRAGON": { "MONO_DRAGON": {
name: "Mono DRAGON", name: "용용 죽겠지",
}, },
"MONO_DARK": { "MONO_DARK": {
name: "It's just a phase", name: "어둠의 다크",
}, },
"MONO_FAIRY": { "MONO_FAIRY": {
name: "Mono FAIRY", name: "설마 자시안으로?",
}, },
} as const; } as const;

View File

@ -58,5 +58,7 @@ export const battle: SimpleTranslationEntries = {
"ivScannerUseQuestion": "{{pokemonName}}에게 개체값탐지기를 사용하시겠습니까?", "ivScannerUseQuestion": "{{pokemonName}}에게 개체값탐지기를 사용하시겠습니까?",
"wildPokemonWithAffix": "야생 {{pokemonName}}", "wildPokemonWithAffix": "야생 {{pokemonName}}",
"foePokemonWithAffix": "상대 {{pokemonName}}", "foePokemonWithAffix": "상대 {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}}의 {{moveName}}!" "useMove": "{{pokemonNameWithAffix}}의 {{moveName}}!",
"drainMessage": "{{pokemonName}}[[로]]부터\n체력을 흡수했다!",
"regainHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!"
} as const; } as const;

View File

@ -383,6 +383,186 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "내가 뱃멀미가 나는 것 같군…" 3: "내가 뱃멀미가 나는 것 같군…"
}, },
}, },
"rocket_grunt": {
"encounter": {
1: "Prepare for trouble!"
},
"victory": {
1: "Team Rocket blasting off again!"
},
},
"magma_grunt": {
"encounter": {
1: " If you get in the way of Team Magma, dont expect any mercy!"
},
"victory": {
1: "Huh? I lost?!"
},
},
"aqua_grunt": {
"encounter": {
1: "No one who crosses Team Aqua gets any mercy, not even kids!"
},
"victory": {
1: "You're kidding me!"
},
},
"galactic_grunt": {
"encounter": {
1: "Don't mess with Team Galactic!"
},
"victory": {
1: "Shut down..."
},
},
"plasma_grunt": {
"encounter": {
1: "We won't tolerate people who have different ideas!"
},
"victory": {
1: "Plasmaaaaaaaaa!"
},
},
"flare_grunt": {
"encounter": {
1: "Fashion is most important to us!"
},
"victory": {
1: "The future doesn't look bright for me."
},
},
"rocket_boss_giovanni_1": {
"encounter": {
1: "So! I must say, I am impressed you got here!"
},
"victory": {
1: "WHAT! This cannot be!"
},
"defeat": {
1: "Mark my words. Not being able to measure your own strength shows that you are still a child."
}
},
"rocket_boss_giovanni_2": {
"encounter": {
1: "My old associates need me... Are you going to get in my way?"
},
"victory": {
1: "How is this possible...?\nThe precious dream of Team Rocket has become little more than an illusion..."
},
"defeat": {
1: "Team Rocket will be reborn again, and I will rule the world!"
}
},
"magma_boss_maxie_1": {
"encounter": {
1: "I will bury you by my own hand. I hope you appreciate this honor!"
},
"victory": {
1: "Ugh! You are... quite capable...\nI fell behind, but only by an inch..."
},
"defeat": {
1: "Team Magma will prevail!"
}
},
"magma_boss_maxie_2": {
"encounter": {
1: "You are the final obstacle remaining between me and my goals.\nBrace yourself for my ultimate attack! Fuhahaha!"
},
"victory": {
1: "This... This is not.. Ngh..."
},
"defeat": {
1: "And now... I will transform this planet to a land ideal for humanity."
}
},
"aqua_boss_archie_1": {
"encounter": {
1: "I'm leader of Team Aqua, so I'm afraid it's the rope's end for you."
},
"victory": {
1: "Let's meet again somewhere. I'll be sure to remember that face."
},
"defeat": {
1: "Brilliant! My team won't hold back now!"
}
},
"aqua_boss_archie_2": {
"encounter": {
1: "I've been waiting so long for this day to come.\nThis is the true power of my team!"
},
"victory": {
1: "Like I figured..."
},
"defeat": {
1: "I'll return everything in this world to its original, pure state!!"
}
},
"galactic_boss_cyrus_1": {
"encounter": {
1: "You were compelled to come here by such vacuous sentimentality\nI will make you regret paying heed to your heart!"
},
"victory": {
1: "Interesting. And quite curious."
},
"defeat": {
1: "I will create my new world..."
}
},
"galactic_boss_cyrus_2": {
"encounter": {
1: "So we meet again. It seems our fates have become intertwined.\nBut here and now, I will finally break that bond!"
},
"victory": {
1: "How? How? HOW?!"
},
"defeat": {
1: "Farewell."
}
},
"plasma_boss_ghetsis_1": {
"encounter": {
1: "I won't allow anyone to stop me! No matter who does what!"
},
"victory": {
1: "How can this be? I'm the creator of Team Plasma! I'm perfect!"
},
"defeat": {
1: "I am the perfect ruler of a perfect new world! Mwa ha ha!"
}
},
"plasma_boss_ghetsis_2": {
"encounter": {
1: "Come now! I want to see your face at the moment you lose all hope!"
},
"victory": {
1: "My calculations... No! My careful schemes! The world should be mine!"
},
"defeat": {
1: "Kyurem! Use Absofusion!"
}
},
"flare_boss_lysandre_1": {
"encounter": {
1: "Do you want to stop me? Show me in battle."
},
"victory": {
1: "You are here to stop me. But I ask you to wait. "
},
"defeat": {
1: "Pokemon...Shall no longer exist."
}
},
"flare_boss_lysandre_2": {
"encounter": {
1: "The future you want, or the future I want... Let us see which one is more deserving, shall we?"
},
"victory": {
1: "Whaugh!"
},
"defeat": {
1: "Fools with no vision will continue to befoul this beautiful world."
}
},
"brock": { "brock": {
"encounter": { "encounter": {
1: "내 전문인 바위 타입 포켓몬으로 널 쓰러뜨려줄게! 덤벼!", 1: "내 전문인 바위 타입 포켓몬으로 널 쓰러뜨려줄게! 덤벼!",

View File

@ -7,5 +7,6 @@ export const pokemonInfoContainer: SimpleTranslationEntries = {
"nature": "성격:", "nature": "성격:",
"epic": "에픽", "epic": "에픽",
"rare": "레어", "rare": "레어",
"common": "커먼" "common": "커먼",
"form": "폼:"
} as const; } as const;

View File

@ -31,11 +31,11 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"unlockPassive": "패시브 해금", "unlockPassive": "패시브 해금",
"reduceCost": "코스트 줄이기", "reduceCost": "코스트 줄이기",
"cycleShiny": ": 특별한 색", "cycleShiny": ": 특별한 색",
"cycleForm": ": 폼 체인지", "cycleForm": ": 폼",
"cycleGender": ": 암수 전환", "cycleGender": ": 암수",
"cycleAbility": ": 특성 전환", "cycleAbility": ": 특성",
"cycleNature": ": 성격 전환", "cycleNature": ": 성격",
"cycleVariant": ": 색상 전환", "cycleVariant": ": 색상",
"enablePassive": "패시브 활성화", "enablePassive": "패시브 활성화",
"disablePassive": "패시브 비활성화", "disablePassive": "패시브 비활성화",
"locked": "잠김", "locked": "잠김",

View File

@ -13,6 +13,12 @@ export const titles: SimpleTranslationEntries = {
"rival": "라이벌", "rival": "라이벌",
"professor": "박사", "professor": "박사",
"frontier_brain": "프런티어 브레인", "frontier_brain": "프런티어 브레인",
"rocket_boss": "로켓단 보스",
"magma_boss": "마그마단 보스",
"aqua_boss": "아쿠아단 보스",
"galactic_boss": "갤럭시단 보스",
"plasma_boss": "플라스마단 보스",
"flare_boss": "플레어단 보스",
// Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc. // Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc.
} as const; } as const;
@ -48,7 +54,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"depot_agent": "역무원", "depot_agent": "역무원",
"doctor": "의사", "doctor": "의사",
"doctor_female": "간호사", // doctor_f.png 파일이 간호사 "doctor_female": "간호사", // doctor_f.png 파일이 간호사
"firebreather": "Firebreather", "firebreather": "불놀이꾼",
"fisherman": "낚시꾼", "fisherman": "낚시꾼",
"fisherman_female": "낚시꾼", "fisherman_female": "낚시꾼",
"gentleman": "신사", "gentleman": "신사",
@ -118,7 +124,19 @@ export const trainerClasses: SimpleTranslationEntries = {
"worker": "작업원", "worker": "작업원",
"worker_female": "작업원", "worker_female": "작업원",
"workers": "작업원", "workers": "작업원",
"youngster": "반바지 꼬마" "youngster": "반바지 꼬마",
"rocket_grunt": "로켓단 조무래기",
"rocket_grunt_female": "로켓단 조무래기",
"magma_grunt": "마그마단 조무래기",
"magma_grunt_female": "마그마단 조무래기",
"aqua_grunt": "아쿠아단 조무래기",
"aqua_grunt_female": "아쿠아단 조무래기",
"galactic_grunt": "갤럭시단 조무래기",
"galactic_grunt_female": "갤럭시단 조무래기",
"plasma_grunt": "플라스마단 조무래기",
"plasma_grunt_female": "플라스마단 조무래기",
"flare_grunt": "플레어단 조무래기",
"flare_grunt_female": "플레어단 조무래기",
} as const; } as const;
// Names of special trainers like gym leaders, elite four, and the champion // Names of special trainers like gym leaders, elite four, and the champion
@ -247,6 +265,11 @@ export const trainerNames: SimpleTranslationEntries = {
"leon": "단델", "leon": "단델",
"rival": "핀", "rival": "핀",
"rival_female": "아이비", "rival_female": "아이비",
"maxie": "마적",
"archie": "아강",
"cyrus": "태홍",
"ghetsis": "게치스",
"lysandre": "플라드리",
// Double Names // Double Names
"blue_red_double": "그린 & 레드", "blue_red_double": "그린 & 레드",

View File

@ -23,7 +23,8 @@ export const tutorial: SimpleTranslationEntries = {
statChange: `포켓몬은 교체하지 않으면 다음 전투에서도 능력치 변화가 유지됩니다. statChange: `포켓몬은 교체하지 않으면 다음 전투에서도 능력치 변화가 유지됩니다.
$대신 . $대신 .
$C Shift를 . $C Shift를 .
$V를 .`, $V를 .
$단, .`,
selectItem: `전투가 끝날때마다 무작위 아이템 3개 중 하나를 선택하여 얻습니다. selectItem: `전투가 끝날때마다 무작위 아이템 3개 중 하나를 선택하여 얻습니다.
$종류는 , , . $종류는 , , .

View File

@ -3,266 +3,266 @@ import { AchievementTranslationEntries } from "#app/plugins/i18n.js";
// Achievement translations for the when the player character is male // Achievement translations for the when the player character is male
export const PGMachv: AchievementTranslationEntries = { export const PGMachv: AchievementTranslationEntries = {
"Achievements": { "Achievements": {
name: "Achievements", name: "成就",
}, },
"Locked": { "Locked": {
name: "Locked", name: "未解锁",
}, },
"MoneyAchv": { "MoneyAchv": {
description: "Accumulate a total of ₽{{moneyAmount}}", description: "累计获得 ₽{{moneyAmount}}",
}, },
"10K_MONEY": { "10K_MONEY": {
name: "Money Haver", name: "小有积蓄",
}, },
"100K_MONEY": { "100K_MONEY": {
name: "Rich", name: "富裕",
}, },
"1M_MONEY": { "1M_MONEY": {
name: "Millionaire", name: "百万富翁",
}, },
"10M_MONEY": { "10M_MONEY": {
name: "One Percenter", name: "百分之一",
}, },
"DamageAchv": { "DamageAchv": {
description: "Inflict {{damageAmount}} damage in one hit", description: "在单次攻击中造成 {{damageAmount}} 点伤害",
}, },
"250_DMG": { "250_DMG": {
name: "Hard Hitter", name: "强力攻击者",
}, },
"1000_DMG": { "1000_DMG": {
name: "Harder Hitter", name: "更强力攻击者",
}, },
"2500_DMG": { "2500_DMG": {
name: "That's a Lotta Damage!", name: "伤害真高!",
}, },
"10000_DMG": { "10000_DMG": {
name: "One Punch Man", name: "一拳超人",
}, },
"HealAchv": { "HealAchv": {
description: "Heal {{healAmount}} {{HP}} at once with a move, ability, or held item", description: "通过技能、能力或携带的道具一次性治疗 {{healAmount}} {{HP}}点",
}, },
"250_HEAL": { "250_HEAL": {
name: "Novice Healer", name: "新手治疗师",
}, },
"1000_HEAL": { "1000_HEAL": {
name: "Big Healer", name: "高阶治疗师",
}, },
"2500_HEAL": { "2500_HEAL": {
name: "Cleric", name: "牧师",
}, },
"10000_HEAL": { "10000_HEAL": {
name: "Recovery Master", name: "恢复大师",
}, },
"LevelAchv": { "LevelAchv": {
description: "Level up a Pokémon to Lv{{level}}", description: "将一只宝可梦提升到 Lv{{level}}",
}, },
"LV_100": { "LV_100": {
name: "But Wait, There's More!", name: "不止于此, 还有更多!",
}, },
"LV_250": { "LV_250": {
name: "Elite", name: "精英",
}, },
"LV_1000": { "LV_1000": {
name: "To Go Even Further Beyond", name: "超越极限",
}, },
"RibbonAchv": { "RibbonAchv": {
description: "Accumulate a total of {{ribbonAmount}} Ribbons", description: "累计获得 {{ribbonAmount}} 个勋章",
}, },
"10_RIBBONS": { "10_RIBBONS": {
name: "Pokémon League Champion", name: "宝可梦联赛冠军",
}, },
"25_RIBBONS": { "25_RIBBONS": {
name: "Great League Champion", name: "超级联赛冠军",
}, },
"50_RIBBONS": { "50_RIBBONS": {
name: "Ultra League Champion", name: "至尊联赛冠军",
}, },
"75_RIBBONS": { "75_RIBBONS": {
name: "Rogue League Champion", name: "肉鸽联赛冠军",
}, },
"100_RIBBONS": { "100_RIBBONS": {
name: "Master League Champion", name: "大师联赛冠军",
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_BATTLE_STAT": {
name: "Teamwork", name: "团队协作",
description: "Baton pass to another party member with at least one stat maxed out", description: "Baton pass to another party member with at least one stat maxed out",
}, },
"MAX_FRIENDSHIP": { "MAX_FRIENDSHIP": {
name: "Friendmaxxing", name: "亲密度最大化",
description: "Reach max friendship on a Pokémon", description: "使一只宝可梦的亲密度达到最大值",
}, },
"MEGA_EVOLVE": { "MEGA_EVOLVE": {
name: "Megamorph", name: "Mega进化",
description: "Mega evolve a Pokémon", description: "Mega进化一只宝可梦",
}, },
"GIGANTAMAX": { "GIGANTAMAX": {
name: "Absolute Unit", name: "极巨化",
description: "Gigantamax a Pokémon", description: "极巨化一只宝可梦",
}, },
"TERASTALLIZE": { "TERASTALLIZE": {
name: "STAB Enthusiast", name: "太晶狂热者",
description: "Terastallize a Pokémon", description: "太晶化一只宝可梦",
}, },
"STELLAR_TERASTALLIZE": { "STELLAR_TERASTALLIZE": {
name: "The Hidden Type", name: "隐藏属性",
description: "Stellar Terastallize a Pokémon", description: "星晶化一只宝可梦",
}, },
"SPLICE": { "SPLICE": {
name: "Infinite Fusion", name: "无限融合",
description: "Splice two Pokémon together with DNA Splicers", description: "使用基因之楔将两只宝可梦融合在一起",
}, },
"MINI_BLACK_HOLE": { "MINI_BLACK_HOLE": {
name: "A Hole Lot of Items", name: "巨量道具",
description: "Acquire a Mini Black Hole", description: "获得一个迷你黑洞",
}, },
"CATCH_MYTHICAL": { "CATCH_MYTHICAL": {
name: "Mythical", name: "幻之宝可梦",
description: "Catch a mythical Pokémon", description: "捕捉一只幻之宝可梦",
}, },
"CATCH_SUB_LEGENDARY": { "CATCH_SUB_LEGENDARY": {
name: "(Sub-)Legendary", name: "准-传说宝可梦",
description: "Catch a sub-legendary Pokémon", description: "捕捉一只准传说宝可梦",
}, },
"CATCH_LEGENDARY": { "CATCH_LEGENDARY": {
name: "Legendary", name: "传说宝可梦",
description: "Catch a legendary Pokémon", description: "捕捉一只传说宝可梦",
}, },
"SEE_SHINY": { "SEE_SHINY": {
name: "Shiny", name: "异色宝可梦",
description: "Find a shiny Pokémon in the wild", description: "在野外找到一只异色宝可梦",
}, },
"SHINY_PARTY": { "SHINY_PARTY": {
name: "That's Dedication", name: "全队异色",
description: "Have a full party of shiny Pokémon", description: "拥有一支由异色宝可梦组成的满员队伍",
}, },
"HATCH_MYTHICAL": { "HATCH_MYTHICAL": {
name: "Mythical Egg", name: "幻之蛋",
description: "Hatch a mythical Pokémon from an egg", description: "从蛋中孵化出一只幻之宝可梦",
}, },
"HATCH_SUB_LEGENDARY": { "HATCH_SUB_LEGENDARY": {
name: "Sub-Legendary Egg", name: "准-传说蛋",
description: "Hatch a sub-legendary Pokémon from an egg", description: "从蛋中孵化出一只准传说宝可梦",
}, },
"HATCH_LEGENDARY": { "HATCH_LEGENDARY": {
name: "Legendary Egg", name: "传说蛋",
description: "Hatch a legendary Pokémon from an egg", description: "从蛋中孵化出一只准-传说宝可梦",
}, },
"HATCH_SHINY": { "HATCH_SHINY": {
name: "Shiny Egg", name: "异色蛋",
description: "Hatch a shiny Pokémon from an egg", description: "从蛋中孵化出一只异色宝可梦",
}, },
"HIDDEN_ABILITY": { "HIDDEN_ABILITY": {
name: "Hidden Potential", name: "隐藏潜力",
description: "Catch a Pokémon with a hidden ability", description: "捕捉一只拥有隐藏特性的宝可梦",
}, },
"PERFECT_IVS": { "PERFECT_IVS": {
name: "Certificate of Authenticity", name: "完美个体",
description: "Get perfect IVs on a Pokémon", description: "获得一只拥有完美个体值的宝可梦",
}, },
"CLASSIC_VICTORY": { "CLASSIC_VICTORY": {
name: "Undefeated", name: "经典无敌",
description: "Beat the game in classic mode", description: "在经典模式中通关游戏",
}, },
"MONO_GEN_ONE": { "MONO_GEN_ONE": {
name: "The Original Rival", name: "初代劲敌",
description: "Complete the generation one only challenge.", description: "完成仅限第一世代的挑战.",
}, },
"MONO_GEN_TWO": { "MONO_GEN_TWO": {
name: "Generation 1.5", name: "1.5世代",
description: "Complete the generation two only challenge.", description: "完成仅限第二世代的挑战.",
}, },
"MONO_GEN_THREE": { "MONO_GEN_THREE": {
name: "Too much water?", name: "水太多了?",
description: "Complete the generation three only challenge.", description: "完成仅限第三世代的挑战.",
}, },
"MONO_GEN_FOUR": { "MONO_GEN_FOUR": {
name: "Is she really the hardest?", name: "她真的是最难的吗?",
description: "Complete the generation four only challenge.", description: "完成仅限第四世代的挑战.",
}, },
"MONO_GEN_FIVE": { "MONO_GEN_FIVE": {
name: "All Original", name: "全为原创",
description: "Complete the generation five only challenge.", description: "完成仅限第五世代的挑战.",
}, },
"MONO_GEN_SIX": { "MONO_GEN_SIX": {
name: "Almost Royalty", name: "近乎贵族",
description: "Complete the generation six only challenge.", description: "完成仅限第六世代的挑战.",
}, },
"MONO_GEN_SEVEN": { "MONO_GEN_SEVEN": {
name: "Only Technically", name: "仅技术上(可行)",
description: "Complete the generation seven only challenge.", description: "完成仅限第七世代的挑战.",
}, },
"MONO_GEN_EIGHT": { "MONO_GEN_EIGHT": {
name: "A Champion Time!", name: "冠军时刻!",
description: "Complete the generation eight only challenge.", description: "完成仅限第八世代的挑战.",
}, },
"MONO_GEN_NINE": { "MONO_GEN_NINE": {
name: "She was going easy on you", name: "她对你手下留情了",
description: "Complete the generation nine only challenge.", description: "完成仅限第九世代的挑战.",
}, },
"MonoType": { "MonoType": {
description: "Complete the {{type}} monotype challenge.", description: "完成 {{type}} 单属性挑战.",
}, },
"MONO_NORMAL": { "MONO_NORMAL": {
name: "Mono NORMAL", name: "Mono 一般",
}, },
"MONO_FIGHTING": { "MONO_FIGHTING": {
name: "I Know Kung Fu", name: "功夫高手",
}, },
"MONO_FLYING": { "MONO_FLYING": {
name: "Mono FLYING", name: "Mono 飞行",
}, },
"MONO_POISON": { "MONO_POISON": {
name: "Kanto's Favourite", name: "关东的最爱",
}, },
"MONO_GROUND": { "MONO_GROUND": {
name: "Mono GROUND", name: "Mono 地面",
}, },
"MONO_ROCK": { "MONO_ROCK": {
name: "Brock Hard", name: "坚如磐石",
}, },
"MONO_BUG": { "MONO_BUG": {
name: "Sting Like A Beedrill", name: "如大针蜂般刺痛",
}, },
"MONO_GHOST": { "MONO_GHOST": {
name: "Who you gonna call?", name: "你将要召唤谁?",
}, },
"MONO_STEEL": { "MONO_STEEL": {
name: "Mono STEEL", name: "Mono ",
}, },
"MONO_FIRE": { "MONO_FIRE": {
name: "Mono FIRE", name: "Mono ",
}, },
"MONO_WATER": { "MONO_WATER": {
name: "When It Rains, It Pours", name: "当雨来临,倾盆而下",
}, },
"MONO_GRASS": { "MONO_GRASS": {
name: "Mono GRASS", name: "Mono ",
}, },
"MONO_ELECTRIC": { "MONO_ELECTRIC": {
name: "Mono ELECTRIC", name: "Mono ",
}, },
"MONO_PSYCHIC": { "MONO_PSYCHIC": {
name: "Mono PSYCHIC", name: "Mono 超能力",
}, },
"MONO_ICE": { "MONO_ICE": {
name: "Mono ICE", name: "Mono ",
}, },
"MONO_DRAGON": { "MONO_DRAGON": {
name: "Mono DRAGON", name: "Mono ",
}, },
"MONO_DARK": { "MONO_DARK": {
name: "It's just a phase", name: "这只是一个阶段",
}, },
"MONO_FAIRY": { "MONO_FAIRY": {
name: "Mono FAIRY", name: "Mono 妖精",
}, },
} as const; } as const;

View File

@ -23,7 +23,7 @@ export const challenges: SimpleTranslationEntries = {
"singleGeneration.desc.7": "你只能使用第七世代的宝可梦", "singleGeneration.desc.7": "你只能使用第七世代的宝可梦",
"singleGeneration.value.8": "第八世代", "singleGeneration.value.8": "第八世代",
"singleGeneration.desc.8": "你只能使用第八世代的宝可梦", "singleGeneration.desc.8": "你只能使用第八世代的宝可梦",
"singleGeneration.value.9": "第世代", "singleGeneration.value.9": "第世代",
"singleGeneration.desc.9": "你只能使用第九世代的宝可梦", "singleGeneration.desc.9": "你只能使用第九世代的宝可梦",
"singleType.name": "单属性", "singleType.name": "单属性",
"singleType.value.0": "关闭", "singleType.value.0": "关闭",
@ -39,7 +39,7 @@ export const challenges: SimpleTranslationEntries = {
"singleType.value.5": "地面", "singleType.value.5": "地面",
"singleType.desc.5": "你只能使用地面属性的宝可梦", "singleType.desc.5": "你只能使用地面属性的宝可梦",
"singleType.value.6": "岩石", "singleType.value.6": "岩石",
"singleType.desc.6": "你只能使用所选属性的宝可梦", "singleType.desc.6": "你只能使用岩石属性的宝可梦",
"singleType.value.7": "虫", "singleType.value.7": "虫",
"singleType.desc.7": "你只能使用虫属性的宝可梦", "singleType.desc.7": "你只能使用虫属性的宝可梦",
"singleType.value.8": "幽灵", "singleType.value.8": "幽灵",

File diff suppressed because it is too large Load Diff

View File

@ -389,42 +389,42 @@ export const modifierType: ModifierTypeTranslationEntries = {
"CHILL_DRIVE": "冰冻卡带", "CHILL_DRIVE": "冰冻卡带",
"DOUSE_DRIVE": "水流卡带", "DOUSE_DRIVE": "水流卡带",
"FIST_PLATE": "拳石板", "FIST_PLATE": "拳石板",
"SKY_PLATE": "天石板", "SKY_PLATE": "天石板",
"TOXIC_PLATE": "毒石板", "TOXIC_PLATE": "毒石板",
"EARTH_PLATE": "大地石板", "EARTH_PLATE": "大地石板",
"STONE_PLATE": "岩石石板", "STONE_PLATE": "岩石石板",
"INSECT_PLATE": "玉石板", "INSECT_PLATE": "玉石板",
"SPOOKY_PLATE": "妖怪石板", "SPOOKY_PLATE": "妖怪石板",
"IRON_PLATE": "鋼鐵石板", "IRON_PLATE": "钢铁石板",
"FLAME_PLATE": "火球石板", "FLAME_PLATE": "火球石板",
"SPLASH_PLATE": "水滴石板", "SPLASH_PLATE": "水滴石板",
"MEADOW_PLATE": "碧石板", "MEADOW_PLATE": "碧绿石板",
"ZAP_PLATE": "雷石板", "ZAP_PLATE": "雷石板",
"MIND_PLATE": "神奇石板", "MIND_PLATE": "神奇石板",
"ICICLE_PLATE": "冰柱石板", "ICICLE_PLATE": "冰柱石板",
"DRACO_PLATE": "之石板", "DRACO_PLATE": "之石板",
"DREAD_PLATE": "惡顏石板", "DREAD_PLATE": "恶颜石板",
"PIXIE_PLATE": "妖精石板", "PIXIE_PLATE": "妖精石板",
"BLANK_PLATE": "空石板", "BLANK_PLATE": "空石板",
"LEGEND_PLATE": "傳說石板", "LEGEND_PLATE": "传说石板",
"FIGHTING_MEMORY": "戰鬥記憶碟", "FIGHTING_MEMORY": "战斗存储碟",
"FLYING_MEMORY": "飛翔記憶碟", "FLYING_MEMORY": "飞翔存储碟",
"POISON_MEMORY": "毒記憶碟", "POISON_MEMORY": "毒存储碟",
"GROUND_MEMORY": "大地記憶碟", "GROUND_MEMORY": "大地存储碟",
"ROCK_MEMORY": "岩石記憶碟", "ROCK_MEMORY": "岩石存储碟",
"BUG_MEMORY": "蟲子記憶碟", "BUG_MEMORY": "虫子存储碟",
"GHOST_MEMORY": "幽靈記憶碟", "GHOST_MEMORY": "幽灵存储碟",
"STEEL_MEMORY": "鋼鐵記憶碟", "STEEL_MEMORY": "钢铁存储碟",
"FIRE_MEMORY": "火焰記憶碟", "FIRE_MEMORY": "火焰存储碟",
"WATER_MEMORY": "清水記憶碟", "WATER_MEMORY": "清水存储碟",
"GRASS_MEMORY": "青草記憶碟", "GRASS_MEMORY": "青草存储碟",
"ELECTRIC_MEMORY": "電子記憶碟", "ELECTRIC_MEMORY": "电子存储碟",
"PSYCHIC_MEMORY": "精神記憶碟", "PSYCHIC_MEMORY": "精神存储碟",
"ICE_MEMORY": "冰雪記憶碟", "ICE_MEMORY": "冰雪存储碟",
"DRAGON_MEMORY": "龍記憶碟", "DRAGON_MEMORY": "龙存储碟",
"DARK_MEMORY": "黑暗記憶碟", "DARK_MEMORY": "黑暗存储碟",
"FAIRY_MEMORY": "妖精記憶碟", "FAIRY_MEMORY": "妖精存储碟",
"BLANK_MEMORY": "空白記憶碟", "BLANK_MEMORY": "空白存储碟",
}, },
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = { export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out", "SEND_OUT": "上场",
"SUMMARY": "Summary", "SUMMARY": "概要",
"CANCEL": "Cancel", "CANCEL": "取消",
"RELEASE": "Release", "RELEASE": "放生",
"APPLY": "Apply", "APPLY": "应用",
"TEACH": "Teach" "TEACH": "教授"
} as const; } as const;

View File

@ -2,7 +2,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const saveSlotSelectUiHandler: SimpleTranslationEntries = { export const saveSlotSelectUiHandler: SimpleTranslationEntries = {
"overwriteData": "Overwrite the data in the selected slot?", "overwriteData": "Overwrite the data in the selected slot?",
"loading": "Loading...", "loading": "正在加载中...",
"wave": "Wave", "wave": "Wave",
"lv": "Lv", "lv": "Lv",
"empty": "空", "empty": "空",

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "选择要替换成的招式", "selectMoveSwapWith": "选择要替换成的招式",
"unlockPassive": "解锁被动", "unlockPassive": "解锁被动",
"reduceCost": "降低花费", "reduceCost": "降低花费",
"cycleShiny": ": 切换闪光", "cycleShiny": ": 闪光",
"cycleForm": ": 切换形态", "cycleForm": ": 形态",
"cycleGender": ": 切换性别", "cycleGender": ": 性别",
"cycleAbility": ": 切换特性", "cycleAbility": ": 特性",
"cycleNature": ": 切换性格", "cycleNature": ": 性格",
"cycleVariant": ": 切换变种", "cycleVariant": ": 变种",
"enablePassive": "启用被动", "enablePassive": "启用被动",
"disablePassive": "禁用被动", "disablePassive": "禁用被动",
"locked": "未解锁", "locked": "未解锁",

View File

@ -30,12 +30,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"selectMoveSwapWith": "選擇想要替換成的招式", "selectMoveSwapWith": "選擇想要替換成的招式",
"unlockPassive": "解鎖被動", "unlockPassive": "解鎖被動",
"reduceCost": "降低花費", "reduceCost": "降低花費",
"cycleShiny": ": 切換閃光", "cycleShiny": ": 閃光",
"cycleForm": ": 切換形態", "cycleForm": ": 形態",
"cycleGender": ": 切換性別", "cycleGender": ": 性別",
"cycleAbility": ": 切換特性", "cycleAbility": ": 特性",
"cycleNature": ": 切換性格", "cycleNature": ": 性格",
"cycleVariant": ": 切換變種", "cycleVariant": ": 變種",
"enablePassive": "啟用被動", "enablePassive": "啟用被動",
"disablePassive": "禁用被動", "disablePassive": "禁用被動",
"locked": "未解鎖", "locked": "未解鎖",

View File

@ -150,6 +150,7 @@ Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative; Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems")); document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems"));
document.fonts.load("12px unifont");
let game; let game;

View File

@ -62,7 +62,7 @@ import { Abilities } from "./data/enums/abilities";
import * as Overrides from "./overrides"; import * as Overrides from "./overrides";
import { TextStyle, addTextObject } from "./ui/text"; import { TextStyle, addTextObject } from "./ui/text";
import { Type } from "./data/type"; import { Type } from "./data/type";
import { BerryUsedEvent, EncounterPhaseEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events"; import { BerryUsedEvent, EncounterPhaseEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./events/battle-scene";
import { ExpNotification } from "./enums/exp-notification"; import { ExpNotification } from "./enums/exp-notification";
@ -661,7 +661,14 @@ export abstract class FieldPhase extends BattlePhase {
const enemyField = this.scene.getEnemyField().filter(p => p.isActive()) as Pokemon[]; const enemyField = this.scene.getEnemyField().filter(p => p.isActive()) as Pokemon[];
// We shuffle the list before sorting so speed ties produce random results // We shuffle the list before sorting so speed ties produce random results
let orderedTargets: Pokemon[] = Utils.randSeedShuffle(playerField.concat(enemyField)).sort((a: Pokemon, b: Pokemon) => { let orderedTargets: Pokemon[] = playerField.concat(enemyField);
// We seed it with the current turn to prevent an inconsistency where it
// was varying based on how long since you last reloaded
this.scene.executeWithSeedOffset(() => {
orderedTargets = Utils.randSeedShuffle(orderedTargets);
}, this.scene.currentBattle.turn, this.scene.waveSeed);
orderedTargets.sort((a: Pokemon, b: Pokemon) => {
const aSpeed = a?.getBattleStat(Stat.SPD) || 0; const aSpeed = a?.getBattleStat(Stat.SPD) || 0;
const bSpeed = b?.getBattleStat(Stat.SPD) || 0; const bSpeed = b?.getBattleStat(Stat.SPD) || 0;
@ -5184,15 +5191,15 @@ export class EggLapsePhase extends Phase {
return Overrides.IMMEDIATE_HATCH_EGGS_OVERRIDE ? true : --egg.hatchWaves < 1; return Overrides.IMMEDIATE_HATCH_EGGS_OVERRIDE ? true : --egg.hatchWaves < 1;
}); });
let eggsToHatchCount: integer = eggsToHatch.length; let eggCount: integer = eggsToHatch.length;
if (eggsToHatchCount) { if (eggCount) {
this.scene.queueMessage(i18next.t("battle:eggHatching")); this.scene.queueMessage(i18next.t("battle:eggHatching"));
for (const egg of eggsToHatch) { for (const egg of eggsToHatch) {
this.scene.unshiftPhase(new EggHatchPhase(this.scene, egg, eggsToHatchCount)); this.scene.unshiftPhase(new EggHatchPhase(this.scene, egg, eggCount));
if (eggsToHatchCount > 0) { if (eggCount > 0) {
eggsToHatchCount--; eggCount--;
} }
} }

View File

@ -88,50 +88,25 @@ export interface Localizable {
localize(): void; localize(): void;
} }
const alternativeFonts = { const fonts = [
"ko": [ new FontFace("emerald", "url(./fonts/PokePT_Wansung.ttf)"),
new FontFace("emerald", "url(./fonts/PokePT_Wansung.ttf)"), new FontFace("emerald", "url(./fonts/pokemon-emerald-pro.ttf"),
], ];
};
function loadFont(language: string) { function initFonts() {
if (!alternativeFonts[language]) { fonts.forEach((fontFace: FontFace) => {
language = language.split(/[-_/]/)[0]; fontFace.load().then(f => document.fonts.add(f)).catch(e => console.error(e));
}
if (alternativeFonts[language]) {
alternativeFonts[language].forEach((fontFace: FontFace) => {
document.fonts.add(fontFace);
});
const altFontLanguages = Object.keys(alternativeFonts);
altFontLanguages.splice(altFontLanguages.indexOf(language), 0);
}
(Object.values(alternativeFonts)).forEach(fontFaces => {
fontFaces.forEach(fontFace => {
if (fontFace && fontFace.status === "loaded") {
document.fonts.delete(fontFace);
}
});
}); });
} }
export function initI18n(): void { export async function initI18n(): Promise<void> {
// Prevent reinitialization // Prevent reinitialization
if (isInitialized) { if (isInitialized) {
return; return;
} }
isInitialized = true; isInitialized = true;
let lang = "";
if (localStorage.getItem("prLang")) { initFonts();
lang = localStorage.getItem("prLang");
}
loadFont(lang);
i18next.on("languageChanged", lng=> {
loadFont(lng);
});
/** /**
* i18next is a localization library for maintaining and using translation resources. * i18next is a localization library for maintaining and using translation resources.
@ -149,11 +124,16 @@ export function initI18n(): void {
* A: In src/system/settings.ts, add a new case to the Setting.Language switch statement. * A: In src/system/settings.ts, add a new case to the Setting.Language switch statement.
*/ */
i18next.use(LanguageDetector).use(processor).use(new KoreanPostpositionProcessor()).init({ i18next.use(LanguageDetector);
lng: lang, i18next.use(processor);
i18next.use(new KoreanPostpositionProcessor());
await i18next.init({
nonExplicitSupportedLngs: true, nonExplicitSupportedLngs: true,
fallbackLng: "en", fallbackLng: "en",
supportedLngs: ["en", "es", "fr", "it", "de", "zh", "pt", "ko"], supportedLngs: ["en", "es", "fr", "it", "de", "zh", "pt", "ko"],
detection: {
lookupLocalStorage: "prLang"
},
debug: true, debug: true,
interpolation: { interpolation: {
escapeValue: false, escapeValue: false,

View File

@ -32,7 +32,7 @@ import { OutdatedPhase, ReloadSessionPhase } from "#app/phases";
import { Variant, variantData } from "#app/data/variant"; import { Variant, variantData } from "#app/data/variant";
import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./settings/settings-gamepad"; import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./settings/settings-gamepad";
import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard"; import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard";
import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js"; import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/events/arena";
import { Device } from "#app/enums/devices.js"; import { Device } from "#app/enums/devices.js";
import { EnemyAttackStatusEffectChanceModifier } from "../modifier/modifier"; import { EnemyAttackStatusEffectChanceModifier } from "../modifier/modifier";
import { StatusEffect } from "#app/data/status-effect.js"; import { StatusEffect } from "#app/data/status-effect.js";

View File

@ -4,7 +4,7 @@ import BattleScene from "../../battle-scene";
import { hasTouchscreen } from "../../touch-controls"; import { hasTouchscreen } from "../../touch-controls";
import { updateWindowType } from "../../ui/ui-theme"; import { updateWindowType } from "../../ui/ui-theme";
import { PlayerGender } from "#app/data/enums/player-gender"; import { PlayerGender } from "#app/data/enums/player-gender";
import { CandyUpgradeNotificationChangedEvent } from "#app/battle-scene-events.js"; import { CandyUpgradeNotificationChangedEvent } from "../../events/battle-scene";
import { MoneyFormat } from "../../enums/money-format"; import { MoneyFormat } from "../../enums/money-format";
import SettingsUiHandler from "#app/ui/settings/settings-ui-handler"; import SettingsUiHandler from "#app/ui/settings/settings-ui-handler";
import { EaseType } from "#app/ui/enums/ease-type.js"; import { EaseType } from "#app/ui/enums/ease-type.js";

View File

@ -162,20 +162,13 @@ export class UiInputs {
} }
case Mode.TITLE: case Mode.TITLE:
case Mode.COMMAND: case Mode.COMMAND:
case Mode.FIGHT: case Mode.MODIFIER_SELECT:
case Mode.BALL:
case Mode.TARGET_SELECT:
case Mode.SAVE_SLOT:
case Mode.PARTY:
case Mode.SUMMARY:
case Mode.STARTER_SELECT:
case Mode.OPTION_SELECT:
this.scene.ui.setOverlayMode(Mode.MENU); this.scene.ui.setOverlayMode(Mode.MENU);
break; break;
case Mode.CONFIRM: case Mode.STARTER_SELECT:
this.buttonTouch();
break;
case Mode.MENU: case Mode.MENU:
case Mode.SETTINGS:
case Mode.ACHIEVEMENTS:
this.scene.ui.revertMode(); this.scene.ui.revertMode();
this.scene.playSound("select"); this.scene.playSound("select");
break; break;

View File

@ -4,8 +4,8 @@ import { ArenaTagSide } from "#app/data/arena-tag.js";
import { WeatherType } from "#app/data/weather.js"; import { WeatherType } from "#app/data/weather.js";
import { TerrainType } from "#app/data/terrain.js"; import { TerrainType } from "#app/data/terrain.js";
import { addWindow, WindowVariant } from "./ui-theme"; import { addWindow, WindowVariant } from "./ui-theme";
import { ArenaEvent, ArenaEventType, TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js"; import { ArenaEvent, ArenaEventType, TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/field/events/arena";
import { BattleSceneEventType, TurnEndEvent } from "#app/battle-scene-events.js"; import { BattleSceneEventType, TurnEndEvent } from "../events/battle-scene";
import { ArenaTagType } from "#app/data/enums/arena-tag-type.js"; import { ArenaTagType } from "#app/data/enums/arena-tag-type.js";
import TimeOfDayWidget from "./time-of-day-widget"; import TimeOfDayWidget from "./time-of-day-widget";
import * as Utils from "../utils"; import * as Utils from "../utils";

View File

@ -4,7 +4,7 @@ import * as Utils from "../utils";
import BattleScene from "#app/battle-scene.js"; import BattleScene from "#app/battle-scene.js";
import { UiTheme } from "#app/enums/ui-theme.js"; import { UiTheme } from "#app/enums/ui-theme.js";
import Move from "#app/data/move.js"; import Move from "#app/data/move.js";
import { BattleSceneEventType, BerryUsedEvent, MoveUsedEvent } from "#app/battle-scene-events.js"; import { BattleSceneEventType, BerryUsedEvent, MoveUsedEvent } from "../events/battle-scene";
import { BerryType } from "#app/data/enums/berry-type.js"; import { BerryType } from "#app/data/enums/berry-type.js";
import { Moves } from "#app/data/enums/moves.js"; import { Moves } from "#app/data/enums/moves.js";

View File

@ -0,0 +1,88 @@
import BattleScene from "#app/battle-scene.js";
import { addWindow } from "./ui-theme";
import { addTextObject, TextStyle } from "./text";
import { EggCountChangedEvent, EggEventType } from "#app/events/egg.js";
import EggHatchSceneHandler from "./egg-hatch-scene-handler";
/**
* A container that displays the count of hatching eggs.
* Extends Phaser.GameObjects.Container.
*/
export default class EggCounterContainer extends Phaser.GameObjects.Container {
private readonly WINDOW_DEFAULT_WIDTH = 37;
private readonly WINDOW_MEDIUM_WIDTH = 42;
private readonly WINDOW_HEIGHT = 26;
private readonly onEggCountChangedEvent = (event: Event) => this.onEggCountChanged(event);
private battleScene: BattleScene;
private eggCount: integer;
private eggCountWindow: Phaser.GameObjects.NineSlice;
private eggCountText: Phaser.GameObjects.Text;
/**
* @param {BattleScene} scene - The scene to which this container belongs.
* @param {number} eggCount - The number of eggs to hatch.
*/
constructor(scene: BattleScene, eggCount: integer) {
super(scene, 0, 0);
this.eggCount = eggCount;
this.battleScene = scene;
const uiHandler = this.battleScene.ui.getHandler() as EggHatchSceneHandler;
uiHandler.eventTarget.addEventListener(EggEventType.EGG_COUNT_CHANGED, this.onEggCountChangedEvent);
this.setup();
}
/**
* Sets up the container, creating the window, egg sprite, and egg count text.
*/
private setup(): void {
const windowWidth = this.eggCount > 9 ? this.WINDOW_MEDIUM_WIDTH : this.WINDOW_DEFAULT_WIDTH;
this.eggCountWindow = addWindow(this.battleScene, 5, 5, windowWidth, this.WINDOW_HEIGHT);
this.setVisible(this.eggCount > 1);
this.add(this.eggCountWindow);
const eggSprite = this.battleScene.add.sprite(19, 18, "egg", "egg_0");
eggSprite.setScale(0.32);
this.eggCountText = addTextObject(this.battleScene, 28, 13, `${this.eggCount}`, TextStyle.MESSAGE, { fontSize: "66px" });
this.add(eggSprite);
this.add(this.eggCountText);
}
/**
* Resets the window size to the default width and height.
*/
private setWindowToDefaultSize(): void {
this.eggCountWindow.setSize(this.WINDOW_DEFAULT_WIDTH, this.WINDOW_HEIGHT);
}
/**
* Handles window size, the egg count to show, and whether it should be displayed.
*
* @param event {@linkcode Event} being sent
* @returns void
*/
private onEggCountChanged(event: Event): void {
const eggCountChangedEvent = event as EggCountChangedEvent;
if (!eggCountChangedEvent) {
return;
}
const eggCount = eggCountChangedEvent.eggCount;
if (eggCount < 10) {
this.setWindowToDefaultSize();
}
if (eggCount > 0) {
this.eggCountText.setText(eggCount.toString());
} else {
this.eggCountText.setVisible(false);
}
}
}

View File

@ -156,15 +156,27 @@ export default class EggGachaUiHandler extends MessageUiHandler {
this.eggGachaOptionSelectBg.setOrigin(1, 1); this.eggGachaOptionSelectBg.setOrigin(1, 1);
this.eggGachaOptionsContainer.add(this.eggGachaOptionSelectBg); this.eggGachaOptionsContainer.add(this.eggGachaOptionSelectBg);
const multiplierOne = "x1";
const multiplierTen = "x10";
const pullOptions = [ const pullOptions = [
{ multiplier: "x1", description: `1 ${i18next.t("egg:pull")}` }, { multiplier: multiplierOne, description: `1 ${i18next.t("egg:pull")}`, icon: getVoucherTypeIcon(VoucherType.REGULAR) },
{ multiplier: "x10", description: `10 ${i18next.t("egg:pulls")}` }, { multiplier: multiplierTen, description: `10 ${i18next.t("egg:pulls")}`, icon: getVoucherTypeIcon(VoucherType.REGULAR) },
{ multiplier: "x1", description: `5 ${i18next.t("egg:pulls")}` }, { multiplier: multiplierOne, description: `5 ${i18next.t("egg:pulls")}`, icon: getVoucherTypeIcon(VoucherType.PLUS) },
{ multiplier: "x1", description: `10 ${i18next.t("egg:pulls")}` }, { multiplier: multiplierOne, description: `10 ${i18next.t("egg:pulls")}`, icon: getVoucherTypeIcon(VoucherType.PREMIUM) },
{ multiplier: "x1", description: `25 ${i18next.t("egg:pulls")}` } { multiplier: multiplierOne, description: `25 ${i18next.t("egg:pulls")}`, icon: getVoucherTypeIcon(VoucherType.GOLDEN) }
]; ];
const pullOptionsText = pullOptions.map(option => ` ${option.multiplier.padEnd(4)} ${option.description}`).join("\n"); const { resolvedLanguage } = i18next;
const pullOptionsText = pullOptions.map(option =>{
const desc = option.description.split(" ");
if (desc[0].length < 2) {
desc[0] += ["zh", "ko"].includes(resolvedLanguage.substring(0,2)) ? " " : " ";
}
if (option.multiplier === multiplierOne) {
desc[0] = " " + desc[0];
}
return ` ${option.multiplier.padEnd(5)}${desc.join(" ")}`;
}).join("\n");
const optionText = addTextObject( const optionText = addTextObject(
this.scene, this.scene,
@ -181,9 +193,8 @@ export default class EggGachaUiHandler extends MessageUiHandler {
optionText.setPositionRelative(this.eggGachaOptionSelectBg, 16, 9); optionText.setPositionRelative(this.eggGachaOptionSelectBg, 16, 9);
new Array(5).fill(null).map((_, i) => { pullOptions.forEach((option, i) => {
const voucherType = i < 2 ? VoucherType.REGULAR : i === 2 ? VoucherType.PLUS : i === 3 ? VoucherType.PREMIUM : VoucherType.GOLDEN; const icon = this.scene.add.sprite(0, 0, "items", option.icon);
const icon = this.scene.add.sprite(0, 0, "items", getVoucherTypeIcon(voucherType));
icon.setScale(0.5); icon.setScale(0.5);
icon.setPositionRelative(this.eggGachaOptionSelectBg, 20, 17 + i * 16); icon.setPositionRelative(this.eggGachaOptionSelectBg, 20, 17 + i * 16);
this.eggGachaOptionsContainer.add(icon); this.eggGachaOptionsContainer.add(icon);
@ -396,7 +407,8 @@ export default class EggGachaUiHandler extends MessageUiHandler {
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();
for (const tier of tiers) { for (const tier of tiers) {
const egg = new Egg(Utils.randInt(EGG_SEED, EGG_SEED * tier), this.gachaCursor, getEggTierDefaultHatchWaves(tier), timestamp); const eggId = Utils.randInt(EGG_SEED, EGG_SEED * tier);
const egg = new Egg(eggId, this.gachaCursor, getEggTierDefaultHatchWaves(tier), timestamp);
if (egg.isManaphyEgg()) { if (egg.isManaphyEgg()) {
this.scene.gameData.gameStats.manaphyEggsPulled++; this.scene.gameData.gameStats.manaphyEggsPulled++;
egg.hatchWaves = getEggTierDefaultHatchWaves(EggTier.ULTRA); egg.hatchWaves = getEggTierDefaultHatchWaves(EggTier.ULTRA);

View File

@ -7,6 +7,14 @@ import {Button} from "../enums/buttons";
export default class EggHatchSceneHandler extends UiHandler { export default class EggHatchSceneHandler extends UiHandler {
public eggHatchContainer: Phaser.GameObjects.Container; public eggHatchContainer: Phaser.GameObjects.Container;
/**
* Allows subscribers to listen for events
*
* Current Events:
* - {@linkcode EggEventType.EGG_COUNT_CHANGED} {@linkcode EggCountChangedEvent}
*/
public readonly eventTarget: EventTarget = new EventTarget();
constructor(scene: BattleScene) { constructor(scene: BattleScene) {
super(scene, Mode.EGG_HATCH_SCENE); super(scene, Mode.EGG_HATCH_SCENE);
} }

View File

@ -98,13 +98,6 @@ export default class EggListUiHandler extends MessageUiHandler {
let e = 0; let e = 0;
/*this.scene.gameData.eggs = [
new Egg(1, 1, 5, new Date().getTime()),
new Egg(1 + EGG_SEED, 1, 15, new Date().getTime()),
new Egg(1 + EGG_SEED * 2, 1, 50, new Date().getTime()),
new Egg(1 + EGG_SEED * 3, GachaType.LEGENDARY, 100, new Date().getTime())
];*/
for (const egg of this.scene.gameData.eggs) { for (const egg of this.scene.gameData.eggs) {
const x = (e % 11) * 18; const x = (e % 11) * 18;
const y = Math.floor(e / 11) * 18; const y = Math.floor(e / 11) * 18;

View File

@ -1,54 +0,0 @@
import BattleScene from "#app/battle-scene.js";
import { addWindow } from "./ui-theme";
import { addTextObject, TextStyle } from "./text";
/**
* A container that displays the count of hatching eggs.
* Extends Phaser.GameObjects.Container.
*/
export default class EggsToHatchCountContainer extends Phaser.GameObjects.Container {
private readonly WINDOW_DEFAULT_WIDTH = 37;
private readonly WINDOW_MEDIUM_WIDTH = 42;
private readonly WINDOW_HEIGHT = 26;
private eggsToHatchCount: integer;
private eggsToHatchCountWindow: Phaser.GameObjects.NineSlice;
public eggCountText: Phaser.GameObjects.Text;
/**
* @param {BattleScene} scene - The scene to which this container belongs.
* @param {number} eggsToHatchCount - The number of eggs to hatch.
*/
constructor(scene: BattleScene, eggsToHatchCount: integer) {
super(scene, 0, 0);
this.eggsToHatchCount = eggsToHatchCount;
}
/**
* Sets up the container, creating the window, egg sprite, and egg count text.
*/
setup(): void {
const windowWidth = this.eggsToHatchCount > 9 ? this.WINDOW_MEDIUM_WIDTH : this.WINDOW_DEFAULT_WIDTH;
this.eggsToHatchCountWindow = addWindow(this.scene as BattleScene, 5, 5, windowWidth, this.WINDOW_HEIGHT);
this.setVisible(this.eggsToHatchCount > 1);
this.add(this.eggsToHatchCountWindow);
const eggSprite = this.scene.add.sprite(19, 18, "egg", "egg_0");
eggSprite.setScale(0.32);
this.eggCountText = addTextObject(this.scene, 28, 13, `${this.eggsToHatchCount}`, TextStyle.MESSAGE, { fontSize: "66px" });
this.add(eggSprite);
this.add(this.eggCountText);
}
/**
* Resets the window size to the default width and height.
*/
setWindowToDefaultSize(): void {
this.eggsToHatchCountWindow.setSize(this.WINDOW_DEFAULT_WIDTH, this.WINDOW_HEIGHT);
}
}

View File

@ -1,4 +1,4 @@
import { BattleSceneEventType, CandyUpgradeNotificationChangedEvent } from "#app/battle-scene-events.js"; import { BattleSceneEventType, CandyUpgradeNotificationChangedEvent } from "../events/battle-scene";
import { pokemonPrevolutions } from "#app/data/pokemon-evolutions"; import { pokemonPrevolutions } from "#app/data/pokemon-evolutions";
import { Variant, getVariantTint } from "#app/data/variant"; import { Variant, getVariantTint } from "#app/data/variant";
import { argbFromRgba } from "@material/material-color-utilities"; import { argbFromRgba } from "@material/material-color-utilities";

View File

@ -1,10 +1,11 @@
import i18next from "i18next";
import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText";
import InputText from "phaser3-rex-plugins/plugins/inputtext"; import InputText from "phaser3-rex-plugins/plugins/inputtext";
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import { EggTier } from "../data/enums/egg-type"; import { EggTier } from "../data/enums/egg-type";
import { UiTheme } from "../enums/ui-theme"; import { UiTheme } from "../enums/ui-theme";
import { ModifierTier } from "../modifier/modifier-tier"; import { ModifierTier } from "../modifier/modifier-tier";
import Phaser from "phaser";
import i18next from "i18next";
export enum TextStyle { export enum TextStyle {
MESSAGE, MESSAGE,
@ -36,30 +37,11 @@ export enum TextStyle {
MOVE_PP_EMPTY MOVE_PP_EMPTY
} }
interface LanguageSetting {
summaryFontSize?: string,
battleInfoFontSize?: string,
partyFontSize?: string,
tooltipContentFontSize?: string,
moveInfoFontSize?: string,
textScale?: number
}
const languageSettings: { [key: string]: LanguageSetting } = {
"en":{},
"de":{},
"es":{},
"fr":{},
"it":{},
"pt_BR":{},
"zh_CN":{},
};
export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text { export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text {
const [ styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); const [ scale, styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions);
const ret = scene.add.text(x, y, content, styleOptions); const ret = scene.add.text(x, y, content, styleOptions);
ret.setScale(0.1666666667); ret.setScale(scale);
ret.setShadow(shadowXpos, shadowYpos, shadowColor); ret.setShadow(shadowXpos, shadowYpos, shadowColor);
if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) { if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) {
ret.setLineSpacing(5); ret.setLineSpacing(5);
@ -69,8 +51,8 @@ export function addTextObject(scene: Phaser.Scene, x: number, y: number, content
} }
export function setTextStyle(obj: Phaser.GameObjects.Text, scene: Phaser.Scene, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle) { export function setTextStyle(obj: Phaser.GameObjects.Text, scene: Phaser.Scene, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle) {
const [ styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); const [ scale, styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions);
obj.setScale(0.1666666667); obj.setScale(scale);
obj.setShadow(shadowXpos, shadowYpos, shadowColor); obj.setShadow(shadowXpos, shadowYpos, shadowColor);
if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) { if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing) {
obj.setLineSpacing(5); obj.setLineSpacing(5);
@ -78,11 +60,11 @@ export function setTextStyle(obj: Phaser.GameObjects.Text, scene: Phaser.Scene,
} }
export function addBBCodeTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): BBCodeText { export function addBBCodeTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): BBCodeText {
const [ styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); const [ scale, styleOptions, shadowColor, shadowXpos, shadowYpos ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions);
const ret = new BBCodeText(scene, x, y, content, styleOptions as BBCodeText.TextStyle); const ret = new BBCodeText(scene, x, y, content, styleOptions as BBCodeText.TextStyle);
scene.add.existing(ret); scene.add.existing(ret);
ret.setScale(0.1666666667); ret.setScale(scale);
ret.setShadow(shadowXpos, shadowYpos, shadowColor); ret.setShadow(shadowXpos, shadowYpos, shadowColor);
if (!(styleOptions as BBCodeText.TextStyle).lineSpacing) { if (!(styleOptions as BBCodeText.TextStyle).lineSpacing) {
ret.setLineSpacing(10); ret.setLineSpacing(10);
@ -92,23 +74,25 @@ export function addBBCodeTextObject(scene: Phaser.Scene, x: number, y: number, c
} }
export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, width: number, height: number, style: TextStyle, extraStyleOptions?: InputText.IConfig): InputText { export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, width: number, height: number, style: TextStyle, extraStyleOptions?: InputText.IConfig): InputText {
const [ styleOptions ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); const [ scale, styleOptions ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions);
const ret = new InputText(scene, x, y, width, height, styleOptions as InputText.IConfig); const ret = new InputText(scene, x, y, width, height, styleOptions as InputText.IConfig);
scene.add.existing(ret); scene.add.existing(ret);
ret.setScale(0.1666666667); ret.setScale(scale);
return ret; return ret;
} }
function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, number, number ] { function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ number, Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, number, number ] {
const lang = i18next.resolvedLanguage; const {resolvedLanguage} = i18next;
let shadowXpos = 4; let shadowXpos = 4;
let shadowYpos = 5; let shadowYpos = 5;
const scale = 0.1666666667;
const defaultFontSize = 96;
let styleOptions: Phaser.Types.GameObjects.Text.TextStyle = { let styleOptions: Phaser.Types.GameObjects.Text.TextStyle = {
fontFamily: "emerald", fontFamily: "emerald, unifont",
fontSize: "96px", fontSize: 96,
color: getTextColor(style, false, uiTheme), color: getTextColor(style, false, uiTheme),
padding: { padding: {
bottom: 6 bottom: 6
@ -126,65 +110,45 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio
case TextStyle.SUMMARY_GREEN: case TextStyle.SUMMARY_GREEN:
case TextStyle.WINDOW: case TextStyle.WINDOW:
case TextStyle.WINDOW_ALT: case TextStyle.WINDOW_ALT:
case TextStyle.STATS_VALUE:
shadowXpos = 3; shadowXpos = 3;
shadowYpos = 3; shadowYpos = 3;
break; break;
case TextStyle.STATS_LABEL: case TextStyle.STATS_LABEL:
let fontSizeLabel = "96px";
switch (lang) {
case "de":
fontSizeLabel = "80px";
break;
default:
fontSizeLabel = "96px";
break;
}
styleOptions.fontSize = fontSizeLabel;
break;
case TextStyle.STATS_VALUE:
shadowXpos = 3;
shadowYpos = 3;
let fontSizeValue = "96px";
switch (lang) {
case "de":
fontSizeValue = "80px";
break;
default:
fontSizeValue = "96px";
break;
}
styleOptions.fontSize = fontSizeValue;
break;
case TextStyle.MESSAGE: case TextStyle.MESSAGE:
case TextStyle.SETTINGS_LABEL: case TextStyle.SETTINGS_LABEL:
case TextStyle.SETTINGS_LOCKED: case TextStyle.SETTINGS_LOCKED:
case TextStyle.SETTINGS_SELECTED: case TextStyle.SETTINGS_SELECTED:
styleOptions.fontSize = languageSettings[lang]?.summaryFontSize || "96px";
break; break;
case TextStyle.BATTLE_INFO: case TextStyle.BATTLE_INFO:
case TextStyle.MONEY: case TextStyle.MONEY:
case TextStyle.TOOLTIP_TITLE: case TextStyle.TOOLTIP_TITLE:
styleOptions.fontSize = languageSettings[lang]?.battleInfoFontSize || "72px"; styleOptions.fontSize = defaultFontSize - 24;
shadowXpos = 3.5; shadowXpos = 3.5;
shadowYpos = 3.5; shadowYpos = 3.5;
break; break;
case TextStyle.PARTY: case TextStyle.PARTY:
case TextStyle.PARTY_RED: case TextStyle.PARTY_RED:
styleOptions.fontSize = languageSettings[lang]?.partyFontSize || "66px"; styleOptions.fontSize = defaultFontSize - 30;
styleOptions.fontFamily = "pkmnems"; styleOptions.fontFamily = "pkmnems";
break; break;
case TextStyle.TOOLTIP_CONTENT: case TextStyle.TOOLTIP_CONTENT:
styleOptions.fontSize = languageSettings[lang]?.tooltipContentFontSize || "64px"; styleOptions.fontSize = defaultFontSize - 32;
shadowXpos = 3; shadowXpos = 3;
shadowYpos = 3; shadowYpos = 3;
break; break;
case TextStyle.MOVE_INFO_CONTENT: case TextStyle.MOVE_INFO_CONTENT:
styleOptions.fontSize = languageSettings[lang]?.moveInfoFontSize || "56px"; styleOptions.fontSize = defaultFontSize - 40;
shadowXpos = 3; shadowXpos = 3;
shadowYpos = 3; shadowYpos = 3;
break; break;
} }
if (["zh"].includes(resolvedLanguage.substring(0,2))) {
shadowXpos = 0;
shadowYpos = 0;
}
const shadowColor = getTextColor(style, true, uiTheme); const shadowColor = getTextColor(style, true, uiTheme);
if (extraStyleOptions) { if (extraStyleOptions) {
@ -195,7 +159,7 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio
styleOptions = Object.assign(styleOptions, extraStyleOptions); styleOptions = Object.assign(styleOptions, extraStyleOptions);
} }
return [ styleOptions, shadowColor, shadowXpos, shadowYpos ]; return [ scale, styleOptions, shadowColor, shadowXpos, shadowYpos ];
} }
export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string { export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string {

View File

@ -1,7 +1,7 @@
import * as Utils from "../utils"; import * as Utils from "../utils";
import BattleScene from "#app/battle-scene.js"; import BattleScene from "#app/battle-scene.js";
import { TimeOfDay } from "#app/data/enums/time-of-day.js"; import { TimeOfDay } from "#app/data/enums/time-of-day.js";
import { BattleSceneEventType } from "#app/battle-scene-events.js"; import { BattleSceneEventType } from "../events/battle-scene";
import { EaseType } from "./enums/ease-type"; import { EaseType } from "./enums/ease-type";
/** A small self contained UI element that displays the time of day as an icon */ /** A small self contained UI element that displays the time of day as an icon */