Compare commits

...

12 Commits

Author SHA1 Message Date
Madmadness65
219f227cab Remove basic Voucher from Ultra item pool
It should only be in the Great item pool now.
2024-06-04 21:53:22 -05:00
sodam
7cc5ca1839
[Localization] Korean Kanto gym leader dialogue ( (#1794)
* localized to korean (Gym leader's dialouge at Kanto region)

* modified Brock's dialogue clearly

* Add missed word to lt_surge's dialogue
2024-06-04 22:17:49 -04:00
Madmadness65
1dd7a792d4 Fix Wide Lens being accidentally added to Rogue pool 2024-06-04 21:15:10 -05:00
damocleas
dd3ffb4315
Voucher Item tier changes/addition (#1516)
* Voucher Item tier changes/addition

- Voucher moved from Ultra -> Great Tier, given a weight of 1 and disappears after first reroll, should still appear more often with a healthy team than in ultra tier at all.
- Voucher Plus moved from Master -> Rogue Tier, with weight starting at 9 -> 5 and decreasing with each reroll with 3 -> 2
Should appear just a bit more often than before.
- Voucher Premium added to Master (based on suggestion from Madmadness) with same weight as new Voucher Plus, and disabled in Endless / Endless Spliced
Should appear ~20% of the time with *perfect luck* in a whole average classic run.

Overall would be a 40-45% increase in total eggs in perfect conditions (luck, healthy team, etc.)

* fixed an extra spacebar at the end of 1303

* fixed an extra spacebar at the end of 1360

* fixed to account for Wide Lens being added
2024-06-04 22:05:29 -04:00
Matthew Olker
7eb0e8e77d revert pokemon info container depth change 2024-06-04 21:45:36 -04:00
Matthew Olker
7c9e5e9f52 loading screen disclaimer 2024-06-04 21:41:36 -04:00
Matthew Olker
5464f964c9 add more gameobject names for debugging 2024-06-04 21:06:46 -04:00
Frede
cfe9b3303a
[QoL] Pokemon Info Container always on top of Battle UI (#1782)
* 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

* pokemonInfoContainer always on top of battle UI when shown

---------

Co-authored-by: Frederik Hobein <frederik.hobein@nterra.com>
2024-06-04 21:05:25 -04:00
Adrian T
48f60a5b50
[QoL] add message when quick claw is triggered (#1684) 2024-06-04 18:11:30 -04:00
Benjamin Odom
d04010226d
[Bug] Fix Leppa Berries not Updating Flyout PP (#1806)
* Fix Leppa Berries not Updating Flyout PP

* Code Cleanup

* Update battle-flyout.ts
2024-06-04 16:59:39 -05:00
AJ Fontaine
eecad0fdc4
Balance endless tokens (#1733)
* Balanced tokens

* Remove existing tokens, all 10 stack limit

* Linter complained

* Sorry Mr. Lint I’ll do better next time

* Removed redundant min

* Used a version system to update tokens

* The linter has peculiar tastes

* See if this works

* I'm at my limit omg wtf Sam

* Call me Swoobat the way I keep it Simple

* Clean up some log statements

* Adjust token weights to make up for removal of sleep and freeze

* Be so fr GitHub that’s not a real merge conflict
2024-06-04 16:39:22 -05:00
Jannik Tappert
a8205ae819
[Bug] Handle if the browser gives a long form of a language (like "de-DE") … (#1795)
* Handle if the browser gives a long form of a language (like "de-DE") for cases where we only have the short form "de".

* Changed it so that now resolved Language is now used anywhere. This is basically what i orignally did manually but provided from i18next directly
2024-06-04 15:11:02 -05:00
35 changed files with 282 additions and 172 deletions

View File

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

View File

@ -213,7 +213,7 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("types", ""); this.loadAtlas("types", "");
// Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang> // Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_<lang>
const lang = i18next.language; const lang = i18next.resolvedLanguage;
if (lang !== "en") { if (lang !== "en") {
if (Utils.verifyLang(lang)) { if (Utils.verifyLang(lang)) {
this.loadAtlas(`types_${lang}`, ""); this.loadAtlas(`types_${lang}`, "");
@ -352,14 +352,17 @@ export class LoadingScene extends SceneBase {
const width = this.cameras.main.width; const width = this.cameras.main.width;
const height = this.cameras.main.height; const height = this.cameras.main.height;
const logo = this.add.image(width / 2, 240, ""); const midWidth = width / 2;
const midHeight = height / 2;
const logo = this.add.image(midWidth, 240, "");
logo.setVisible(false); logo.setVisible(false);
logo.setOrigin(0.5, 0.5); logo.setOrigin(0.5, 0.5);
logo.setScale(4); logo.setScale(4);
const percentText = this.make.text({ const percentText = this.make.text({
x: width / 2, x: midWidth,
y: height / 2 - 24, y: midHeight - 24,
text: "0%", text: "0%",
style: { style: {
font: "72px emerald", font: "72px emerald",
@ -369,8 +372,8 @@ export class LoadingScene extends SceneBase {
percentText.setOrigin(0.5, 0.5); percentText.setOrigin(0.5, 0.5);
const assetText = this.make.text({ const assetText = this.make.text({
x: width / 2, x: midWidth,
y: height / 2 + 48, y: midHeight + 48,
text: "", text: "",
style: { style: {
font: "48px emerald", font: "48px emerald",
@ -379,6 +382,32 @@ export class LoadingScene extends SceneBase {
}); });
assetText.setOrigin(0.5, 0.5); assetText.setOrigin(0.5, 0.5);
const disclaimerText = this.make.text({
x: midWidth,
y: assetText.y + 152,
text: i18next.t("menu:disclaimer"),
style: {
font: "72px emerald",
color: "#DA3838",
},
});
disclaimerText.setOrigin(0.5, 0.5);
const disclaimerDescriptionText = this.make.text({
x: midWidth,
y: disclaimerText.y + 120,
text: i18next.t("menu:disclaimerDescription"),
style: {
font: "48px emerald",
color: "#ffffff",
align: "center"
},
});
disclaimerDescriptionText.setOrigin(0.5, 0.5);
disclaimerText.setVisible(false);
disclaimerDescriptionText.setVisible(false);
const intro = this.add.video(0, 0); const intro = this.add.video(0, 0);
intro.setOrigin(0, 0); intro.setOrigin(0, 0);
intro.setScale(3); intro.setScale(3);
@ -388,7 +417,7 @@ export class LoadingScene extends SceneBase {
percentText.setText(`${Math.floor(parsedValue * 100)}%`); percentText.setText(`${Math.floor(parsedValue * 100)}%`);
progressBar.clear(); progressBar.clear();
progressBar.fillStyle(0xffffff, 0.8); progressBar.fillStyle(0xffffff, 0.8);
progressBar.fillRect(width / 2 - 320, 360, 640 * parsedValue, 64); progressBar.fillRect(midWidth - 320, 360, 640 * parsedValue, 64);
}); });
this.load.on("fileprogress", file => { this.load.on("fileprogress", file => {
@ -423,6 +452,8 @@ export class LoadingScene extends SceneBase {
ease: "Sine.easeIn" ease: "Sine.easeIn"
}); });
loadingGraphics.map(g => g.setVisible(true)); loadingGraphics.map(g => g.setVisible(true));
disclaimerText.setVisible(true);
disclaimerDescriptionText.setVisible(true);
}); });
intro.play(); intro.play();
break; break;

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"Leer", "empty":"Leer",
"yes":"Ja", "yes":"Ja",
"no":"Nein", "no":"Nein",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" }, "ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" },
"ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" },
"ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" },
"ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" }, "ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 10%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 2,5%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" },
"ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" }, "ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" },
"ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" }, "ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"Empty", "empty":"Empty",
"yes":"Yes", "yes":"Yes",
"no":"No", "no":"No",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Recovery Token", description: "Heals 2% of max HP every turn" }, "ENEMY_HEAL": { name: "Recovery Token", description: "Heals 2% of max HP every turn" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 10% chance every turn to heal a status condition" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 2.5% chance every turn to heal a status condition" },
"ENEMY_ENDURE_CHANCE": { name: "Endure Token" }, "ENEMY_ENDURE_CHANCE": { name: "Endure Token" },
"ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Adds a 1% chance that a wild Pokémon will be a fusion" }, "ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Adds a 1% chance that a wild Pokémon will be a fusion" },
}, },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"Vacío", "empty":"Vacío",
"yes":"Sí", "yes":"Sí",
"no":"No", "no":"No",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Recovery Token", description: "Cura el 2% de los PS máximo en cada turno" }, "ENEMY_HEAL": { name: "Recovery Token", description: "Cura el 2% de los PS máximo en cada turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 10% de probabilidad cada turno de curar un problema de estado" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 2.5% de probabilidad cada turno de curar un problema de estado" },
"ENEMY_ENDURE_CHANCE": { name: "Endure Token" }, "ENEMY_ENDURE_CHANCE": { name: "Endure Token" },
"ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión" }, "ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión" },
}, },

View File

@ -44,4 +44,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"Vide", "empty":"Vide",
"yes":"Oui", "yes":"Oui",
"no":"Non", "no":"Non",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Jeton Soin", description: "Soigne 2% des PV max à chaque tour" }, "ENEMY_HEAL": { name: "Jeton Soin", description: "Soigne 2% des PV max à chaque tour" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Jeton Poison" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Jeton Poison" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Jeton Paralysie" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Jeton Paralysie" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Jeton Sommeil" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Jeton Gel" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Jeton Brulure" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Jeton Brulure" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 10% de chances à chaque tour de se soigner dun problème de statut." }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 2.5% de chances à chaque tour de se soigner dun problème de statut." },
"ENEMY_ENDURE_CHANCE": { name: "Jeton Ténacité" }, "ENEMY_ENDURE_CHANCE": { name: "Jeton Ténacité" },
"ENEMY_FUSED_CHANCE": { name: "Jeton Fusion", description: "Ajoute 1% de chances quun Pokémon sauvage soit une fusion." }, "ENEMY_FUSED_CHANCE": { name: "Jeton Fusion", description: "Ajoute 1% de chances quun Pokémon sauvage soit une fusion." },
}, },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"Vuoto", "empty":"Vuoto",
"yes":"Si", "yes":"Si",
"no":"No", "no":"No",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Gettone del Recupero", description: "Cura il 2% dei PS massimi ogni turno" }, "ENEMY_HEAL": { name: "Gettone del Recupero", description: "Cura il 2% dei PS massimi ogni turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del Veleno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del Veleno" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della Paralisi" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della Paralisi" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Gettone del Sonno" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Gettone del Congelamento" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della Bruciatura" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della Bruciatura" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 10% a ogni turno di curare una condizione di stato" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 2.5% a ogni turno di curare una condizione di stato" },
"ENEMY_ENDURE_CHANCE": { name: "Gettone di Resistenza" }, "ENEMY_ENDURE_CHANCE": { name: "Gettone di Resistenza" },
"ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione" }, "ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione" },
}, },

