Compare commits

...

12 Commits

Author SHA1 Message Date
Arxalc
7c3ace7204
[Bug] Fixed primal weather interaction. (#1744)
* Fixed primal weather interaction.

* Made adjustments

* Improved code readability
2024-06-07 15:22:06 -04:00
Corrade
c177f3c1fb
[Bug] Ignored strong winds for stealth rock and anticipation (#1682) 2024-06-07 15:15:24 -04:00
Lee ByungHoon
d592187f2c
[Localization] Add localization in party-ui-handler (#1712)
* [Localization] Add localization in party-ui-handler

* [Localization] Add "Release", "Apply", "Teach" localization, changed translation of Korean

* [Localization] Translated party-ui-handler's localization to Deutsch
2024-06-07 15:08:34 -04:00
Madmadness65
a224f5e822 Add Partner Pikachu & Eevee party icons
This also necessitated giving them unique front & back sprites too, even if they are currently just duplicates of the normal forms. This change will help players identify when they are using/have encountered a Partner Pikachu or Eevee.
2024-06-07 13:58:48 -05:00
Adam Clemons
fb21caa769
[Bug] Fix ability Download switch in (1669) (#1679)
* Update ability Dowbload

* Remove whitespace

* Update ability.ts
2024-06-07 14:17:22 -04:00
hayuna
bb1dde5b0c
[Refactor] Move enum ExpNotification into separated file (#1909)
* Move enum ExpNotification into separated file

* Update phases.ts

* Change type of this.scene.expParty into enum
2024-06-07 13:14:52 -04:00
雪霁
19712e0d43
fix language auto detect (#1784) 2024-06-07 11:27:42 -05:00
Matthew Olker
20a3a4f60f added a few more gameobject names for debug 2024-06-07 10:27:36 -04:00
MutenYoshii
f17a4ff3f2
[Move] Implemented Court Change (#1799)
* [Move] Implemented Court Change

* Returned overides to normal

* Added recommended changes

* Removed an unnecessary if statement for swaparenatagsattr

* Move the swaptags array to the call as well as changes to the quiet boolean

---------

Co-authored-by: Juan <jmora279@fiu.edu>
2024-06-07 09:27:11 -05:00
MadridPawmot
4745b591c2
[Localization] Spanish dialogues (#1892)
* Update dialogue.ts

* Fixed typo
2024-06-07 15:02:24 +01:00
Sangmin Lee
50bf717c5c
[Localization] #1761 Korean trainer dialogue (roark, gardenia, maylene, fantina) (#1905)
* [Localization] #1761 Korean trainer dialogue (roark, gardenia)

* [Localization] #1761 Korean trainer dialogue (maylene, fantina)

* Modified Roark's dialogue more natural

Co-authored-by: returntoice <dieandbecome@gmail.com>

---------

Co-authored-by: returntoice <dieandbecome@gmail.com>
2024-06-07 09:57:14 -04:00
DustinLin
ffdbdc1139
fix sleep talk targeting (#1813) 2024-06-07 13:38:22 +01:00
63 changed files with 36100 additions and 4729 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -62,6 +62,7 @@ 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";
import { ExpNotification } from "./enums/exp-notification";
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
@ -141,7 +142,7 @@ export default class BattleScene extends SceneBase {
* Modes `1` and `2` are still compatible with stats display, level up, new move, etc.
* @default 0 - Uses the default normal experience gain display.
*/
public expParty: integer = 0;
public expParty: ExpNotification = 0;
public hpBarSpeed: integer = 0;
public fusionPaletteSwaps: boolean = true;
public enableTouchControls: boolean = false;
@ -320,6 +321,7 @@ export default class BattleScene extends SceneBase {
const field = this.add.container(0, 0);
field.setScale(6);
field.setName("container-field");
this.field = field;
@ -455,9 +457,13 @@ export default class BattleScene extends SceneBase {
const loadPokemonAssets = [];
this.arenaPlayer = new ArenaBase(this, true);
this.arenaPlayer.setName("container-arena-player");
this.arenaPlayerTransition = new ArenaBase(this, true);
this.arenaPlayerTransition.setName("container-arena-player-transition");
this.arenaEnemy = new ArenaBase(this, false);
this.arenaEnemy.setName("container-arena-enemy");
this.arenaNextEnemy = new ArenaBase(this, false);
this.arenaNextEnemy.setName("container-arena-next-enemy");
this.arenaBgTransition.setVisible(false);
this.arenaPlayerTransition.setVisible(false);
@ -472,6 +478,7 @@ export default class BattleScene extends SceneBase {
const trainer = this.addFieldSprite(0, 0, `trainer_${this.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
trainer.setOrigin(0.5, 1);
trainer.setName("sprite-trainer");
field.add(trainer);

View File

@ -1693,15 +1693,13 @@ export class DownloadAbAttr extends PostSummonAbAttr {
this.enemySpDef = 0;
this.enemyCountTally = 0;
if (pokemon.getOpponents()[0].summonData !== undefined) {
for (const opponent of pokemon.getOpponents()) {
this.enemyCountTally++;
this.enemyDef += opponent.getBattleStat(Stat.DEF);
this.enemySpDef += opponent.getBattleStat(Stat.SPDEF);
}
this.enemyDef = Math.round(this.enemyDef / this.enemyCountTally);
this.enemySpDef = Math.round(this.enemySpDef / this.enemyCountTally);
for (const opponent of pokemon.getOpponents()) {
this.enemyCountTally++;
this.enemyDef += opponent.getBattleStat(Stat.DEF);
this.enemySpDef += opponent.getBattleStat(Stat.SPDEF);
}
this.enemyDef = Math.round(this.enemyDef / this.enemyCountTally);
this.enemySpDef = Math.round(this.enemySpDef / this.enemyCountTally);
if (this.enemyDef < this.enemySpDef) {
this.stats = [BattleStat.ATK];
@ -1728,7 +1726,9 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
}
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) {
if ((this.weatherType === WeatherType.HEAVY_RAIN ||
this.weatherType === WeatherType.HARSH_SUN ||
this.weatherType === WeatherType.STRONG_WINDS) || !pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
@ -1856,6 +1856,52 @@ export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr {
}
}
/**
* Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon switching out.
*/
export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr {
/**
* @param pokemon The {@linkcode Pokemon} with the ability
* @param passive N/A
* @param args N/A
* @returns {boolean} Returns true if the weather clears, otherwise false.
*/
applyPreSwitchOut(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
const weatherType = pokemon.scene.arena.weather.weatherType;
let turnOffWeather = false;
// Clear weather only if user's ability matches the weather and no other pokemon has the ability.
switch (weatherType) {
case (WeatherType.HARSH_SUN):
if (pokemon.hasAbility(Abilities.DESOLATE_LAND)
&& pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.HEAVY_RAIN):
if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA)
&& pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.STRONG_WINDS):
if (pokemon.hasAbility(Abilities.DELTA_STREAM)
&& pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
turnOffWeather = true;
}
break;
}
if (turnOffWeather) {
pokemon.scene.arena.trySetWeather(WeatherType.NONE, false);
return true;
}
return false;
}
}
export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr {
applyPreSwitchOut(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
if (pokemon.getHpRatio() < 1 ) {
@ -2216,7 +2262,7 @@ function getAnticipationCondition(): AbAttrCondition {
for (const opponent of pokemon.getOpponents()) {
for (const move of opponent.moveset) {
// move is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) {
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent, true) >= 2) {
return true;
}
// move is a OHKO
@ -2987,6 +3033,55 @@ export class PostFaintAbAttr extends AbAttr {
}
}
/**
* Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon fainting
*/
export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr {
/**
* @param pokemon The {@linkcode Pokemon} with the ability
* @param passive N/A
* @param attacker N/A
* @param move N/A
* @param hitResult N/A
* @param args N/A
* @returns {boolean} Returns true if the weather clears, otherwise false.
*/
applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
const weatherType = pokemon.scene.arena.weather.weatherType;
let turnOffWeather = false;
// Clear weather only if user's ability matches the weather and no other pokemon has the ability.
switch (weatherType) {
case (WeatherType.HARSH_SUN):
if (pokemon.hasAbility(Abilities.DESOLATE_LAND)
&& pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.HEAVY_RAIN):
if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA)
&& pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.STRONG_WINDS):
if (pokemon.hasAbility(Abilities.DELTA_STREAM)
&& pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
turnOffWeather = true;
}
break;
}
if (turnOffWeather) {
pokemon.scene.arena.trySetWeather(WeatherType.NONE, false);
return true;
}
return false;
}
}
export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
private damageRatio: integer;
@ -4163,13 +4258,22 @@ export function initAbilities() {
.unimplemented(),
new Ability(Abilities.PRIMORDIAL_SEA, 6)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN),
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
.attr(PreSwitchOutClearWeatherAbAttr)
.attr(PostFaintClearWeatherAbAttr)
.bypassFaint(),
new Ability(Abilities.DESOLATE_LAND, 6)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HARSH_SUN)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HARSH_SUN),
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HARSH_SUN)
.attr(PreSwitchOutClearWeatherAbAttr)
.attr(PostFaintClearWeatherAbAttr)
.bypassFaint(),
new Ability(Abilities.DELTA_STREAM, 6)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.STRONG_WINDS)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.STRONG_WINDS),
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.STRONG_WINDS)
.attr(PreSwitchOutClearWeatherAbAttr)
.attr(PostFaintClearWeatherAbAttr)
.bypassFaint(),
new Ability(Abilities.STAMINA, 7)
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, BattleStat.DEF, 1),
new Ability(Abilities.WIMP_OUT, 7)

View File

@ -29,6 +29,7 @@ export abstract class ArenaTag {
public sourceId: integer;
public side: ArenaTagSide;
constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId?: integer, side: ArenaTagSide = ArenaTagSide.BOTH) {
this.tagType = tagType;
this.turnCount = turnCount;
@ -41,10 +42,12 @@ export abstract class ArenaTag {
return true;
}
onAdd(arena: Arena): void { }
onAdd(arena: Arena, quiet: boolean = false): void { }
onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.getMoveName()}\'s effect wore off${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
onRemove(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`${this.getMoveName()}\'s effect wore off${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
}
}
onOverlap(arena: Arena): void { }
@ -65,11 +68,13 @@ export class MistTag extends ArenaTag {
super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side);
}
onAdd(arena: Arena): void {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(getPokemonMessage(source, "'s team became\nshrouded in mist!"));
if (!quiet) {
arena.scene.queueMessage(getPokemonMessage(source, "'s team became\nshrouded in mist!"));
}
}
apply(arena: Arena, args: any[]): boolean {
@ -113,8 +118,10 @@ class ReflectTag extends WeakenMoveScreenTag {
return false;
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`Reflect reduced the damage of physical moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`Reflect reduced the damage of physical moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
}
}
}
@ -135,8 +142,10 @@ class LightScreenTag extends WeakenMoveScreenTag {
return false;
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`Light Screen reduced the damage of special moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`Light Screen reduced the damage of special moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
}
}
}
@ -145,8 +154,10 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side);
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`Aurora Veil reduced the damage of moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`Aurora Veil reduced the damage of moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`);
}
}
}
@ -386,11 +397,13 @@ class SpikesTag extends ArenaTrapTag {
super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3);
}
onAdd(arena: Arena): void {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
if (!quiet) {
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
}
}
activateTrap(pokemon: Pokemon): boolean {
@ -423,11 +436,13 @@ class ToxicSpikesTag extends ArenaTrapTag {
this.neutralized = false;
}
onAdd(arena: Arena): void {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
if (!quiet) {
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
}
}
onRemove(arena: Arena): void {
@ -493,15 +508,17 @@ class StealthRockTag extends ArenaTrapTag {
super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1);
}
onAdd(arena: Arena): void {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`);
if (!quiet) {
arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`);
}
}
getDamageHpRatio(pokemon: Pokemon): number {
const effectiveness = pokemon.getAttackTypeEffectiveness(Type.ROCK);
const effectiveness = pokemon.getAttackTypeEffectiveness(Type.ROCK, undefined, true);
let damageHpRatio: number;
@ -562,13 +579,15 @@ class StickyWebTag extends ArenaTrapTag {
super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1);
}
onAdd(arena: Arena): void {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
// does not seem to be used anywhere
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`A ${this.getMoveName()} has been laid out on the ground around the opposing team!`);
if (!quiet) {
arena.scene.queueMessage(`A ${this.getMoveName()} has been laid out on the ground around the opposing team!`);
}
}
activateTrap(pokemon: Pokemon): boolean {
@ -626,8 +645,10 @@ class TailwindTag extends ArenaTag {
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side);
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`);
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`);
}
const source = arena.scene.getPokemonById(this.sourceId);
const party = source.isPlayer() ? source.scene.getPlayerField() : source.scene.getEnemyField();
@ -646,8 +667,10 @@ class TailwindTag extends ArenaTag {
}
}
onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? "Your" : this.side === ArenaTagSide.ENEMY ? "The opposing" : ""} team's Tailwind petered out!`);
onRemove(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? "Your" : this.side === ArenaTagSide.ENEMY ? "The opposing" : ""} team's Tailwind petered out!`);
}
}
}

View File

@ -2195,7 +2195,7 @@ export class DelayedAttackAttr extends OverrideMoveEffectAttr {
(args[0] as Utils.BooleanHolder).value = true;
user.scene.queueMessage(getPokemonMessage(user, ` ${this.chargeText.replace("{TARGET}", target.name)}`));
user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER });
user.scene.arena.addTag(this.tagType, 3, move.id, user.id, ArenaTagSide.BOTH, target.getBattlerIndex());
user.scene.arena.addTag(this.tagType, 3, move.id, user.id, ArenaTagSide.BOTH, false, target.getBattlerIndex());
resolve(true);
});
@ -4224,6 +4224,48 @@ export class RemoveScreensAttr extends MoveEffectAttr {
}
}
/*Swaps arena effects between the player and enemy side
* @extends MoveEffectAttr
* @see {@linkcode apply}
*/
export class SwapArenaTagsAttr extends MoveEffectAttr {
public SwapTags: ArenaTagType[];
constructor(SwapTags: ArenaTagType[]) {
super(true, MoveEffectTrigger.POST_APPLY);
this.SwapTags = SwapTags;
}
apply(user:Pokemon, target:Pokemon, move:Move, args: any[]): boolean {
if (!super.apply(user, target, move, args)) {
return false;
}
const tagPlayerTemp = user.scene.arena.findTagsOnSide((t => this.SwapTags.includes(t.tagType)), ArenaTagSide.PLAYER);
const tagEnemyTemp = user.scene.arena.findTagsOnSide((t => this.SwapTags.includes(t.tagType)), ArenaTagSide.ENEMY);
if (tagPlayerTemp) {
for (const swapTagsType of tagPlayerTemp) {
user.scene.arena.removeTagOnSide(swapTagsType.tagType, ArenaTagSide.PLAYER, true);
user.scene.arena.addTag(swapTagsType.tagType, swapTagsType.turnCount, swapTagsType.sourceMove, swapTagsType.sourceId, ArenaTagSide.ENEMY, true);
}
}
if (tagEnemyTemp) {
for (const swapTagsType of tagEnemyTemp) {
user.scene.arena.removeTagOnSide(swapTagsType.tagType, ArenaTagSide.ENEMY, true);
user.scene.arena.addTag(swapTagsType.tagType, swapTagsType.turnCount, swapTagsType.sourceMove, swapTagsType.sourceId, ArenaTagSide.PLAYER, true);
}
}
user.scene.queueMessage( `${user.name} swapped the battle effects affecting each side of the field!`);
return true;
}
}
/**
* Attribute used for Revival Blessing.
* @extends MoveEffectAttr
@ -5913,6 +5955,7 @@ export function initMoves() {
.attr(BypassSleepAttr)
.attr(RandomMovesetMoveAttr)
.condition(userSleptOrComatoseCondition)
.target(MoveTarget.ALL_ENEMIES)
.ignoresVirtual(),
new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2)
.attr(PartyStatusCureAttr, "A bell chimed!", Abilities.SOUNDPROOF)
@ -7460,9 +7503,7 @@ export function initMoves() {
.attr(FirstAttackDoublePowerAttr)
.bitingMove(),
new StatusMove(Moves.COURT_CHANGE, Type.NORMAL, 100, 10, -1, 0, 8)
.target(MoveTarget.BOTH_SIDES)
.unimplemented(),
/* Unused */
.attr(SwapArenaTagsAttr, [ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.MIST, ArenaTagType.REFLECT, ArenaTagType.SPIKES, ArenaTagType.STEALTH_ROCK, ArenaTagType.STICKY_WEB, ArenaTagType.TAILWIND, ArenaTagType.TOXIC_SPIKES]),
new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented()

