From c20f37bcf953c2367230cad9344b144432464fdc Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:39:52 -0700 Subject: [PATCH 01/11] [P3 Bug] Add dialog lines for Rood (#3970) --- src/data/dialogue.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index 3ef6d30643c..a2ba06b657f 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -1,6 +1,6 @@ import { BattleSpec } from "#enums/battle-spec"; import { TrainerType } from "#enums/trainer-type"; -import {trainerConfigs} from "./trainer-config"; +import { trainerConfigs } from "./trainer-config"; export interface TrainerTypeMessages { encounter?: string | string[], @@ -707,6 +707,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.ROOD]: [ + { + encounter: [ + "dialogue:rood.encounter.1", + "dialogue:rood.encounter.2", + "dialogue:rood.encounter.3", + ], + victory: [ + "dialogue:rood.victory.1", + "dialogue:rood.victory.2", + "dialogue:rood.victory.3", + ] + } + ], [TrainerType.FLARE_GRUNT]: [ { encounter: [ From ad778101e4b74efceb8c87118db718815e08e8cd Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Mon, 2 Sep 2024 19:32:49 +0200 Subject: [PATCH 02/11] [DEV] Remove female achv file (#3977) --- src/locales/en/achv-female.json | 268 -------------------------------- 1 file changed, 268 deletions(-) delete mode 100644 src/locales/en/achv-female.json diff --git a/src/locales/en/achv-female.json b/src/locales/en/achv-female.json deleted file mode 100644 index edcd8c53fb7..00000000000 --- a/src/locales/en/achv-female.json +++ /dev/null @@ -1,268 +0,0 @@ -{ - "Achievements": { - "name": "Achievements" - }, - "Locked": { - "name": "Locked" - }, - "MoneyAchv": { - "description": "Accumulate a total of ₽{{moneyAmount}}" - }, - "10K_MONEY": { - "name": "Money Haver" - }, - "100K_MONEY": { - "name": "Rich" - }, - "1M_MONEY": { - "name": "Millionaire" - }, - "10M_MONEY": { - "name": "One Percenter" - }, - "DamageAchv": { - "description": "Inflict {{damageAmount}} damage in one hit" - }, - "250_DMG": { - "name": "Hard Hitter" - }, - "1000_DMG": { - "name": "Harder Hitter" - }, - "2500_DMG": { - "name": "That's a Lotta Damage!" - }, - "10000_DMG": { - "name": "One Punch Man" - }, - "HealAchv": { - "description": "Heal {{healAmount}} {{HP}} at once with a move, ability, or held item" - }, - "250_HEAL": { - "name": "Novice Healer" - }, - "1000_HEAL": { - "name": "Big Healer" - }, - "2500_HEAL": { - "name": "Cleric" - }, - "10000_HEAL": { - "name": "Recovery Master" - }, - "LevelAchv": { - "description": "Level up a Pokémon to Lv{{level}}" - }, - "LV_100": { - "name": "But Wait, There's More!" - }, - "LV_250": { - "name": "Elite" - }, - "LV_1000": { - "name": "To Go Even Further Beyond" - }, - "RibbonAchv": { - "description": "Accumulate a total of {{ribbonAmount}} Ribbons" - }, - "10_RIBBONS": { - "name": "Pokémon League Champion" - }, - "25_RIBBONS": { - "name": "Great League Champion" - }, - "50_RIBBONS": { - "name": "Ultra League Champion" - }, - "75_RIBBONS": { - "name": "Rogue League Champion" - }, - "100_RIBBONS": { - "name": "Master League Champion" - }, - "TRANSFER_MAX_BATTLE_STAT": { - "name": "Teamwork", - "description": "Baton pass to another party member with at least one stat maxed out" - }, - "MAX_FRIENDSHIP": { - "name": "Friendmaxxing", - "description": "Reach max friendship on a Pokémon" - }, - "MEGA_EVOLVE": { - "name": "Megamorph", - "description": "Mega evolve a Pokémon" - }, - "GIGANTAMAX": { - "name": "Absolute Unit", - "description": "Gigantamax a Pokémon" - }, - "TERASTALLIZE": { - "name": "STAB Enthusiast", - "description": "Terastallize a Pokémon" - }, - "STELLAR_TERASTALLIZE": { - "name": "The Hidden Type", - "description": "Stellar Terastallize a Pokémon" - }, - "SPLICE": { - "name": "Infinite Fusion", - "description": "Splice two Pokémon together with DNA Splicers" - }, - "MINI_BLACK_HOLE": { - "name": "A Hole Lot of Items", - "description": "Acquire a Mini Black Hole" - }, - "CATCH_MYTHICAL": { - "name": "Mythical", - "description": "Catch a mythical Pokémon" - }, - "CATCH_SUB_LEGENDARY": { - "name": "(Sub-)Legendary", - "description": "Catch a sub-legendary Pokémon" - }, - "CATCH_LEGENDARY": { - "name": "Legendary", - "description": "Catch a legendary Pokémon" - }, - "SEE_SHINY": { - "name": "Shiny", - "description": "Find a shiny Pokémon in the wild" - }, - "SHINY_PARTY": { - "name": "That's Dedication", - "description": "Have a full party of shiny Pokémon" - }, - "HATCH_MYTHICAL": { - "name": "Mythical Egg", - "description": "Hatch a mythical Pokémon from an egg" - }, - "HATCH_SUB_LEGENDARY": { - "name": "Sub-Legendary Egg", - "description": "Hatch a sub-legendary Pokémon from an egg" - }, - "HATCH_LEGENDARY": { - "name": "Legendary Egg", - "description": "Hatch a legendary Pokémon from an egg" - }, - "HATCH_SHINY": { - "name": "Shiny Egg", - "description": "Hatch a shiny Pokémon from an egg" - }, - "HIDDEN_ABILITY": { - "name": "Hidden Potential", - "description": "Catch a Pokémon with a hidden ability" - }, - "PERFECT_IVS": { - "name": "Certificate of Authenticity", - "description": "Get perfect IVs on a Pokémon" - }, - "CLASSIC_VICTORY": { - "name": "Undefeated", - "description": "Beat the game in classic mode" - }, - "UNEVOLVED_CLASSIC_VICTORY": { - "name": "Bring Your Child To Work Day", - "description": "Beat the game in Classic Mode with at least one unevolved party member." - }, - "MONO_GEN_ONE": { - "name": "The Original Rival", - "description": "Complete the generation one only challenge." - }, - "MONO_GEN_TWO": { - "name": "Generation 1.5", - "description": "Complete the generation two only challenge." - }, - "MONO_GEN_THREE": { - "name": "Too much water?", - "description": "Complete the generation three only challenge." - }, - "MONO_GEN_FOUR": { - "name": "Is she really the hardest?", - "description": "Complete the generation four only challenge." - }, - "MONO_GEN_FIVE": { - "name": "All Original", - "description": "Complete the generation five only challenge." - }, - "MONO_GEN_SIX": { - "name": "Almost Royalty", - "description": "Complete the generation six only challenge." - }, - "MONO_GEN_SEVEN": { - "name": "Only Technically", - "description": "Complete the generation seven only challenge." - }, - "MONO_GEN_EIGHT": { - "name": "A Champion Time!", - "description": "Complete the generation eight only challenge." - }, - "MONO_GEN_NINE": { - "name": "She was going easy on you", - "description": "Complete the generation nine only challenge." - }, - "MonoType": { - "description": "Complete the {{type}} monotype challenge." - }, - "MONO_NORMAL": { - "name": "Extra Ordinary" - }, - "MONO_FIGHTING": { - "name": "I Know Kung Fu" - }, - "MONO_FLYING": { - "name": "Angry Birds" - }, - "MONO_POISON": { - "name": "Kanto's Favourite" - }, - "MONO_GROUND": { - "name": "Forecast: Earthquakes" - }, - "MONO_ROCK": { - "name": "Brock Hard" - }, - "MONO_BUG": { - "name": "You Like Jazz?" - }, - "MONO_GHOST": { - "name": "Who You Gonna Call?" - }, - "MONO_STEEL": { - "name": "Iron Giant" - }, - "MONO_FIRE": { - "name": "I Cast Fireball!" - }, - "MONO_WATER": { - "name": "When It Rains, It Pours" - }, - "MONO_GRASS": { - "name": "Can't Touch This" - }, - "MONO_ELECTRIC": { - "name": "Aim For The Horn!" - }, - "MONO_PSYCHIC": { - "name": "Big Brain Energy" - }, - "MONO_ICE": { - "name": "Walking On Thin Ice" - }, - "MONO_DRAGON": { - "name": "Pseudo-Legend Club" - }, - "MONO_DARK": { - "name": "It's Just A Phase" - }, - "MONO_FAIRY": { - "name": "Hey! Listen!" - }, - "FRESH_START": { - "name": "First Try!", - "description": "Complete the Fresh Start challenge." - }, - "INVERSE_BATTLE": { - "name": "Mirror rorriM", - "description": "Complete the Inverse Battle challenge.\n.egnellahc elttaB esrevnI eht etelpmoC" - } -} \ No newline at end of file From 86316bd6f875a7e39aceaf4321843a05f09e7fb6 Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Mon, 2 Sep 2024 19:55:57 +0200 Subject: [PATCH 03/11] [Localization] [DE] DisguiseChange (#3979) * [Localization] [DE] DisguiseChange * Update src/locales/de/pokemon-form-battle.json --- src/locales/de/pokemon-form-battle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/de/pokemon-form-battle.json b/src/locales/de/pokemon-form-battle.json index 8651b3d1318..35060c33d0b 100644 --- a/src/locales/de/pokemon-form-battle.json +++ b/src/locales/de/pokemon-form-battle.json @@ -10,5 +10,5 @@ "eternamaxChange": "{{preName}} hat sich zu {{pokemonName}} unendynamaximiert!", "revertChange": "{{pokemonName}} hat seine ursprüngliche Form zurückerlangt!", "formChange": "{{preName}} hat seine Form geändert!", - "disguiseChange": "Its disguise served it as a decoy!" + "disguiseChange": "Sein Kostüm hat die Attacke absorbiert!" } \ No newline at end of file From 256dfbde6ee5064eb326ae72c9735de2bb208d03 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:27:29 -0700 Subject: [PATCH 04/11] Fixed conditional (#3983) Co-authored-by: frutescens --- src/modifier/modifier-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index e693ca01052..d7937692a8d 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -2225,7 +2225,7 @@ export class ModifierTypeOption { } export function getPartyLuckValue(party: Pokemon[]): integer { - const luck = Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.getLuck()) + const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() : 0) .reduce((total: integer, value: integer) => total += value, 0), 0, 14); return luck || 0; } From aae4d6933c22990e70511e31cd9ef61bf6595175 Mon Sep 17 00:00:00 2001 From: timchi94 <110631289+timchi94@users.noreply.github.com> Date: Mon, 2 Sep 2024 15:43:44 -0400 Subject: [PATCH 05/11] =?UTF-8?q?=20[QoL]=20Enable=20female=20gender=20for?= =?UTF-8?q?=20all=20default=20starters=20and=20all=20existing=20s=E2=80=A6?= =?UTF-8?q?=20(#2194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Enable female gender for all default starters and all existing saves * Fixed Fresh Start so it doesn't restrict gender --------- Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com> Co-authored-by: frutescens --- src/data/challenge.ts | 2 -- src/system/game-data.ts | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 36f696e63c1..62751b92f9c 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -13,7 +13,6 @@ import { TrainerType } from "#enums/trainer-type"; import { Nature } from "./nature"; import { Moves } from "#app/enums/moves.js"; import { TypeColor, TypeShadow } from "#app/enums/color.js"; -import { Gender } from "./gender"; import { pokemonEvolutions } from "./pokemon-evolutions"; import { pokemonFormChanges } from "./pokemon-forms"; @@ -659,7 +658,6 @@ export class FreshStartChallenge extends Challenge { pokemon.luck = 0; // No luck pokemon.shiny = false; // Not shiny pokemon.variant = 0; // Not shiny - pokemon.gender = Gender.MALE; // Starters default to male pokemon.formIndex = 0; // Froakie should be base form pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats return true; diff --git a/src/system/game-data.ts b/src/system/game-data.ts index a4c276fa770..29bb6057722 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1488,7 +1488,7 @@ export class GameData { }; } - const defaultStarterAttr = DexAttr.NON_SHINY | DexAttr.MALE | DexAttr.DEFAULT_VARIANT | DexAttr.DEFAULT_FORM; + const defaultStarterAttr = DexAttr.NON_SHINY | DexAttr.MALE | DexAttr.FEMALE | DexAttr.DEFAULT_VARIANT | DexAttr.DEFAULT_FORM; const defaultStarterNatures: Nature[] = []; @@ -1919,6 +1919,7 @@ export class GameData { fixStarterData(systemData: SystemSaveData): void { for (const starterId of defaultStarterSpecies) { systemData.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; + systemData.dexData[starterId].caughtAttr |= DexAttr.FEMALE; } } From e9998fcc16ced78ff9559886f5d9b85ab06dfe14 Mon Sep 17 00:00:00 2001 From: Asdar Date: Mon, 2 Sep 2024 23:20:05 +0200 Subject: [PATCH 06/11] [Localisation] [ES] Bugfix pokemon-form-battle.json (#3981) Removed an extra tab added by GitLocalize --- src/locales/es/pokemon-form-battle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/es/pokemon-form-battle.json b/src/locales/es/pokemon-form-battle.json index 5266baa7049..d6eed9e93cc 100644 --- a/src/locales/es/pokemon-form-battle.json +++ b/src/locales/es/pokemon-form-battle.json @@ -10,5 +10,5 @@ "eternamaxChange": "¡{{preName}} ha eternamaxizado a {{pokemonName}}!", "revertChange": "¡{{pokemonName}} ha revertido a su forma original!", "formChange": "¡{{preName}} ha cambiado de forma!", - "disguiseChange": "¡El disfraz ha actuado como señuelo!\t" + "disguiseChange": "¡El disfraz ha actuado como señuelo!" } From ce5a92325c4c8e0f1d2fa0919988ae2d3003775b Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Mon, 2 Sep 2024 14:54:56 -0700 Subject: [PATCH 07/11] [UI][Misc] Rename Space to Action in voucher/achv menu (#3982) * Changing only achvs-ui-handler for now * Add ACTION sprite --------- Co-authored-by: frutescens Co-authored-by: chaosgrimmon <31082757+chaosgrimmon@users.noreply.github.com> --- public/images/inputs/keyboard.json | 1200 ++++++++++++++-------------- public/images/inputs/keyboard.png | Bin 1973 -> 2157 bytes src/ui/achvs-ui-handler.ts | 2 +- 3 files changed, 605 insertions(+), 597 deletions(-) diff --git a/public/images/inputs/keyboard.json b/public/images/inputs/keyboard.json index b1902df10d6..a8124004c12 100644 --- a/public/images/inputs/keyboard.json +++ b/public/images/inputs/keyboard.json @@ -1,596 +1,604 @@ -{"frames": [ - -{ - "filename": "0.png", - "frame": {"x":0,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "1.png", - "frame": {"x":12,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "2.png", - "frame": {"x":24,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "3.png", - "frame": {"x":36,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "4.png", - "frame": {"x":48,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "5.png", - "frame": {"x":60,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "6.png", - "frame": {"x":72,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "7.png", - "frame": {"x":84,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "8.png", - "frame": {"x":96,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "9.png", - "frame": {"x":108,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "A.png", - "frame": {"x":120,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "ALT.png", - "frame": {"x":132,"y":0,"w":16,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, - "sourceSize": {"w":16,"h":12} -}, -{ - "filename": "B.png", - "frame": {"x":148,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "BACK.png", - "frame": {"x":160,"y":0,"w":24,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":24,"h":12}, - "sourceSize": {"w":24,"h":12} -}, -{ - "filename": "C.png", - "frame": {"x":184,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "CTRL.png", - "frame": {"x":196,"y":0,"w":22,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":22,"h":12}, - "sourceSize": {"w":22,"h":12} -}, -{ - "filename": "D.png", - "frame": {"x":218,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "DEL.png", - "frame": {"x":230,"y":0,"w":17,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":17,"h":12}, - "sourceSize": {"w":17,"h":12} -}, -{ - "filename": "E.png", - "frame": {"x":247,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "END.png", - "frame": {"x":259,"y":0,"w":18,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":18,"h":12}, - "sourceSize": {"w":18,"h":12} -}, -{ - "filename": "ENTER.png", - "frame": {"x":277,"y":0,"w":27,"h":11}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":27,"h":11}, - "sourceSize": {"w":27,"h":11} -}, -{ - "filename": "ESC.png", - "frame": {"x":304,"y":0,"w":17,"h":11}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":17,"h":11}, - "sourceSize": {"w":17,"h":11} -}, -{ - "filename": "F.png", - "frame": {"x":321,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "F1.png", - "frame": {"x":333,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F2.png", - "frame": {"x":346,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F3.png", - "frame": {"x":359,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F4.png", - "frame": {"x":372,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F5.png", - "frame": {"x":385,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F6.png", - "frame": {"x":398,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F7.png", - "frame": {"x":411,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F8.png", - "frame": {"x":424,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F9.png", - "frame": {"x":437,"y":0,"w":13,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, - "sourceSize": {"w":13,"h":12} -}, -{ - "filename": "F10.png", - "frame": {"x":450,"y":0,"w":16,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, - "sourceSize": {"w":16,"h":12} -}, -{ - "filename": "F11.png", - "frame": {"x":466,"y":0,"w":15,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":15,"h":12}, - "sourceSize": {"w":15,"h":12} -}, -{ - "filename": "F12.png", - "frame": {"x":481,"y":0,"w":16,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, - "sourceSize": {"w":16,"h":12} -}, -{ - "filename": "G.png", - "frame": {"x":497,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "H.png", - "frame": {"x":509,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "HOME.png", - "frame": {"x":521,"y":0,"w":23,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":23,"h":12}, - "sourceSize": {"w":23,"h":12} -}, -{ - "filename": "I.png", - "frame": {"x":544,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "INS.png", - "frame": {"x":556,"y":0,"w":16,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, - "sourceSize": {"w":16,"h":12} -}, -{ - "filename": "J.png", - "frame": {"x":572,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "K.png", - "frame": {"x":584,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "KEY_ARROW_DOWN.png", - "frame": {"x":596,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "KEY_ARROW_LEFT.png", - "frame": {"x":608,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "KEY_ARROW_RIGHT.png", - "frame": {"x":620,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "KEY_ARROW_UP.png", - "frame": {"x":632,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "L.png", - "frame": {"x":644,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "LEFT_BRACKET.png", - "frame": {"x":656,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "M.png", - "frame": {"x":668,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "MINUS.png", - "frame": {"x":680,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "N.png", - "frame": {"x":692,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "O.png", - "frame": {"x":704,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "P.png", - "frame": {"x":716,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "PAGE_DOWN.png", - "frame": {"x":728,"y":0,"w":20,"h":11}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":20,"h":11}, - "sourceSize": {"w":20,"h":11} -}, -{ - "filename": "PAGE_UP.png", - "frame": {"x":748,"y":0,"w":20,"h":11}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":20,"h":11}, - "sourceSize": {"w":20,"h":11} -}, -{ - "filename": "PLUS.png", - "frame": {"x":768,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "Q.png", - "frame": {"x":780,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "QUOTE.png", - "frame": {"x":792,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "R.png", - "frame": {"x":804,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "RIGHT_BRACKET.png", - "frame": {"x":816,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "S.png", - "frame": {"x":828,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "SEMICOLON.png", - "frame": {"x":840,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "SHIFT.png", - "frame": {"x":852,"y":0,"w":23,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":23,"h":12}, - "sourceSize": {"w":23,"h":12} -}, -{ - "filename": "SPACE.png", - "frame": {"x":875,"y":0,"w":25,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":25,"h":12}, - "sourceSize": {"w":25,"h":12} -}, -{ - "filename": "T.png", - "frame": {"x":900,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "TAB.png", - "frame": {"x":912,"y":0,"w":19,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":19,"h":12}, - "sourceSize": {"w":19,"h":12} -}, -{ - "filename": "TILDE.png", - "frame": {"x":931,"y":0,"w":15,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":15,"h":12}, - "sourceSize": {"w":15,"h":12} -}, -{ - "filename": "U.png", - "frame": {"x":946,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "V.png", - "frame": {"x":958,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "W.png", - "frame": {"x":970,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "X.png", - "frame": {"x":982,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "Y.png", - "frame": {"x":994,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}, -{ - "filename": "Z.png", - "frame": {"x":1006,"y":0,"w":12,"h":12}, - "rotated": false, - "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, - "sourceSize": {"w":12,"h":12} -}], -"meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "1.0", - "image": "keyboard.png", - "format": "RGBA8888", - "size": {"w":1018,"h":12}, - "scale": "1", - "smartupdate": "$TexturePacker:SmartUpdate:085d4353a5c4d18c90f82f8926710d72:45908b22b446cf7f4904d4e0b658b16a:bad03abb89ad027d879c383c13fd51bc$" -} -} +{"frames": [ + +{ + "filename": "0.png", + "frame": {"x":0,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "1.png", + "frame": {"x":12,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "2.png", + "frame": {"x":24,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "3.png", + "frame": {"x":36,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "4.png", + "frame": {"x":48,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "5.png", + "frame": {"x":60,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "6.png", + "frame": {"x":72,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "7.png", + "frame": {"x":84,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "8.png", + "frame": {"x":96,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "9.png", + "frame": {"x":108,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "A.png", + "frame": {"x":120,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "ALT.png", + "frame": {"x":132,"y":0,"w":16,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, + "sourceSize": {"w":16,"h":12} +}, +{ + "filename": "B.png", + "frame": {"x":148,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "BACK.png", + "frame": {"x":160,"y":0,"w":24,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":24,"h":12}, + "sourceSize": {"w":24,"h":12} +}, +{ + "filename": "C.png", + "frame": {"x":184,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "CTRL.png", + "frame": {"x":196,"y":0,"w":22,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":22,"h":12}, + "sourceSize": {"w":22,"h":12} +}, +{ + "filename": "D.png", + "frame": {"x":218,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "DEL.png", + "frame": {"x":230,"y":0,"w":17,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":17,"h":12}, + "sourceSize": {"w":17,"h":12} +}, +{ + "filename": "E.png", + "frame": {"x":247,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "END.png", + "frame": {"x":259,"y":0,"w":18,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":18,"h":12}, + "sourceSize": {"w":18,"h":12} +}, +{ + "filename": "ENTER.png", + "frame": {"x":277,"y":0,"w":27,"h":11}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":27,"h":11}, + "sourceSize": {"w":27,"h":11} +}, +{ + "filename": "ESC.png", + "frame": {"x":304,"y":0,"w":17,"h":11}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":17,"h":11}, + "sourceSize": {"w":17,"h":11} +}, +{ + "filename": "F.png", + "frame": {"x":321,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "F1.png", + "frame": {"x":333,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F2.png", + "frame": {"x":346,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F3.png", + "frame": {"x":359,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F4.png", + "frame": {"x":372,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F5.png", + "frame": {"x":385,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F6.png", + "frame": {"x":398,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F7.png", + "frame": {"x":411,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F8.png", + "frame": {"x":424,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F9.png", + "frame": {"x":437,"y":0,"w":13,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":13,"h":12}, + "sourceSize": {"w":13,"h":12} +}, +{ + "filename": "F10.png", + "frame": {"x":450,"y":0,"w":16,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, + "sourceSize": {"w":16,"h":12} +}, +{ + "filename": "F11.png", + "frame": {"x":466,"y":0,"w":15,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":15,"h":12}, + "sourceSize": {"w":15,"h":12} +}, +{ + "filename": "F12.png", + "frame": {"x":481,"y":0,"w":16,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, + "sourceSize": {"w":16,"h":12} +}, +{ + "filename": "G.png", + "frame": {"x":497,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "H.png", + "frame": {"x":509,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "HOME.png", + "frame": {"x":521,"y":0,"w":23,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":23,"h":12}, + "sourceSize": {"w":23,"h":12} +}, +{ + "filename": "I.png", + "frame": {"x":544,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "INS.png", + "frame": {"x":556,"y":0,"w":16,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":16,"h":12}, + "sourceSize": {"w":16,"h":12} +}, +{ + "filename": "J.png", + "frame": {"x":572,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "K.png", + "frame": {"x":584,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "KEY_ARROW_DOWN.png", + "frame": {"x":596,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "KEY_ARROW_LEFT.png", + "frame": {"x":608,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "KEY_ARROW_RIGHT.png", + "frame": {"x":620,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "KEY_ARROW_UP.png", + "frame": {"x":632,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "L.png", + "frame": {"x":644,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "LEFT_BRACKET.png", + "frame": {"x":656,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "M.png", + "frame": {"x":668,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "MINUS.png", + "frame": {"x":680,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "N.png", + "frame": {"x":692,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "O.png", + "frame": {"x":704,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "P.png", + "frame": {"x":716,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "PAGE_DOWN.png", + "frame": {"x":728,"y":0,"w":20,"h":11}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":20,"h":11}, + "sourceSize": {"w":20,"h":11} +}, +{ + "filename": "PAGE_UP.png", + "frame": {"x":748,"y":0,"w":20,"h":11}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":20,"h":11}, + "sourceSize": {"w":20,"h":11} +}, +{ + "filename": "PLUS.png", + "frame": {"x":768,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "Q.png", + "frame": {"x":780,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "QUOTE.png", + "frame": {"x":792,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "R.png", + "frame": {"x":804,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "RIGHT_BRACKET.png", + "frame": {"x":816,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "S.png", + "frame": {"x":828,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "SEMICOLON.png", + "frame": {"x":840,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "SHIFT.png", + "frame": {"x":852,"y":0,"w":23,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":23,"h":12}, + "sourceSize": {"w":23,"h":12} +}, +{ + "filename": "SPACE.png", + "frame": {"x":875,"y":0,"w":25,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":25,"h":12}, + "sourceSize": {"w":25,"h":12} +}, +{ + "filename": "T.png", + "frame": {"x":900,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "TAB.png", + "frame": {"x":912,"y":0,"w":19,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":19,"h":12}, + "sourceSize": {"w":19,"h":12} +}, +{ + "filename": "TILDE.png", + "frame": {"x":931,"y":0,"w":15,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":15,"h":12}, + "sourceSize": {"w":15,"h":12} +}, +{ + "filename": "U.png", + "frame": {"x":946,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "V.png", + "frame": {"x":958,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "W.png", + "frame": {"x":970,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "X.png", + "frame": {"x":982,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "Y.png", + "frame": {"x":994,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "Z.png", + "frame": {"x":1006,"y":0,"w":12,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, + "sourceSize": {"w":12,"h":12} +}, +{ + "filename": "ACTION.png", + "frame": {"x":1018,"y":0,"w":28,"h":12}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":28,"h":12}, + "sourceSize": {"w":28,"h":12} +}], +"meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "1.0", + "image": "keyboard.png", + "format": "RGBA8888", + "size": {"w":1018,"h":12}, + "scale": "1", + "smartupdate": "$TexturePacker:SmartUpdate:085d4353a5c4d18c90f82f8926710d72:45908b22b446cf7f4904d4e0b658b16a:bad03abb89ad027d879c383c13fd51bc$" +} +} diff --git a/public/images/inputs/keyboard.png b/public/images/inputs/keyboard.png index 67b26af12de5b3c938d6422361e3d7972fa287fe..1fc5adfa31cbea3f5b52a02618d39e43ce652abb 100644 GIT binary patch literal 2157 zcmV-z2$J`SP)Px-CrLy>RCt{2T)}Q#MGWoWiVIQ#9#RcWl?9!RKPg`ei$9`R#;{&*&81n3b-h)-Mcv3Dp38?^!2N>(06;v*cmA^Z zln-g+vxq0vGuHZB(lOPuh~uu;hw$q48SEbn@buY}Th7VxDLj4l1Wt}m0RV14V;t^# zz>B`F^50rMV?Ngl0sfya4!M3;;!lz<@BGev|7rMISo{&iGKTefYc9=NtLrWEb2EAF zJNG*P-1)p-AHom^44{frTG(R5jyZlTE{$Qu#}+%Ko|gErP40Q+Hc}chr%xM?(;NTB zZE$Y=sZWc8YRP*b%?p)#k9SXVA&~kRcCO+2pW%*uj8reShSUbj@33(uPd{774v^M3P8+39I&9Qv#|}n0Ev50OxEAvT zg}}w;FDeJM`6|&v`R4pnx>NtuUh&c|^{<(KbA24^g~0~PZQ6Tczf`~D{KbAHy^rE@ z`?ch}kb--D@mh2K(|14S<@Bd9YR@~l{ww{%iqv<_cWS-0^LuV~rF>~%bq?6NCR>Y1S@RVqBwr~K&<&3C_Yt;E%+t+v6s+_uYJB)p^kr- z>J?8~d$ote;M-FdcgUOq)Ly~B zUDQZoctNwzB)t$j%t`tk<_~)(PL5Aef8Ot^whnq~p)^S$eSf6A$DK;iQnhxR(2sLoPpFI=JHD@$SXHNe=2)SMOl|;8OswX_|5D)DIP_rm5BDNo%7W zBGY%GC7bYFYon5uyprHShYm~W{+P0ytcZjxN3drOmFZ5`A2 z*X%#({7B6p)PBV-jVKM$HBi1&j`WW=-g7FZGk3{_&3e^ONIy=O=|^15)de>?etTYL7||o@ud_ z?mvm1w1{##B)(G}*di-4*@#oxdmVOU*5BBy< z-;oj<>GMnZ-r7pzaF31dmYI~oy)^L3u++uZzyL`mnQ_WnyI(qo%X1o0W zUw`u@yNH)B{(#M9_tv=c?>B$ycyrM+g^sD#p8D~IMJ(?;b(`hcSlPE;b3JSH()yEz zAGqOP!C#V|bg+$m1AP2f`CHcS#kYW`zbW%O_x)GG*T8#LE{S2OY0Msa-}z%;v)TRc zVnJ#EAQ#yA%jQoVZ!UVK&@t88H=AA9Za=_hM`eGx)!@zfTL6HnSZ~hX-fEVhBv0LD zc{Wz|t=C-78ojjsq~WIrsU_>d4tAFQ;~1^vGw>~Yp+&z-{YiVDcYf!-|4R58jBz-e za=l~r(EG?AYbFQySXTy3Ky6{`{AKf}jyD%QQ|Op#?ZHp@?-;0!|3w7 zo;7-D{Yk?Q+*al4mg9g0@c64-%jf>0YP0e4PdO}a|TyJan1Zck(YVzfs j-?{It>|k^VlX z0bm38?bqA1@!J-+wz+;gn-l%dB?G_~$oE+Xl+bnpfX*ePkN25W$sFd@m2kgp^eukF z0Y4)j*Jl|XZQfjYm0_9h_ZH%x!Pu9f(IRR6n0+St^v2j5kl13b;|oHr)()GD_rhnL z^Xl17H+9NJJW%bu+1X5I}{8-=3f{EIy=uB`HBY01#n4(a}-b7DJ>(fV4Ko z2_9m>!(U#NiA_x&VJ^(oEu5sng+({kKLm88EiY#r(EOrXu+ei^EyQB6C55?cnWs{> zG63My=N>Qk12);Q`R12_#H(u~heD%&AKo)AKLzdDkQLwaBDYX;pH)5l-=f5K5C|Le z<`}PXL^?f-n1mRm9(beT3fFORUktgXH)UQkus%eTgsn}x)n{4DdE#}lnMHO4fO?&o zT7Il1%<|c-OKIDeIxl5=Jd)(N&ZiSM)nOSet1SSE?)gzp+r{|fUNvQ8e8mWeP$3=# zfo^}M6S>-K46LI&oj4ux{{lIK-e1&wen@~28WGz(Fz5nsd-?42HqaXWS{`hey>M{V zRjH_5kgDp8f2WQ853{)KsWT?w99cQ6I-fA=HQqcbP{s6~iWR)0wAdo@LqM5tq?`~Y zrp`KCL*}ftwWCby3KG=rvE6Pn)$%Hy>lM*D4xA^!(-7_22&L03MxdPfX~yqa!dd-f zmHR9qD>OS8bX(!Bdfe}`&8?Ezp-NX`VtDK;LFqQuZ0d66!52njm9*mJZ5h52X-|$W z)FjRWR@+CofqaX=f7L7FTX|SAse3ItT{xc11mKrJ@@57?F$GdP`9_o|%q^w;_4uCE zuFv7^i~`kT#PgR9{>v11Xd$?1#!Elsm`4R_MWQrhz&3f^f_<5KDslNNy>AH3fIG1 zEf!c=y2BhF8#++AG=FDcb!aN%*|h3Fm1;paSA(3j(@6_AHWW=omn zemjk1C+#=eJ_{#u4Dp1+g3f3K(wM<~RrIa-wV82@;im(zh7U_gR6z=GJTp=_h@|rUHO)FMb zRa2DUmR1NS2Km>9a@p@@1qDvP%`GgU@y!KC@?f#6o2RcPjS*~Xke6$A+FabZk>`w0 zEMK~iJ@x+W>j~0mvcXZ}Xq#d_$FpGMu#JA}X(DX9K|WH4xK$%X*NL&s_ zKiGGJZl29Vzd#1fTfhn1t|{Q_Q|*s~K7!ef%jqO1YYvw63(v*sVFS zsas>eLg80uRxM3Mq@*NtFWo*%e@fF=CbsW$iKB@HKTuw#)xC*{lMEW(Hp_v)aGWQ` zDGc^vpiKY76IA#MM`APsw{lkT>6kFce9-MtlTwWyJ=*R|6Qr1u*-~h0iD5Uo%w8NZ|_gC(`cbedgRlqg3_)@UDC?u z#)my7-D?>iKDeXvr$G*yEKf~t|Bk~jy!;Is7MV7{{0r9I*3opWQ~7$j>hnDxuj$OS z15K3#vA5H*{-+5(-Qg7-i}^xLZjNs_{tvwee|4xQ zicz<_u`_WsbUNm;jDmLfx8(UbqOwQ-TW3|}+`$k)ymK|dedBeR_<}Aib~D~%aWie0 t_px8@rUNhN6*e{{FYw{vVTEh!P)AbS?%usw{jG-qq;H^4?a_!|{|1Nm93}t& diff --git a/src/ui/achvs-ui-handler.ts b/src/ui/achvs-ui-handler.ts index eb4316dc24b..605b8c538a9 100644 --- a/src/ui/achvs-ui-handler.ts +++ b/src/ui/achvs-ui-handler.ts @@ -74,7 +74,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.headerText = addTextObject(this.scene, 0, 0, "", TextStyle.SETTINGS_LABEL); this.headerText.setOrigin(0, 0); this.headerText.setPositionRelative(this.headerBg, 8, 4); - this.headerActionButton = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "keyboard", "SPACE.png"); + this.headerActionButton = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "keyboard", "ACTION.png"); this.headerActionButton.setOrigin(0, 0); this.headerActionButton.setPositionRelative(this.headerBg, 236, 6); this.headerActionText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, {fontSize:"60px"}); From 4c4a2c1900b15a1b3ef29276280d6fba31215eac Mon Sep 17 00:00:00 2001 From: Chapybara-jp Date: Mon, 2 Sep 2024 22:57:24 +0100 Subject: [PATCH 08/11] [Localisation] [JA] Translated trainer-classes.json, trainer-names.json, trainer-titles.json (#3978) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Localisation] [JA] trainer-classes.json Names taken from Poke Corpus and Bulbapedia. Some double team names do not exist in the official games so I created some new fitting/localised/funny ones (e.g. (solo) サイキッカー -> (double) サイキッ家) As we are using Scarlet/Violet Kanji usage conventions, I decided to write all class titles that were Hiragana only in BW/B2W2 with Kanji instead. * Translate trainer-names.json Should we localise the names of Finn and Ivy? Two possible ideas: Finn -> チトセ (Finn may come from the "Whale Fin" snake plant; Latin Name Sansevieria Masoniana. The Sansevieria family is known as チトセラン属 in Japanese. チトセ(千歳 millenium;long time) can be a reference to endless loop of Classic Mode) Ivy -> タイチ (Ivy -> IV. IV in Japanese is 固体値 (こたいち). タイチ also sounds like 対置 (opposition) * Update trainer-classes.json * Translate trainer-titles.json --- src/locales/ja/trainer-classes.json | 131 +++++++++++++++++++++- src/locales/ja/trainer-names.json | 165 +++++++++++++++++++++++++++- src/locales/ja/trainer-titles.json | 39 ++++++- 3 files changed, 332 insertions(+), 3 deletions(-) diff --git a/src/locales/ja/trainer-classes.json b/src/locales/ja/trainer-classes.json index 9e26dfeeb6e..aba294fbbbd 100644 --- a/src/locales/ja/trainer-classes.json +++ b/src/locales/ja/trainer-classes.json @@ -1 +1,130 @@ -{} \ No newline at end of file +{ + "ace_trainer": "エリートトレーナー", + "ace_trainer_female": "エリートトレーナー", + "ace_duo": "エリートコンビ", + "artist": "芸術家", + "artist_female": "芸術家", + "backers": "ファンクラブ", + "backpacker": "バックパッカー", + "backpacker_female": "バックパッカー", + "backpackers": "バックパッカーズ", + "baker": "ベーカリー", + "battle_girl": "バトルガール", + "beauty": "大人のおねえさん", + "beginners": "初心者", + "biker": "暴走族", + "black_belt": "カラテ王", + "breeder": "ポケモンブリーダー", + "breeder_female": "ポケモンブリーダー", + "breeders": "ブリーダーコンビ", + "clerk": "ビジネスマン", + "clerk_female": "OL", + "colleagues": "ビジネスパートナー", + "crush_kin": "格闘兄妹", + "cyclist": "サイクリング", + "cyclist_female": "サイクリング", + "cyclists": "サイクリングチーム", + "dancer": "ダンサー", + "dancer_female": "ダンサー", + "depot_agent": "鉄道員", + "doctor": "ドクター", + "doctor_female": "ドクター", + "firebreather": "火吹きやろう", + "fisherman": "釣り人", + "fisherman_female": "釣り人", + "gentleman": "ジェントルマン", + "guitarist": "ギタリスト", + "guitarist_female": "ギタリスト", + "harlequin": "クラウン", + "hiker": "山男", + "hooligans": "バッドチーム", + "hoopster": "バスケ選手", + "infielder": "野球選手", + "janitor": "清掃員", + "lady": "お嬢さま", + "lass": "ミニスカート", + "linebacker": "フットボーラー", + "maid": "メイド", + "madame": "マダム", + "medical_team": "医療チーム", + "musician": "ミュージシャン", + "hex_maniac": "オカルトマニア", + "nurse": "ナース", + "nursery_aide": "保育士", + "officer": "お巡りさん", + "parasol_lady": "パラソルおねえさん", + "pilot": "パイロット", + "pokéfan": "大好きクラブ", + "pokéfan_female": "大好きクラブ", + "pokéfan_family": "大好き夫婦", + "preschooler": "園児", + "preschooler_female": "園児", + "preschoolers": "園児たち", + "psychic": "サイキッカー", + "psychic_female": "サイキッカー", + "psychics": "サイキッ家", + "pokémon_ranger": "ポケモンレンジャー", + "pokémon_ranger_female": "ポケモンレンジャー", + "pokémon_rangers": "レンジャーズ", + "ranger": "レンジャー", + "restaurant_staff": "レストランスタッフ", + "rich": "お金持ち", + "rich_female": "お金持ち", + "rich_boy": "お坊っちゃま", + "rich_couple": "お二人さま", + "rich_kid": "ブルジョワ男子", + "rich_kid_female": "ブルジョワ女子", + "rich_kids": "ブルジョワ子達", + "roughneck": "スキンヘッズ", + "sailor": "船乗り", + "scientist": "研究員", + "scientist_female": "研究員", + "scientists": "研究チーム", + "smasher": "テニスプレイヤー", + "snow_worker": "冷凍作業員", + "snow_worker_female": "冷凍作業員", + "striker": "サッカー選手", + "school_kid": "塾帰り", + "school_kid_female": "塾帰り", + "school_kids": "塾生たち", + "swimmer": "海パンやろう", + "swimmer_female": "ビキニのおねえさん", + "swimmers": "水着カップル", + "twins": "双子ちゃん", + "veteran": "ベテラントレーナー", + "veteran_female": "ベテラントレーナー", + "veteran_duo": "ベテランコンビ", + "waiter": "ウエーター", + "waitress": "ウエートレス", + "worker": "作業員", + "worker_female": "作業員", + "workers": "作業班", + "youngster": "短パン小僧", + "rocket_grunt": "ロケット団の下っ端", + "rocket_grunts": " ロケット団の下っ端", + "rocket_grunt_female": "ロケット団の下っ端", + "magma_grunt": "マグマ団の下っ端", + "magma_grunt_female": "マグマ団の下っ端", + "magma_grunts": "マグマ団の下っ端", + "aqua_grunt": "アクア団の下っ端", + "aqua_grunt_female": "アクア団の下っ端", + "aqua_grunts": "アクア団の下っ端", + "galactic_grunt": "ギンガ団の下っ端", + "galactic_grunt_female": "ギンガ団の下っ端", + "galactic_grunts": "ギンガ団の下っ端", + "plasma_grunt": "プラスマ団の下っ端", + "plasma_grunt_female": "プラズマ団の下っ端", + "plasma_grunts": "プラズマ団の下っ端", + "flare_grunt": "フレア団の下っ端", + "flare_grunt_female": "フレア団の下っ端", + "flare_grunts": "フレア団の下っ端", + "aether_grunt": "エーテル財団の職員", + "aether_grunt_female": "エーテル財団の職員", + "aether_grunts": "エーテル財団の職員", + "skull_grunt": "スカル団の下っ端", + "skull_grunt_female": "スカル団の下っ端", + "skull_grunts": "スカル団の下っ端", + "macro_grunt": "マクロコスモスのトレーナ", + "macro_grunt_female": "マクロコスモスのトレーナ", + "macro_grunts": "マクロコスモスのトレーナ" +} diff --git a/src/locales/ja/trainer-names.json b/src/locales/ja/trainer-names.json index 9e26dfeeb6e..70841734b5b 100644 --- a/src/locales/ja/trainer-names.json +++ b/src/locales/ja/trainer-names.json @@ -1 +1,164 @@ -{} \ No newline at end of file +{ + "brock": "タケシ", + "misty": "カスミ", + "lt_surge": "マチス", + "erika": "エリカ", + "janine": "アンズ", + "sabrina": "ナツメ", + "blaine": "カツラ", + "giovanni": "サカキ", + "falkner": "ハヤト", + "bugsy": "ツクシ", + "whitney": "アカネ", + "morty": "マツバ", + "chuck": "シジマ", + "jasmine": "ミカン", + "pryce": "ヤナギ", + "clair": "イブキ", + "roxanne": "ツツジ", + "brawly": "トウキ", + "wattson": "テッセン", + "flannery": "アスナ", + "norman": "センリ", + "winona": "ナギ", + "tate": "フウ", + "liza": "ラン", + "juan": "アダン", + "roark": "ヒョウタ", + "gardenia": "ナタネ", + "maylene": "スモモ", + "crasher_wake": "マキシ", + "fantina": "メリッサ", + "byron": "トウガン", + "candice": "スズナ", + "volkner": "デンジ", + "cilan": "デント", + "chili": "ポッド", + "cress": "コーン", + "cheren": "チェレン", + "lenora": "アロエ", + "roxie": "ホミカ", + "burgh": "アーティ", + "elesa": "カミツレ", + "clay": "ヤーコン", + "skyla": "フウロ", + "brycen": "ハチク", + "drayden": "シャガ", + "marlon": "シズイ", + "viola": "ビオラ", + "grant": "ザクロ", + "korrina": "コルニ", + "ramos": "フクジ", + "clemont": "シトロン", + "valerie": "マーシュ", + "olympia": "ゴジカ", + "wulfric": "ウルップ", + "milo": "ヤロー", + "nessa": "ルリナ", + "kabu": "カブ", + "bea": "サイトウ", + "allister": "オニオン", + "opal": "ポプラ", + "bede": "ビート", + "gordie": "マクワ", + "melony": "メロン", + "piers": "ネズ", + "marnie": "マリィ", + "raihan": "キバナ", + "katy": "カエデ", + "brassius": "コルサ", + "iono": " ナンジャモ", + "kofu": "ハイダイ", + "larry": "アオキ", + "ryme": "ライム", + "tulip": "リップ", + "grusha": "グルーシャ", + "lorelei": "カンナ", + "bruno": "シバ", + "agatha": "キクコ", + "lance": "ワタル", + "will": "イツキ", + "koga": "キョウ", + "karen": "カリン", + "sidney": "カゲツ", + "phoebe": "フヨウ", + "glacia": "プリム", + "drake": "ゲンジ", + "aaron": "リョウ", + "bertha": "キクノ", + "flint": "オーバ", + "lucian": "ゴヨウ", + "shauntal": "シキミ", + "marshal": "レンブ", + "grimsley": "ギーマ", + "caitlin": "カトレア", + "malva": "パキラ", + "siebold": "ズミ", + "wikstrom": "ガンピ", + "drasna": "ドラセナ", + "hala": "ハラ", + "molayne": "マーレイン", + "olivia": "ライチ", + "acerola": "アセロラ", + "kahili": "カヒリ", + "rika": "チリ", + "poppy": "ポピー", + "hassel": "ハッサク", + "crispin": "アカマツ", + "amarys": "ネリネ", + "lacey": "タロ", + "drayton": "カキツバタ", + "blue": "グリーン", + "red": "レッド", + "steven": "ダイゴ", + "wallace": "ミクリ", + "cynthia": "シロナ", + "alder": "アデク", + "iris": "アイリス", + "diantha": "カルネ", + "hau": "ハウ", + "geeta": "オモダカ", + "nemona": "ネモ", + "kieran": "スグリ", + "leon": "ダンデ", + "rival": "フィン", + "rival_female": "アイヴィー", + "archer": "アポロ", + "ariana": "アテナ", + "proton": "ランス", + "petrel": "ラムダ", + "tabitha": "ホムラ", + "courtney": "カガリ", + "shelly": "イズミ", + "matt": "ウシオ", + "mars": "マーズ", + "jupiter": "ジュピター", + "saturn": "サターン", + "zinzolin": "ヴィオ", + "rood": "ロット", + "xerosic": "クセロシキ", + "bryony": "バラ", + "faba": "ザオボー", + "plumeria": "プルメリ", + "oleana": "オリーヴ", + + "maxie": "マツブサ", + "archie": "アオギリ", + "cyrus": "アカギ", + "ghetsis": "ゲーチス", + "lysandre": "フラダリ", + "lusamine": "ルザミーネ", + "guzma": "グズマ", + "rose": "ローズ", + + "blue_red_double": "グリーンとレッド", + "red_blue_double": "レッドとグリーン", + "tate_liza_double": "フウとラン", + "liza_tate_double": "ランとフウ", + "steven_wallace_double": "ダイゴとミクリ", + "wallace_steven_double": "ミクリとダイゴ", + "alder_iris_double": "アデクとアイリス", + "iris_alder_double": "アイリスとアデク", + "marnie_piers_double": "マリィとネズ", + "piers_marnie_double": "ネズとマリィ" +} diff --git a/src/locales/ja/trainer-titles.json b/src/locales/ja/trainer-titles.json index 9e26dfeeb6e..b3829c701e5 100644 --- a/src/locales/ja/trainer-titles.json +++ b/src/locales/ja/trainer-titles.json @@ -1 +1,38 @@ -{} \ No newline at end of file +{ + "elite_four": "四天王", + "elite_four_female": "四天王", + "gym_leader": "ジムリーダー", + "gym_leader_female": "ジムリーダー", + "gym_leader_double": "ジムリーダーコンビ", + "champion": "チャンピオン", + "champion_female": "チャンピオン", + "champion_double": "チャンピオンコンビ", + "rival": "ライバル", + "professor": "ポケモン博士", + "frontier_brain": "フロンティアブレーン", + "rocket_boss": "ロケット団ボス", + "magma_boss": "マグマ団リーダー", + "aqua_boss": "アクア団リーダー", + "galactic_boss": "ギンガ団ボス", + "plasma_boss": "プラズマ団ボス", + "flare_boss": "フレア団ボス", + "aether_boss": "エーテル代表", + "skull_boss": "スカル団ボス", + "macro_boss": "マクロコスモス社長", + + "rocket_admin": "ロケット団幹部", + "rocket_admin_female": "ロケット団幹部", + "magma_admin": "マグマ団幹部", + "magma_admin_female": "マグマロケット団幹部", + "aqua_admin": "アクア団幹部", + "aqua_admin_female": "アクア団幹部", + "galactic_commander": "ギンガ団幹部", + "galactic_commander_female": "ギンガ団幹部", + "plasma_sage": "プラズマ団賢人", + "plasma_admin": "プラズマ団賢人", + "flare_admin": "フレア団幹部", + "flare_admin_female": "フレア団幹部", + "aether_admin": "エーテル支部長", + "skull_admin": "スカル団幹部", + "macro_admin": "マクロコスモス" +} From 03567ed56cb3e1923b40802cdaf52aeec713f13d Mon Sep 17 00:00:00 2001 From: njahja Date: Mon, 2 Sep 2024 14:59:26 -0700 Subject: [PATCH 09/11] [Bugfix #3930] Moves That a Pokemon Knows and are not in their List of Learnable TMs Display as "Not Able" Rather than Learned (#3935) * fix for [Bug] Moves That a Pokemon Knows and are not in their List of Learnable TMs Display as "Not Able" Rather than Learned #3930 * convert switch case block to if/elif/else --- src/ui/party-ui-handler.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index a61037548e6..176a7098347 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -1321,16 +1321,13 @@ class PartySlot extends Phaser.GameObjects.Container { this.slotHpOverlay.setVisible(false); this.slotHpText.setVisible(false); let slotTmText: string; - switch (true) { - case (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1): - slotTmText = i18next.t("partyUiHandler:notAble"); - break; - case (this.pokemon.getMoveset().filter(m => m?.moveId === tmMoveId).length > 0): + + if (this.pokemon.getMoveset().filter(m => m?.moveId === tmMoveId).length > 0) { slotTmText = i18next.t("partyUiHandler:learned"); - break; - default: + } else if (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1) { + slotTmText = i18next.t("partyUiHandler:notAble"); + } else { slotTmText = i18next.t("partyUiHandler:able"); - break; } this.slotDescriptionLabel.setText(slotTmText); From 9c30e5b21332e445d05096acc1dcbff050142da5 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Tue, 3 Sep 2024 00:03:21 +0200 Subject: [PATCH 10/11] [Localization] [FR] [Fix] Dialogue fixs batch + ignored entries form previous PR (#3985) * Update dialogue-misc.json * Update dialogue.json * Update dialogue.json * Update dialogue-misc.json * Update dialogue.json * Update dialogue.json * Update dialogue.json * Update dialogue.json * Update dialogue.json * Update dialogue.json --- src/locales/en/dialogue.json | 12 ++- src/locales/fr/dialogue-misc.json | 4 +- src/locales/fr/dialogue.json | 118 ++++++++++++++++++++++++++---- 3 files changed, 117 insertions(+), 17 deletions(-) diff --git a/src/locales/en/dialogue.json b/src/locales/en/dialogue.json index 90b03a176d1..cd544395a27 100644 --- a/src/locales/en/dialogue.json +++ b/src/locales/en/dialogue.json @@ -699,6 +699,7 @@ "encounter": { "1": "I'll fight you with all I have to wipe you out!", "2": "I don't care if you're a kid or what. I'll send you flying if you threaten us!", + "2_female": "I don't care if you're a kid or what. I'll send you flying if you threaten us!", "3": "I was told to turn away Trainers, whomever they might be!", "4": "I'll show you the power of Aether Paradise!", "5": "Now that you've learned of the darkness at the heart of Aether Paradise, we'll need you to conveniently disappear!" @@ -715,11 +716,13 @@ "encounter": { "1": "I, Branch Chief Faba, shall show you the harshness of the real world!", "2": "The man who is called Aether Paradise's last line of defense is to battle a mere child?", + "2_female": "The man who is called Aether Paradise's last line of defense is to battle a mere child?", "3": "I, Faba, am the Aether Branch Chief. The only one in the world, I'm irreplaceable." }, "victory": { "1": "Aiyee!", "2": "H-h-how can this be?! How could this child...", + "2_female": "H-h-how can this be?! How could this child...", "3": "This is why... This is why I can't bring myself to like children." } }, @@ -727,9 +730,12 @@ "encounter": { "1": "We're not bad-we're just hard!", "2": "You want some? That's how we say hello! Nice knowing you, punks!", + "2_female": "You want some? That's how we say hello! Nice knowing you, punks!", "3": "We're just a bunch of guys and gals with a great interest in other people's Pokémon!", "4": "Why you trying to act hard when we're already hard as bones out here, homie?", - "5": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!" + "4_female": "Why you trying to act hard when we're already hard as bones out here, homie?", + "5": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!", + "5_female": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!" }, "victory": { "1": "Huh? Is it over already?", @@ -742,11 +748,13 @@ "plumeria": { "encounter": { "1": " ...Hmph. You don't look like anything special to me.", + "1_female": " ...Hmph. You don't look like anything special to me.", "2": "It takes these dumb Grunts way too long to deal with you kids...", "3": "Mess with anyone in Team Skull, and I'll show you how serious I can get." }, "victory": { "1": "Hmmph! You're pretty strong. I'll give you that.", + "1_female": "Hmmph! You're pretty strong. I'll give you that.", "2": "Hmmph. Guess you are pretty tough. Now I understand why my Grunts waste so much time battling kids.", "3": "Hmmph! I guess I just have to hold that loss." } @@ -755,6 +763,7 @@ "encounter": { "1": "It looks like this is the end of the line for you!", "2": "You are a trainer aren't you? I'm afraid that doesn't give you the right to interfere in our work.", + "2_female": "You are a trainer aren't you? I'm afraid that doesn't give you the right to interfere in our work.", "3": "I'm from Macro Cosmos Insurance! Do you have a life insurance policy?" }, "victory": { @@ -772,6 +781,7 @@ "victory": { "1": "*sigh* I wasn't able to win... Oleana...you really are a hopeless woman.", "2": "Arghhh! This is inexcusable... What was I thinking... Any trainer who's made it this far would be no pushover..", + "2_female": "Arghhh! This is inexcusable... What was I thinking... Any trainer who's made it this far would be no pushover..", "3": "*sigh* I am one tired Oleana..." } }, diff --git a/src/locales/fr/dialogue-misc.json b/src/locales/fr/dialogue-misc.json index 359c2dfb46b..306714dee4e 100644 --- a/src/locales/fr/dialogue-misc.json +++ b/src/locales/fr/dialogue-misc.json @@ -1,6 +1,6 @@ { - "ending": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû le savoir.\nMais de voilà de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.", - "ending_female": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû le savoir.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maitenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un p’tit combat, comme au bon vieux temps ?", + "ending": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû m’en douter.\nMais te voilà enfin de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.", + "ending_female": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû m’en douter.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maintenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un p’tit combat, comme au bon vieux temps ?", "ending_endless": "Félicitations ! Vous avez atteint la fin actuelle.\nPlus de contenu à venir bientôt !", "ending_name": "Les devs" } diff --git a/src/locales/fr/dialogue.json b/src/locales/fr/dialogue.json index c9bb3c417c7..d9d13a8f1e8 100644 --- a/src/locales/fr/dialogue.json +++ b/src/locales/fr/dialogue.json @@ -9,7 +9,7 @@ "6": "Allez, c’est parti !", "7": "Attention, me voilà !\nTu vas voir comment j’suis fort !", "8": "Coucou… Tu veux voir mes bô Pokémon ?", - "9": "Trève de mondanités. Ramène-toi quand tu le sens !", + "9": "Trêve de mondanités. Ramène-toi quand tu le sens !", "10": "Baisse pas ta garde si tu veux pas pleurer d’avoir perdu face à un gamin.", "11": "J’ai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !", "12": "Incroyable que t’y sois parvenu ! Mais la suite va pas être une partie de plaisir.", @@ -68,7 +68,7 @@ "3": "Hum, t’es pas trop laxiste avec tes Pokémon ?\nTrop les chouchouter n’est pas bon." }, "victory": { - "1": "Il est primordial de nourir et développer toutes les caractéristiques de chaque Pokémon.", + "1": "Il est primordial de nourrir et développer toutes les caractéristiques de chaque Pokémon.", "2": "Contrairement à moi, ces Pokémon ont un bon fond.", "3": "Trop d’éloges peut ruiner les Pokémon et les gens." }, @@ -229,7 +229,7 @@ "encounter": { "1": "Ne te mets pas en travers de la Team Galaxie !", "2": "Sois témoin de la puissance de notre technologie et du futur qui se profile !", - "3": "Au nom de la Team Galaxie, j’éliminerai quiconque se mettera sur notre route !", + "3": "Au nom de la Team Galaxie, j’éliminerai quiconque se mettra sur notre route !", "4": "Prépare ta défaite !", "5": "J’espère que t’es prêt à te prendre une raclée de l’espace !", "5_female": "J’espère que t’es prête à te prendre une raclée de l’espace !" @@ -244,7 +244,7 @@ }, "plasma_grunt": { "encounter": { - "1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !", + "1": "Pas de quartiers à quiconque ne suit pas notre idéal !", "2": "Si je gagne, tu relâches tous tes Pokémon !", "3": "Si tu te mets en travers de la Team Plasma, je m’occuperai de toi personnellement !", "4": "La Team Plasma va libérer les Pokémon de tous les humains égoïstes dans ton genre !", @@ -275,6 +275,96 @@ "5": "J’appelle pas ça perdre, j’appelle ça échouer avec panache !" } }, + "aether_grunt": { + "encounter": { + "1": "Je vais te mettre ta raclée !", + "2": "J’en ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !", + "2_female": "J’en ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !", + "3": "J’ai pour ordre de ne laisser passer aucun Dresseur, peu importe qui c’est !", + "4": "Je vais te montrer le pouvoir du Paradis Æther !", + "5": "Maintenant que t’es au courant de ce qu’il se passe au cœur du Paradis Æther, fais-moi une faveur et disparait !" + }, + "victory": { + "1": "C’est plutôt toi qui devrait m’apprendre à en mettre…", + "2": "Pardon ? J’ai pas compris…", + "3": "Peu importe les ordres, jamais j’aurais pu te retenir en fait…", + "4": "Mhh… Il semblerait que j’ai perdu.", + "5": "C’est plutôt moi qui va disparaitre je crois." + } + }, + "faba": { + "encounter": { + "1": "Moi, Directeur Saubohne, je vais te montrer de quel bois je me chauffe !", + "2": "Donc là, l’homme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?", + "2_female": "Donc là, l’homme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?", + "3": "S’il n’y a qu’un seul nom à retenir au sein de la Fondation Æther, c’est le mien : Saubohne !" + }, + "victory": { + "1": "Gloups !", + "2": "Malheur ! J’ai perdu face à un simple enfant ?!", + "2_female": "Malheur ! J’ai perdu face à une simple enfant ?!", + "3": "J’ai HORREUR des enfants !" + } + }, + "skull_grunt": { + "encounter": { + "1": "Oush oush ! On est pas méchants, sauf si tu viens nous allumer la mèche-han !", + "2": "Ce manque de respect, j’hallucine ! T’es allé trop loin, le mioche !", + "2_female": "Ce manque de respect, j’hallucine ! T’es allée trop loin, la mioche !", + "3": "On est juste des gars et des meufs normaux, on voit un Pokémon on le prend !", + "4": "Pourquoi tu te la joue comme ça ? C'est avec tes dents que t’vas jouer frérot.", + "4_female": "Pourquoi tu te la joue comme ça ? C'est avec tes dents que t’vas jouer ma reus.", + "5": "Cousin, écoute-nous bien ! ♪\nSe taper dessus, ça sert à rien ! ♪\n$Tu t’incrustes chez nous, ça s’fait pas ! ♪\n$Mais on est sympa, on a un plan pour toi ! ♪", + "5_female": "Cousine, écoute-nous bien ! ♪\nSe taper dessus, ça sert à rien ! ♪\n$Tu t’incrustes chez nous, ça s’fait pas ! ♪\n$Mais on est sympa, on a un plan pour toi ! ♪" + }, + "victory": { + "1": "Hein ? C’est déjà terminé ?", + "2": "… Ça craint grave ! On s’tire !", + "3": "Ouais de toute on en avait pas b’soin de ton Pokémon… Ah ah…", + "4": "Ouh là, c’est bon, j’en demandais pas tant…", + "5": "On pèse plus que des Pokémon, t’entends ?\nAlors tu vas nous respecter, oush !" + } + }, + "plumeria": { + "encounter": { + "1": "Tsk. T’es un gamin tout ce qu’il y a de plus banal, en fait.", + "1_female": "Tsk. T’es une gamine tout ce qu’il y a de plus banal, en fait.", + "2": "Abrutis de sbires. Trop incompétents pour arriver à se débarasser de gamins…", + "3": "Si tu touches encore à un cheveu de mes lascars, tu vas pas comprendre c’qui t’arrive !" + }, + "victory": { + "1": "Tsk. T’es pas mauvais. J’te l’accorde.", + "1_female": "Tsk. T’es pas mauvaise. J’te l’accorde.", + "2": "Tsk. J’dois reconnaitre que t’en as dans le ventre.\n$Maintenant, j’comprends pourquoi mes gars n’arrêtent pas de se faire battre par toi.", + "3": "Tsk. J’crois que j'ai plus qu’à assumer ma défaite." + } + }, + "macro_grunt": { + "encounter": { + "1": "Hop hop hop ! Terminus !", + "2": "T’es un Dresseur n’est-ce pas ?\n$J’ai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.", + "2_female": "T’es une Dresseuse n’est-ce pas ?\n$J’ai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.", + "3": "Je travaille à Macro Cosmos Assurances !\nBesoin d’une assurance-vie ?" + }, + "victory": { + "1": "Je n’ai d’autre choix que respectueusement me retirer.", + "2": "Mon argent de poche…\nPlus qu’à manger des pâtes pour la fin du mois…", + "3": "Chez Macro Cosmos, rien n’est comparable à notre dévotion au travail !" + } + }, + "oleana": { + "encounter": { + "1": "Je ne laisserai personne interférer avec les projets du président Shehroz.", + "2": "Je vois que vous avez su vous défaire de mes subalternes.\n$Mais assez joué. Il est temps de rentrer chez vous, maintenant.", + "3": "Je gagnerai en votre nom, monsieur le président." + }, + "victory": { + "1": "*soupir* Comment ai-je fait pour perdre ainsi… ?\nJe ne suis vraiment pas à la hauteur…", + "2": "Ah ! Quelle erreur… Je n’aurais pas dû sous-estimer un Dresseur de ton calibre…", + "2_female": "Ah ! Quelle erreur… Je n’aurais pas dû sous-estimer une Dresseuse de ton calibre…", + "3": "*soupir* Je suis fatiguée parton…" + } + }, "rocket_boss_giovanni_1": { "encounter": { "1": "Bien. Je dois admettre que je suis impressionné de te voir ici !" @@ -468,7 +558,7 @@ "4": "Voir un tel jardin rempli de fleurs est si apaisant…" }, "victory": { - "1": "Bien joué, c’est mértié.", + "1": "Bien joué, c’est mérité.", "2": "Dommage, on s’amusait si bien…", "3": "Oh non, le combat est terminé…", "4": "Aaah, ça fait du bien !\nMerci, j’en avais besoin." @@ -505,15 +595,15 @@ }, "rival": { "encounter": { - "1": "@c{smile}Ah, je te cherchais ! Je savais que t’étais pressé de partir, mais je m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prêt.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !" + "1": "@c{smile}Ah, je te cherchais ! Je savais que t’étais pressée de partir, mais je m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !" }, "victory": { - "1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment un débutant ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" + "1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment une débutante ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" } }, "rival_female": { "encounter": { - "1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une conditon. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?" + "1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?" }, "victory": { "1": "@c{shock}Tu viens de commencer et t’es déjà si fort ?!@d{96}\n@c{angry}T’as triché non ? Avoue !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile_eclosed}J’ai perdu dans les règles…\nJ’ai le sentiment que tu vas très bien t’en sortir.\n$@c{smile}D’ailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" @@ -521,10 +611,10 @@ }, "rival_2": { "encounter": { - "1": "@c{smile}Hé, toi aussi t’es là ?\n@c{smile_eclosed}Toujours invaincu, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivi ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nC’est parti !" + "1": "@c{smile}Hé, toi aussi t’es là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivie ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nC’est parti !" }, "victory": { - "1": "@c{neutral_eclosed}Oh. Je crois que j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi et profite bien de l’évènement !" + "1": "@c{neutral_eclosed}Oh. Je crois que j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !" } }, "rival_2_female": { @@ -532,7 +622,7 @@ "1": "@c{smile_wave}Hé, sympa de te croiser ici. T’as toujours l’air invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je t’espionne pas.\n@c{smile_eclosed}C’est juste que j’étais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que c’est pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, t’as intérêt à tout donner !" }, "victory": { - "1": "@c{neutral}Je… J’étais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus m’entrainer !\n$@c{smile_wave}J’ai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}C’étaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup et profite bien de l’évènement !" + "1": "@c{neutral}Je… J’étais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus m’entrainer !\n$@c{smile_wave}J’ai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}C’étaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !" }, "defeat": { "1": "Je suppose que c’est parfois normal de perdre…" @@ -540,7 +630,7 @@ }, "rival_3": { "encounter": { - "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}T’es… toujours invaincu ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prêt pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le." + "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}T’es… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prête pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le." }, "victory": { "1": "@c{angry_mhalf}C’est lunaire… J’ai presque fait que m’entrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?" @@ -559,7 +649,7 @@ }, "rival_4": { "encounter": { - "1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}J’ai appris à maximiser tout mon potentiel en m’entrainant d’arrachepied.\n$@c{smile}C’est fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien n’a d’importance désormais, pas tant que j’aurai pas gagné.\n$@c{neutral_eclosed}J’ai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, c’est pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prêt." + "1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}J’ai appris à maximiser tout mon potentiel en m’entrainant d’arrachepied.\n$@c{smile}C’est fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien n’a d’importance désormais, pas tant que j’aurai pas gagné.\n$@c{neutral_eclosed}J’ai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, c’est pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prête." }, "victory": { "1": "@c{neutral}Que…@d{64} Qui es-tu ?" @@ -597,7 +687,7 @@ }, "rival_6": { "encounter": { - "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}J’ai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}C’est même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est comme si quelque chose ici me parlait.\n$Comme si c’était tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es le seul à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." + "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}J’ai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}C’est même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est comme si quelque chose ici me parlait.\n$Comme si c’était tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." }, "victory": { "1": "@c{smile_eclosed}J’ai fait ce que j’avais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison." From 89a1ff7b5b73202ab9e75d23b7bfb7c154af2315 Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Tue, 3 Sep 2024 00:29:15 +0200 Subject: [PATCH 11/11] [Bug] Fix Inconsistency with stat boost when breaking through boss shields + tests (#3785) * fix boss shield stats up calculation and add tests * update test to remove usage of deprecated startBattle --- src/battle-scene.ts | 16 +- src/field/pokemon.ts | 20 +- src/overrides.ts | 8 + src/phases/encounter-phase.ts | 8 +- src/test/boss-pokemon.test.ts | 220 ++++++++++++++++++++++ src/test/moves/fusion_flare.test.ts | 2 +- src/test/utils/helpers/overridesHelper.ts | 14 ++ 7 files changed, 268 insertions(+), 20 deletions(-) create mode 100644 src/test/boss-pokemon.test.ts diff --git a/src/battle-scene.ts b/src/battle-scene.ts index e761d8fca39..70f214f57c6 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -841,12 +841,13 @@ export default class BattleScene extends SceneBase { } addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon { + if (Overrides.OPP_LEVEL_OVERRIDE > 0) { + level = Overrides.OPP_LEVEL_OVERRIDE; + } if (Overrides.OPP_SPECIES_OVERRIDE) { species = getPokemonSpecies(Overrides.OPP_SPECIES_OVERRIDE); - } - - if (Overrides.OPP_LEVEL_OVERRIDE !== 0) { - level = Overrides.OPP_LEVEL_OVERRIDE; + // The fact that a Pokemon is a boss or not can change based on its Species and level + boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1; } const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource); @@ -1327,6 +1328,13 @@ export default class BattleScene extends SceneBase { } getEncounterBossSegments(waveIndex: integer, level: integer, species?: PokemonSpecies, forceBoss: boolean = false): integer { + if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE > 1) { + return Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE; + } else if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE === 1) { + // The rest of the code expects to be returned 0 and not 1 if the enemy is not a boss + return 0; + } + if (this.gameMode.isDaily && this.gameMode.isWaveFinal(waveIndex)) { return 5; } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8594d5b769b..cce613f1ec4 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4176,7 +4176,7 @@ export class EnemyPokemon extends Pokemon { //console.log('damage', damage, 'segment', segmentsBypassed + 1, 'segment size', segmentSize, 'damage needed', Math.round(segmentSize * Math.pow(2, segmentsBypassed + 1))); } - damage = hpRemainder + Math.round(segmentSize * segmentsBypassed); + damage = Utils.toDmgValue(this.hp - hpThreshold + segmentSize * segmentsBypassed); clearedBossSegmentIndex = s - segmentsBypassed; } break; @@ -4241,17 +4241,13 @@ export class EnemyPokemon extends Pokemon { let statLevels = 1; - switch (segmentIndex) { - case 1: - if (this.bossSegments >= 3) { - statLevels++; - } - break; - case 2: - if (this.bossSegments >= 5) { - statLevels++; - } - break; + // increase the boost if the boss has at least 3 segments and we passed last shield + if (this.bossSegments >= 3 && this.bossSegmentIndex === 1) { + statLevels++; + } + // increase the boost if the boss has at least 5 segments and we passed the second to last shield + if (this.bossSegments >= 5 && this.bossSegmentIndex === 2) { + statLevels++; } this.scene.unshiftPhase(new StatChangePhase(this.scene, this.getBattlerIndex(), true, [ boostedStat ], statLevels, true, true)); diff --git a/src/overrides.ts b/src/overrides.ts index 32ff116f41d..48c118b55bc 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -116,6 +116,14 @@ class DefaultOverrides { readonly OPP_VARIANT_OVERRIDE: Variant = 0; readonly OPP_IVS_OVERRIDE: number | number[] = []; readonly OPP_FORM_OVERRIDES: Partial> = {}; + /** + * Override to give the enemy Pokemon a given amount of health segments + * + * 0 (default): the health segments will be handled normally based on wave, level and species + * 1: the Pokemon will have a single health segment and therefore will not be a boss + * 2+: the Pokemon will be a boss with the given number of health segments + */ + readonly OPP_HEALTH_SEGMENTS_OVERRIDE: number = 0; // ------------- // EGG OVERRIDES diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 07bfd72a8bf..6e0658d4ccb 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -26,6 +26,7 @@ import { ScanIvsPhase } from "./scan-ivs-phase"; import { ShinySparklePhase } from "./shiny-sparkle-phase"; import { SummonPhase } from "./summon-phase"; import { ToggleDoublePositionPhase } from "./toggle-double-position-phase"; +import Overrides from "#app/overrides"; export class EncounterPhase extends BattlePhase { private loaded: boolean; @@ -112,10 +113,11 @@ export class EncounterPhase extends BattlePhase { if (battle.battleType === BattleType.TRAINER) { loadEnemyAssets.push(battle.trainer?.loadAssets().then(() => battle.trainer?.initSprite())!); // TODO: is this bang correct? } else { - // This block only applies for double battles to init the boss segments (idk why it's split up like this) - if (battle.enemyParty.filter(p => p.isBoss()).length > 1) { + const overridedBossSegments = Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE > 1; + // for double battles, reduce the health segments for boss Pokemon unless there is an override + if (!overridedBossSegments && battle.enemyParty.filter(p => p.isBoss()).length > 1) { for (const enemyPokemon of battle.enemyParty) { - // If the enemy pokemon is a boss and wasn't populated from data source, then set it up + // If the enemy pokemon is a boss and wasn't populated from data source, then update the number of segments if (enemyPokemon.isBoss() && !enemyPokemon.isPopulatedFromDataSource) { enemyPokemon.setBoss(true, Math.ceil(enemyPokemon.bossSegments * (enemyPokemon.getSpeciesForm().baseTotal / totalBst))); enemyPokemon.initBattleInfo(); diff --git a/src/test/boss-pokemon.test.ts b/src/test/boss-pokemon.test.ts new file mode 100644 index 00000000000..3e6701c7e4f --- /dev/null +++ b/src/test/boss-pokemon.test.ts @@ -0,0 +1,220 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import GameManager from "./utils/gameManager"; +import { Species } from "#app/enums/species"; +import { getPokemonSpecies } from "#app/data/pokemon-species"; +import { SPLASH_ONLY } from "./utils/testUtils"; +import { Abilities } from "#app/enums/abilities"; +import { Moves } from "#app/enums/moves"; +import { BattleStat } from "#app/data/battle-stat"; +import { EnemyPokemon } from "#app/field/pokemon"; +import { toDmgValue } from "#app/utils"; + +describe("Boss Pokemon / Shields", () => { + const TIMEOUT = 2500; + + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .battleType("single") + .disableTrainerWaves() + .disableCrits() + .enemySpecies(Species.RATTATA) + .enemyMoveset(SPLASH_ONLY) + .enemyHeldItems([]) + .startingLevel(1000) + .moveset([Moves.FALSE_SWIPE, Moves.SUPER_FANG, Moves.SPLASH]) + .ability(Abilities.NO_GUARD); + }); + + it("Pokemon should get shields based on their Species and level and the current wave", async () => { + let level = 50; + let wave = 5; + + // On normal waves, no shields... + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(0); + // ... expect (sub)-legendary and mythical Pokemon who always get shields + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.MEW))).toBe(2); + // Pokemon with 670+ BST get an extra shield + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.MEWTWO))).toBe(3); + + // Every 10 waves will always be a boss Pokemon with shield(s) + wave = 50; + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(2); + // Every extra 250 waves adds a shield + wave += 250; + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(3); + wave += 750; + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(6); + + // Pokemon above level 100 get an extra shield + level = 100; + expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(7); + }, TIMEOUT); + + it("should reduce the number of shields if we are in a double battle", async () => { + game.override + .battleType("double") + .startingWave(150); // Floor 150 > 2 shields / 3 health segments + + await game.classicMode.startBattle([ Species.MEWTWO ]); + + const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; + const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + expect(boss1.isBoss()).toBe(true); + expect(boss1.bossSegments).toBe(2); + expect(boss2.isBoss()).toBe(true); + expect(boss2.bossSegments).toBe(2); + }, TIMEOUT); + + it("shields should stop overflow damage and give stat boosts when broken", async () => { + game.override.startingWave(150); // Floor 150 > 2 shields / 3 health segments + + await game.classicMode.startBattle([ Species.MEWTWO ]); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + const segmentHp = enemyPokemon.getMaxHp() / enemyPokemon.bossSegments; + expect(enemyPokemon.isBoss()).toBe(true); + expect(enemyPokemon.bossSegments).toBe(3); + expect(getTotalStatBoosts(enemyPokemon)).toBe(0); + + game.move.select(Moves.SUPER_FANG); // Enough to break the first shield + await game.toNextTurn(); + + // Broke 1st of 2 shields, health at 2/3rd + expect(enemyPokemon.bossSegmentIndex).toBe(1); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - toDmgValue(segmentHp)); + // Breaking the shield gives a +1 boost to ATK, DEF, SP ATK, SP DEF or SPD + expect(getTotalStatBoosts(enemyPokemon)).toBe(1); + + game.move.select(Moves.FALSE_SWIPE); // Enough to break last shield but not kill + await game.toNextTurn(); + + expect(enemyPokemon.bossSegmentIndex).toBe(0); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - toDmgValue(2 * segmentHp)); + // Breaking the last shield gives a +2 boost to ATK, DEF, SP ATK, SP DEF or SPD + expect(getTotalStatBoosts(enemyPokemon)).toBe(3); + + }, TIMEOUT); + + it("breaking multiple shields at once requires extra damage", async () => { + game.override + .battleType("double") + .enemyHealthSegments(5); + + await game.classicMode.startBattle([ Species.MEWTWO ]); + + // In this test we want to break through 3 shields at once + const brokenShields = 3; + + const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; + const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments; + const requiredDamageBoss1 = boss1SegmentHp * (1 + Math.pow(2, brokenShields)); + expect(boss1.isBoss()).toBe(true); + expect(boss1.bossSegments).toBe(5); + expect(boss1.bossSegmentIndex).toBe(4); + + // Not enough damage to break through all shields + boss1.damageAndUpdate(Math.floor(requiredDamageBoss1 - 5)); + expect(boss1.bossSegmentIndex).toBe(1); + expect(boss1.hp).toBe(boss1.getMaxHp() - toDmgValue(boss1SegmentHp * 3)); + + const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments; + const requiredDamageBoss2 = boss2SegmentHp * (1 + Math.pow(2, brokenShields)); + + expect(boss2.isBoss()).toBe(true); + expect(boss2.bossSegments).toBe(5); + + // Enough damage to break through all shields + boss2.damageAndUpdate(Math.ceil(requiredDamageBoss2)); + expect(boss2.bossSegmentIndex).toBe(0); + expect(boss2.hp).toBe(boss2.getMaxHp() - toDmgValue(boss2SegmentHp * 4)); + + }, TIMEOUT); + + it("the number of stats boosts is consistent when several shields are broken at once", async () => { + const shieldsToBreak = 4; + + game.override + .battleType("double") + .enemyHealthSegments(shieldsToBreak + 1); + + await game.classicMode.startBattle([ Species.MEWTWO ]); + + const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; + const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments; + const singleShieldDamage = Math.ceil(boss1SegmentHp); + expect(boss1.isBoss()).toBe(true); + expect(boss1.bossSegments).toBe(shieldsToBreak + 1); + expect(boss1.bossSegmentIndex).toBe(shieldsToBreak); + expect(getTotalStatBoosts(boss1)).toBe(0); + + + let totalStats = 0; + + // Break the shields one by one + for (let i = 1; i <= shieldsToBreak; i++) { + boss1.damageAndUpdate(singleShieldDamage); + expect(boss1.bossSegmentIndex).toBe(shieldsToBreak - i); + expect(boss1.hp).toBe(boss1.getMaxHp() - toDmgValue(boss1SegmentHp * i)); + // Do nothing and go to next turn so that the StatChangePhase gets applied + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + // All broken shields give +1 stat boost, except the last two that gives +2 + totalStats += i >= shieldsToBreak -1? 2 : 1; + expect(getTotalStatBoosts(boss1)).toBe(totalStats); + } + + const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments; + const requiredDamage = boss2SegmentHp * (1 + Math.pow(2, shieldsToBreak - 1)); + + expect(boss2.isBoss()).toBe(true); + expect(boss2.bossSegments).toBe(shieldsToBreak + 1); + expect(boss2.bossSegmentIndex).toBe(shieldsToBreak); + expect(getTotalStatBoosts(boss2)).toBe(0); + + // Enough damage to break all shields at once + boss2.damageAndUpdate(Math.ceil(requiredDamage)); + expect(boss2.bossSegmentIndex).toBe(0); + expect(boss2.hp).toBe(boss2.getMaxHp() - toDmgValue(boss2SegmentHp * shieldsToBreak)); + // Do nothing and go to next turn so that the StatChangePhase gets applied + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(getTotalStatBoosts(boss2)).toBe(totalStats); + + }, TIMEOUT); + + /** + * Gets the sum of the ATK, DEF, SP ATK, SP DEF and SPD boosts for the given Pokemon + * @param enemyPokemon the pokemon to get stats from + * @returns the total stats boosts + */ + function getTotalStatBoosts(enemyPokemon: EnemyPokemon): number { + const enemyBattleStats = enemyPokemon.summonData.battleStats; + return enemyBattleStats?.reduce(statsSum, 0); + } + + function statsSum(total: number, value: number, index: number) { + if (index <= BattleStat.SPD) { + return total + value; + } + return total; + } + +}); + diff --git a/src/test/moves/fusion_flare.test.ts b/src/test/moves/fusion_flare.test.ts index 471f6a2ac7b..0a8f6f9115d 100644 --- a/src/test/moves/fusion_flare.test.ts +++ b/src/test/moves/fusion_flare.test.ts @@ -27,7 +27,7 @@ describe("Moves - Fusion Flare", () => { game.override.moveset([fusionFlare]); game.override.startingLevel(1); - game.override.enemySpecies(Species.RESHIRAM); + game.override.enemySpecies(Species.RATTATA); game.override.enemyMoveset([Moves.REST, Moves.REST, Moves.REST, Moves.REST]); game.override.battleType("single"); diff --git a/src/test/utils/helpers/overridesHelper.ts b/src/test/utils/helpers/overridesHelper.ts index d5eaee003db..6451155cf17 100644 --- a/src/test/utils/helpers/overridesHelper.ts +++ b/src/test/utils/helpers/overridesHelper.ts @@ -281,6 +281,20 @@ export class OverridesHelper extends GameManagerHelper { return this; } + /** + * Override the enemy (Pokemon) to have the given amount of health segments + * @param healthSegments the number of segments to give + * default: 0, the health segments will be handled like in the game based on wave, level and species + * 1: the Pokemon will not be a boss + * 2+: the Pokemon will be a boss with the given number of health segments + * @returns this + */ + enemyHealthSegments(healthSegments: number) { + vi.spyOn(Overrides, "OPP_HEALTH_SEGMENTS_OVERRIDE", "get").mockReturnValue(healthSegments); + this.log("Enemy Pokemon health segments set to:", healthSegments); + return this; + } + private log(...params: any[]) { console.log("Overrides:", ...params); }