View File

@ -373,141 +373,141 @@ export const PGMdialogue: DialogueTranslationEntries = {
}, },
"brock": { "brock": {
"encounter": { "encounter": {
1: "My expertise on Rock-type Pokémon will take you down! Come on!", 1: "내 전문인 바위 타입 포켓몬으로 널 쓰러뜨려줄게! 덤벼!",
2: "My rock-hard willpower will overwhelm you!", 2: "바위같은 의지로 널 압도하겠어!",
3: "Allow me to show you the true strength of my Pokémon!" 3: "내 포켓몬의 진정한 힘을 보여줄게!"
}, },
"victory": { "victory": {
1: "Your Pokémon's strength have overcome my rock-hard defenses!", 1: "네 포켓몬의 힘이 바위같은 내 방어를 이겼어!",
2: "The world is huge! I'm glad to have had a chance to battle you.", 2: "세상은 넓구나! 너랑 겨뤄볼 수 있어서 즐거웠어.",
3: "Perhaps I should go back to pursuing my dream as a Pokémon Breeder…" 3: "아마도 난 포켓몬 브리더의 꿈을 이루러 가야할지도…"
}, },
"defeat": { "defeat": {
1: "The best offense is a good defense!\nThat's my way of doing things!", 1: "최선의 공격은 적절한 방어지!\n그게 내 방식이야!",
2: "Come study rocks with me next time to better learn how to fight them!", 2: "다음에 나한테 더 배우러와. 바위타입과 어떻게 싸워야하는지 알려주지!",
3: "Hah, all my traveling around the regions is paying off!" 3: "아, 여러 지역을 돌아다니며 여행한 보람이 있군!"
} }
}, },
"misty": { "misty": {
"encounter": { "encounter": {
1: "My policy is an all out offensive with Water-type Pokémon!", 1: "내 방침은 물타입 포켓몬으로 공격하고 공격하고 또 공격하는 거!",
2: "Hiya, I'll show you the strength of my aquatic Pokémon!", 2: "아하핫, 너한테 내 물타입 포켓몬들의 힘을 보여줄게!",
3: "My dream was to go on a journey and battle powerful trainers…\nWill you be a sufficient challenge?" 3: "내 꿈은 여행을 다니며 강한 트레이너들과 배틀하는 거였어…\n네가 그 충분한 도전자가 될 수 있는지 볼까?"
}, },
"victory": { "victory": {
1: "You really are strong… I'll admit that you are skilled…", 1: "너 정말로 강하구나… 그 실력 인정하도록 할게…",
2: "Grrr… You know you just got lucky, right?!", 2: "으으… 너 그냥 운이 좋았던거야, 그치?!",
3: "Wow, you're too much! I can't believe you beat me!" 3: "우와, 너 대단해! 날 이기다니 믿을 수 없어!"
}, },
"defeat": { "defeat": {
1: "Was the mighty Misty too much for you?", 1: "최강인 최이슬! 너한테 좀 심했나?",
2: "I hope you saw my Pokémon's elegant swimming techniques!", 2: "내 포켓몬들의 우아한 수영 테크닉을 봤길 바랄게!",
3: "Your Pokémon were no match for my pride and joys!" 3: "내 프라이드와 즐거움엔 네 포켓몬들은 상대가 안 돼. "
} }
}, },
"lt_surge": { "lt_surge": {
"encounter": { "encounter": {
1: "My Electric Pokémon saved me during the war! I'll show you how!", 1: "마이 전기 포켓몬은 전쟁에서 미를 구했어요! 하우를 유에게 보여줄게요!",
2: "Ten-hut! I'll shock you into surrender!", 2: "헤이! 쇼크로 유를 항복시키겠어요!",
3: "I'll zap you just like I do to all my enemies in battle!" 3: "배틀에서 마이 에너미에게 했던 것처럼 유에게도 펀치를 날리겠어요!"
}, },
"victory": { "victory": {
1: "Whoa! Your team's the real deal, kid!", 1: "와우, 키드! 유어 팀은 진짜 대단하군요!",
2: "Aaargh, you're strong! Even my electric tricks lost against you.", 2: "으흐흑, 유는 스트롱하네요! 마이 전기 트릭도 유에겐 로스트입니다.",
3: "That was an absolutely shocking loss!" 3: "앱솔루트하고 쇼킹한 패배였어요!"
}, },
"defeat": { "defeat": {
1: "Oh yeah! When it comes to Electric-type Pokémon, I'm number one in the world!", 1: "오우 예! 전기 타입 포켓몬이라면, 미가 월드에서 넘버 원이에요!",
2: "Hahaha! That was an electrifying battle, kid!", 2: "하하하! 키드, 이것이 찌릿찌릿 일렉트릭 배틀입니다!",
3: "A Pokémon battle is war, and I have showed you first-hand combat!" 3: "포켓몬 배틀은 전쟁, 앤드 나는 유에게 직접 전투를 보여줬습니다!"
} }
}, },
"erika": { "erika": {
"encounter": { "encounter": {
1: "Ah, the weather is lovely here…\nOh, a battle? Very well then.", 1: "아, 오늘은 날씨가 좋네요…\n음, 배틀일까요? 그럼 더 좋죠.",
2: "My Pokémon battling skills rival that of my flower arranging skills.", 2: "제 포켓몬들의 배틀 실력은 제 꽃꽂이 실력만큼 대단하답니다.",
3: "Oh, I hope the pleasant aroma of my Pokémon doesn't put me to sleep again…", 3: "아, 제 포켓몬의 달콤한 향기가 저를 다시 잠들게 하지 않았으면 좋겠는데……",
4: "Seeing flowers in a garden is so soothing." 4: "정원에서 꽃을 보면 마음이 편안해져요.”."
}, },
"victory": { "victory": {
1: "Oh! I concede defeat.", 1: "앗! 제 패배를 인정합니다.",
2: "That match was most delightful.", 2: "방금 경기 정말 달콤했어요.",
3: "Ah, it appears it is my loss…", 3: "아, 제가 진 것 같네요…",
4: "Oh, my goodness." 4: "앗, 맙소사."
}, },
"defeat": { "defeat": {
1: "I was afraid I would doze off…", 1: "저 조금 걱정했어요. 너무 졸려서…",
2: "Oh my, it seems my Grass Pokémon overwhelmed you.", 2: "어머, 제 풀 포켓몬이 당신을 압도한 것 같네요.",
3: "That battle was such a soothing experience.", 3: "이 배틀 정말로 편안한 경험이었네요.",
4: "Oh… Is that all?" 4: "어머… 이게 끝인가요?"
} }
}, },
"janine": { "janine": {
"encounter": { "encounter": {
1: "I am mastering the art of poisonous attacks.\nI shall spar with you today!", 1: "난 독을 사용하는 인술을 갈고 닦고 있어.\n오늘 수련에서는 너랑 대련할거야!",
2: "Father trusts that I can hold my own.\nI will prove him right!", 2: "아버지는 내가 잘해낼 수 있다고 신뢰하셔.\n 그게 맞는다는 걸 증명할게!",
3: "My ninja techniques are only second to my Father's!\nCan you keep up?" 3: "내 인술은 아버지한테 뒤처지지 않아! 따라올 수 있겠어? "
}, },
"victory": { "victory": {
1: "Even now, I still need training… I understand.", 1: "역시 아직도, 난 더 수련이 필요해… 납득했어.",
2: "Your battle technique has outmatched mine.", 2: "네 배틀 기술이 내 인술보다 한 수위야.",
3: "I'm going to really apply myself and improve my skills." 3: "더 스스로 갈고 닦아서, 내 인술을 향상 시키겠어."
}, },
"defeat": { "defeat": {
1: "Fufufu… the poison has sapped all your strength to battle.", 1: "후후후… 독이 네 기력을 모두 가져가버렸네.",
2: "Ha! You didn't stand a chance against my superior ninja skills!", 2: "하핫, 너 내 인술에 맞설 기회를 잡지 못했구나!",
3: "Father's faith in me has proven to not be misplaced." 3: "나를 향한 아버지의 신뢰, 틀리지 않았다는 걸 증명해냈어."
} }
}, },
"sabrina": { "sabrina": {
"encounter": { "encounter": {
1: "Through my psychic ability, I had a vision of your arrival!", 1: "내 초능력을 통해서, 너의 도착은 예상하고 있었어!",
2: "I dislike fighting, but if you wish, I will show you my powers!", 2: "싸우는 건 좋아하지 않지만 네가 원한다면… 나의 힘을 보여줄게!",
3: "I can sense great ambition in you. I shall see if it not unfounded." 3: "네게서 큰 염원이 느껴져. 그것이 근거 없는 것이 아닌지 지켜보겠어."
}, },
"victory": { "victory": {
1: "Your power… It far exceeds what I foresaw…", 1: "너의 힘은… 내가 예견했던 것보다 훨씬 뛰어나…",
2: "I failed to accurately predict your power.", 2: "나는 너의 힘을 정확하게 예측하지 못했어.",
3: "Even with my immense psychic powers, I cannot sense another as strong as you." 3: "나 엄청난 초능력을 가지고도, 너처럼 강한 사람을 느끼지 못했네."
}, },
"defeat": { "defeat": {
1: "This victory… It is exactly as I foresaw in my visions!", 1: "이 승리는… 내가 환상에서 예견한 그대로네!",
2: "Perhaps it was another I sensed a great desire in…", 2: "아마도 그건, 내가 깊이 느꼈던 또 다른 염원이었을거야…",
3: "Hone your abilities before recklessly charging into battle.\nYou never know what the future may hold if you do…" 3: "무모하게 배틀에 임하기 전에 능력을 갈고닦도록.\n넌 미래가 어떻게 될지 예지할 수 없으니까…"
} }
}, },
"blaine": { "blaine": {
"encounter": { "encounter": {
1: "Hah! Hope you brought a Burn Heal!", 1: "우오오~옷! 화상치료제는 잘 준비했는가!",
2: "My fiery Pokémon will incinerate all challengers!", 2: "나의 포켓몬은 모든 것을 불꽃으로 태워버리는 강한 녀석들뿐이다!",
3: "Get ready to play with fire!" 3: "불꽃과 함께할 준비는 됐는가!"
}, },
"victory": { "victory": {
1: "I have burned down to nothing! Not even ashes remain!", 1: "아무것도 남지 않고 불타버렸다! 재조차 남지 않았어!",
2: "Didn't I stoke the flames high enough?", 2: "내가 불을 너무 세게 피우지 않았나?",
3: "I'm all burned out… But this makes my motivation to improve burn even hotter!" 3: "불태웠다… 하지만 이건 불꽃을 향상시키려는 내 동기를 더욱 뜨겁게 만드는군!"
}, },
"defeat": { "defeat": {
1: "My raging inferno cannot be quelled!", 1: "나의 타오르는 불길은 진압할 수 없다!",
2: "My Pokémon have been powered up with the heat from this victory!", 2: "내 포켓몬은 이번 승리의 열기로 더욱 강해졌다!",
3: "Hah! My passion burns brighter than yours!" 3: "하! 내 열정이 네 것보다 더 밝게 타오르고 있군!"
} }
}, },
"giovanni": { "giovanni": {
"encounter": { "encounter": {
1: "I, the leader of Team Rocket, will make you feel a world of pain!", 1: "나, 로켓단의 리더가, 고통의 세계를 느끼게 해주마!",
2: "My training here will be vital before I am to face my old associates again.", 2: "옛 동료들과 다시 만나기 전, 이곳에서의 훈련은 매우 중요하겠군.",
3: "I do not think you are prepared for the level of failure you are about to experience!" 3: "너는 곧 경험하게 될 실패에 대한 준비가 되어 있지 않군!"
}, },
"victory": { "victory": {
1: "WHAT! Me, lose?! There is nothing I wish to say to you!", 1: "하! 내가 졌다고?! 더 이상 할말이 없군!",
2: "Hmph… You could never understand what I hope to achieve.", 2: "흐음… 넌 내가 이루고자 하는 것을 결코 이해할 수 없을 거다.",
3: "This defeat is merely delaying the inevitable.\nI will rise Team Rocket from the ashes in due time." 3: "이 패배는 피할 수 없는 것을 단지 지연시킬 뿐.\n때가 되면 잿더미에서 로켓단을 일으켜 세울 것이다."
}, },
"defeat": { "defeat": {
1: "Not being able to measure your own strength shows that you are still but a child.", 1: "자신의 힘을 스스로 잴수 없다는 것은 네가 아직 꼬맹이라는 것을 보여준다고 할 수 있지.",
2: "Do not try to interfere with me again.", 2: "다시는 나를 방해하지 말도록.",
3: "I hope you understand how foolish challenging me was." 3: "나에게 도전하는 것이 얼마나 어리석은 짓인지 이해했으면 좋겠군."
} }
}, },
"roxanne": { "roxanne": {

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"빈 슬롯", "empty":"빈 슬롯",
"yes":"예", "yes":"예",
"no":"아니오", "no":"아니오",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "회복 토큰", description: "매 턴 최대 체력의 2%를 회복" }, "ENEMY_HEAL": { name: "회복 토큰", description: "매 턴 최대 체력의 2%를 회복" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "독 토큰" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "독 토큰" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "마비 토큰" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "마비 토큰" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "잠듦 토큰" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "얼음 토큰" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "화상 토큰" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "화상 토큰" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 10% 추가" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 2.5% 추가" },
"ENEMY_ENDURE_CHANCE": { name: "버티기 토큰" }, "ENEMY_ENDURE_CHANCE": { name: "버티기 토큰" },
"ENEMY_FUSED_CHANCE": { name: "합체 토큰", description: "야생 포켓몬이 합체할 확률 1% 추가" }, "ENEMY_FUSED_CHANCE": { name: "합체 토큰", description: "야생 포켓몬이 합체할 확률 1% 추가" },
}, },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty": "Vazio", "empty": "Vazio",
"yes": "Sim", "yes": "Sim",
"no": "Não", "no": "Não",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "Token de Recuperação", description: "Cura 2% dos PS máximos a cada turno" }, "ENEMY_HEAL": { name: "Token de Recuperação", description: "Cura 2% dos PS máximos a cada turno" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Token de Veneno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Token de Veneno" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Token de Paralisia" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Token de Paralisia" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "Token de Sono" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "Token de Congelamento" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Token de Queimadura" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Token de Queimadura" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 10% a cada turno de curar uma condição de status" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 2.5% a cada turno de curar uma condição de status" },
"ENEMY_ENDURE_CHANCE": { name: "Token de Persistência" }, "ENEMY_ENDURE_CHANCE": { name: "Token de Persistência" },
"ENEMY_FUSED_CHANCE": { name: "Token de Fusão", description: "Adiciona uma chance de 1% de que um Pokémon selvagem seja uma fusão" }, "ENEMY_FUSED_CHANCE": { name: "Token de Fusão", description: "Adiciona uma chance de 1% de que um Pokémon selvagem seja uma fusão" },
}, },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty": "空", "empty": "空",
"yes": "是", "yes": "是",
"no": "否", "no": "否",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_HEAL": { name: "回复硬币", description: "每回合回复2%最大HP" }, "ENEMY_HEAL": { name: "回复硬币", description: "每回合回复2%最大HP" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "剧毒硬币" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "剧毒硬币" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "麻痹硬币" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "麻痹硬币" },
"ENEMY_ATTACK_SLEEP_CHANCE": { name: "睡眠硬币" },
"ENEMY_ATTACK_FREEZE_CHANCE": { name: "冰冻硬币" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "灼烧硬币" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "灼烧硬币" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加10%每回合治愈异常状态的概率" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加2.5%每回合治愈异常状态的概率" },
"ENEMY_ENDURE_CHANCE": { name: "忍受硬币" }, "ENEMY_ENDURE_CHANCE": { name: "忍受硬币" },
"ENEMY_FUSED_CHANCE": { name: "融合硬币", description: "增加1%野生融合宝可梦出现概率" }, "ENEMY_FUSED_CHANCE": { name: "融合硬币", description: "增加1%野生融合宝可梦出现概率" },
}, },