View File

@ -917,7 +917,7 @@ export function initSpecies() {
new PokemonSpecies(Species.ARBOK, 1, false, false, false, "Cobra Pokémon", Type.POISON, null, 3.5, 65, Abilities.INTIMIDATE, Abilities.SHED_SKIN, Abilities.UNNERVE, 448, 60, 95, 69, 65, 79, 80, 90, 70, 157, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PIKACHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, GrowthRate.MEDIUM_FAST, 50, true, true,
new PokemonForm("Normal", "", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 320, 35, 55, 40, 50, 50, 90, 190, 50, 112, true, null, true),
new PokemonForm("Partner", "partner", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, "", true),
new PokemonForm("Partner", "partner", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true),
new PokemonForm("Cosplay", "cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
new PokemonForm("Cool Cosplay", "cool-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
new PokemonForm("Beauty Cosplay", "beauty-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
@ -1066,7 +1066,7 @@ export function initSpecies() {
new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", Type.NORMAL, null, 0.3, 4, Abilities.LIMBER, Abilities.NONE, Abilities.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false),
new PokemonSpecies(Species.EEVEE, 1, false, false, false, "Evolution Pokémon", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true,
new PokemonForm("Normal", "", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true),
new PokemonForm("Partner", "partner", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, "", true),
new PokemonForm("Partner", "partner", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 18, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 425, 70, 75, 80, 60, 95, 45, 45, 50, 65),
),
new PokemonSpecies(Species.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", Type.WATER, null, 1, 29, Abilities.WATER_ABSORB, Abilities.NONE, Abilities.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false),

View File

@ -0,0 +1,11 @@
/**
* Determines exp notification style.
* - Default - the normal exp gain display, nothing changed
* - Only level up - we display the level up in the small frame instead of a message
* - Skip - no level up frame nor message
*/
export enum ExpNotification {
DEFAULT,
ONLY_LEVEL_UP,
SKIP
}

View File

@ -545,7 +545,7 @@ export class Arena {
this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args);
}
addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, targetIndex?: BattlerIndex): boolean {
addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, quiet: boolean = false, targetIndex?: BattlerIndex): boolean {
const existingTag = this.getTagOnSide(tagType, side);
if (existingTag) {
existingTag.onOverlap(this);
@ -554,7 +554,7 @@ export class Arena {
const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, targetIndex, side);
this.tags.push(newTag);
newTag.onAdd(this);
newTag.onAdd(this, quiet);
this.eventTarget.dispatchEvent(new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount));
@ -600,10 +600,10 @@ export class Arena {
return !!tag;
}
removeTagOnSide(tagType: ArenaTagType, side: ArenaTagSide): boolean {
removeTagOnSide(tagType: ArenaTagType, side: ArenaTagSide, quiet: boolean = false): boolean {
const tag = this.getTagOnSide(tagType, side);
if (tag) {
tag.onRemove(this);
tag.onRemove(this, quiet);
this.tags.splice(this.tags.indexOf(tag), 1);
this.eventTarget.dispatchEvent(new TagRemovedEvent(tag.tagType, tag.side, tag.turnCount));

View File

@ -1070,7 +1070,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return (!cancelled.value ? typeMultiplier.value : 0) as TypeDamageMultiplier;
}
getAttackTypeEffectiveness(moveType: Type, source?: Pokemon): TypeDamageMultiplier {
getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false): TypeDamageMultiplier {
if (moveType === Type.STELLAR) {
return this.isTerastallized() ? 2 : 1;
}
@ -1089,7 +1089,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
// Handle strong winds lowering effectiveness of types super effective against pure flying
if (this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && multiplier >= 2 && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2) {
if (!ignoreStrongWinds && this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && multiplier >= 2 && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2) {
multiplier /= 2;
}
return multiplier;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const deConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const deConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Einwechseln",
"SUMMARY": "Bericht",
"CANCEL": "Abbrechen",
"RELEASE": "Freilassen",
"APPLY": "Anwenden",
"TEACH": "Erlernen"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const enConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const enConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const esConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const esConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -4,104 +4,104 @@ import {DialogueTranslationEntries, SimpleTranslationEntries} from "#app/plugins
export const PGMdialogue: DialogueTranslationEntries = {
"youngster": {
"encounter": {
1: "Hey, wanna battle?",
2: "Are you a new trainer too?",
3: "Hey, I haven't seen you before. Let's battle!",
4: "I just lost, so I'm trying to find more Pokémon.\nWait! You look weak! Come on, let's battle!",
5: "Have we met or not? I don't really remember. Well, I guess it's nice to meet you anyway!",
6: "All right! Let's go!",
7: "All right! Here I come! I'll show you my power!",
8: "Haw haw haw... I'll show you how hawesome my Pokémon are!",
9: "No need to waste time saying hello. Bring it on whenever you're ready!",
10: "Don't let your guard down, or you may be crying when a kid beats you.",
11: "I've raised my Pokémon with great care. You're not allowed to hurt them!",
12: "Glad you made it! It won't be an easy job from here.",
13: "The battles continue forever! Welcome to the world with no end!"
1: "Hey, ¿quieres luchar?",
2: "¿También eres un entrenador novato?",
3: "No te había visto antes. ¡Vamos a luchar!",
4: "Perdí y estoy intentando buscar nuevos Pokémon.\n¡Espera, pareces débil! ¡Vamos, a luchar!",
5: "¿Nos conocimos o no? Ni me acuerdo. ¡Supongo que es un gusto conocerte!",
6: "¡Venga, vamos!",
7: "¡Allá voy! ¡Te enseñaré mi poder!",
8: "¡Ja ja ja! ¡Te enseñaré lo jimpresionante que es mi equipo!",
9: "No pierdas tiempo saludando. ¡Adelante, cuando estés listo!",
10: "No bajes la guardia o llorarás porque un niño te ganó.",
11: "He cuidado a mis Pokémon con cariño. ¡Prohibido hacerles daño!",
12: "¡Encantado de que lo lograses! A partir de aquí no será fácil.",
13: "¡Las batallas continúan para siempre! ¡Bienvenido al mundo sin fin!"
},
"victory": {
1: "Wow! You're strong!",
2: "I didn't stand a chance, huh?",
3: "I'll find you again when I'm older and beat you!",
4: "Ugh. I don't have any more Pokémon.",
5: "No way… NO WAY! How could I lose again…",
6: "No! I lost!",
7: "Whoa! You are incredible! I'm amazed and surprised!",
8: "Could it be… How… My Pokémon and I are the strongest, though…",
9: "I won't lose next time! Let's battle again sometime!",
10: "Sheesh! Can't you see that I'm just a kid! It wasn't fair of you to go all out like that!",
11: "Your Pokémon are more amazing! Trade with me!",
12: "I got a little carried away earlier, but what job was I talking about?",
13: "Ahaha! There it is! That's right! You're already right at home in this world!"
1: "¡Guau! ¡Eres fuerte!",
2: "¿No tuve oportunidad, eh?",
3: "¡Cuando sea mayor te encontraré y te ganaré!",
4: "Ay. No tengo más Pokémon.",
5: "Imposible… ¡IMPOSIBLE! Cómo pude perder de nuevo…",
6: "¡No! ¡Perdí!",
7: "¡Guau! ¡Eres increíble! ¡Estoy alucinado y sorprendido!",
8: "Puede ser… Cómo… Aunque mis Pokémon y yo somos los más fuertes…",
9: "¡No perderé a la próxima! ¡Luchemos otra vez pronto!",
10: "¡Oye! ¡No ves que solo soy un niño! ¡No es justo que vayas así conmigo!",
11: "¡Tus Pokémon molan más! ¡Intercámbiamelos!",
12: "Me perdí antes pero, ¿de qué tarea estaba hablando antes?",
13: "¡Jajaja! ¡Esa es! ¡Correcto! ¡Ya te sientes como en casa en este mundo!"
}
},
"lass": {
"encounter": {
1: "Let's have a battle, shall we?",
2: "You look like a new trainer. Let's have a battle!",
3: "I don't recognize you. How about a battle?",
4: "Let's have a fun Pokémon battle!",
5: "I'll show you the ropes of how to really use Pokémon!",
6: "A serious battle starts from a serious beginning! Are you sure you're ready?",
7: "You're only young once. And you only get one shot at a given battle. Soon, you'll be nothing but a memory.",
8: "You'd better go easy on me, OK? Though I'll be seriously fighting!",
9: "School is boring. I've got nothing to do. Yawn. I'm only battling to kill the time."
1: "¿Luchemos, podría ser?",
2: "Pareces novato. ¡Luchemos!",
3: "No te reconozco. ¿Un combate?",
4: "¡Tengamos un combate Pokémon divertido!",
5: "¡Te enseñaré lo básico de cómo entrenar Pokémon!",
6: "¡Un combate serio empieza por un comienzo serio! ¿Seguro que estás listo?",
7: "Solo se es joven una vez. Y solo tienes una oportunidad en una batalla. Pronto, solo serás un recuerdo.",
8: "Asegúrate de ir fácil conmigo, ¿vale? ¡Pero seré seria luchando!",
9: "El colegio es aburrido. No hay nada que hacer. Uaa. Solo lucho para pasar el tiempo."
},
"victory": {
1: "That was impressive! I've got a lot to learn.",
2: "I didn't think you'd beat me that bad…",
3: "I hope we get to have a rematch some day.",
4: "That was pretty amazingly fun! You've totally exhausted me…",
5: "You actually taught me a lesson! You're pretty amazing!",
6: "Seriously, I lost. That is, like, seriously depressing, but you were seriously cool.",
7: "I don't need memories like this. Deleting memory…",
8: "Hey! I told you to go easy on me! Still, you're pretty cool when you're serious.",
9: "I'm actually getting tired of battling… There's gotta be something new to do…"
1: "¡Impresionante! Tengo mucho que aprender.",
2: "No pensé que me vencerías así…",
3: "Espero la revancha algún día.",
4: "¡Fue increíblemente divertido! Me dejaste cansada…",
5: "¡Me enseñaste una lección! ¡Eres increíble!",
6: "En serio, he perdido. O sea, es seriamente decepcionante, pero tú eres realmente guay.",
7: "No necesito estos recuerdos. Borrando recuerdos…",
8: "¡Te dije que fueses fácil conmigo! Aun así, me gusta cuando eres serio.",
9: "Me canso de luchar… Habrá algo nuevo que hacer…"
}
},
"breeder": {
"encounter": {
1: "Obedient Pokémon, selfish Pokémon… Pokémon have unique characteristics.",
2: "Even though my upbringing and behavior are poor, I've raised my Pokémon well.",
3: "Hmm, do you discipline your Pokémon? Pampering them too much is no good.",
1: "Pokémon obedientes, Pokémon egoístas… Los Pokémon tienen características únicas.",
2: "Aunque tengo descendencia y comportamiento pobre, he cuidado muy bien a mis Pokémon.",
3: "¿Tienes disciplina con tus Pokémon? Malcriarlos mucho no es bueno.",
},
"victory": {
1: "It is important to nurture and train each Pokémon's characteristics.",
2: "Unlike my diabolical self, these are some good Pokémon.",
3: "Too much praise can spoil both Pokémon and people.",
1: "Es importante cuidar y mimar todas las características de los Pokémon.",
2: "No como mi diabólica personalidad, mis Pokémon son muy buenos.",
3: "Malcriar puede arruinar a los Pokémon y a los humanos.",
},
"defeat": {
1: "You should not get angry at your Pokémon, even if you lose a battle.",
2: "Right? Pretty good Pokémon, huh? I'm suited to raising things.",
3: "No matter how much you love your Pokémon, you still have to discipline them when they misbehave."
1: "No deberías enfadarte con tu Pokémon, aún tras un combate perdido.",
2: "¿Eh? ¿Buen Pokémon? Me acostumbro a cuidarlos.",
3: "No importa el cariño que le tengas a tus Pokémon, tienes que ser serio si se portan mal."
}
},
"breeder_female": {
"encounter": {
1: "Pokémon never betray you. They return all the love you give them.",
2: "Shall I give you a tip for training good Pokémon?",
3: "I have raised these very special Pokémon using a special method."
1: "Los Pokémon nunca te traicionan, te devuelven el amor que les diste.",
2: "¿Puedo darte un consejo para entrenar bien tus Pokémon?",
3: "Cuidé estos Pokémon con un método especial."
},
"victory": {
1: "Ugh… It wasn't supposed to be like this. Did I administer the wrong blend?",
2: "How could that happen to my Pokémon… What are you feeding your Pokémon?",
3: "If I lose, that tells you I was just killing time. It doesn't damage my ego at all."
1: "Ugh… No se supone que acabaría así. ¿Les cuidé de forma errónea?",
2: "Cómo pudo pasarle esto a mi Pokémon... ¿Qué le das a tu Pokémon?",
3: "Si pierdo, solo fue un pasatiempo. Mi ego se ve intacto."
},
"defeat": {
1: "This proves my Pokémon have accepted my love.",
2: "The real trick behind training good Pokémon is catching good Pokémon.",
3: "Pokémon will be strong or weak depending on how you raise them."
1: "Esto demuestra que los Pokémon aceptaron mi amor.",
2: "El truco detrás de atrapar buenos Pokémon es cuidar buenos Pokémon.",
3: "Los Pokémon serán fuertes o débiles según los cuides."
}
},
"fisherman": {
"encounter": {
1: "Aack! You made me lose a bite!\nWhat are you going to do about it?",
2: "Go away! You're scaring the Pokémon!",
3: "Let's see if you can reel in a victory!",
1: "¡Uy uy uy! ¡Hiciste que huyera un pez!\n¿Qué harás al respecto?",
2: "¡Vete! ¡Espantas los Pokémon!",
3: "¡Veamos si pescas una victoria!",
},
"victory": {
1: "Just forget about it.",
2: "Next time, I'll be reelin' in the triumph!",
3: "Guess I underestimated the currents this time.",
1: "Olvídalo.",
2: "A la siguiente, ¡pescaré mi victoria!",
3: "Infravaloré la corriente esta vez.",
},
},
"fisherman_female": {

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const frConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const frConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const itConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const itConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const koConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const koConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -854,22 +854,22 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"roark": {
"encounter": {
1: "I need to see your potential as a Trainer. And, I'll need to see the toughness of the Pokémon that battle with you!",
2: "Here goes! These are my rocking Pokémon, my pride and joy!",
3: "Rock-type Pokémon are simply the best!",
4: "I need to see your potential as a Trainer. And, I'll need to see the toughness of the Pokémon that battle with you!"
1: "트레이너로서 너의 실력이 어느 정도인지 그리고 함께 싸울 포켓몬이 얼마나 강한지 확인해보겠어!",
2: "자 간다! 내 자랑이자 기쁨인 바위타입 포켓몬들이야!",
3: "바위타입 포켓몬이야말로 최고지!",
4: "트레이너로서 너의 실력이 어느 정도인지 그리고 함께 싸울 포켓몬이 얼마나 강한지 확인해보겠어!"
},
"victory": {
1: "W-what? That can't be! My buffed-up Pokémon!",
2: "…We lost control there. Next time I'd like to challenge you to a Fossil-digging race underground.",
3: "With skill like yours, it's natural for you to win.",
4: "Wh-what?! It can't be! Even that wasn't enough?",
5: "I blew it."
1: "이-이럴수가! 열심히 단련시킨 포켓몬들이!",
2: "…져버린 건가. 다음엔 지하통로에서 화석캐기 승부를 하고 싶구나.",
3: "네 실력이라면 승리는 당연한 결과겠지.",
4: "뭐-뭐야?! 이럴 수가! 이것도 부족했단 말인가?",
5: "내가 실수했군."
},
"defeat": {
1: "See? I'm proud of my rocking battle style!",
2: "Thanks! The battle gave me confidence that I may be able to beat my dad!",
3: "I feel like I just smashed through a really stubborn boulder!"
1: "봤지? 이게 바로 내가 자랑하는 바위 스타일 전투야!",
2: "고마워! 이번 승부로 아버지를 이길 수 있겠다는 자신감이 생겼어!",
3: "정말 단단한 바위를 뚫고 나온 기분인데!"
}
},
"morty": {
@ -1001,13 +1001,13 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"gardenia": {
"encounter": {
1: "You have a winning aura about you. So, anyway, this will be fun. Let's have our battle!"
1: "너에게선 승리의 기운이 느껴져. 어쨌든 재밌을 것 같아. 포켓몬 승부하자!"
},
"victory": {
1: "Amazing! You're very good, aren't you?"
1: "대단해! 너 정말 강하구나!"
},
"defeat": {
1: "Yes! My Pokémon and I are perfectly good!"
1: "그렇지! 나와 포켓몬은 완벽해!"
}
},
"aaron": {
@ -1707,26 +1707,26 @@ export const PGMdialogue: DialogueTranslationEntries = {
},
"maylene": {
"encounter": {
1: `I've come to challenge you now, and I won't hold anything back.
$Please prepare yourself for battle!`,
1: `지금 당신에게 도전하러 왔어요.
$전력을 !`,
},
"victory": {
1: "I admit defeat…"
1: "나의 패배입니다…"
},
"defeat": {
1: "That was awesome."
1: "멋진 승부였습니다."
}
},
"fantina": {
"encounter": {
1: `You shall challenge me, yes? But I shall win.
$That is what the Gym Leader of Hearthome does, non?`,
1: `당신도 도전해 보세요. 전 당신을 이기겠어요.
$그것이 !`,
},
"victory": {
1: "You are so fantastically strong. I know why I have lost."
1: "당신 최고로 강해요. 나 진 것 알아요."
},
"defeat": {
1: "I am so, so, very happy!"
1: "너무, 너무 행복해요!"
}
},
"byron": {

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "교체한다",
"SUMMARY": "능력치를 본다",
"CANCEL": "그만둔다",
"RELEASE": "놓아준다",
"APPLY": "사용한다",
"TEACH": "가르친다"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const ptBrConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const ptBrConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const zhCnConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const zhCnConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = {
"intro": `欢迎来到PokéRogue这是一款以战斗为核心的融合了roguelite元素的宝可梦同人游戏。
"intro": `欢迎来到PokéRogue这是一款以战斗为核心的\n融合了roguelite元素的宝可梦同人游戏。
$本游戏未进行商业化\nPokémon或Pokémon使用的版
$权资产的所有权
$游戏仍在开发中\n告错误 Discord

View File

@ -35,6 +35,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const zhTwConfig = {
ability: ability,
@ -73,5 +74,6 @@ export const zhTwConfig = {
trainerNames: trainerNames,
tutorial: tutorial,
voucher: voucher,
weather: weather
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
} as const;

View File

@ -63,6 +63,7 @@ import * as Overrides from "./overrides";
import { TextStyle, addTextObject } from "./ui/text";
import { Type } from "./data/type";
import { BerryUsedEvent, EncounterPhaseEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events";
import { ExpNotification } from "./enums/exp-notification";
export class LoginPhase extends Phase {
@ -4289,20 +4290,20 @@ export class ShowPartyExpBarPhase extends PlayerPartyMemberPokemonPhase {
this.scene.unshiftPhase(new HidePartyExpBarPhase(this.scene));
pokemon.updateInfo();
if (this.scene.expParty === 2) { // 2 - Skip - no level up frame nor message
if (this.scene.expParty === ExpNotification.SKIP) {
this.end();
} else if (this.scene.expParty === 1) { // 1 - Only level up - we display the level up in the small frame instead of a message
} else if (this.scene.expParty === ExpNotification.ONLY_LEVEL_UP) {
if (newLevel > lastLevel) { // this means if we level up
// instead of displaying the exp gain in the small frame, we display the new level
// we use the same method for mode 0 & 1, by giving a parameter saying to display the exp or the level
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, this.scene.expParty === 1, newLevel).then(() => {
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, this.scene.expParty === ExpNotification.ONLY_LEVEL_UP, newLevel).then(() => {
setTimeout(() => this.end(), 800 / Math.pow(2, this.scene.expGainsSpeed));
});
} else {
this.end();
}
} else if (this.scene.expGainsSpeed < 3) {
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, this.scene.expParty === 1, newLevel).then(() => {
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, false, newLevel).then(() => {
setTimeout(() => this.end(), 500 / Math.pow(2, this.scene.expGainsSpeed));
});
} else {
@ -4349,12 +4350,12 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
const prevStats = pokemon.stats.slice(0);
pokemon.calculateStats();
pokemon.updateInfo();
if (this.scene.expParty === 0) { // 0 - default - the normal exp gain display, nothing changed
if (this.scene.expParty === ExpNotification.DEFAULT) {
this.scene.playSound("level_up_fanfare");
this.scene.ui.showText(i18next.t("battle:levelUp", { pokemonName: this.getPokemon().name, level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
} else if (this.scene.expParty === 2) { // 2 - Skip - no level up frame nor message
} else if (this.scene.expParty === ExpNotification.SKIP) {
this.end();
} else { // 1 - Only level up - we display the level up in the small frame instead of a message
} else {
// we still want to display the stats if activated
this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end());
}

View File

@ -174,13 +174,13 @@ export function initI18n(): void {
de: {
...deConfig
},
pt_BR: {
"pt-BR": {
...ptBrConfig
},
zh_CN: {
"zh-CN": {
...zhCnConfig
},
zh_TW: {
"zh-TW": {
...zhTwConfig
},
ko: {
@ -233,6 +233,7 @@ declare module "i18next" {
PGFbattleSpecDialogue: SimpleTranslationEntries;
PGFmiscDialogue: SimpleTranslationEntries;
PGFdoubleBattleDialogue: DialogueTranslationEntries;
partyUiHandler: SimpleTranslationEntries;
};
}
}

View File

@ -480,15 +480,15 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
},
{
label: "Português (BR)",
handler: () => changeLocaleHandler("pt_BR")
handler: () => changeLocaleHandler("pt-BR")
},
{
label: "简体中文",
handler: () => changeLocaleHandler("zh_CN")
handler: () => changeLocaleHandler("zh-CN")
},
{
label: "繁體中文",
handler: () => changeLocaleHandler("zh_TW")
handler: () => changeLocaleHandler("zh-TW")
},
{
label: "한국어",

View File

@ -18,6 +18,7 @@ import { SpeciesFormChangeItemTrigger } from "../data/pokemon-forms";
import { getVariantTint } from "#app/data/variant";
import {Button} from "../enums/buttons";
import MoveInfoOverlay from "./move-info-overlay";
import i18next from "i18next";
const defaultMessage = "Choose a Pokémon.";
@ -131,6 +132,8 @@ export default class PartyUiHandler extends MessageUiHandler {
public static NoEffectMessage = "It won't have any effect.";
private localizedOptions = [PartyOption.SEND_OUT, PartyOption.SUMMARY, PartyOption.CANCEL, PartyOption.APPLY, PartyOption.RELEASE, PartyOption.TEACH];
constructor(scene: BattleScene) {
super(scene, Mode.PARTY);
}
@ -810,7 +813,11 @@ export default class PartyUiHandler extends MessageUiHandler {
const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM];
optionName = `${modifier.active ? "Deactivate" : "Activate"} ${modifier.type.name}`;
} else {
optionName = Utils.toReadableString(PartyOption[option]);
if (this.localizedOptions.includes(option)) {
optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`);
} else {
optionName = Utils.toReadableString(PartyOption[option]);
}
}
break;
}