Compare commits

...

23 Commits

Author SHA1 Message Date
Jannik Tappert
1312d4f825
[Qol] The title will now be displayed in the voucher overview (and flyout) (#1886)
* The title will now be displayed in the voucher overview

* Update src/system/voucher.ts

* Intend
2024-06-06 15:01:21 -04:00
Tempoanon
ac8ae6c724
Thunderclap should not let the AI read your inputs (#1884) 2024-06-06 12:59:22 -05:00
Tempoanon
609efb0cf9
Fix typo in healing charm for Chinese localization (#1874) 2024-06-06 12:58:02 -05:00
Matthew Olker
1276006de3 Money shouldn't cover full screen even if its funny 2024-06-06 13:30:43 -04:00
HighMans
17edaeb708
[QoL] Sort items on summary screen (#1880) 2024-06-06 13:13:14 -04:00
MadridPawmot
f3de114d2b
[enhancement] Added Sailor trainer class (#1411)
* Add files via upload

* Update trainer-type.ts

* Update biomes.ts

* Update trainer-config.ts

* Update trainer-names.ts

* Update trainer-names.ts

* Update trainers.ts

* Update trainers.ts

* Added German translation

Thanks to CodeTappert

* Update trainers.ts

* Update trainers.ts

* Update trainers.ts

* Update trainers.ts

* Update trainers.ts

* Update trainers.ts

* Update trainers.ts to resolve conflicts

* Fixed syntax error

* Update biomes.ts

* Re-added possible biomes for the Sailor trainer class

* Added data for dialogue lines for the sailor class

* Added dialogue from FRLG

* Added locale

* Added locale

* Added locale

* Update trainers.ts

* Added locale

* Added locale

* Added Korean translation

* Added locale

* Added Portuguese translation

* Added locale

* Added locale

* Added Mandarin Chinese translation

* Added Cantonese Chinese translation

* Added images

* Recentered sprite

* Added Spanish translation for the dialogue

* Delete duplicate

* Delete duplicate

* Updated dialogue with requested changes

* Update Spanish translation to reflect the changes

* Update dialogue.ts

* Update dialogue.ts

* Update dialogue.ts

* Update dialogue.ts

* Update dialogue.ts

* Update dialogue.ts

* Update dialogue.ts
2024-06-06 11:55:32 -05:00
Noor Q
14b5d141c1
[QoL] Added an indicator when money changes. (#1772)
* added an animation and color shift when adding/removing money

* eslint fix

* The animation is now vertically centered, larger and faster.
2024-06-06 11:50:02 -05:00
Lee ByungHoon
90aa9b4209
[Localization] #1761 Korean trainer dialogue (#1853)
* [Localization] #1761 Translation to Korean about some trainers

### trainer list
- ace_trainer
- parasol_lady
- twins
- cyclist
- black_belt

* fixed the grammar of some sentences. and changed Korean about ace trainer.

* Modify translation dialogue with parasol lday and cyclist
2024-06-06 12:22:31 -04:00
HighMans
a221a46220
Attempt to sort items on summary & battle screen for user's party. (#1188)
* Sort items in summary screen by type then name.

* Use modifierSortFunc from modifier.ts

* Implement proper sort function which also applies to the battle scene.

* Implement proper sort function which also applies to the battle scene.

* Run linter.

* Fix type assertions.
2024-06-06 11:10:38 -05:00
Dmitriy K
223d8a731d
[Feature] Implement Full Heal/Lum/Full Restore to heal Confusion #1658 (#1876)
* Added Confusion to be healed with Full Heals and Full Restores

* Semi-Colon oversight

* Changed resetStatus to have a condition whether to include confusion or not, defaults to false so you manually have to add

* Fixed spacing and semicolon

* Refactored the Lum Berry case

* Fix berry conflicts

* Update {}

* Fix PP Conflict

* Build fix?

* Fix Modifier

* Build Fix

* Fix

* Fix StatuHeal from eslint

* Fix revive (will show testing through everything again)

* Update documentation

---------

Co-authored-by: Ethan <hensley.ethan64@gmail.com>
Co-authored-by: Ethan <71776311+EvasiveAce@users.noreply.github.com>
2024-06-06 12:04:16 -04:00
Adrian T
8d6a0bb0a1
[Ability] Implement Ice Face (#1755)
* implement ice face ability

* remove showing ability bar

* fixes

* add documentations

* move code out of phases.ts

* add hardcoded eiscue check, localization

* add KO locale

* remove unnecessary constructor

* use && instead of || to specify ice form on eiscue
2024-06-06 11:49:50 -04:00
MrWaterT
ba66f2c916
[Bug] Remove text on summary bg (#1709) 2024-06-06 11:31:31 -04:00
SeafoamQueen
3fea384dc1
[Feature] Added Battle Style setting (#1872)
* Added Battle Style setting with Shift and Set options

* Changed 'Shift' option to 'Switch' to match the Gen 8 setting.
2024-06-06 11:26:04 -04:00
José Ricardo Fleury Oliveira
cb27fc2b06
[Localization] ptBR removing capital letters in battle.ts (#1873) 2024-06-06 11:19:38 -04:00
h44451890
94099e0fba
Fix all ability name and description of zh_tw (#1478) 2024-06-06 10:17:53 -05:00
Lee ByungHoon
081d813540
[Feature] Move to start button when you can't add party anymore (#1673)
* [Feature] Move to start button when you can't add party anymore

* Add comment about #1673

* Update starter-select-ui-handler.ts

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-06-06 10:12:19 -05:00
c4vv
e0401a93aa
[Bug] Fix generateVariant to account for forms (#1783)
* Add form check to generateVaraint

* Add index check

* Fix for typedoc
2024-06-06 10:55:50 -04:00
SeafoamQueen
5ac1b7245f
[Feature] Refactored Game Settings UI navigation menu and sorting (#1860)
* Refactored settings UI menu options and added the battle style setting

* Removed the new Battle Style setting. It will be added in a seperate PR.

* Fixed typo and spacing
2024-06-06 10:38:54 -04:00
dorri-riddo
63ce24afb2
[Localization] #1761 Korean trainer dialogue (ramos, viola) (#1868) 2024-06-06 10:22:46 -04:00
José Ricardo Fleury Oliveira
9c4c4005ae
[Localization] ptBr battle.ts translations (#1870) 2024-06-06 10:12:40 -04:00
Greenlamp2
5764324f61
fix display touch control V in battle (#1869) 2024-06-06 09:47:08 -04:00
Laeticia PIERRE
f53dce432b
useMove + pokemon affix localization (#1276)
* useMove + pokemonPrefix localization

* Rename prefix to affix + line break fr

* getPokemonAffix to getPokemonNameWithAffix + remove space + replace

* Better getPokemonNameWithAffix switch

* Ko locale + fix es locale

* Doc getPokemonNameWithAffix + getPokemonMessage + fix

* Ko translate / missing weather changes

* Fix conflicts getPokemonPrefix

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-06-06 08:36:12 -05:00
Frede
40328d5712
[BUG] Fix Move Info Overlay Scroll Bug (#1856)
* Added "Skip Dialogues" option (if at least 1 classic win)

* Removed error sound and hide option instead when classic wins = 0

* Add skip dialogues option to Unlockables and show unlocked message on first classic win

* Only skips seen dialogues, removed dialogue option from unlockables, seen dialogues get saved to local storage

* oops

* dont show charSprite when skipping a dialogue, small fixes

* correctly reset move description scrolling when changing move

* override fix

---------

Co-authored-by: Frederik Hobein <frederik.hobein@nterra.com>
2024-06-06 08:22:37 -05:00
80 changed files with 1076 additions and 572 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_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
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):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_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer
{
display: none;
}

View File

@ -0,0 +1,41 @@
{
"textures": [
{
"image": "sailor.png",
"format": "RGBA8888",
"size": {
"w": 72,
"h": 72
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 72,
"h": 72
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 73,
"h": 73
},
"frame": {
"x": 0,
"y": 0,
"w": 39,
"h": 72
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:f692676a166fc1915532cd94d5799af4:fb833f76fb6797474657726bb59a7eee:aeb55e30992938f494b6cd2420158dda$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -13,7 +13,7 @@ import { Biome } from "./data/enums/biome";
import { Arena, ArenaBase } from "./field/arena";
import { GameData } from "./system/game-data";
import { PlayerGender } from "./data/enums/player-gender";
import { TextStyle, addTextObject } from "./ui/text";
import { TextStyle, addTextObject, getTextColor } from "./ui/text";
import { Moves } from "./data/enums/moves";
import { allMoves } from "./data/move";
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from "./modifier/modifier-type";
@ -59,6 +59,7 @@ import {InputsController} from "./inputs-controller";
import {UiInputs} from "./ui-inputs";
import { MoneyFormat } from "./enums/money-format";
import { NewArenaEvent } from "./battle-scene-events";
import { Abilities } from "./data/enums/abilities";
import ArenaFlyout from "./ui/arena-flyout";
import { EaseType } from "./ui/enums/ease-type";
@ -145,6 +146,12 @@ export default class BattleScene extends SceneBase {
public fusionPaletteSwaps: boolean = true;
public enableTouchControls: boolean = false;
public enableVibration: boolean = false;
/**
* Determines the selected battle style.
* - 0 = 'Shift'
* - 1 = 'Set' - The option to switch the active pokemon at the start of a battle will not display.
*/
public battleStyle: integer = 0;
public disableMenu: boolean = false;
@ -402,28 +409,28 @@ export default class BattleScene extends SceneBase {
this.biomeWaveText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO);
this.biomeWaveText.setName("text-biome-wave");
this.biomeWaveText.setOrigin(1, 0);
this.biomeWaveText.setOrigin(1, 0.5);
this.fieldUI.add(this.biomeWaveText);
this.moneyText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "", TextStyle.MONEY);
this.moneyText.setName("text-money");
this.moneyText.setOrigin(1, 0);
this.moneyText.setOrigin(1, 0.5);
this.fieldUI.add(this.moneyText);
this.scoreText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "", TextStyle.PARTY, { fontSize: "54px" });
this.scoreText.setName("text-score");
this.scoreText.setOrigin(1, 0);
this.scoreText.setOrigin(1, 0.5);
this.fieldUI.add(this.scoreText);
this.luckText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "", TextStyle.PARTY, { fontSize: "54px" });
this.luckText.setName("text-luck");
this.luckText.setOrigin(1, 0);
this.luckText.setOrigin(1, 0.5);
this.luckText.setVisible(false);
this.fieldUI.add(this.luckText);
this.luckLabelText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "Luck:", TextStyle.PARTY, { fontSize: "54px" });
this.luckLabelText.setName("text-luck-label");
this.luckLabelText.setOrigin(1, 0);
this.luckLabelText.setOrigin(1, 0.5);
this.luckLabelText.setVisible(false);
this.fieldUI.add(this.luckLabelText);
@ -1042,6 +1049,12 @@ export default class BattleScene extends SceneBase {
if (resetArenaState) {
this.arena.removeAllTags();
playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p)));
for (const pokemon of this.getParty()) {
if (pokemon.hasAbility(Abilities.ICE_FACE)) {
pokemon.formIndex = 0;
}
}
this.unshiftPhase(new ShowTrainerPhase(this));
}
for (const pokemon of this.getParty()) {
@ -1365,6 +1378,22 @@ export default class BattleScene extends SceneBase {
}
}
animateMoneyChanged(positiveChange: boolean): void {
if (this.tweens.getTweensOf(this.moneyText).length > 0) {
return;
}
const deltaScale = this.moneyText.scale * 0.14 * (positiveChange ? 1 : -1);
this.moneyText.setShadowColor(positiveChange ? "#008000" : "#FF0000");
this.tweens.add({
targets: this.moneyText,
duration: 250,
scale: this.moneyText.scale + deltaScale,
loop: 0,
yoyo: true,
onComplete: (_) => this.moneyText.setShadowColor(getTextColor(TextStyle.MONEY, true)),
});
}
updateScoreText(): void {
this.scoreText.setText(`Score: ${this.score.toString()}`);
this.scoreText.setVisible(this.gameMode.isDaily);
@ -1408,7 +1437,10 @@ export default class BattleScene extends SceneBase {
updateUIPositions(): void {
const enemyModifierCount = this.enemyModifiers.filter(m => m.isIconVisible(this)).length;
this.biomeWaveText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0));
const biomeWaveTextHeight = this.biomeWaveText.getBottomLeft().y - this.biomeWaveText.getTopLeft().y;
this.biomeWaveText.setY(
-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0) + (biomeWaveTextHeight / 2)
);
this.moneyText.setY(this.biomeWaveText.y + 10);
this.scoreText.setY(this.moneyText.y + 10);
[ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10));
@ -1810,6 +1842,7 @@ export default class BattleScene extends SceneBase {
addMoney(amount: integer): void {
this.money = Math.min(this.money + amount, Number.MAX_SAFE_INTEGER);
this.updateMoneyText();
this.animateMoneyChanged(true);
this.validateAchvs(MoneyAchv);
}

View File

@ -3,7 +3,7 @@ import { Type } from "./type";
import * as Utils from "../utils";
import { BattleStat, getBattleStatName } from "./battle-stat";
import { MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases";
import { getPokemonMessage, getPokemonPrefix } from "../messages";
import { getPokemonMessage, getPokemonNameWithAffix } from "../messages";
import { Weather, WeatherType } from "./weather";
import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type";
@ -156,7 +156,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName});
return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
}
}
@ -878,7 +878,7 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:perishBody", {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName});
return i18next.t("abilityTriggers:perishBody", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
}
}
@ -2666,7 +2666,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
for (const opp of pokemon.getOpponents()) {
if (opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) {
opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER);
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`}));
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: getPokemonNameWithAffix(opp)}));
hadEffect = true;
}
@ -3344,6 +3344,48 @@ export class PostSummonStatChangeOnArenaAbAttr extends PostSummonStatChangeAbAtt
}
}
/**
* Applies immunity to physical moves.
* This is used in Ice Face ability.
*/
export class IceFaceMoveImmunityAbAttr extends MoveImmunityAbAttr {
/**
* Applies the Ice Face pre-defense ability to the Pokémon.
* Removes BattlerTagType.ICE_FACE hit by physical attack and is in Ice Face form.
*
* @param {Pokemon} pokemon - The Pokémon with the Ice Face ability.
* @param {boolean} passive - Whether the ability is passive.
* @param {Pokemon} attacker - The attacking Pokémon.
* @param {PokemonMove} move - The move being used.
* @param {Utils.BooleanHolder} cancelled - A holder for whether the move was cancelled.
* @param {any[]} args - Additional arguments.
* @returns {boolean} - Whether the immunity was applied.
*/
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const isImmune = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args);
if (isImmune) {
const simulated = args.length > 1 && args[1];
if (!simulated) {
pokemon.removeTag(BattlerTagType.ICE_FACE);
}
}
return isImmune;
}
/**
* Gets the message triggered when the Pokémon avoids damage using the Ice Face ability.
* @param {Pokemon} pokemon - The Pokémon with the Ice Face ability.
* @param {string} abilityName - The name of the ability.
* @param {...any} args - Additional arguments.
* @returns {string} - The trigger message.
*/
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonName: pokemon.name, abilityName: abilityName });
}
}
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => {
@ -4330,8 +4372,14 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr)
.attr(NoFusionAbilityAbAttr)
.ignorable()
.unimplemented(),
// Add BattlerTagType.ICE_FACE if the pokemon is in ice face form
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0, false)
// When summoned with active HAIL or SNOW, add BattlerTagType.ICE_FACE
.conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0)
// When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE
.attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW)
.attr(IceFaceMoveImmunityAbAttr, (target, user, move) => move.getMove().category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE))
.ignorable(),
new Ability(Abilities.POWER_SPOT, 8)
.unimplemented(),
new Ability(Abilities.MIMICRY, 8)

View File

@ -1,6 +1,6 @@
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
import { CommonAnimPhase, MoveEffectPhase, MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases";
import { getPokemonMessage, getPokemonPrefix } from "../messages";
import { getPokemonMessage, getPokemonNameWithAffix } from "../messages";
import Pokemon, { MoveResult, HitResult } from "../field/pokemon";
import { Stat, getStatName } from "./pokemon-stat";
import { StatusEffect } from "./status-effect";
@ -15,6 +15,8 @@ import { TerrainType } from "./terrain";
import { WeatherType } from "./weather";
import { BattleStat } from "./battle-stat";
import { allAbilities } from "./ability";
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Species } from "./enums/species";
export enum BattlerTagLapseType {
FAINT,
@ -803,7 +805,7 @@ export class ThunderCageTag extends DamagingTrapTag {
}
getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` trapped\n${getPokemonPrefix(pokemon).toLowerCase()}${pokemon.name}!`);
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` trapped\n${getPokemonNameWithAffix(pokemon)}!`);
}
}
@ -813,7 +815,7 @@ export class InfestationTag extends DamagingTrapTag {
}
getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` has been afflicted \nwith an infestation by ${getPokemonPrefix(pokemon.scene.getPokemonById(this.sourceId))}${pokemon.scene.getPokemonById(this.sourceId).name}!`);
return getPokemonMessage(pokemon, ` has been afflicted \nwith an infestation by ${getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId))}!`);
}
}
@ -1354,6 +1356,57 @@ export class CursedTag extends BattlerTag {
}
}
/**
* Provides the Ice Face ability's effects.
*/
export class IceFaceTag extends BattlerTag {
constructor(sourceMove: Moves) {
super(BattlerTagType.ICE_FACE, BattlerTagLapseType.CUSTOM, 1, sourceMove);
}
/**
* Determines if the Ice Face tag can be added to the Pokémon.
* @param {Pokemon} pokemon - The Pokémon to which the tag might be added.
* @returns {boolean} - True if the tag can be added, false otherwise.
*/
canAdd(pokemon: Pokemon): boolean {
const weatherType = pokemon.scene.arena.weather?.weatherType;
const isWeatherSnowOrHail = weatherType === WeatherType.HAIL || weatherType === WeatherType.SNOW;
const isFormIceFace = pokemon.formIndex === 0;
// Hard code Eiscue for now, this is to prevent the game from crashing if fused pokemon has Ice Face
if ((pokemon.species.speciesId === Species.EISCUE && isFormIceFace) || isWeatherSnowOrHail) {
return true;
}
return false;
}
/**
* Applies the Ice Face tag to the Pokémon.
* Triggers a form change to Ice Face if the Pokémon is not in its Ice Face form.
* @param {Pokemon} pokemon - The Pokémon to which the tag is added.
*/
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
if (pokemon.formIndex !== 0) {
pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
}
/**
* Removes the Ice Face tag from the Pokémon.
* Triggers a form change to Noice when the tag is removed.
* @param {Pokemon} pokemon - The Pokémon from which the tag is removed.
*/
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
}
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag {
switch (tagType) {
case BattlerTagType.RECHARGING:
@ -1467,6 +1520,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new MinimizeTag();
case BattlerTagType.DESTINY_BOND:
return new DestinyBondTag(sourceMove, sourceId);
case BattlerTagType.ICE_FACE:
return new IceFaceTag(sourceMove);
case BattlerTagType.NONE:
default:
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);

View File

@ -81,12 +81,9 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
}
if (pokemon.status) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
pokemon.resetStatus();
}
pokemon.resetStatus(true, true);
pokemon.updateInfo();
}
if (pokemon.getTag(BattlerTagType.CONFUSED)) {
pokemon.lapseTag(BattlerTagType.CONFUSED);
}
};
case BerryType.LIECHI:
case BerryType.GANLON:

View File

@ -1691,7 +1691,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
[BiomePoolTier.BOSS_ULTRA_RARE]: []
},
[Biome.SEA]: {
[BiomePoolTier.COMMON]: [ TrainerType.SWIMMER ],
[BiomePoolTier.COMMON]: [ TrainerType.SWIMMER, TrainerType.SAILOR ],
[BiomePoolTier.UNCOMMON]: [],
[BiomePoolTier.RARE]: [],
[BiomePoolTier.SUPER_RARE]: [],
@ -1713,7 +1713,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
[BiomePoolTier.BOSS_ULTRA_RARE]: []
},
[Biome.BEACH]: {
[BiomePoolTier.COMMON]: [ TrainerType.FISHERMAN, TrainerType.PARASOL_LADY ],
[BiomePoolTier.COMMON]: [ TrainerType.FISHERMAN, TrainerType.PARASOL_LADY, TrainerType.SAILOR ],
[BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BREEDER ],
[BiomePoolTier.RARE]: [ TrainerType.BLACK_BELT ],
[BiomePoolTier.SUPER_RARE]: [],
@ -7308,6 +7308,11 @@ export function initBiomes() {
[ Biome.VOLCANO, BiomePoolTier.COMMON ]
]
],
[ TrainerType.SAILOR, [
[ Biome.SEA, BiomePoolTier.COMMON ],
[ Biome.BEACH, BiomePoolTier.COMMON ]
]
],
[ TrainerType.BROCK, [
[ Biome.CAVE, BiomePoolTier.BOSS ]
]

View File

@ -435,6 +435,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
]
}
],
[TrainerType.SAILOR]: [
{
encounter: [
"dialogue:sailor.encounter.1",
"dialogue:sailor.encounter.2",
"dialogue:sailor.encounter.3",
],
victory: [
"dialogue:sailor.victory.1",
"dialogue:sailor.victory.2",
"dialogue:sailor.victory.3",
]
}
],
[TrainerType.BROCK]: {
encounter: [
"dialogue:brock.encounter.1",

View File

@ -57,5 +57,6 @@ export enum BattlerTagType {
GROUNDED = "GROUNDED",
MAGNET_RISEN = "MAGNET_RISEN",
MINIMIZED = "MINIMIZED",
DESTINY_BOND = "DESTINY_BOND"
DESTINY_BOND = "DESTINY_BOND",
ICE_FACE = "ICE_FACE"
}

View File

@ -40,6 +40,7 @@ export enum TrainerType {
RICH,
RICH_KID,
ROUGHNECK,
SAILOR,
SCIENTIST,
SMASHER,
SNOW_WORKER,

View File

@ -730,6 +730,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
[Species.GALAR_DARMANITAN]: [
new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
],
[Species.EISCUE]: [
new SpeciesFormChange(Species.EISCUE, "", "no-ice", new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.EISCUE, "no-ice", "", new SpeciesFormChangeManualTrigger(), true),
]
};

View File

@ -1059,6 +1059,7 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName("Gentleman").setHasGenders("Madame").setHasDouble("Rich Couple"),
[TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName("Rich Boy").setHasGenders("Lady").setHasDouble("Rich Kids").setEncounterBgm(TrainerType.RICH),
[TrainerType.ROUGHNECK]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)),
[TrainerType.SAILOR]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.BACKPACKER).setSpeciesFilter(s => s.isOfType(Type.WATER) || s.isOfType(Type.FIGHTING)),
[TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders("Scientist Female").setHasDouble("Scientists").setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST)
.setSpeciesPools({
[TrainerPoolTier.COMMON]: [Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING],

View File

@ -60,6 +60,7 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, "Gentleman").hasGenderVariant("Madame"),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, "Rich_Boy").hasGenderVariant("Lady"),
[TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK),
[TrainerType.SAILOR]: new TrainerNameConfig(TrainerType.SAILOR),
[TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST),
[TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER),
[TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, "Worker"),
@ -111,6 +112,7 @@ export const trainerNamePools = {
[TrainerType.RICH]: [["Alfred","Edward","Gregory","Preston","Thomas","Tucker","Walter","Clifford","Everett","Micah","Nate","Pierre","Terrance","Arthur","Brooks","Emanuel","Lamar","Jeremy","Leonardo","Milton","Frederic","Renaud","Robert","Yan","Daniel","Sheldon","Stonewall","Gerald","Ronald","Smith","Stanley","Reginald","Orson","Wilco","Caden","Glenn"],["Rebecca","Reina","Cassandra","Emilia","Grace","Marian","Elizabeth","Kathleen","Sayuri","Caroline","Judy"]],
[TrainerType.RICH_KID]: [["Garret","Winston","Dawson","Enrique","Jason","Roman","Trey","Liam","Anthony","Brad","Cody","Manuel","Martin","Pierce","Rolan","Keenan","Filbert","Antoin","Cyus","Diek","Dugo","Flitz","Jurek","Lond","Perd","Quint","Basto","Benit","Brot","Denc","Guyit","Marcon","Perc","Puros","Roex","Sainz","Symin","Tark","Venak"],["Anette","Brianna","Cindy","Colleen","Daphne","Elizabeth","Naomi","Sarah","Charlotte","Gillian","Jacki","Lady","Melissa","Celeste","Colette","Elizandra","Isabel","Lynette","Magnolia","Sophie","Lina","Dulcie","Auro","Brin","Caril","Eloos","Gwin","Illa","Kowly","Rima","Ristin","Vesey","Brena","Deasy","Denslon","Kylet","Nemi","Rene","Sanol","Stouner","Sturk","Talmen","Zoila"]],
[TrainerType.ROUGHNECK]: ["Camron","Corey","Gabriel","Isaiah","Jamal","Koji","Luke","Paxton","Raul","Zeek","Kirby","Chance","Dave","Fletcher","Johnny","Reese","Joey","Ricky","Silvester","Martin"],
[TrainerType.SAILOR]: ["Alberto","Bost","Brennan","Brenden","Claude","Cory","Damian","Dirk","Duncan","Dwayne","Dylan","Eddie","Edmond","Elijah","Ernest","Eugene","Garrett","Golos","Gratin","Grestly","Harry","Hols","Hudson","Huey","Jebol","Jeff","Leonald","Luther","Kelvin","Kenneth","Kent","Knook","Marc","Mifis","Monar","Morkor","Ordes","Oxlin","Parker","Paul","Philip","Roberto","Samson","Skyler","Stanly","Tebu","Terrell","Trevor","Yasu","Zachariah"],
[TrainerType.SCIENTIST]: [["Jed","Marc","Mitch","Rich","Ross","Beau","Braydon","Connor","Ed","Ivan","Jerry","Jose","Joshua","Parker","Rodney","Taylor","Ted","Travis","Zackery","Darrius","Emilio","Fredrick","Shaun","Stefano","Travon","Daniel","Garett","Gregg","Linden","Lowell","Trenton","Dudley","Luke","Markus","Nathan","Orville","Randall","Ron","Ronald","Simon","Steve","William","Franklin","Clarke","Jacques","Terrance","Ernst","Justus","Ikaika","Jayson","Kyle","Reid","Tyrone","Adam","Albert","Alphonse","Cory","Donnie","Elton","Francis","Gordon","Herbert","Humphrey","Jordan","Julian","Keaton","Levi","Melvin","Murray","West","Craig","Coren","Dubik","Kotan","Lethco","Mante","Mort","Myron","Odlow","Ribek","Roeck","Vogi","Vonder","Zogo","Doimo","Doton","Durel","Hildon","Kukla","Messa","Nanot","Platen","Raburn","Reman","Acrod","Coffy","Elrok","Foss","Hardig","Hombol","Hospel","Kaller","Klots","Krilok","Limar","Loket","Mesak","Morbit","Newin","Orill","Tabor","Tekot"],["Blythe","Chan","Kathrine","Marie","Maria","Naoko","Samantha","Satomi","Shannon","Athena","Caroline","Lumi","Lumina","Marissa","Sonia"]],
[TrainerType.SMASHER]: ["Aspen","Elena","Mari","Amy","Lizzy"],
[TrainerType.SNOW_WORKER]: [["Braden","Brendon","Colin","Conrad","Dillan","Gary","Gerardo","Holden","Jackson","Mason","Quentin","Willy","Noel","Arnold","Brady","Brand","Cairn","Cliff","Don","Eddie","Felix","Filipe","Glenn","Gus","Heath","Matthew","Patton","Rich","Rob","Ryan","Scott","Shelby","Sterling","Tyler","Victor","Zack","Friedrich","Herman","Isaac","Leo","Maynard","Mitchell","Morgann","Nathan","Niel","Pasqual","Paul","Tavarius","Tibor","Dimitri","Narek","Yusif","Frank","Jeff","Vaclav","Ovid","Francis","Keith","Russel","Sangon","Toway","Bomber","Chean","Demit","Hubor","Kebile","Laber","Ordo","Retay","Ronix","Wagel","Dobit","Kaster","Lobel","Releo","Saken","Rustix"],["Georgia","Sandra","Yvonne"]],

View File

@ -1,5 +1,5 @@
import { Biome } from "./enums/biome";
import { getPokemonMessage, getPokemonPrefix } from "../messages";
import { getPokemonMessage, getPokemonNameWithAffix } from "../messages";
import Pokemon from "../field/pokemon";
import { Type } from "./type";
import Move, { AttackMove } from "./move";
@ -180,9 +180,9 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string {
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string {
switch (weatherType) {
case WeatherType.SANDSTORM:
return i18next.t("weather:sandstormDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
return i18next.t("weather:sandstormDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
case WeatherType.HAIL:
return i18next.t("weather:hailDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
return i18next.t("weather:hailDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
}
return null;

View File

@ -1277,7 +1277,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns the shiny variant
*/
generateVariant(): Variant {
if (!this.shiny || !variantData.hasOwnProperty(this.species.speciesId)) {
const formIndex: number = this.formIndex;
let variantDataIndex: string | number = this.species.speciesId;
if (this.species.forms.length > 0) {
const formKey = this.species.forms[formIndex]?.formKey;
if (formKey) {
variantDataIndex = `${variantDataIndex}-${formKey}`;
}
}
// Checks if there is no variant data for both the index or index with form
if (!this.shiny || (!variantData.hasOwnProperty(variantDataIndex) && !variantData.hasOwnProperty(this.species.speciesId))) {
return 0;
}
const rand = Utils.randSeedInt(10);
@ -2429,10 +2438,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/**
* Resets the status of a pokemon
* @param revive whether revive should be cured, defaults to true
* Resets the status of a pokemon.
* @param revive Whether revive should be cured; defaults to true.
* @param confusion Whether resetStatus should include confusion or not; defaults to false.
*/
resetStatus(revive: boolean = true): void {
resetStatus(revive: boolean = true, confusion: boolean = false): void {
const lastStatus = this.status?.effect;
if (!revive && lastStatus === StatusEffect.FAINT) {
return;
@ -2444,6 +2454,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.lapseTag(BattlerTagType.NIGHTMARE);
}
}
if (confusion) {
if (this.getTag(BattlerTagType.CONFUSED)) {
this.lapseTag(BattlerTagType.CONFUSED);
}
}
}
primeSummonData(summonDataPrimer: PokemonSummonData): void {
@ -3381,7 +3396,7 @@ export class EnemyPokemon extends Pokemon {
const target = this.scene.getField()[mt];
let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1);
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND].includes(move.id)) {
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) {
targetScore = -20;
} else if (move instanceof AttackMove) {
const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove);

View File

@ -4,4 +4,5 @@ export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!",
"badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!",
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"notDisabled": "{{pokemonName}}'s {{moveName}} ist\nnicht mehr deaktiviert!",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "IV-Scanner auf {{pokemonName}} benutzen?",
"wildPokemonWithAffix": "{{pokemonName}} (wild)",
"foePokemonWithAffix": "{{pokemonName}} (Gegner)",
"useMove": "{{pokemonNameWithAffix}} setzt {{moveName}} ein!",
"drainMessage": "{{pokemonName}} wurde Energie abgesaugt",
"regainHealth": "KP von {{pokemonName}} wurden wieder aufgefrischt!"
} as const;

View File

@ -379,6 +379,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "Meine Expertise in Bezug auf Gesteins-Pokémon wird dich besiegen! Komm schon!",

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Rich Kid",
"rich_kids": "Schnösel",
"roughneck": "Raufbold",
"sailor": "Matrose",
"scientist": "Forscher",
"scientist_female": "Forscherin",
"scientists": "Forscher",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "Ein Sandsturm kommt auf!",
"sandstormLapseMessage": "Der Sandsturm tobt.",
"sandstormClearMessage": "Der Sandsturm legt sich.",
"sandstormDamageMessage": " Der Sandsturm fügt {{pokemonPrefix}}{{pokemonName}} Schaden zu!",
"sandstormDamageMessage": " Der Sandsturm fügt {{pokemonNameWithAffix}} Schaden zu!",
"hailStartMessage": "Es fängt an zu hageln!",
"hailLapseMessage": "Der Hagelsturm tobt.",
"hailClearMessage": "Der Hagelsturm legt sich.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} wird von Hagelkörnern getroffen!",
"hailDamageMessage": "{{pokemonNameWithAffix}} wird von Hagelkörnern getroffen!",
"snowStartMessage": "Es fängt an zu schneien!",
"snowLapseMessage": "Der Schneesturm tobt.",

View File

@ -5,5 +5,6 @@ export const abilityTriggers: SimpleTranslationEntries = {
"badDreams": "{{pokemonName}} is tormented!",
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!",
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!"
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
"wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}} used {{moveName}}!",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Rich Kid",
"rich_kids": "Rich Kids",
"roughneck": "Roughneck",
"sailor": "Sailor",
"scientist": "Scientist",
"scientist_female": "Scientist",
"scientists": "Scientists",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "A sandstorm brewed!",
"sandstormLapseMessage": "The sandstorm rages.",
"sandstormClearMessage": "The sandstorm subsided.",
"sandstormDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is buffeted\nby the sandstorm!",
"sandstormDamageMessage": "{{pokemonNameWithAffix}} is buffeted\nby the sandstorm!",
"hailStartMessage": "It started to hail!",
"hailLapseMessage": "Hail continues to fall.",
"hailClearMessage": "The hail stopped.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is pelted\nby the hail!",
"hailDamageMessage": "{{pokemonNameWithAffix}} is pelted\nby the hail!",
"snowStartMessage": "It started to snow!",
"snowLapseMessage": "The snow is falling down.",

View File

@ -4,4 +4,5 @@ export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "¡{{abilityName}} de {{pokemonName}}\nlo protegió del daño de retroceso!",
"badDreams": "¡{{pokemonName}} está atormentado!",
"windPowerCharged": "¡{{pokemonName}} se ha cargado de electricidad gracias a {{moveName}}!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
"eggHatching": "¿Y esto?",
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?",
"wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}} used {{moveName}}!",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "¡Amigo, te haré caminar por la borda si pierdes!",
2: "¡Adelante! ¡Mi orgullo como marinero está en auge!",
3: "¡Ah del barco! ¿Estás mareado?"
},
"victory": {
1: "¡Argh! ¡Derrotado por un niño!",
2: "¡Tu espíritu me ha hundido!",
3: "Creo que soy yo quien está mareado..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -94,6 +94,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Niña Bien",
"rich_kids": "Niños Bien",
"roughneck": "Calvo",
"sailor": "Marinero",
"scientist": "Científico",
"scientist_female": "Científica",
"scientists": "Científicos",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "¡Se ha desatado una tormenta de arena!",
"sandstormLapseMessage": "La tormenta de arena arrecia...",
"sandstormClearMessage": "La tormenta de arena termino.",
"sandstormDamageMessage": "¡La tormenta de arena zarandea al\n{{pokemonName}} {{pokemonPrefix}}!",
"sandstormDamageMessage": "¡La tormenta de arena zarandea al\n{{pokemonNameWithAffix}}!",
"hailStartMessage": "¡Ha empezado a granizar!",
"hailLapseMessage": "Sigue granizando...",
"hailClearMessage": "Had dejado de granizar.",
"hailDamageMessage": "El granizo golpea al\n{{pokemonName}} {{pokemonPrefix}}!",
"hailDamageMessage": "El granizo golpea al\n{{pokemonNameWithAffix}}!",
"snowStartMessage": "¡Ha empezado a nevar!",
"snowLapseMessage": "Sigue nevando...",

View File

@ -3,5 +3,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
"badDreams": "{{pokemonName}} a le sommeil agité !",
"windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !"
"windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"eggHatching": "Oh ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV sur {{pokemonName}} ?",
"wildPokemonWithAffix": "{{pokemonName}} sauvage",
"foePokemonWithAffix": "{{pokemonName}} ennemi",
"useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Mademoiselle",
"rich_kids": "Richards",
"roughneck": "Loubard",
"sailor": "Marin",
"scientist": "Scientifique",
"scientist_female": "Scientifique",
"scientists": "Scientifiques",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "Une tempête de sable se prépare !",
"sandstormLapseMessage": "La tempête de sable fait rage !",
"sandstormClearMessage": "La tempête de sable se calme !",
"sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonPrefix}}{{pokemonName}} !",
"sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonNameWithAffix}} !",
"hailStartMessage": "Il commence à grêler !",
"hailLapseMessage": "La grêle continue de tomber !",
"hailClearMessage": "La grêle sest arrêtée !",
"hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonPrefix}}{{pokemonName}} !",
"hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonNameWithAffix}} !",
"snowStartMessage": "Il commence à neiger !",
"snowLapseMessage": "Il y a une tempête de neige !",

View File

@ -4,4 +4,5 @@ export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!",
"badDreams": "{{pokemonName}} è tormentato!",
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?",
"eggHatching": "Oh!",
"ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?",
"wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}} used {{moveName}}!",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Rich Kid",
"rich_kids": "Rich Kids",
"roughneck": "Roughneck",
"sailor": "Sailor",
"scientist": "Scientist",
"scientist_female": "Scientist",
"scientists": "Scientists",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "Si è scatenata una tempesta di sabbia!",
"sandstormLapseMessage": "La tempesta di sabbia infuria.",
"sandstormClearMessage": "La tempesta di sabbia si è placata.",
"sandstormDamageMessage": "{{pokemonPrefix}}{{pokemonName}} è stato colpito\ndalla tempesta di sabbia!",
"sandstormDamageMessage": "{{pokemonNameWithAffix}} è stato colpito\ndalla tempesta di sabbia!",
"hailStartMessage": "Ha iniziato a grandinare!",
"hailLapseMessage": "La grandine continua a cadere.",
"hailClearMessage": "Ha smesso di grandinare.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} è stato colpito\ndalla grandine!",
"hailDamageMessage": "{{pokemonNameWithAffix}} è stato colpito\ndalla grandine!",
"snowStartMessage": "Ha iniziato a nevicare!",
"snowLapseMessage": "La neve sta continuando a cadere.",

View File

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

View File

@ -55,5 +55,8 @@ export const battle: SimpleTranslationEntries = {
"notDisabled": "{{pokemonName}}의\n{{moveName}} 사슬묶기가 풀렸다!",
"skipItemQuestion": "아이템을 받지 않고 넘어가시겠습니까?",
"eggHatching": "어라…?",
"ivScannerUseQuestion": "{{pokemonName}}에게 개체값탐지기를 사용하시겠습니까?"
"ivScannerUseQuestion": "{{pokemonName}}에게 개체값탐지기를 사용하시겠습니까?",
"wildPokemonWithAffix": "야생 {{pokemonName}}",
"foePokemonWithAffix": "상대 {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}}의 {{moveName}}!"
} as const;

View File

@ -144,69 +144,69 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"ace_trainer": {
"encounter": {
1: "You seem quite confident.",
2: "Your Pokémon… Show them to me…",
3: "Because I'm an Ace Trainer, people think I'm strong.",
4: "Are you aware of what it takes to be an Ace Trainer?"
1: "너는 꽤 자신만만해 보이는구나.",
2: "너의 포켓몬들… 나에게 보여줘…",
3: "내가 엘리트 트레이너라서, 사람들은 내가 강하다고 생각해.",
4: "엘리트 트레이너가 되려면 무엇이 필요한지 알고 있니?"
},
"victory": {
1: "Yes… You have good Pokémon…",
2: "What?! But I'm a battling genius!",
3: "Of course, you are the main character!",
4: "OK! OK! You could be an Ace Trainer!"
1: "그러네… 넌 좋은 포켓몬을 가졌구나…",
2: "뭐? 말도 안 돼, 난 배틀 천재라구!",
3: "그래도 역시, 네가 주인공이구나!",
4: "좋아! 좋아! 너도 엘리트 트레이너가 될 수 있겠어!"
},
"defeat": {
1: "I am devoting my body and soul to Pokémon battles!",
2: "All within my expectations… Nothing to be surprised about…",
3: "I thought I'd grow up to be a frail person who looked like they would break if you squeezed them too hard.",
4: "Of course I'm strong and don't lose. It's important that I win gracefully."
1: "난 내 몸과 마음을 포켓몬 배틀에 바치고 있어!",
2: "모두 예상된 일이었어… 이건 놀랄 일이 아니야…",
3: "난 내가 강하게 압박하면 무너질 연약한 사람이라고 생각했어.",
4: "난 강하고, 지지 않아. 그저 멋지게 이길 수 없었기 때문이야."
}
},
"parasol_lady": {
"encounter": {
1: "Time to grace the battlefield with elegance and poise!",
1: "우아함과 침착함으로 승부하겠습니다!",
},
"victory": {
1: "My elegance remains unbroken!",
1: "그래도 제 우아함은 무너지지 않아요!",
}
},
"twins": {
"encounter": {
1: "Get ready, because when we team up, it's double the trouble!",
2: "Two hearts, one strategy let's see if you can keep up with our twin power!",
3: "Hope you're ready for double trouble, because we're about to bring the heat!"
1: "각오해, 우리가 한 팀이 되면 두 배로 강해진다구!",
2: "마음은 두 개지만 우리는 하나 네가 쌍둥이의 파워를 따라잡을 수 있는지 보겠어!",
3: "두 배로 각오하는 게 좋을 거야. 우리가 곧 화나게 할 거거든!"
},
"victory": {
1: "We may have lost this round, but our bond remains unbreakable!",
2: "Our twin spirit won't be dimmed for long.",
3: "We'll come back stronger as a dynamic duo!"
1: "비록 우리는 졌지만, 우리의 관계는 깨지지 않아!",
2: "그래도 우리의 영혼은 오랫동안 흐려지지 않을 거야.",
3: "더 강력한 듀오로 강해져서 돌아오겠어!"
},
"defeat": {
1: "Twin power reigns supreme!",
2: "Two hearts, one triumph!",
3: "Double the smiles, double the victory dance!"
1: "우리 쌍둥이의 파워는 최고야!",
2: "마음은 두 개지만 승리는 하나!",
3: "미소도 두 배, 승리의 댄스도 두 배!"
}
},
"cyclist": {
"encounter": {
1: "Get ready to eat my dust!",
2: "Gear up, challenger! I'm about to leave you in the dust!",
3: "Pedal to the metal, let's see if you can keep pace!"
1: "내가 만든 먼지나 마실 준비하시지!",
2: "준비하라구! 난 널 먼지 속에 놓고 올 거니까!",
3: "전력을 다해야 할 거야, 네가 날 따라올 수 있는지 지켜보겠어!"
},
"victory": {
1: "Spokes may be still, but determination pedals on.",
2: "Outpaced!",
3: "The road to victory has many twists and turns yet to explore."
1: "바퀴가 움직이지 않더라도, 나의 페달은 그렇지 않아.",
2: "이런, 따라잡혔어!",
3: "승리로 가는 길에는 아직 만나지 못한 우여곡절이 많이 있구나."
},
},
"black_belt": {
"encounter": {
1: "I praise your courage in challenging me! For I am the one with the strongest kick!",
2: "Oh, I see. Would you like to be cut to pieces? Or do you prefer the role of punching bag?"
1: "네 용기가 대단하구나! 난 최고의 발차기 실력을 갖추고 있다구!",
2: "오, 알겠어. 산산조각이 나고 싶구나? 아니면 샌드백이 되고 싶은 거야?"
},
"victory": {
1: "Oh. The Pokémon did the fighting. My strong kick didn't help a bit.",
2: "Hmmm… If I was going to lose anyway, I was hoping to get totally messed up in the process."
1: "이런, 포켓몬이 배틀을 하는 동안 내 발차기는 전혀 도움이 되지 않았어.",
2: "음… 어차피 내가 질거라면, 완전 엉망진창이 되길 바랬는데…"
},
},
"battle_girl": {
@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "내 전문인 바위 타입 포켓몬으로 널 쓰러뜨려줄게! 덤벼!",
@ -943,31 +955,31 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"ramos": {
"encounter": {
1: `Did yeh enjoy the garden playground I made with all these sturdy plants o' mine?
$Their strength is a sign o' my strength as a gardener and a Gym Leader! Yeh sure yer up to facing all that?`,
1: `그래, 올곧게 자란 초목을 모아서 만든 풀 정글짐은 어땠는가?
$자네가 ! ?`,
},
"victory": {
1: "Yeh believe in yer Pokémon… And they believe in yeh, too… It was a fine battle, sprout."
1: "포켓몬은 자네를 믿고, 자네는 그들을 믿는다…가슴이 후련해지는 승부였구먼."
},
"defeat": {
1: "Hohoho… Indeed. Frail little blades o' grass'll break through even concrete."
1: "호호호…연약해 보이는 풀잎은 콘크리트도 뚫을 수 있다네."
}
},
"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!
$Now come at me!`,
2: "My lens is always focused on victory--I won't let anything ruin this shot!"
1: `패배의 분함도 승리의 순간도
$ ! !
$, !`,
2: "나 비올라는 셔트 찬스를 노리는 것처럼--승리를 노릴 거야!"
},
"victory": {
1: "You and your Pokémon have shown me a whole new depth of field! Fantastic! Just fantastic!",
2: `The world you see through a lens, and the world you see with a Pokémon by your side
$The same world can look entirely different depending on your view.`
1: "너와 네 포켓몬은 최고의 콤비구나! 정말 멋져 멋져!",
2: `렌즈 너머의 세계와 포켓몬의 마음으로 보는 세계
$똑같이 .`
},
"defeat": {
1: "The photo from the moment of my victory will be a real winner, all right!",
2: "Yes! I took some great photos!"
1: "내가 승리한 순간을 찍은 사진은 정말 멋져 멋져!",
2: "좋아! 멋진 사진을 찍었어!"
}
},
"candice": {

View File

@ -101,6 +101,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"smasher": "테니스선수",
"snow_worker": "작업원",
"snow_worker_female": "작업원",
"sailor": "선원",
"striker": "축구선수",
"school_kid": "학원끝난 아이",
"school_kid_female": "학원끝난 아이",

View File

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

View File

@ -3,5 +3,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano de recuo!",
"badDreams": "{{pokemonName}} está tendo pesadelos!",
"windPowerCharged": "Ser atingido por {{moveName}} carregou {{pokemonName}} com poder!"
"windPowerCharged": "Ser atingido por {{moveName}} carregou {{pokemonName}} com poder!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "Tem certeza de que não quer escolher um item?",
"eggHatching": "Opa?",
"ivScannerUseQuestion": "Quer usar o Scanner de IVs em {{pokemonName}}?",
"wildPokemonWithAffix": "{{pokemonName}} selvagem",
"foePokemonWithAffix": "{{pokemonName}} adversário",
"useMove": "{{pokemonNameWithAffix}} usou {{moveName}}!",
"drainMessage": "{{pokemonName}} teve sua\nenergia drenada!",
"regainHealth": "{{pokemonName}} recuperou\npontos de saúde!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ai! Queimei minha língua!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "Minha especialidade em Pokémon do tipo Pedra vai te derrubar! Vamos lá!",

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Garota Rica",
"rich_kids": "Garotos Ricos",
"roughneck": "Arruaceiro",
"sailor": "Marinheiro",
"scientist": "Cientista",
"scientist_female": "Cientista",
"scientists": "Cientistas",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "Uma tempestade de areia se formou!",
"sandstormLapseMessage": "A tempestade de areia é violenta.",
"sandstormClearMessage": "A tempestade de areia diminuiu.",
"sandstormDamageMessage": "{{pokemonPrefix}}{{pokemonName}} é atingido\npela tempestade de areia!",
"sandstormDamageMessage": "{{pokemonNameWithAffix}} é atingido\npela tempestade de areia!",
"hailStartMessage": "Começou a chover granizo!",
"hailLapseMessage": "Granizo cai do céu.",
"hailClearMessage": "O granizo parou.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} é atingido\npelo granizo!",
"hailDamageMessage": "{{pokemonNameWithAffix}} é atingido\npelo granizo!",
"snowStartMessage": "Começou a nevar!",
"snowLapseMessage": "A neve continua caindo.",

View File

@ -3,5 +3,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力",
"badDreams": "{{pokemonName}} 被折磨着!",
"windPowerCharged": "受 {{moveName}} 的影响, {{pokemonName}} 提升了能力!"
"windPowerCharged": "受 {{moveName}} 的影响, {{pokemonName}} 提升了能力!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

View File

@ -56,6 +56,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "你确定要跳过拾取道具吗?",
"eggHatching": "咦?",
"ivScannerUseQuestion": "对 {{pokemonName}} 使用个体值扫描仪?",
"wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}} used {{moveName}}!",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -199,7 +199,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"MULTI_LENS": { name: "多重镜" },
"HEALING_CHARM": { name: "治愈护符", description: "HP回复量增加10% (含复活)" },
"HEALING_CHARM": { name: "治愈护符", description: "HP回复量增加10% (含复活)" },
"CANDY_JAR": { name: "糖果罐", description: "神奇糖果提供的升级额外增加1级" },
"BERRY_POUCH": { name: "树果袋", description: "使用树果时有30%的几率不会消耗树果" },

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "Rich Kid",
"rich_kids": "富二代组合",
"roughneck": "光头男",
"sailor": "水手",
"scientist": "研究员",
"scientist_female": "研究员",
"scientists": "研究员组合",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "开始刮沙暴了!",
"sandstormLapseMessage": "沙暴肆虐。",
"sandstormClearMessage": "沙暴停止了!",
"sandstormDamageMessage": "沙暴袭击了{{pokemonPrefix}}{{pokemonName}}",
"sandstormDamageMessage": "沙暴袭击了{{pokemonNameWithAffix}}",
"hailStartMessage": "开始下冰雹了!",
"hailLapseMessage": "冰雹继续肆虐。",
"hailClearMessage": "冰雹不再下了。",
"hailDamageMessage": "冰雹袭击了{{pokemonPrefix}}{{pokemonName}}",
"hailDamageMessage": "冰雹袭击了{{pokemonNameWithAffix}}",
"snowStartMessage": "开始下雪了!",
"snowLapseMessage": "雪继续下。",

View File

@ -3,5 +3,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
"badDreams": "{{pokemonName}} 被折磨着!",
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!"
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
} as const;

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,9 @@ export const battle: SimpleTranslationEntries = {
"skipItemQuestion": "你要跳過拾取道具嗎?",
"eggHatching": "咦?",
"ivScannerUseQuestion": "對 {{pokemonName}} 使用個體值掃描?",
"wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}",
"useMove": "{{pokemonNameWithAffix}} used {{moveName}}!",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} regained\nhealth!"
} as const;

View File

@ -371,6 +371,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
3: "Ow! I scorched the tip of my nose!"
},
},
"sailor": {
"encounter": {
1: "Matey, you're walking the plank if you lose!",
2: "Come on then! My sailor's pride is at stake!",
3: "Ahoy there! Are you seasick?"
},
"victory": {
1: "Argh! Beaten by a kid!",
2: "Your spirit sank me!",
3: "I think it's me that's seasick..."
},
},
"brock": {
"encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!",

View File

@ -212,7 +212,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
MULTI_LENS: { name: "多重鏡" },
HEALING_CHARM: {
name: "治癒護符",
description: "HP恢復量增加10% (含復活)",
description: "HP恢復量增加10% (含復活)",
},
CANDY_JAR: { name: "糖果罐", description: "神奇糖果提供的升級提升1級" },
BERRY_POUCH: {

View File

@ -95,6 +95,7 @@ export const trainerClasses: SimpleTranslationEntries = {
"rich_kid_female": "富家孩子",
"rich_kids": "富二代組合",
"roughneck": "光頭男",
"sailor": "水手",
"scientist": "研究員",
"scientist_female": "研究員",
"scientists": "研究員組合",

View File

@ -15,12 +15,12 @@ export const weather: SimpleTranslationEntries = {
"sandstormStartMessage": "開始刮沙暴了!",
"sandstormLapseMessage": "沙暴肆虐。",
"sandstormClearMessage": "沙暴停止了。",
"sandstormDamageMessage": "沙暴襲擊了{{pokemonPrefix}}{{pokemonName}}!",
"sandstormDamageMessage": "沙暴襲擊了{{pokemonNameWithAffix}}!",
"hailStartMessage": "開始下冰雹了!",
"hailLapseMessage": "冰雹繼續肆虐。",
"hailClearMessage": "冰雹不再下了。",
"hailDamageMessage": "冰雹襲擊了{{pokemonPrefix}}{{pokemonName}}!",
"hailDamageMessage": "冰雹襲擊了{{pokemonNameWithAffix}}!",
"snowStartMessage": "開始下雪了!",
"snowLapseMessage": "雪繼續下。",

View File

@ -1,19 +1,40 @@
import { BattleSpec } from "./enums/battle-spec";
import Pokemon from "./field/pokemon";
import i18next from "./plugins/i18n";
/**
* Builds a message by concatenating the Pokemon name with its potential affix and the given text
* @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance for {@linkcode getPokemonNameWithAffix}
* @param {string} content any text
* @returns {string} ex: "Wild Gengar fainted!", "Ectoplasma sauvage est K.O!"
* @see {@linkcode getPokemonNameWithAffix} for the Pokemon's name and potentiel affix
*/
export function getPokemonMessage(pokemon: Pokemon, content: string): string {
return `${getPokemonPrefix(pokemon)}${pokemon.name}${content}`;
return `${getPokemonNameWithAffix(pokemon)}${content}`;
}
export function getPokemonPrefix(pokemon: Pokemon): string {
let prefix: string;
/**
* Retrieves the Pokemon's name, potentially with an affix indicating its role (wild or foe) in the current battle context, translated
* @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance
* @returns {string} ex: "Wild Gengar", "Ectoplasma sauvage"
*/
export function getPokemonNameWithAffix(pokemon: Pokemon): string {
switch (pokemon.scene.currentBattle.battleSpec) {
case BattleSpec.DEFAULT:
prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? "Foe " : "Wild " : "";
break;
return !pokemon.isPlayer()
? pokemon.hasTrainer()
? i18next.t("battle:foePokemonWithAffix", {
pokemonName: pokemon.name,
})
: i18next.t("battle:wildPokemonWithAffix", {
pokemonName: pokemon.name,
})
: pokemon.name;
case BattleSpec.FINAL_BOSS:
prefix = !pokemon.isPlayer() ? "Foe " : "";
break;
return !pokemon.isPlayer()
? i18next.t("battle:foePokemonWithAffix", { pokemonName: pokemon.name })
: pokemon.name;
default:
return pokemon.name;
}
return prefix;
}

View File

@ -23,6 +23,7 @@ import { ModifierTier } from "./modifier-tier";
import { Nature, getNatureName, getNatureStatMultiplier } from "#app/data/nature";
import i18next from "#app/plugins/i18n";
import { getModifierTierTextTint } from "#app/ui/text";
import { BattlerTagType } from "#app/data/enums/battler-tag-type.js";
import * as Overrides from "../overrides";
const outputModifierData = false;
@ -233,7 +234,7 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, group?: string) {
super(localeKey, iconImage, newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)),
selectFilter || ((pokemon: PlayerPokemon) => {
if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) {
if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))))) {
return PartyUiHandler.NoEffectMessage;
}
return null;
@ -283,7 +284,7 @@ export class PokemonStatusHealModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, ((_type, args) => new Modifiers.PokemonStatusHealModifier(this, (args[0] as PlayerPokemon).id)),
((pokemon: PlayerPokemon) => {
if (!pokemon.hp || !pokemon.status) {
if (!pokemon.hp || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))) {
return PartyUiHandler.NoEffectMessage;
}
return null;

View File

@ -29,10 +29,25 @@ export type ModifierPredicate = (modifier: Modifier) => boolean;
const iconOverflowIndex = 24;
export const modifierSortFunc = (a: Modifier, b: Modifier) => {
const itemNameMatch = a.type.name.localeCompare(b.type.name);
const typeNameMatch = a.constructor.name.localeCompare(b.constructor.name);
const aId = a instanceof PokemonHeldItemModifier ? a.pokemonId : 4294967295;
const bId = b instanceof PokemonHeldItemModifier ? b.pokemonId : 4294967295;
return aId < bId ? 1 : aId > bId ? -1 : 0;
//First sort by pokemonID
if (aId < bId) {
return 1;
} else if (aId>bId) {
return -1;
} else if (aId === bId) {
//Then sort by item type
if (typeNameMatch === 0) {
return itemNameMatch;
//Finally sort by item name
} else {
return typeNameMatch;
}
}
};
export class ModifierBar extends Phaser.GameObjects.Container {
@ -50,18 +65,19 @@ export class ModifierBar extends Phaser.GameObjects.Container {
this.removeAll(true);
const visibleIconModifiers = modifiers.filter(m => m.isIconVisible(this.scene as BattleScene));
visibleIconModifiers.sort(modifierSortFunc);
const nonPokemonSpecificModifiers = visibleIconModifiers.filter(m => !(m as PokemonHeldItemModifier).pokemonId).sort(modifierSortFunc);
const pokemonSpecificModifiers = visibleIconModifiers.filter(m => (m as PokemonHeldItemModifier).pokemonId).sort(modifierSortFunc);
const sortedVisibleIconModifiers = nonPokemonSpecificModifiers.concat(pokemonSpecificModifiers);
const thisArg = this;
visibleIconModifiers.forEach((modifier: PersistentModifier, i: integer) => {
sortedVisibleIconModifiers.forEach((modifier: PersistentModifier, i: integer) => {
const icon = modifier.getIcon(this.scene as BattleScene);
if (i >= iconOverflowIndex) {
icon.setVisible(false);
}
this.add(icon);
this.setModifierIconPosition(icon, visibleIconModifiers.length);
this.setModifierIconPosition(icon, sortedVisibleIconModifiers.length);
icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 24), Phaser.Geom.Rectangle.Contains);
icon.on("pointerover", () => {
(this.scene as BattleScene).ui.showTooltip(modifier.type.name, modifier.type.getDescription(this.scene as BattleScene));
@ -1130,13 +1146,11 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
restorePoints = Math.floor(restorePoints * (args[1] as number));
}
if (this.fainted || this.healStatus) {
pokemon.resetStatus();
pokemon.resetStatus(true, true);
}
pokemon.hp = Math.min(pokemon.hp + Math.max(Math.ceil(Math.max(Math.floor((this.restorePercent * 0.01) * pokemon.getMaxHp()), restorePoints)), 1), pokemon.getMaxHp());
return true;
}
return false;
}
}
@ -1148,8 +1162,7 @@ export class PokemonStatusHealModifier extends ConsumablePokemonModifier {
apply(args: any[]): boolean {
const pokemon = args[0] as Pokemon;
pokemon.resetStatus();
pokemon.resetStatus(true, true);
return true;
}
}

View File

@ -23,7 +23,7 @@ import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFu
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags";
import { BattlerTagType } from "./data/enums/battler-tag-type";
import { getPokemonMessage, getPokemonPrefix } from "./messages";
import { getPokemonMessage, getPokemonNameWithAffix } from "./messages";
import { Starter } from "./ui/starter-select-ui-handler";
import { Gender } from "./data/gender";
import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
@ -1667,6 +1667,11 @@ export class CheckSwitchPhase extends BattlePhase {
const pokemon = this.scene.getPlayerField()[this.fieldIndex];
if (this.scene.battleStyle === 1) {
super.end();
return;
}
if (this.scene.field.getAll().indexOf(pokemon) === -1) {
this.scene.unshiftPhase(new SummonMissingPhase(this.scene, this.fieldIndex));
super.end();
@ -2276,7 +2281,7 @@ export class TurnEndPhase extends FieldPhase {
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t("battle:notDisabled", { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name })));
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t("battle:notDisabled", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: allMoves[pokemon.summonData.disabledMove].name })));
pokemon.summonData.disabledMove = Moves.NONE;
}
@ -2643,7 +2648,10 @@ export class MovePhase extends BattlePhase {
if (this.move.getMove().hasAttr(ChargeAttr)) {
const lastMove = this.pokemon.getLastXMoves() as TurnMove[];
if (!lastMove.length || lastMove[0].move !== this.move.getMove().id || lastMove[0].result !== MoveResult.OTHER) {
this.scene.queueMessage(getPokemonMessage(this.pokemon, ` used\n${this.move.getName()}!`), 500);
this.scene.queueMessage(i18next.t("battle:useMove", {
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
moveName: this.move.getName()
}), 500);
return;
}
}
@ -2652,7 +2660,10 @@ export class MovePhase extends BattlePhase {
return;
}
this.scene.queueMessage(getPokemonMessage(this.pokemon, ` used\n${this.move.getName()}!`), 500);
this.scene.queueMessage(i18next.t("battle:useMove", {
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
moveName: this.move.getName()
}), 500);
applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true), this.move.getMove());
}
@ -4910,6 +4921,7 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end());
this.scene.money -= rerollCost;
this.scene.updateMoneyText();
this.scene.animateMoneyChanged(false);
this.scene.playSound("buy");
}
} else if (cursor === 1) {
@ -4955,6 +4967,7 @@ export class SelectModifierPhase extends BattlePhase {
if (success) {
this.scene.money -= cost;
this.scene.updateMoneyText();
this.scene.animateMoneyChanged(false);
this.scene.playSound("buy");
(this.scene.ui.getHandler() as ModifierSelectUiHandler).updateCostText();
} else {

View File

@ -19,7 +19,8 @@ const AUTO_DISABLED = ["Auto", "Disabled"];
*/
export enum SettingType {
GENERAL,
ACCESSIBILITY
DISPLAY,
AUDIO
}
export interface Setting {
@ -37,34 +38,35 @@ export interface Setting {
*/
export const SettingKeys = {
Game_Speed: "GAME_SPEED",
Master_Volume: "MASTER_VOLUME",
BGM_Volume: "BGM_VOLUME",
SE_Volume: "SE_VOLUME",
HP_Bar_Speed: "HP_BAR_SPEED",
EXP_Gains_Speed: "EXP_GAINS_SPEED",
EXP_Party_Display: "EXP_PARTY_DISPLAY",
Skip_Seen_Dialogues: "SKIP_SEEN_DIALOGUES",
Battle_Style: "BATTLE_STYLE",
Enable_Retries: "ENABLE_RETRIES",
Tutorials: "TUTORIALS",
Touch_Controls: "TOUCH_CONTROLS",
Vibration: "VIBRATION",
Language: "LANGUAGE",
Damage_Numbers: "DAMAGE_NUMBERS",
UI_Theme: "UI_THEME",
Window_Type: "WINDOW_TYPE",
Tutorials: "TUTORIALS",
Move_Info: "MOVE_INFO",
Enable_Retries: "ENABLE_RETRIES",
Skip_Seen_Dialogues: "SKIP_SEEN_DIALOGUES",
Money_Format: "MONEY_FORMAT",
Damage_Numbers: "DAMAGE_NUMBERS",
Move_Animations: "MOVE_ANIMATIONS",
Show_Stats_on_Level_Up: "SHOW_LEVEL_UP_STATS",
Candy_Upgrade_Notification: "CANDY_UPGRADE_NOTIFICATION",
Candy_Upgrade_Display: "CANDY_UPGRADE_DISPLAY",
Money_Format: "MONEY_FORMAT",
Sprite_Set: "SPRITE_SET",
Move_Animations: "MOVE_ANIMATIONS",
Move_Info: "MOVE_INFO",
Show_Moveset_Flyout: "SHOW_MOVESET_FLYOUT",
Show_Arena_Flyout: "SHOW_ARENA_FLYOUT",
Show_Time_Of_Day_Widget: "SHOW_TIME_OF_DAY_WIDGET",
Time_Of_Day_Animation: "TIME_OF_DAY_ANIMATION",
Show_Stats_on_Level_Up: "SHOW_LEVEL_UP_STATS",
EXP_Gains_Speed: "EXP_GAINS_SPEED",
EXP_Party_Display: "EXP_PARTY_DISPLAY",
HP_Bar_Speed: "HP_BAR_SPEED",
Sprite_Set: "SPRITE_SET",
Fusion_Palette_Swaps: "FUSION_PALETTE_SWAPS",
Player_Gender: "PLAYER_GENDER",
Touch_Controls: "TOUCH_CONTROLS",
Vibration: "VIBRATION"
Master_Volume: "MASTER_VOLUME",
BGM_Volume: "BGM_VOLUME",
SE_Volume: "SE_VOLUME"
};
/**
@ -79,155 +81,10 @@ export const Setting: Array<Setting> = [
type: SettingType.GENERAL
},
{
key: SettingKeys.Master_Volume,
label: "Master Volume",
options: VOLUME_OPTIONS,
default: 5,
type: SettingType.GENERAL
},
{
key: SettingKeys.BGM_Volume,
label: "BGM Volume",
options: VOLUME_OPTIONS,
default: 10,
type: SettingType.GENERAL
},
{
key: SettingKeys.SE_Volume,
label: "SE Volume",
options: VOLUME_OPTIONS,
default: 10,
type: SettingType.GENERAL
},
{
key: SettingKeys.Language,
label: "Language",
options: ["English", "Change"],
key: SettingKeys.HP_Bar_Speed,
label: "HP Bar Speed",
options: ["Normal", "Fast", "Faster", "Skip"],
default: 0,
type: SettingType.GENERAL,
requireReload: true
},
{
key: SettingKeys.Damage_Numbers,
label: "Damage Numbers",
options: ["Off", "Simple", "Fancy"],
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.UI_Theme,
label: "UI Theme",
options: ["Default", "Legacy"],
default: 0,
type: SettingType.GENERAL,
requireReload: true
},
{
key: SettingKeys.Window_Type,
label: "Window Type",
options: new Array(5).fill(null).map((_, i) => (i + 1).toString()),
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Tutorials,
label: "Tutorials",
options: OFF_ON,
default: 1,
type: SettingType.GENERAL
},
{
key: SettingKeys.Move_Info,
label: "Move Info",
options: OFF_ON,
default: 1,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Enable_Retries,
label: "Enable Retries",
options: OFF_ON,
default: 0,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Skip_Seen_Dialogues,
label: "Skip Seen Dialogues",
options: OFF_ON,
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Candy_Upgrade_Notification,
label: "Candy Upgrade Notification",
options: ["Off", "Passives Only", "On"],
default: 0,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Candy_Upgrade_Display,
label: "Candy Upgrade Display",
options: ["Icon", "Animation"],
default: 0,
type: SettingType.ACCESSIBILITY,
requireReload: true
},
{
key: SettingKeys.Money_Format,
label: "Money Format",
options: ["Normal", "Abbreviated"],
default: 0,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Sprite_Set,
label: "Sprite Set",
options: ["Consistent", "Mixed Animated"],
default: 0,
type: SettingType.GENERAL,
requireReload: true
},
{
key: SettingKeys.Move_Animations,
label: "Move Animations",
options: OFF_ON,
default: 1,
type: SettingType.GENERAL
},
{
key: SettingKeys.Show_Moveset_Flyout,
label: "Show Moveset Flyout",
options: OFF_ON,
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_Time_Of_Day_Widget,
label: "Show Time of Day Widget",
options: OFF_ON,
default: 1,
type: SettingType.ACCESSIBILITY,
requireReload: true,
},
{
key: SettingKeys.Time_Of_Day_Animation,
label: "Time of Day Animation",
options: ["Bounce", "Back"],
default: 0,
type: SettingType.ACCESSIBILITY
},
{
key: SettingKeys.Show_Stats_on_Level_Up,
label: "Show Stats on Level Up",
options: OFF_ON,
default: 1,
type: SettingType.GENERAL
},
{
@ -245,26 +102,33 @@ export const Setting: Array<Setting> = [
type: SettingType.GENERAL
},
{
key: SettingKeys.HP_Bar_Speed,
label: "HP Bar Speed",
options: ["Normal", "Fast", "Faster", "Skip"],
key: SettingKeys.Skip_Seen_Dialogues,
label: "Skip Seen Dialogues",
options: OFF_ON,
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Fusion_Palette_Swaps,
label: "Fusion Palette Swaps",
key: SettingKeys.Battle_Style,
label: "Battle Style",
options: ["Switch", "Set"],
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Enable_Retries,
label: "Enable Retries",
options: OFF_ON,
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Tutorials,
label: "Tutorials",
options: OFF_ON,
default: 1,
type: SettingType.GENERAL
},
{
key: SettingKeys.Player_Gender,
label: "Player Gender",
options: ["Boy", "Girl"],
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Touch_Controls,
label: "Touch Controls",
@ -278,6 +142,151 @@ export const Setting: Array<Setting> = [
options: AUTO_DISABLED,
default: 0,
type: SettingType.GENERAL
},
{
key: SettingKeys.Language,
label: "Language",
options: ["English", "Change"],
default: 0,
type: SettingType.DISPLAY,
requireReload: true
},
{
key: SettingKeys.UI_Theme,
label: "UI Theme",
options: ["Default", "Legacy"],
default: 0,
type: SettingType.DISPLAY,
requireReload: true
},
{
key: SettingKeys.Window_Type,
label: "Window Type",
options: new Array(5).fill(null).map((_, i) => (i + 1).toString()),
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Money_Format,
label: "Money Format",
options: ["Normal", "Abbreviated"],
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Damage_Numbers,
label: "Damage Numbers",
options: ["Off", "Simple", "Fancy"],
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Move_Animations,
label: "Move Animations",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Show_Stats_on_Level_Up,
label: "Show Stats on Level Up",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Candy_Upgrade_Notification,
label: "Candy Upgrade Notification",
options: ["Off", "Passives Only", "On"],
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Candy_Upgrade_Display,
label: "Candy Upgrade Display",
options: ["Icon", "Animation"],
default: 0,
type: SettingType.DISPLAY,
requireReload: true
},
{
key: SettingKeys.Move_Info,
label: "Move Info",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Show_Moveset_Flyout,
label: "Show Moveset Flyout",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Show_Arena_Flyout,
label: "Show Battle Effects Flyout",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Show_Time_Of_Day_Widget,
label: "Show Time of Day Widget",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY,
requireReload: true,
},
{
key: SettingKeys.Time_Of_Day_Animation,
label: "Time of Day Animation",
options: ["Bounce", "Back"],
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Sprite_Set,
label: "Sprite Set",
options: ["Consistent", "Mixed Animated"],
default: 0,
type: SettingType.DISPLAY,
requireReload: true
},
{
key: SettingKeys.Fusion_Palette_Swaps,
label: "Fusion Palette Swaps",
options: OFF_ON,
default: 1,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Player_Gender,
label: "Player Gender",
options: ["Boy", "Girl"],
default: 0,
type: SettingType.DISPLAY
},
{
key: SettingKeys.Master_Volume,
label: "Master Volume",
options: VOLUME_OPTIONS,
default: 5,
type: SettingType.AUDIO
},
{
key: SettingKeys.BGM_Volume,
label: "BGM Volume",
options: VOLUME_OPTIONS,
default: 10,
type: SettingType.AUDIO
},
{
key: SettingKeys.SE_Volume,
label: "SE Volume",
options: VOLUME_OPTIONS,
default: 10,
type: SettingType.AUDIO
}
];
@ -347,6 +356,9 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
case SettingKeys.Skip_Seen_Dialogues:
scene.skipSeenDialogues = Setting[index].options[value] === "On";
break;
case SettingKeys.Battle_Style:
scene.battleStyle = value;
break;
case SettingKeys.Candy_Upgrade_Notification:
if (scene.candyUpgradeNotification === value) {
break;

View File

@ -108,12 +108,13 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ];
: VoucherType.PREMIUM;
const key = TrainerType[trainerType];
const trainerName = trainerConfigs[trainerType].name;
const trainer = trainerConfigs[trainerType];
const title = trainer.title ? ` (${trainer.title})` : "";
vouchers[key] = new Voucher(
voucherType,
i18next.t("voucher:defeatTrainer", { trainerName })
`${i18next.t("voucher:defeatTrainer", { trainerName })} ${title}`,
);
}
const voucherKeys = Object.keys(vouchers);
for (const k of voucherKeys) {
vouchers[k].id = k;

View File

@ -9,7 +9,8 @@ import {Button} from "./enums/buttons";
import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler";
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
import BattleScene from "./battle-scene";
import SettingsAccessibilityUiHandler from "./ui/settings/settings-accessiblity-ui-handler";
import SettingsDisplayUiHandler from "./ui/settings/settings-display-ui-handler";
import SettingsAudioUiHandler from "./ui/settings/settings-audio-ui-handler";
type ActionKeys = Record<Button, () => void>;
@ -169,7 +170,7 @@ export class UiInputs {
}
buttonCycleOption(button: Button): void {
const whitelist = [StarterSelectUiHandler, SettingsUiHandler, SettingsAccessibilityUiHandler, SettingsGamepadUiHandler, SettingsKeyboardUiHandler];
const whitelist = [StarterSelectUiHandler, SettingsUiHandler, SettingsDisplayUiHandler, SettingsAudioUiHandler, SettingsGamepadUiHandler, SettingsKeyboardUiHandler];
const uiHandler = this.scene.ui?.getHandler();
if (whitelist.some(handler => uiHandler instanceof handler)) {
this.scene.ui.processInput(button);

View File

@ -142,10 +142,11 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
this.desc.setText(move?.effect || "");
// stop previous scrolling effects
// stop previous scrolling effects and reset y position
if (this.descScroll) {
this.descScroll.remove();
this.descScroll = null;
this.desc.y = (this.options?.top ? EFF_HEIGHT : 0) + BORDER - 2;
}
// determine if we need to add new scrolling effects

View File

@ -27,11 +27,12 @@ export class NavigationManager {
constructor() {
this.modes = [
Mode.SETTINGS,
Mode.SETTINGS_ACCESSIBILITY,
Mode.SETTINGS_DISPLAY,
Mode.SETTINGS_AUDIO,
Mode.SETTINGS_GAMEPAD,
Mode.SETTINGS_KEYBOARD,
];
this.labels = ["General", "Accessibility", "Gamepad", "Keyboard"];
this.labels = ["General", "Display", "Audio", "Gamepad", "Keyboard"];
}
public reset() {

View File

@ -4,7 +4,7 @@ import { Mode } from "../ui";
import AbstractSettingsUiHandler from "./abstract-settings-ui-handler";
import { Setting, SettingType } from "#app/system/settings/settings";
export default class SettingsAccessibilityUiHandler extends AbstractSettingsUiHandler {
export default class SettingsAudioUiHandler extends AbstractSettingsUiHandler {
/**
* Creates an instance of SettingsGamepadUiHandler.
*
@ -13,8 +13,8 @@ export default class SettingsAccessibilityUiHandler extends AbstractSettingsUiHa
*/
constructor(scene: BattleScene, mode?: Mode) {
super(scene, mode);
this.title = "Accessibility";
this.settings = Setting.filter(s => s.type === SettingType.ACCESSIBILITY);
this.title = "Audio";
this.settings = Setting.filter(s => s.type === SettingType.AUDIO);
this.localStorageKey = "settings";
}
}

View File

@ -0,0 +1,20 @@
import BattleScene from "../../battle-scene";
import { Mode } from "../ui";
"#app/inputs-controller.js";
import AbstractSettingsUiHandler from "./abstract-settings-ui-handler";
import { Setting, SettingType } from "#app/system/settings/settings";
export default class SettingsDisplayUiHandler extends AbstractSettingsUiHandler {
/**
* Creates an instance of SettingsGamepadUiHandler.
*
* @param scene - The BattleScene instance.
* @param mode - The UI mode, optional.
*/
constructor(scene: BattleScene, mode?: Mode) {
super(scene, mode);
this.title = "Display";
this.settings = Setting.filter(s => s.type === SettingType.DISPLAY);
this.localStorageKey = "settings";
}
}

View File

@ -224,6 +224,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
private canCycleNature: boolean;
private canCycleVariant: boolean;
private value: integer = 0;
private canAddParty: boolean;
private assetLoadCancelled: Utils.BooleanHolder;
private cursorObj: Phaser.GameObjects.Image;
@ -1047,6 +1048,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.tryStart();
}
this.updateInstructions();
/**
* If the user can't select a pokemon anymore,
* go to start button.
*/
if (!this.canAddParty) {
this.startCursorObj.setVisible(true);
this.setGenMode(true);
}
ui.playSelect();
} else {
ui.playError();
@ -2131,11 +2142,43 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.scene.time.delayedCall(Utils.fixedInt(500), () => this.tryUpdateValue());
return false;
}
/**
* this loop is used to set the Sprite's alpha value and check if the user can select other pokemon more.
*/
this.canAddParty = false;
const remainValue = valueLimit - newValue;
for (let g = 0; g < this.genSpecies.length; g++) {
for (let s = 0; s < this.genSpecies[g].length; s++) {
(this.starterSelectGenIconContainers[g].getAt(s) as Phaser.GameObjects.Sprite).setAlpha((newValue + this.scene.gameData.getSpeciesStarterValue(this.genSpecies[g][s].speciesId)) > valueLimit ? 0.375 : 1);
/** Cost of pokemon species */
const speciesStarterValue = this.scene.gameData.getSpeciesStarterValue(this.genSpecies[g][s].speciesId);
/** Used to detect if this pokemon is registered in starter */
const speciesStarterDexEntry = this.scene.gameData.dexData[this.genSpecies[g][s].speciesId];
/** {@linkcode Phaser.GameObjects.Sprite} object of Pokémon for setting the alpha value */
const speciesSprite = this.starterSelectGenIconContainers[g].getAt(s) as Phaser.GameObjects.Sprite;
/**
* If remainValue greater than or equal pokemon species, the user can select.
* so that the alpha value of pokemon sprite set 1.
*
* If speciesStarterDexEntry?.caughtAttr is true, this species registered in stater.
* we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too.
*/
if (remainValue >= speciesStarterValue) {
speciesSprite.setAlpha(1);
if (speciesStarterDexEntry?.caughtAttr) {
this.canAddParty = true;
}
} else {
/**
* If remainValue less than pokemon, the use can't select.
* so that the alpha value of pokemon sprite set 0.375.
*/
speciesSprite.setAlpha(0.375);
}
}
}
this.value = newValue;
return true;
}

View File

@ -22,6 +22,8 @@ import { Variant, getVariantTint } from "#app/data/variant";
import {Button} from "../enums/buttons";
import { Ability } from "../data/ability.js";
import i18next from "i18next";
import {modifierSortFunc} from "../modifier/modifier";
enum Page {
PROFILE,
@ -828,8 +830,9 @@ export default class SummaryUiHandler extends UiHandler {
statsContainer.add(statValue);
});
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === this.pokemon.id, true) as PokemonHeldItemModifier[];
const itemModifiers = (this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === this.pokemon.id, true) as PokemonHeldItemModifier[])
.sort(modifierSortFunc);
itemModifiers.forEach((item, i) => {
const icon = item.getIcon(this.scene, true);

View File

@ -42,7 +42,8 @@ import { PlayerGender } from "#app/data/enums/player-gender";
import GamepadBindingUiHandler from "./settings/gamepad-binding-ui-handler";
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
import KeyboardBindingUiHandler from "#app/ui/settings/keyboard-binding-ui-handler";
import SettingsAccessibilityUiHandler from "./settings/settings-accessiblity-ui-handler";
import SettingsDisplayUiHandler from "./settings/settings-display-ui-handler";
import SettingsAudioUiHandler from "./settings/settings-audio-ui-handler";
export enum Mode {
MESSAGE,
@ -63,7 +64,8 @@ export enum Mode {
MENU,
MENU_OPTION_SELECT,
SETTINGS,
SETTINGS_ACCESSIBILITY,
SETTINGS_DISPLAY,
SETTINGS_AUDIO,
SETTINGS_GAMEPAD,
GAMEPAD_BINDING,
SETTINGS_KEYBOARD,
@ -101,7 +103,8 @@ const noTransitionModes = [
Mode.GAMEPAD_BINDING,
Mode.KEYBOARD_BINDING,
Mode.SETTINGS,
Mode.SETTINGS_ACCESSIBILITY,
Mode.SETTINGS_AUDIO,
Mode.SETTINGS_DISPLAY,
Mode.SETTINGS_GAMEPAD,
Mode.SETTINGS_KEYBOARD,
Mode.ACHIEVEMENTS,
@ -154,7 +157,8 @@ export default class UI extends Phaser.GameObjects.Container {
new MenuUiHandler(scene),
new OptionSelectUiHandler(scene, Mode.MENU_OPTION_SELECT),
new SettingsUiHandler(scene),
new SettingsAccessibilityUiHandler(scene),
new SettingsDisplayUiHandler(scene),
new SettingsAudioUiHandler(scene),
new SettingsGamepadUiHandler(scene),
new GamepadBindingUiHandler(scene),
new SettingsKeyboardUiHandler(scene),