View File

@ -49,4 +49,6 @@ export const menu: SimpleTranslationEntries = {
"empty":"空", "empty":"空",
"yes":"是", "yes":"是",
"no":"否", "no":"否",
"disclaimer": "DISCLAIMER",
"disclaimerDescription": "This game is an unfinished product; it might have playability issues (including the potential loss of save data),\n change without notice, and may or may not be updated further or completed."
} as const; } as const;

View File

@ -282,12 +282,10 @@ export const modifierType: ModifierTypeTranslationEntries = {
ENEMY_HEAL: { name: "恢復硬幣", description: "每回合恢復2%最大HP" }, ENEMY_HEAL: { name: "恢復硬幣", description: "每回合恢復2%最大HP" },
ENEMY_ATTACK_POISON_CHANCE: { name: "劇毒硬幣" }, ENEMY_ATTACK_POISON_CHANCE: { name: "劇毒硬幣" },
ENEMY_ATTACK_PARALYZE_CHANCE: { name: "麻痹硬幣" }, ENEMY_ATTACK_PARALYZE_CHANCE: { name: "麻痹硬幣" },
ENEMY_ATTACK_SLEEP_CHANCE: { name: "睡眠硬幣" },
ENEMY_ATTACK_FREEZE_CHANCE: { name: "冰凍硬幣" },
ENEMY_ATTACK_BURN_CHANCE: { name: "灼燒硬幣" }, ENEMY_ATTACK_BURN_CHANCE: { name: "灼燒硬幣" },
ENEMY_STATUS_EFFECT_HEAL_CHANCE: { ENEMY_STATUS_EFFECT_HEAL_CHANCE: {
name: "萬靈藥硬幣", name: "萬靈藥硬幣",
description: "增加10%每回合治癒異常狀態的概率", description: "增加2.5%每回合治癒異常狀態的概率",
}, },
ENEMY_ENDURE_CHANCE: { name: "忍受硬幣" }, ENEMY_ENDURE_CHANCE: { name: "忍受硬幣" },
ENEMY_FUSED_CHANCE: { ENEMY_FUSED_CHANCE: {

View File

@ -978,8 +978,8 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType {
private chancePercent: integer; private chancePercent: integer;
private effect: StatusEffect; private effect: StatusEffect;
constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect) { constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect, stackCount?: integer) {
super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent), "enemy_status_chance"); super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance");
this.chancePercent = chancePercent; this.chancePercent = chancePercent;
this.effect = effect; this.effect = effect;
@ -1216,14 +1216,12 @@ export const modifierTypes = {
ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)), ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)), ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'), //ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2)), ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2, 10)),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 10, StatusEffect.POISON), ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 5, StatusEffect.POISON, 10),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 10, StatusEffect.PARALYSIS), ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 2.5, StatusEffect.PARALYSIS, 10),
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_SLEEP_CHANCE", "wl_awakening", 10, StatusEffect.SLEEP), ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 5, StatusEffect.BURN, 10),
ENEMY_ATTACK_FREEZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_FREEZE_CHANCE", "wl_ice_heal", 10, StatusEffect.FREEZE), ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)),
ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 10, StatusEffect.BURN), ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2),
ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 10)),
ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2.5),
ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)), ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)),
}; };
@ -1324,6 +1322,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
new WeightedModifierType(modifierTypes.TERA_SHARD, 1), new WeightedModifierType(modifierTypes.TERA_SHARD, 1),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0), new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0),
new WeightedModifierType(modifierTypes.VOUCHER, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0, 1),
].map(m => { ].map(m => {
m.setTier(ModifierTier.GREAT); return m; m.setTier(ModifierTier.GREAT); return m;
}), }),
@ -1359,7 +1358,6 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.EXP_SHARE, 12), new WeightedModifierType(modifierTypes.EXP_SHARE, 12),
new WeightedModifierType(modifierTypes.EXP_BALANCE, 4), new WeightedModifierType(modifierTypes.EXP_BALANCE, 4),
new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(party[0].scene.currentBattle.waveIndex / 50) * 2, 1), 4), 4), new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(party[0].scene.currentBattle.waveIndex / 50) * 2, 1), 4), 4),
new WeightedModifierType(modifierTypes.VOUCHER, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily ? Math.max(3 - rerollCount, 0) : 0, 3),
new WeightedModifierType(modifierTypes.WIDE_LENS, 4), new WeightedModifierType(modifierTypes.WIDE_LENS, 4),
].map(m => { ].map(m => {
m.setTier(ModifierTier.ULTRA); return m; m.setTier(ModifierTier.ULTRA); return m;
@ -1384,6 +1382,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, 18), new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, 18),
new WeightedModifierType(modifierTypes.MEGA_BRACELET, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 8, 32), new WeightedModifierType(modifierTypes.MEGA_BRACELET, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 8, 32),
new WeightedModifierType(modifierTypes.DYNAMAX_BAND, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 8, 32), new WeightedModifierType(modifierTypes.DYNAMAX_BAND, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 8, 32),
new WeightedModifierType(modifierTypes.VOUCHER_PLUS, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily ? Math.max(5 - rerollCount * 2, 0) : 0, 5),
].map(m => { ].map(m => {
m.setTier(ModifierTier.ROGUE); return m; m.setTier(ModifierTier.ROGUE); return m;
}), }),
@ -1392,7 +1391,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.SHINY_CHARM, 14), new WeightedModifierType(modifierTypes.SHINY_CHARM, 14),
new WeightedModifierType(modifierTypes.HEALING_CHARM, 18), new WeightedModifierType(modifierTypes.HEALING_CHARM, 18),
new WeightedModifierType(modifierTypes.MULTI_LENS, 18), new WeightedModifierType(modifierTypes.MULTI_LENS, 18),
new WeightedModifierType(modifierTypes.VOUCHER_PLUS, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily ? Math.max(9 - rerollCount * 3, 0) : 0, 9), new WeightedModifierType(modifierTypes.VOUCHER_PREMIUM, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily && !party[0].scene.gameMode.isEndless && !party[0].scene.gameMode.isSplicedOnly ? Math.max(6 - rerollCount * 2, 0) : 0, 6),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24), new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24),
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE] ? 1 : 0, 1), new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE] ? 1 : 0, 1),
].map(m => { ].map(m => {
@ -1466,15 +1465,13 @@ const trainerModifierPool: ModifierPool = {
const enemyBuffModifierPool: ModifierPool = { const enemyBuffModifierPool: ModifierPool = {
[ModifierTier.COMMON]: [ [ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10), new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 9),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10), new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 9),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_SLEEP_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 3),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 9),
new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 4),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10),
new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1)
].map(m => { ].map(m => {
m.setTier(ModifierTier.COMMON); return m; m.setTier(ModifierTier.COMMON); return m;

View File

@ -776,6 +776,9 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) {
bypassSpeed.value = true; bypassSpeed.value = true;
if (this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW") {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " used its quick claw to move faster!"));
}
return true; return true;
} }
@ -2141,7 +2144,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier {
} }
export class EnemyTurnHealModifier extends EnemyPersistentModifier { export class EnemyTurnHealModifier extends EnemyPersistentModifier {
private healPercent: number; public healPercent: number;
constructor(type: ModifierType, healPercent: number, stackCount?: integer) { constructor(type: ModifierType, healPercent: number, stackCount?: integer) {
super(type, stackCount); super(type, stackCount);
@ -2176,23 +2179,23 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
} }
getMaxStackCount(scene: BattleScene): integer { getMaxStackCount(scene: BattleScene): integer {
return 15; return 10;
} }
} }
export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier { export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier {
public effect: StatusEffect; public effect: StatusEffect;
private chance: number; public chance: number;
constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) { constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) {
super(type, stackCount); super(type, stackCount);
this.effect = effect; this.effect = effect;
this.chance = (chancePercent || 10) / 100; this.chance = (chancePercent || 5) / 100;
} }
match(modifier: Modifier): boolean { match(modifier: Modifier): boolean {
return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect && modifier.chance === this.chance; return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect;
} }
clone(): EnemyAttackStatusEffectChanceModifier { clone(): EnemyAttackStatusEffectChanceModifier {
@ -2211,19 +2214,23 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi
return false; return false;
} }
getMaxStackCount(scene: BattleScene): integer {
return 10;
}
} }
export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier { export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier {
private chance: number; public chance: number;
constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { constructor(type: ModifierType, chancePercent: number, stackCount?: integer) {
super(type, stackCount); super(type, stackCount);
this.chance = (chancePercent || 10) / 100; this.chance = (chancePercent || 2.5) / 100;
} }
match(modifier: Modifier): boolean { match(modifier: Modifier): boolean {
return modifier instanceof EnemyStatusEffectHealChanceModifier && modifier.chance === this.chance; return modifier instanceof EnemyStatusEffectHealChanceModifier;
} }
clone(): EnemyStatusEffectHealChanceModifier { clone(): EnemyStatusEffectHealChanceModifier {
@ -2245,19 +2252,23 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier
return false; return false;
} }
getMaxStackCount(scene: BattleScene): integer {
return 10;
}
} }
export class EnemyEndureChanceModifier extends EnemyPersistentModifier { export class EnemyEndureChanceModifier extends EnemyPersistentModifier {
private chance: number; public chance: number;
constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { constructor(type: ModifierType, chancePercent?: number, stackCount?: integer) {
super(type, stackCount); super(type, stackCount || 10);
this.chance = (chancePercent || 2.5) / 100; this.chance = (chancePercent || 2) / 100;
} }
match(modifier: Modifier) { match(modifier: Modifier) {
return modifier instanceof EnemyEndureChanceModifier && modifier.chance === this.chance; return modifier instanceof EnemyEndureChanceModifier;
} }
clone() { clone() {

View File

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

View File

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

View File

@ -81,11 +81,11 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container {
private readonly fieldEffectInfo: ArenaEffectInfo[] = []; private readonly fieldEffectInfo: ArenaEffectInfo[] = [];
// Stores callbacks in a variable so they can be unsubscribed from when destroyed // Stores callbacks in a variable so they can be unsubscribed from when destroyed
private onNewArenaEvent = (event: Event) => this.onNewArena(event); private readonly onNewArenaEvent = (event: Event) => this.onNewArena(event);
private onTurnInitEvent = (event: Event) => this.onTurnInit(event); private readonly onTurnInitEvent = (event: Event) => this.onTurnInit(event);
private onTurnEndEvent = (event: Event) => this.onTurnEnd(event); private readonly onTurnEndEvent = (event: Event) => this.onTurnEnd(event);
private onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event); private readonly onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event);
constructor(scene: Phaser.Scene) { constructor(scene: Phaser.Scene) {
super(scene, 0, 0); super(scene, 0, 0);
@ -379,6 +379,6 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container {
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent); this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent);
this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent); this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent);
super.destroy(); super.destroy(fromScene);
} }
} }

View File

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

View File

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

View File

@ -73,13 +73,16 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
} }
setup(): void { setup(): void {
const currentLanguage = i18next.language; this.setName("container-pkmn-info");
const currentLanguage = i18next.resolvedLanguage;
const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)); const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang));
const textSettings = languageSettings[langSettingKey]; const textSettings = languageSettings[langSettingKey];
const infoBg = addWindow(this.scene, 0, 0, this.infoWindowWidth, 132); const infoBg = addWindow(this.scene, 0, 0, this.infoWindowWidth, 132);
infoBg.setOrigin(0.5, 0.5); infoBg.setOrigin(0.5, 0.5);
infoBg.setName("window-info-bg");
this.pokemonMovesContainer = this.scene.add.container(6, 14); this.pokemonMovesContainer = this.scene.add.container(6, 14);
this.pokemonMovesContainer.setName("container-pkmn-moves");
this.movesContainerInitialX = this.pokemonMovesContainer.x; this.movesContainerInitialX = this.pokemonMovesContainer.x;
@ -89,21 +92,26 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
const movesBg = addWindow(this.scene, 0, 0, 58, 52); const movesBg = addWindow(this.scene, 0, 0, 58, 52);
movesBg.setOrigin(1, 0); movesBg.setOrigin(1, 0);
movesBg.setName("window-moves-bg");
this.pokemonMovesContainer.add(movesBg); this.pokemonMovesContainer.add(movesBg);
const movesLabel = addTextObject(this.scene, -movesBg.width / 2, 6, i18next.t("pokemonInfoContainer:moveset"), TextStyle.WINDOW, { fontSize: "64px" }); const movesLabel = addTextObject(this.scene, -movesBg.width / 2, 6, i18next.t("pokemonInfoContainer:moveset"), TextStyle.WINDOW, { fontSize: "64px" });
movesLabel.setOrigin(0.5, 0); movesLabel.setOrigin(0.5, 0);
movesLabel.setName("text-moves");
this.pokemonMovesContainer.add(movesLabel); this.pokemonMovesContainer.add(movesLabel);
for (let m = 0; m < 4; m++) { for (let m = 0; m < 4; m++) {
const moveContainer = this.scene.add.container(-6, 18 + 7 * m); const moveContainer = this.scene.add.container(-6, 18 + 7 * m);
moveContainer.setScale(0.5); moveContainer.setScale(0.5);
moveContainer.setName("container-move");
const moveBg = this.scene.add.nineslice(0, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2); const moveBg = this.scene.add.nineslice(0, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2);
moveBg.setOrigin(1, 0); moveBg.setOrigin(1, 0);
moveBg.setName("nineslice-move-bg");
const moveLabel = addTextObject(this.scene, -moveBg.width / 2, 0, "-", TextStyle.PARTY); const moveLabel = addTextObject(this.scene, -moveBg.width / 2, 0, "-", TextStyle.PARTY);
moveLabel.setOrigin(0.5, 0); moveLabel.setOrigin(0.5, 0);
moveLabel.setName("text-move-label");
this.pokemonMoveBgs.push(moveBg); this.pokemonMoveBgs.push(moveBg);
this.pokemonMoveLabels.push(moveLabel); this.pokemonMoveLabels.push(moveLabel);
@ -132,38 +140,46 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
this.pokemonGenderLabelText = addTextObject(this.scene, infoContainerLabelXPos, 18, i18next.t("pokemonInfoContainer:gender"), TextStyle.WINDOW, { fontSize: infoContainerTextSize }); this.pokemonGenderLabelText = addTextObject(this.scene, infoContainerLabelXPos, 18, i18next.t("pokemonInfoContainer:gender"), TextStyle.WINDOW, { fontSize: infoContainerTextSize });
this.pokemonGenderLabelText.setOrigin(1, 0); this.pokemonGenderLabelText.setOrigin(1, 0);
this.pokemonGenderLabelText.setVisible(false); this.pokemonGenderLabelText.setVisible(false);
this.pokemonGenderLabelText.setName("text-pkmn-gender-label");
this.add(this.pokemonGenderLabelText); this.add(this.pokemonGenderLabelText);
this.pokemonGenderText = addTextObject(this.scene, infoContainerTextXPos, 18, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize }); this.pokemonGenderText = addTextObject(this.scene, infoContainerTextXPos, 18, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize });
this.pokemonGenderText.setOrigin(0, 0); this.pokemonGenderText.setOrigin(0, 0);
this.pokemonGenderText.setVisible(false); this.pokemonGenderText.setVisible(false);
this.pokemonGenderText.setName("text-pkmn-gender");
this.add(this.pokemonGenderText); this.add(this.pokemonGenderText);
this.pokemonAbilityLabelText = addTextObject(this.scene, infoContainerLabelXPos, 28, i18next.t("pokemonInfoContainer:ability"), TextStyle.WINDOW, { fontSize: infoContainerTextSize }); this.pokemonAbilityLabelText = addTextObject(this.scene, infoContainerLabelXPos, 28, i18next.t("pokemonInfoContainer:ability"), TextStyle.WINDOW, { fontSize: infoContainerTextSize });
this.pokemonAbilityLabelText.setOrigin(1, 0); this.pokemonAbilityLabelText.setOrigin(1, 0);
this.pokemonAbilityLabelText.setName("text-pkmn-ability-label");
this.add(this.pokemonAbilityLabelText); this.add(this.pokemonAbilityLabelText);
this.pokemonAbilityText = addTextObject(this.scene, infoContainerTextXPos, 28, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize }); this.pokemonAbilityText = addTextObject(this.scene, infoContainerTextXPos, 28, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize });
this.pokemonAbilityText.setOrigin(0, 0); this.pokemonAbilityText.setOrigin(0, 0);
this.pokemonAbilityText.setName("text-pkmn-ability");
this.add(this.pokemonAbilityText); this.add(this.pokemonAbilityText);
this.pokemonNatureLabelText = addTextObject(this.scene, infoContainerLabelXPos, 38, i18next.t("pokemonInfoContainer:nature"), TextStyle.WINDOW, { fontSize: infoContainerTextSize }); this.pokemonNatureLabelText = addTextObject(this.scene, infoContainerLabelXPos, 38, i18next.t("pokemonInfoContainer:nature"), TextStyle.WINDOW, { fontSize: infoContainerTextSize });
this.pokemonNatureLabelText.setOrigin(1, 0); this.pokemonNatureLabelText.setOrigin(1, 0);
this.pokemonNatureLabelText.setName("text-pkmn-nature-label");
this.add(this.pokemonNatureLabelText); this.add(this.pokemonNatureLabelText);
this.pokemonNatureText = addBBCodeTextObject(this.scene, infoContainerTextXPos, 38, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize, lineSpacing: 3, maxLines: 2 }); this.pokemonNatureText = addBBCodeTextObject(this.scene, infoContainerTextXPos, 38, "", TextStyle.WINDOW, { fontSize: infoContainerTextSize, lineSpacing: 3, maxLines: 2 });
this.pokemonNatureText.setOrigin(0, 0); this.pokemonNatureText.setOrigin(0, 0);
this.pokemonNatureText.setName("text-pkmn-nature");
this.add(this.pokemonNatureText); this.add(this.pokemonNatureText);
this.pokemonShinyIcon = this.scene.add.image(-43.5, 48.5, "shiny_star"); this.pokemonShinyIcon = this.scene.add.image(-43.5, 48.5, "shiny_star");
this.pokemonShinyIcon.setOrigin(0, 0); this.pokemonShinyIcon.setOrigin(0, 0);
this.pokemonShinyIcon.setScale(0.75); this.pokemonShinyIcon.setScale(0.75);
this.pokemonShinyIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains); this.pokemonShinyIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 12, 15), Phaser.Geom.Rectangle.Contains);
this.pokemonShinyIcon.setName("img-pkmn-shiny-icon");
this.add(this.pokemonShinyIcon); this.add(this.pokemonShinyIcon);
this.pokemonFusionShinyIcon = this.scene.add.image(this.pokemonShinyIcon.x, this.pokemonShinyIcon.y, "shiny_star_2"); this.pokemonFusionShinyIcon = this.scene.add.image(this.pokemonShinyIcon.x, this.pokemonShinyIcon.y, "shiny_star_2");
this.pokemonFusionShinyIcon.setOrigin(0, 0); this.pokemonFusionShinyIcon.setOrigin(0, 0);
this.pokemonFusionShinyIcon.setScale(0.75); this.pokemonFusionShinyIcon.setScale(0.75);
this.pokemonFusionShinyIcon.setName("img-pkmn-fusion-shiny-icon");
this.add(this.pokemonFusionShinyIcon); this.add(this.pokemonFusionShinyIcon);
this.setVisible(false); this.setVisible(false);

View File

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

View File

@ -23,6 +23,7 @@ export class StatsContainer extends Phaser.GameObjects.Container {
} }
setup() { setup() {
this.setName("container-stats");
const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][0], ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][1] ] ).flat(); const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][0], ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][1] ] ).flat();
const ivChartBg = this.scene.add.polygon(48, 44, ivChartBgData, 0xd8e0f0, 0.625); const ivChartBg = this.scene.add.polygon(48, 44, ivChartBgData, 0xd8e0f0, 0.625);

View File

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

View File

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

View File

@ -174,6 +174,7 @@ export default class UI extends Phaser.GameObjects.Container {
} }
setup(): void { setup(): void {
this.setName("container-ui");
for (const handler of this.handlers) { for (const handler of this.handlers) {
handler.setup(); handler.setup();
} }

View File

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