From 13f2cafe5ee9924e9e886cd60c448599124c47fb Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Sun, 19 May 2024 21:52:48 +0200 Subject: [PATCH 01/12] Female Variant Trainer Class Names set explicitly in definition of trainer classes (#1126) * Set the name for the ace trainer female class * Wrote out the name for all females trainer classes explicitly so they are always used. Also made some changes (added missing classes) to languages --- src/data/trainer-config.ts | 32 ++++++++++++++++---------------- src/locales/de/trainers.ts | 6 ++++-- src/locales/en/trainers.ts | 6 ++++-- src/locales/es/trainers.ts | 5 +++-- src/locales/fr/trainers.ts | 6 ++++-- src/locales/it/trainers.ts | 6 ++++-- src/locales/pt_BR/trainers.ts | 6 ++++-- src/locales/zh_CN/trainers.ts | 6 ++++-- 8 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 3d40ceb2ba7..0abd153ff25 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -687,12 +687,12 @@ function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: T export const trainerConfigs: TrainerConfigs = { [TrainerType.UNKNOWN]: new TrainerConfig(0).setHasGenders(), - [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders().setHasDouble('Ace Duo').setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) + [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders('Ace Trainer Female').setHasDouble('Ace Duo').setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)), [TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG) .setSpeciesPools([ Species.SMEARGLE ]), - [TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders().setDoubleOnly().setEncounterBgm(TrainerType.CYCLIST), - [TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders().setHasDouble('Backpackers').setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER) + [TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders("Backers").setDoubleOnly().setEncounterBgm(TrainerType.CYCLIST), + [TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders("Backpacker Female").setHasDouble('Backpackers').setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER) .setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.ONE_WEAK_ONE_STRONG, trainerPartyTemplates.ONE_AVG_ONE_STRONG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.RHYHORN, Species.AIPOM, Species.MAKUHITA, Species.MAWILE, Species.NUMEL, Species.LILLIPUP, Species.SANDILE, Species.WOOLOO ], @@ -712,17 +712,17 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.SUPER_RARE]: [ Species.HITMONTOP, Species.INFERNAPE, Species.GALLADE, Species.HAWLUCHA, Species.HAKAMO_O ], [TrainerPoolTier.ULTRA_RARE]: [ Species.KUBFU ] }), - [TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders().setHasDouble('Breeders') + [TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders("Breeder Female").setHasDouble('Breeders') .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)) .setSpeciesFilter(s => s.baseTotal < 450), - [TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders().setHasDouble('Colleagues').setEncounterBgm(TrainerType.CLERK) + [TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders("Clerk Female").setHasDouble('Colleagues').setEncounterBgm(TrainerType.CLERK) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.MEOWTH, Species.PSYDUCK, Species.BUDEW, Species.PIDOVE, Species.CINCCINO, Species.LITLEO ], [TrainerPoolTier.UNCOMMON]: [ Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO ], [TrainerPoolTier.RARE]: [ Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE ] }), - [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders().setHasDouble('Cyclists').setEncounterBgm(TrainerType.CYCLIST) + [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders("Cyclist Female").setHasDouble('Cyclists').setEncounterBgm(TrainerType.CYCLIST) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ], @@ -781,9 +781,9 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), - [TrainerType.POKEFAN]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('Poké Fan').setHasGenders().setHasDouble('Poké Fan Family').setEncounterBgm(TrainerType.POKEFAN) + [TrainerType.POKEFAN]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('PokéFan').setHasGenders("PokéFan Female").setHasDouble('PokéFan Family').setEncounterBgm(TrainerType.POKEFAN) .setPartyTemplates(trainerPartyTemplates.SIX_WEAKER, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME), - [TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders(undefined, 'lass').setHasDouble('Preschoolers') + [TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Preschooler Female", 'lass').setHasDouble('Preschoolers') .setPartyTemplates(trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.FIVE_WEAKER) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.CATERPIE, Species.PICHU, Species.SANDSHREW, Species.LEDYBA, Species.BUDEW, Species.BURMY, Species.WOOLOO, Species.PAWMI, Species.SMOLIV ], @@ -791,7 +791,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [ Species.RALTS, Species.RIOLU, Species.JOLTIK, Species.TANDEMAUS ], [TrainerPoolTier.SUPER_RARE]: [ Species.DARUMAKA, Species.TINKATINK ], }), - [TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders().setHasDouble('Psychics').setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC) + [TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders("Psychic Female").setHasDouble('Psychics').setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.TWO_WEAK_SAME_TWO_WEAK_SAME, trainerPartyTemplates.ONE_STRONGER) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.ABRA, Species.DROWZEE, Species.RALTS, Species.SPOINK, Species.GOTHITA, Species.SOLOSIS, Species.BLIPBUG, Species.ESPURR, Species.HATENNA ], @@ -799,7 +799,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [ Species.ELGYEM, Species.SIGILYPH, Species.BALTOY, Species.GIRAFARIG, Species.MEOWSTIC ], [TrainerPoolTier.SUPER_RARE]: [ Species.BELDUM, Species.ESPEON, Species.STANTLER ], }), - [TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('Pokémon Ranger').setEncounterBgm(TrainerType.BACKPACKER).setHasGenders().setHasDouble('Pokémon Rangers') + [TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName('Pokémon Ranger').setEncounterBgm(TrainerType.BACKPACKER).setHasGenders("Pokémon Ranger Female").setHasDouble('Pokémon Rangers') .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.GROWLITHE, Species.PONYTA, Species.ZIGZAGOON, Species.SEEDOT, Species.BIDOOF, Species.RIOLU, Species.SEWADDLE, Species.SKIDDO, Species.SALANDIT, Species.YAMPER ], [TrainerPoolTier.UNCOMMON]: [ Species.AZURILL, Species.TAUROS, Species.MAREEP, Species.FARFETCHD, Species.TEDDIURSA, Species.SHROOMISH, Species.ELECTRIKE, Species.BUDEW, Species.BUIZEL, Species.MUDBRAY, Species.STUFFUL ], @@ -809,7 +809,7 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName('Gentleman').setHasGenders('Madame').setHasDouble('Rich Couple'), [TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName('Rich Boy').setHasGenders('Lady').setHasDouble('Rich Kids').setEncounterBgm(TrainerType.RICH), [TrainerType.ROUGHNECK]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)), - [TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders().setHasDouble('Scientists').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST) + [TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders("Scientist Female").setHasDouble('Scientists').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ], [TrainerPoolTier.UNCOMMON]: [ Species.BALTOY, Species.BRONZOR, Species.FERROSEED, Species.KLINK, Species.CHARJABUG, Species.BLIPBUG, Species.HELIOPTILE ], @@ -818,29 +818,29 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.ULTRA_RARE]: [ Species.ROTOM, Species.MELTAN ] }), [TrainerType.SMASHER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), - [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setHasGenders().setHasDouble('Workers').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), + [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setHasGenders("Worker Female").setHasDouble('Workers').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), [TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), - [TrainerType.SCHOOL_KID]: new TrainerConfig(++t).setMoneyMultiplier(0.75).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders(undefined, 'lass').setHasDouble('School Kids') + [TrainerType.SCHOOL_KID]: new TrainerConfig(++t).setMoneyMultiplier(0.75).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("School Kid Female", 'lass').setHasDouble('School Kids') .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.ODDISH, Species.EXEGGCUTE, Species.TEDDIURSA, Species.WURMPLE, Species.RALTS, Species.SHROOMISH, Species.FLETCHLING ], [TrainerPoolTier.UNCOMMON]: [ Species.VOLTORB, Species.WHISMUR, Species.MEDITITE, Species.MIME_JR, Species.NYMBLE ], [TrainerPoolTier.RARE]: [ Species.TANGELA, Species.EEVEE, Species.YANMA ], [TrainerPoolTier.SUPER_RARE]: [ Species.TADBULB ] }), - [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders().setHasDouble('Swimmers').setSpecialtyTypes(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)), + [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders("Swimmer Female").setHasDouble('Swimmers').setSpecialtyTypes(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.TWINS]: new TrainerConfig(++t).setDoubleOnly().setMoneyMultiplier(0.65).setUseSameSeedForAllMembers() .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_STRONG)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE ], TrainerSlot.TRAINER_PARTNER)) .setEncounterBgm(TrainerType.TWINS), - [TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders().setHasDouble('Veteran Duo').setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.ACE_TRAINER).setSpeciesFilter(s => s.isOfType(Type.DRAGON)), + [TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders("Veteran Female").setHasDouble('Veteran Duo').setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.ACE_TRAINER).setSpeciesFilter(s => s.isOfType(Type.DRAGON)), [TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders('Waitress').setHasDouble('Restaurant Staff').setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.CLERK) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.CHATOT, Species.PANSAGE, Species.PANSEAR, Species.PANPOUR, Species.MINCCINO ], [TrainerPoolTier.UNCOMMON]: [ Species.TROPIUS, Species.PETILIL, Species.BOUNSWEET, Species.INDEEDEE ], [TrainerPoolTier.RARE]: [ Species.APPLIN, Species.SINISTEA, Species.POLTCHAGEIST ] }), - [TrainerType.WORKER]: new TrainerConfig(++t).setHasGenders().setHasDouble('Workers').setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)), + [TrainerType.WORKER]: new TrainerConfig(++t).setHasGenders("Worker Female").setHasDouble('Workers').setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)), [TrainerType.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders('Lass', 'lass').setHasDouble('Beginners').setPartyTemplates(trainerPartyTemplates.TWO_WEAKER) .setSpeciesPools( [ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ] diff --git a/src/locales/de/trainers.ts b/src/locales/de/trainers.ts index 11e8d914842..93eb04cca67 100644 --- a/src/locales/de/trainers.ts +++ b/src/locales/de/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Polizist", "parasol_lady": "Schirmdame", "pilot": "Pilot", - "pokefan": "Pokéfan", - "pokefan_family": "Pokéfan-Pärchen", + "pokéfan": "Pokéfan", + "pokéfan_female": "Pokéfan", + "pokéfan_family": "Pokéfan-Pärchen", "preschooler": "Vorschüler", "preschooler_female": "Vorschülerin", "preschoolers": "Vorschüler", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "Seherin", "psychics": "Seher", "pokémon_ranger": "Pokémon-Ranger", + "pokémon_ranger_female": "Pokémon-Ranger", "pokémon_rangers": "Pokémon-Ranger", "ranger": "Ranger", "restaurant_staff": "Restaurant Angestellte", diff --git a/src/locales/en/trainers.ts b/src/locales/en/trainers.ts index 03c3e22c12c..1eff742e23a 100644 --- a/src/locales/en/trainers.ts +++ b/src/locales/en/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Officer", "parasol_lady": "Parasol Lady", "pilot": "Pilot", - "pokefan": "Poké Fan", - "pokefan_family": "Poké Fan Family", + "pokéfan": "Poké Fan", + "pokéfan_female": "Poké Fan", + "pokéfan_family": "Poké Fan Family", "preschooler": "Preschooler", "preschooler_female": "Preschooler", "preschoolers": "Preschoolers", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "Psychic", "psychics": "Psychics", "pokémon_ranger": "Pokémon Ranger", + "pokémon_ranger_female": "Pokémon Ranger", "pokémon_rangers": "Pokémon Ranger", "ranger": "Ranger", "restaurant_staff": "Restaurant Staff", diff --git a/src/locales/es/trainers.ts b/src/locales/es/trainers.ts index 916ef8fb838..e0af5aac1c4 100644 --- a/src/locales/es/trainers.ts +++ b/src/locales/es/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Officer", "parasol_lady": "Parasol Lady", "pilot": "Pilot", - "pokefan": "Poké Fan", - "pokefan_family": "Poké Fan Family", + "pokéfan": "Poké Fan", + "pokéfan_female": "Poké Fan", + "pokéfan_family": "Poké Fan Family", "preschooler": "Preschooler", "preschooler_female": "Preschooler", "preschoolers": "Preschoolers", diff --git a/src/locales/fr/trainers.ts b/src/locales/fr/trainers.ts index 3d22b00f89e..bfc77b5a8cf 100644 --- a/src/locales/fr/trainers.ts +++ b/src/locales/fr/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Policier", "parasol_lady": "Sœur Parasol", "pilot": "Pilote", - "pokefan": "Poké Fan", - "pokefan_family": "Couple de Pokéfans", + "pokéfan": "Poké Fan", + "pokéfan_female": "Poké Fan", + "pokéfan_family": "Couple de Pokéfans", "preschooler": "Petit", "preschooler_female": "Petite", "preschoolers": "Petits", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "Kinésiste", "psychics": "Kinésistes", "pokémon_ranger": "Pokémon Ranger", + "pokémon_ranger_female": "Pokémon Ranger", "pokémon_rangers": "Pokémon Rangers", "ranger": "Ranger", "restaurant_staff": "Serveurs", diff --git a/src/locales/it/trainers.ts b/src/locales/it/trainers.ts index 24c40acdac4..6fcd157a0f1 100644 --- a/src/locales/it/trainers.ts +++ b/src/locales/it/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Officer", "parasol_lady": "Parasol Lady", "pilot": "Pilot", - "pokefan": "Poké Fan", - "pokefan_family": "Poké Fan Family", + "pokéfan": "Poké Fan", + "pokéfan_female": "Poké Fan", + "pokéfan_family": "Poké Fan Family", "preschooler": "Preschooler", "preschooler_female": "Preschooler", "preschoolers": "Preschoolers", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "Psychic", "psychics": "Psychics", "pokémon_ranger": "Pokémon Ranger", + "pokémon_ranger_female": "Pokémon Ranger", "pokémon_rangers": "Pokémon Ranger", "ranger": "Ranger", "restaurant_staff": "Restaurant Staff", diff --git a/src/locales/pt_BR/trainers.ts b/src/locales/pt_BR/trainers.ts index bc79f98b41b..96dc7d1934e 100644 --- a/src/locales/pt_BR/trainers.ts +++ b/src/locales/pt_BR/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "Policial", "parasol_lady": "Moça de Sombrinha", "pilot": "Piloto", - "poké_fan": "Pokefã", - "poké_fan_family": "Família Pokefã", + "pokéfan": "Pokefã", + "pokéfan_female": "Pokéfã", + "pokéfan_family": "Família Pokefã", "preschooler": "Menino do Prezinho", "preschooler_female": "Menina do Prezinho", "preschoolers": "Alunos do Prezinho", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "Médium", "psychics": "Médiuns", "pokémon_ranger": "Guarda Pokémon", + "pokémon_ranger_female": "Guarda Pokémon", "pokémon_rangers": "Guardas Pokémon", "ranger": "Guarda", "restaurant_staff": "Equipe do Restaurante", diff --git a/src/locales/zh_CN/trainers.ts b/src/locales/zh_CN/trainers.ts index 2dd10d49ef4..7fa16d87fad 100644 --- a/src/locales/zh_CN/trainers.ts +++ b/src/locales/zh_CN/trainers.ts @@ -68,8 +68,9 @@ export const trainerClasses: SimpleTranslationEntries = { "officer": "警察", "parasol_lady": "阳伞姐姐", "pilot": "飞行员", - "poké_fan": "发烧友俱乐部", - "poké_fan_family": "同好夫妇", + "pokéfan": "发烧友俱乐部", + "pokéfan_female": "发烧友俱乐部", + "pokéfan_family": "同好夫妇", "preschooler": "幼儿园小朋友", "preschooler_female": "幼儿园小朋友", "preschoolers": "幼儿园小朋友组合", @@ -77,6 +78,7 @@ export const trainerClasses: SimpleTranslationEntries = { "psychic_female": "超能力者", "psychics": "超能力者组合", "pokémon_ranger": "宝可梦巡护员", + "pokémon_ranger_female": "宝可梦巡护员", "pokémon_rangers": "宝可梦巡护员组合", "ranger": "巡护员", "restaurant_staff": "服务生组合", From 7216990d872c5e203d2db04767c459d9342f2a21 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Mon, 20 May 2024 00:25:52 +0200 Subject: [PATCH 02/12] Locales for Voucher names + Voucher rewards (#1137) * Update voucher.ts * Update vouchers-ui-handler.ts * Update i18n.ts * Update config.ts * Update config.ts * Update config.ts * Update config.ts * Update config.ts * Update config.ts * Update config.ts * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload --- src/locales/de/config.ts | 4 +++- src/locales/de/voucher.ts | 11 +++++++++++ src/locales/en/config.ts | 4 +++- src/locales/en/voucher.ts | 11 +++++++++++ src/locales/es/config.ts | 4 +++- src/locales/es/voucher.ts | 11 +++++++++++ src/locales/fr/config.ts | 4 +++- src/locales/fr/voucher.ts | 11 +++++++++++ src/locales/it/config.ts | 4 +++- src/locales/it/voucher.ts | 11 +++++++++++ src/locales/pt_BR/config.ts | 2 ++ src/locales/pt_BR/voucher.ts | 11 +++++++++++ src/locales/zh_CN/config.ts | 4 +++- src/locales/zh_CN/voucher.ts | 11 +++++++++++ src/plugins/i18n.ts | 1 + src/system/voucher.ts | 26 ++++++++++++++++---------- src/ui/vouchers-ui-handler.ts | 7 ++++--- 17 files changed, 118 insertions(+), 19 deletions(-) create mode 100644 src/locales/de/voucher.ts create mode 100644 src/locales/en/voucher.ts create mode 100644 src/locales/es/voucher.ts create mode 100644 src/locales/fr/voucher.ts create mode 100644 src/locales/it/voucher.ts create mode 100644 src/locales/pt_BR/voucher.ts create mode 100644 src/locales/zh_CN/voucher.ts diff --git a/src/locales/de/config.ts b/src/locales/de/config.ts index af52d8bc51b..3580d74876d 100644 --- a/src/locales/de/config.ts +++ b/src/locales/de/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const deConfig = { ability: ability, @@ -46,4 +47,5 @@ export const deConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/de/voucher.ts b/src/locales/de/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/de/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/en/config.ts b/src/locales/en/config.ts index 984b0fa239f..f25c0b5e278 100644 --- a/src/locales/en/config.ts +++ b/src/locales/en/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const enConfig = { ability: ability, @@ -46,4 +47,5 @@ export const enConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/en/voucher.ts b/src/locales/en/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/en/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/es/config.ts b/src/locales/es/config.ts index 92349028899..2d0a8a536b2 100644 --- a/src/locales/es/config.ts +++ b/src/locales/es/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const esConfig = { ability: ability, @@ -46,4 +47,5 @@ export const esConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/es/voucher.ts b/src/locales/es/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/es/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/fr/config.ts b/src/locales/fr/config.ts index ecec8de6cb0..a6bdfe5cd59 100644 --- a/src/locales/fr/config.ts +++ b/src/locales/fr/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const frConfig = { ability: ability, @@ -46,4 +47,5 @@ export const frConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/fr/voucher.ts b/src/locales/fr/voucher.ts new file mode 100644 index 00000000000..a432cfed53f --- /dev/null +++ b/src/locales/fr/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Coupons", + "eggVoucher": "Coupon Œuf", + "eggVoucherPlus": "Coupon Œuf +", + "eggVoucherPremium": "Coupon Œuf Premium", + "eggVoucherGold": "Coupon Œuf Or", + "locked": "Verrouillé", + "defeatTrainer": "Vaincre {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/it/config.ts b/src/locales/it/config.ts index a9c80dc673d..807d136040c 100644 --- a/src/locales/it/config.ts +++ b/src/locales/it/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const itConfig = { ability: ability, @@ -46,4 +47,5 @@ export const itConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/it/voucher.ts b/src/locales/it/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/it/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/pt_BR/config.ts b/src/locales/pt_BR/config.ts index 457fc4c125a..a9244f5e9db 100644 --- a/src/locales/pt_BR/config.ts +++ b/src/locales/pt_BR/config.ts @@ -19,6 +19,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers"; import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const ptBrConfig = { @@ -45,4 +46,5 @@ export const ptBrConfig = { weather: weather, modifierType: modifierType, berry: berry, + voucher: voucher, } diff --git a/src/locales/pt_BR/voucher.ts b/src/locales/pt_BR/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/pt_BR/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/locales/zh_CN/config.ts b/src/locales/zh_CN/config.ts index 10fe2bc884e..89d8d628f0e 100644 --- a/src/locales/zh_CN/config.ts +++ b/src/locales/zh_CN/config.ts @@ -20,6 +20,7 @@ import { tutorial } from "./tutorial"; import { weather } from "./weather"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; import { berry } from "./berry"; +import { voucher } from "./voucher"; export const zhCnConfig = { @@ -47,4 +48,5 @@ export const zhCnConfig = { weather: weather, battleMessageUiHandler: battleMessageUiHandler, berry: berry, -} \ No newline at end of file + voucher: voucher, +} diff --git a/src/locales/zh_CN/voucher.ts b/src/locales/zh_CN/voucher.ts new file mode 100644 index 00000000000..7af569e88cb --- /dev/null +++ b/src/locales/zh_CN/voucher.ts @@ -0,0 +1,11 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const voucher: SimpleTranslationEntries = { + "vouchers": "Vouchers", + "eggVoucher": "Egg Voucher", + "eggVoucherPlus": "Egg Voucher Plus", + "eggVoucherPremium": "Egg Voucher Premium", + "eggVoucherGold": "Egg Voucher Gold", + "locked": "Locked", + "defeatTrainer": "Defeat {{trainerName}}" +} as const; \ No newline at end of file diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 790a3c729c8..29e28f60f39 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -153,6 +153,7 @@ declare module 'i18next' { modifierType: ModifierTypeTranslationEntries; battleMessageUiHandler: SimpleTranslationEntries; berry: BerryTranslationEntries; + voucher: SimpleTranslationEntries; }; } } diff --git a/src/system/voucher.ts b/src/system/voucher.ts index 276e74eeb0d..507c14b5bfe 100644 --- a/src/system/voucher.ts +++ b/src/system/voucher.ts @@ -2,6 +2,7 @@ import BattleScene from "../battle-scene"; import { TrainerType } from "../data/enums/trainer-type"; import { ModifierTier } from "../modifier/modifier-tier"; import { Achv, AchvTier, achvs } from "./achv"; +import i18next from '../plugins/i18n'; export enum VoucherType { REGULAR, @@ -52,13 +53,13 @@ export class Voucher { export function getVoucherTypeName(voucherType: VoucherType): string { switch (voucherType) { case VoucherType.REGULAR: - return 'Egg Voucher'; + return i18next.t("voucher:eggVoucher"); case VoucherType.PLUS: - return 'Egg Voucher Plus'; + return i18next.t("voucher:eggVoucherPlus"); case VoucherType.PREMIUM: - return 'Egg Voucher Premium'; + return i18next.t("voucher:eggVoucherPremium"); case VoucherType.GOLDEN: - return 'Egg Voucher Gold'; + return i18next.t("voucher:eggVoucherGold"); } } @@ -75,9 +76,8 @@ export function getVoucherTypeIcon(voucherType: VoucherType): string { } } - export interface Vouchers { - [key: string]: Voucher + [key: string]: Voucher; } export const vouchers: Vouchers = {}; @@ -87,6 +87,8 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ]; { (function() { import('../data/trainer-config').then(tc => { + const trainerConfigs = tc.trainerConfigs; + for (let achv of voucherAchvs) { const voucherType = achv.score >= 150 ? VoucherType.GOLDEN @@ -98,7 +100,6 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ]; vouchers[achv.id] = new Voucher(voucherType, achv.description); } - const trainerConfigs = tc.trainerConfigs; const bossTrainerTypes = Object.keys(trainerConfigs) .filter(tt => trainerConfigs[tt].isBoss && trainerConfigs[tt].getDerivedType() !== TrainerType.RIVAL); @@ -107,12 +108,17 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ]; ? VoucherType.PLUS : VoucherType.PREMIUM; const key = TrainerType[trainerType]; - vouchers[key] = new Voucher(voucherType, `Defeat ${trainerConfigs[trainerType].name}`); + const trainerName = trainerConfigs[trainerType].name; + vouchers[key] = new Voucher( + voucherType, + i18next.t("voucher:defeatTrainer", { trainerName }) + ); } const voucherKeys = Object.keys(vouchers); - for (let k of voucherKeys) + for (let k of voucherKeys) { vouchers[k].id = k; + } }); })(); -} \ No newline at end of file +} diff --git a/src/ui/vouchers-ui-handler.ts b/src/ui/vouchers-ui-handler.ts index e28e211ee53..55f3ac224aa 100644 --- a/src/ui/vouchers-ui-handler.ts +++ b/src/ui/vouchers-ui-handler.ts @@ -5,6 +5,7 @@ import { TextStyle, addTextObject } from "./text"; import { Mode } from "./ui"; import { addWindow } from "./ui-theme"; import {Button} from "../enums/buttons"; +import i18next from '../plugins/i18n'; const itemRows = 4; const itemCols = 17; @@ -40,7 +41,7 @@ export default class VouchersUiHandler extends MessageUiHandler { const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24); headerBg.setOrigin(0, 0); - const headerText = addTextObject(this.scene, 0, 0, 'Vouchers', TextStyle.SETTINGS_LABEL); + const headerText = addTextObject(this.scene, 0, 0, i18next.t("voucher:vouchers"), TextStyle.SETTINGS_LABEL); headerText.setOrigin(0, 0); headerText.setPositionRelative(headerBg, 8, 4); @@ -127,7 +128,7 @@ export default class VouchersUiHandler extends MessageUiHandler { this.titleText.setText(getVoucherTypeName(voucher.voucherType)); this.showText(voucher.description); - this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : 'Locked'); + this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : i18next.t("voucher:locked")); } processInput(button: Button): boolean { @@ -246,4 +247,4 @@ export default class VouchersUiHandler extends MessageUiHandler { this.cursorObj.destroy(); this.cursorObj = null; } -} \ No newline at end of file +} From a4f4a37e5ccb3cc3b4786c78d7e2fc3fddf8b90f Mon Sep 17 00:00:00 2001 From: GhostFlys Date: Mon, 20 May 2024 06:27:17 +0800 Subject: [PATCH 03/12] add egg.ts (#1138) --- src/locales/zh_CN/egg.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/locales/zh_CN/egg.ts diff --git a/src/locales/zh_CN/egg.ts b/src/locales/zh_CN/egg.ts new file mode 100644 index 00000000000..cc137d717aa --- /dev/null +++ b/src/locales/zh_CN/egg.ts @@ -0,0 +1,21 @@ +import { SimpleTranslationEntries } from "#app/plugins/i18n"; + +export const egg: SimpleTranslationEntries = { + "egg": "蛋", + "greatTier": "稀有", + "ultraTier": "史诗", + "masterTier": "传说", + "defaultTier": "普通", + "hatchWavesMessageSoon": "里面传来声音!似乎快要孵化了!", + "hatchWavesMessageClose": "有时好像会动一下。就快孵化了吧?", + "hatchWavesMessageNotClose": "会孵化出什么呢?看来还需要很长时间才能孵化。", + "hatchWavesMessageLongTime": "这个蛋需要很长时间才能孵化。", + "gachaTypeLegendary": "传说概率上升", + "gachaTypeMove": "稀有概率上升", + "gachaTypeShiny": "闪光概率上升", + "selectMachine": "选择一个机器。", + "notEnoughVouchers": "你没有足够的兑换券!", + "tooManyEggs": "你的蛋太多啦!", + "pull": "抽", + "pulls": "连抽" +} as const; \ No newline at end of file From a30fc9b82d94a7d760dcffcdd46e088c0f9860a4 Mon Sep 17 00:00:00 2001 From: Matthew Olker Date: Sun, 19 May 2024 18:39:21 -0400 Subject: [PATCH 04/12] Update variant palettes and masterlist --- public/images/pokemon/variant/169.json | 18 +- public/images/pokemon/variant/42.json | 24 +-- .../images/pokemon/variant/_masterlist.json | 34 +++- public/images/pokemon/variant/back/383.json | 17 ++ public/images/pokemon/variant/back/622.json | 26 +-- .../pokemon/variant/back/female/41.json | 24 +++ .../pokemon/variant/back/female/42.json | 24 +++ public/images/pokemon/variant/exp/747_2.json | 188 ++++++++++++++++++ public/images/pokemon/variant/female/41.json | 26 +++ public/images/pokemon/variant/female/42.json | 30 +++ 10 files changed, 375 insertions(+), 36 deletions(-) create mode 100644 public/images/pokemon/variant/back/female/41.json create mode 100644 public/images/pokemon/variant/back/female/42.json create mode 100644 public/images/pokemon/variant/exp/747_2.json create mode 100644 public/images/pokemon/variant/female/41.json create mode 100644 public/images/pokemon/variant/female/42.json diff --git a/public/images/pokemon/variant/169.json b/public/images/pokemon/variant/169.json index 92577fd0c34..3824fc5e351 100644 --- a/public/images/pokemon/variant/169.json +++ b/public/images/pokemon/variant/169.json @@ -1,15 +1,15 @@ { "0": { - "7b4a9c": "323f81", - "63197b": "142557", - "a55ace": "6265b4", + "7b4a9c": "d684ce", + "63197b": "9c528c", + "a55ace": "ffb5f7", "101010": "101010", - "b57bce": "99a3ee", - "08426b": "277eb2", - "ce0021": "ce0021", - "ffd600": "ffc3f4", - "d69400": "ff61e2", - "216b94": "4aa6ce", + "b57bce": "ffd6ef", + "08426b": "638400", + "ce0021": "940821", + "ffd600": "ffd600", + "d69400": "d69400", + "216b94": "8ca508", "ffffff": "ffffff", "a5a5a5": "a5a5a5", "6b6b6b": "6b6b6b" diff --git a/public/images/pokemon/variant/42.json b/public/images/pokemon/variant/42.json index 4ae5bf088cf..74311a59fb2 100644 --- a/public/images/pokemon/variant/42.json +++ b/public/images/pokemon/variant/42.json @@ -14,26 +14,26 @@ "943a7b": "175990" }, "1": { - "3a3a7b": "1d0f4e", - "5aadef": "3d4381", - "6384ce": "2f2a5f", - "631052": "892d03", - "ce6bb5": "f1a139", - "adceff": "666fb4", + "3a3a7b": "084a00", + "5aadef": "6b9c29", + "6384ce": "317300", + "631052": "c52931", + "ce6bb5": "ffada5", + "adceff": "84d64a", "000000": "000000", - "ad52ad": "d5711b", + "ad52ad": "e6737b", "636363": "636363", "ffffff": "ffffff", "d6d6d6": "d6d6d6", - "943a7b": "af4e0c" + "943a7b": "d6525a" }, "2": { - "3a3a7b": "584055", - "5aadef": "c1aec0", - "6384ce": "866881", + "3a3a7b": "3d2349", + "5aadef": "cbabca", + "6384ce": "916c8b", "631052": "54070c", "ce6bb5": "bc3b1d", - "adceff": "dfcddd", + "adceff": "e8d2e6", "000000": "000000", "ad52ad": "94241c", "636363": "636363", diff --git a/public/images/pokemon/variant/_masterlist.json b/public/images/pokemon/variant/_masterlist.json index 22cb44852ea..ea9fe53622b 100644 --- a/public/images/pokemon/variant/_masterlist.json +++ b/public/images/pokemon/variant/_masterlist.json @@ -909,6 +909,11 @@ 2, 2 ], + "472": [ + 0, + 0, + 0 + ], "475-mega": [ 0, 2, @@ -2050,6 +2055,16 @@ 2, 1 ], + "41": [ + 0, + 1, + 1 + ], + "42": [ + 0, + 1, + 1 + ], "308": [ 0, 1, @@ -2869,7 +2884,7 @@ ], "383": [ 0, - 2, + 1, 1 ], "384-mega": [ @@ -4143,6 +4158,16 @@ 1, 1 ], + "41": [ + 0, + 1, + 1 + ], + "42": [ + 0, + 1, + 1 + ], "308": [ 0, 1, @@ -4538,7 +4563,7 @@ ], "747": [ 0, - 1, + 2, 1 ], "748": [ @@ -4591,6 +4616,11 @@ 1, 1 ], + "770": [ + 0, + 0, + 0 + ], "771": [ 0, 2, diff --git a/public/images/pokemon/variant/back/383.json b/public/images/pokemon/variant/back/383.json index bfa8917302b..f3760c0244e 100644 --- a/public/images/pokemon/variant/back/383.json +++ b/public/images/pokemon/variant/back/383.json @@ -1,4 +1,21 @@ { + "1": { + "000000": "000000", + "7b2129": "032a10", + "9c2929": "10371a", + "ff736b": "419e49", + "ff2129": "2b5b32", + "bd3131": "0f461c", + "3a3a3a": "383540", + "736363": "625769", + "ffffff": "fff6de", + "bdbdd6": "e5d4b6", + "9c6b31": "d51b3e", + "ffce31": "ff435d", + "94848c": "72798b", + "ffbdbd": "49c74f", + "ad9ca5": "ad9ca5" + }, "2": { "000000": "000000", "7b2129": "123953", diff --git a/public/images/pokemon/variant/back/622.json b/public/images/pokemon/variant/back/622.json index 4f0338f4e15..9ad7426a9d7 100644 --- a/public/images/pokemon/variant/back/622.json +++ b/public/images/pokemon/variant/back/622.json @@ -1,19 +1,19 @@ { "0": { - "298c8c": "1c3820", - "5aada5": "3e5d43", - "84cece": "758076", - "004a52": "102c16", - "106b63": "0d1e10", + "298c8c": "427373", + "5aada5": "6b9c94", + "84cece": "94bdbd", + "004a52": "192121", + "106b63": "21524a", "191921": "191921", - "106b7b": "102c16", - "29848c": "224427", - "6b4200": "54190e", - "c59c52": "a65c3f", - "9c7329": "763826", - "dece94": "e46424", - "ffefa5": "ff9942", - "bdad73": "cb3000" + "106b7b": "293a42", + "29848c": "424a5a", + "6b4200": "523a10", + "c59c52": "b59463", + "9c7329": "846b3a", + "dece94": "b5de21", + "ffefa5": "d6ff42", + "bdad73": "94bd00" }, "1": { "298c8c": "793907", diff --git a/public/images/pokemon/variant/back/female/41.json b/public/images/pokemon/variant/back/female/41.json new file mode 100644 index 00000000000..87c18df01ac --- /dev/null +++ b/public/images/pokemon/variant/back/female/41.json @@ -0,0 +1,24 @@ +{ + "1": { + "101010": "101010", + "8cb5ef": "4e538f", + "4a427b": "14093b", + "637bb5": "37326f", + "73215a": "aa4c18", + "b5529c": "cc7b32", + "bdceff": "868ecc", + "ffffff": "ffffff", + "636363": "636363" + }, + "2": { + "101010": "101010", + "8cb5ef": "cbabca", + "4a427b": "4d3259", + "637bb5": "916c8b", + "73215a": "670f10", + "b5529c": "94241c", + "bdceff": "e8d2e6", + "ffffff": "ffffff", + "636363": "636363" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/42.json b/public/images/pokemon/variant/back/female/42.json new file mode 100644 index 00000000000..d2be9f7ced5 --- /dev/null +++ b/public/images/pokemon/variant/back/female/42.json @@ -0,0 +1,24 @@ +{ + "1": { + "3a3a7b": "1d0f4e", + "6384ce": "2f2a5f", + "adceff": "666fb4", + "5aadef": "3d4381", + "631052": "892d03", + "000000": "000000", + "ce6bb5": "f1a139", + "ad52ad": "d5711b", + "943a7b": "af4e0c" + }, + "2": { + "3a3a7b": "3d2349", + "6384ce": "916c8b", + "adceff": "e8d2e6", + "5aadef": "cbabca", + "631052": "54070c", + "000000": "000000", + "ce6bb5": "bc3b1d", + "ad52ad": "94241c", + "943a7b": "6c1314" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/747_2.json b/public/images/pokemon/variant/exp/747_2.json new file mode 100644 index 00000000000..4273c853522 --- /dev/null +++ b/public/images/pokemon/variant/exp/747_2.json @@ -0,0 +1,188 @@ +{ + "textures": [ + { + "image": "747_2.png", + "format": "RGBA8888", + "size": { + "w": 110, + "h": 110 + }, + "scale": 1, + "frames": [ + { + "filename": "0003.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + }, + "frame": { + "x": 0, + "y": 0, + "w": 55, + "h": 47 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 55, + "y": 0, + "w": 55, + "h": 46 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 55, + "y": 0, + "w": 55, + "h": 46 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 55, + "h": 46 + }, + "frame": { + "x": 55, + "y": 46, + "w": 55, + "h": 46 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 55, + "h": 47 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 55, + "h": 46 + }, + "frame": { + "x": 55, + "y": 46, + "w": 55, + "h": 46 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:e4c4f790c4f0286f608dcdb15a609059:464f7ae7db1c0d034c2a1a65612b0da8:b26f7254994561969f00f765318acf1c$" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/41.json b/public/images/pokemon/variant/female/41.json new file mode 100644 index 00000000000..08446ef4908 --- /dev/null +++ b/public/images/pokemon/variant/female/41.json @@ -0,0 +1,26 @@ +{ + "1": { + "101010": "101010", + "637bb5": "37326f", + "4a427b": "14093b", + "bdceff": "868ecc", + "8cb5ef": "4e538f", + "b5529c": "cc7b32", + "73215a": "aa4c18", + "d673bd": "f0ad57", + "ffffff": "ffffff", + "636363": "636363" + }, + "2": { + "101010": "101010", + "637bb5": "916c8b", + "4a427b": "4d3259", + "bdceff": "e8d2e6", + "8cb5ef": "cbabca", + "b5529c": "94241c", + "73215a": "670f10", + "d673bd": "bc3b1d", + "ffffff": "ffffff", + "636363": "636363" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/42.json b/public/images/pokemon/variant/female/42.json new file mode 100644 index 00000000000..000e127793e --- /dev/null +++ b/public/images/pokemon/variant/female/42.json @@ -0,0 +1,30 @@ +{ + "1": { + "3a3a7b": "1d0f4e", + "5aadef": "3d4381", + "6384ce": "2f2a5f", + "631052": "892d03", + "ce6bb5": "f1a139", + "adceff": "666fb4", + "000000": "000000", + "ad52ad": "d5711b", + "636363": "636363", + "ffffff": "ffffff", + "d6d6d6": "d6d6d6", + "943a7b": "af4e0c" + }, + "2": { + "3a3a7b": "3d2349", + "5aadef": "cbabca", + "6384ce": "916c8b", + "631052": "54070c", + "ce6bb5": "bc3b1d", + "adceff": "e8d2e6", + "000000": "000000", + "ad52ad": "94241c", + "636363": "636363", + "ffffff": "ffffff", + "d6d6d6": "d6d6d6", + "943a7b": "6c1314" + } +} \ No newline at end of file From 9f699537bc3c6b5e8336c1cdd33a5de2caad4d61 Mon Sep 17 00:00:00 2001 From: lucfd <83493765+lucfd@users.noreply.github.com> Date: Sun, 19 May 2024 18:47:30 -0400 Subject: [PATCH 05/12] Implemented Bug Bite, Pluck, Teatime (#232) * implemented pluck, bug bite * steal blocked by sticky hold * implemented teatime * added stuff cheeks * added berry pouch support * fixed StealEatBerryAttr sometimes eating 2 stacks of a berry * added comments & documentation * added more comments * added comment on stuff cheeks condition * fixed 0 stack berry modifier not disappearing * stuff cheeks bug fix * fix leppa berry logic * removed stuff cheeks --- src/data/berry.ts | 8 ++-- src/data/move.ts | 102 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/src/data/berry.ts b/src/data/berry.ts index 1521f3488ef..e13d4532b3e 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -130,9 +130,11 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { return (pokemon: Pokemon) => { if (pokemon.battleData) pokemon.battleData.berriesEaten.push(berryType); - const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()); - ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`)); + const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1); + if(ppRestoreMove !== undefined){ + ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0); + pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`)); + } }; } } \ No newline at end of file diff --git a/src/data/move.ts b/src/data/move.ts index d71edda691d..9043935c176 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -12,10 +12,10 @@ import * as Utils from "../utils"; import { WeatherType } from "./weather"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagType } from "./enums/arena-tag-type"; -import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr } from "./ability"; +import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, PreventBerryUseAbAttr, BlockItemTheftAbAttr } from "./ability"; import { Abilities } from "./enums/abilities"; import { allAbilities } from './ability'; -import { PokemonHeldItemModifier } from "../modifier/modifier"; +import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier } from "../modifier/modifier"; import { BattlerIndex } from "../battle"; import { Stat } from "./pokemon-stat"; import { TerrainType } from "./terrain"; @@ -25,6 +25,7 @@ import { ModifierPoolType } from "#app/modifier/modifier-type"; import { Command } from "../ui/command-ui-handler"; import { Biome } from "./enums/biome"; import i18next, { Localizable } from '../plugins/i18n'; +import { BerryType, BerryEffectFunc, getBerryEffectFunc } from './berry'; export enum MoveCategory { PHYSICAL, @@ -1443,6 +1444,95 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { } } +/** + * Attribute that causes targets of the move to eat a berry. If chosenBerry is not overriden, a random berry will be picked from the target's inventory. + */ +export class EatBerryAttr extends MoveEffectAttr { + protected chosenBerry: BerryModifier; + constructor() { + super(true, MoveEffectTrigger.HIT); + this.chosenBerry = undefined; + } +/** + * Causes the target to eat a berry. + * @param user {@linkcode Pokemon} Pokemon that used the move + * @param target {@linkcode Pokemon} Pokemon that will eat a berry + * @param move {@linkcode Move} The move being used + * @param args Unused + * @returns {boolean} true if the function succeeds + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!super.apply(user, target, move, args)) + return false; + + if(this.chosenBerry === undefined) { // if no berry has been provided, pick a random berry from their inventory + const heldBerries = this.getTargetHeldBerries(target); + if(heldBerries.length <= 0) + return false; + this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; + } + + getBerryEffectFunc(this.chosenBerry.berryType)(target); // target eats the berry + + const preserve = new Utils.BooleanHolder(false); + target.scene.applyModifiers(PreserveBerryModifier, target.isPlayer(), target, preserve); + + if (!preserve.value){ // remove the eaten berry if not preserved + if (!--this.chosenBerry.stackCount) + target.scene.removeModifier(this.chosenBerry, !target.isPlayer()); + target.scene.updateModifiers(target.isPlayer()); +} + this.chosenBerry = undefined; + + return true; + } + + getTargetHeldBerries(target: Pokemon): BerryModifier[] { + return target.scene.findModifiers(m => m instanceof BerryModifier + && (m as BerryModifier).pokemonId === target.id, target.isPlayer()) as BerryModifier[]; + } + +} +/** + * Attribute used for moves that steal a random berry from the target. The user then eats the stolen berry. + * Used for Pluck & Bug Bite. + */ +export class StealEatBerryAttr extends EatBerryAttr { + constructor() { + super(); + } +/** + * User steals a random berry from the target and then eats it. + * @param {Pokemon} user Pokemon that used the move and will eat the stolen berry + * @param {Pokemon} target Pokemon that will have its berry stolen + * @param {Move} move Move being used + * @param {any[]} args Unused + * @returns {boolean} true if the function succeeds + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + + const cancelled = new Utils.BooleanHolder(false); + applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // check for abilities that block item theft + if(cancelled.value == true) + return false; + + const heldBerries = this.getTargetHeldBerries(target).filter(i => i.getTransferrable(false)); + + if (heldBerries.length) { // if the target has berries, pick a random berry and steal it + this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; + + if (this.chosenBerry.stackCount == 1) // remove modifier if its the last berry + target.scene.removeModifier(this.chosenBerry, !target.isPlayer()); + target.scene.updateModifiers(target.isPlayer()); + + user.scene.queueMessage(getPokemonMessage(user, ` stole and ate\n${target.name}'s ${this.chosenBerry.type.name}!`)); + return super.apply(user, user, move, args); + } + + return false; + } +} + export class HealStatusEffectAttr extends MoveEffectAttr { private effects: StatusEffect[]; @@ -5556,7 +5646,7 @@ export function initMoves() { .makesContact(false) .ignoresProtect(), new AttackMove(Moves.PLUCK, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4) - .partial(), + .attr(StealEatBerryAttr), new StatusMove(Moves.TAILWIND, Type.FLYING, -1, 15, -1, 0, 4) .windMove() .attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true) @@ -5793,7 +5883,7 @@ export function initMoves() { new AttackMove(Moves.JUDGMENT, Type.NORMAL, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 4) .partial(), new AttackMove(Moves.BUG_BITE, Type.BUG, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4) - .partial(), + .attr(StealEatBerryAttr), new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4) .attr(StatChangeAttr, BattleStat.SPATK, 1, true), new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4) @@ -6655,8 +6745,8 @@ export function initMoves() { .makesContact(false) .partial(), new StatusMove(Moves.TEATIME, Type.NORMAL, -1, 10, -1, 0, 8) - .target(MoveTarget.ALL) - .unimplemented(), + .attr(EatBerryAttr) + .target(MoveTarget.ALL), new StatusMove(Moves.OCTOLOCK, Type.FIGHTING, 100, 15, -1, 0, 8) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, true, 1) .partial(), From f649179e24e20befb00e9424101f4b2e74394464 Mon Sep 17 00:00:00 2001 From: arColm Date: Mon, 20 May 2024 07:52:51 +0900 Subject: [PATCH 06/12] Implement Grassy Glide (#272) --- src/data/ability.ts | 7 ++++++- src/data/move.ts | 38 +++++++++++++++++++++++++++++++++++++- src/phases.ts | 5 ++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 2c472871bab..c44357cc3c6 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags"; import { BattlerTagType } from "./enums/battler-tag-type"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { Gender } from "./gender"; -import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs } from "./move"; +import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagType } from "./enums/arena-tag-type"; import { Stat } from "./pokemon-stat"; @@ -491,8 +491,13 @@ export class PostDefendFormChangeAbAttr extends PostDefendAbAttr { export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { const attackPriority = new Utils.IntegerHolder(move.getMove().priority); + applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority); applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority); + if(move.getMove().moveTarget===MoveTarget.USER) { + return false; + } + if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) { cancelled.value = true; return true; diff --git a/src/data/move.ts b/src/data/move.ts index 9043935c176..2eaa9c2620e 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1169,6 +1169,42 @@ export class StrengthSapHealAttr extends MoveEffectAttr { return true; } } +/** + * Attribute used for moves that change priority in a turn given a condition, + * e.g. Grassy Glide + * Called when move order is calculated in {@linkcode TurnStartPhase}. + * @extends MoveAttr + * @see {@linkcode apply} + */ +export class IncrementMovePriorityAttr extends MoveAttr { + /** The condition for a move's priority being incremented */ + private moveIncrementFunc: (pokemon: Pokemon, target:Pokemon, move: Move) => boolean; + /** The amount to increment priority by, if condition passes. */ + private increaseAmount: integer; + + constructor(moveIncrementFunc: (pokemon: Pokemon, target:Pokemon, move: Move) => boolean, increaseAmount = 1) { + super(); + + this.moveIncrementFunc = moveIncrementFunc; + this.increaseAmount = increaseAmount; + } + + /** + * Increments move priority by set amount if condition passes + * @param user {@linkcode Pokemon} using this move + * @param target {@linkcode Pokemon} target of this move + * @param move {@linkcode Move} being used + * @param args [0] {@linkcode Utils.IntegerHolder} for move priority. + * @returns true if function succeeds + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!this.moveIncrementFunc(user, target, move)) + return false; + + (args[0] as Utils.IntegerHolder).value += this.increaseAmount; + return true; + } +} export class MultiHitAttr extends MoveAttr { private multiHitType: MultiHitType; @@ -6916,7 +6952,7 @@ export function initMoves() { .condition(failIfDampCondition) .makesContact(false), new AttackMove(Moves.GRASSY_GLIDE, Type.GRASS, MoveCategory.PHYSICAL, 55, 100, 20, -1, 0, 8) - .partial(), + .attr(IncrementMovePriorityAttr,(user,target,move) =>user.scene.arena.getTerrainType()===TerrainType.GRASSY&&user.isGrounded()), new AttackMove(Moves.RISING_VOLTAGE, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 20, -1, 0, 8) .attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && target.isGrounded() ? 2 : 1), new AttackMove(Moves.TERRAIN_PULSE, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 8) diff --git a/src/phases.ts b/src/phases.ts index a6df54c4cea..99308a20941 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -2,7 +2,7 @@ import BattleScene, { AnySound, bypassLogin, startingWave } from "./battle-scene import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon"; import * as Utils from './utils'; import { Moves } from "./data/enums/moves"; -import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, BypassRedirectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr, SacrificialAttr } from "./data/move"; +import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, BypassRedirectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr, SacrificialAttr, IncrementMovePriorityAttr } from "./data/move"; import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; @@ -2012,6 +2012,9 @@ export class TurnStartPhase extends FieldPhase { const aPriority = new Utils.IntegerHolder(aMove.priority); const bPriority = new Utils.IntegerHolder(bMove.priority); + applyMoveAttrs(IncrementMovePriorityAttr,this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a),null,aMove,aPriority); + applyMoveAttrs(IncrementMovePriorityAttr,this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b),null,bMove,bPriority); + applyAbAttrs(IncrementMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a), null, aMove, aPriority); applyAbAttrs(IncrementMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b), null, bMove, bPriority); From f1394307f4f495087b18ac5ae8b8c1ff4c370d9a Mon Sep 17 00:00:00 2001 From: rayanzmn <129906641+rayanzmn@users.noreply.github.com> Date: Mon, 20 May 2024 00:54:17 +0200 Subject: [PATCH 07/12] Fixes recoil damage calculation (#1063) Recoil damage previously used the total damage dealt by the user instead of using the damage dealt in the current turn. --- src/data/move.ts | 4 ++-- src/field/pokemon.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 2eaa9c2620e..59691f39de7 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -782,8 +782,8 @@ export class RecoilAttr extends MoveEffectAttr { if (cancelled.value) return false; - const recoilDamage = Math.max(Math.floor((!this.useHp ? user.turnData.damageDealt : user.getMaxHp()) * this.damageRatio), - user.turnData.damageDealt ? 1 : 0); + const recoilDamage = Math.max(Math.floor((!this.useHp ? user.turnData.currDamageDealt : user.getMaxHp()) * this.damageRatio), + user.turnData.currDamageDealt ? 1 : 0); if (!recoilDamage) return false; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a1347bcd256..e8a63635448 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1659,6 +1659,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.gameData.gameStats.highestDamage = damage.value; } source.turnData.damageDealt += damage.value; + source.turnData.currDamageDealt = damage.value; this.battleData.hitCount++; const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id }; this.turnData.attacksReceived.unshift(attackResult); @@ -3381,6 +3382,7 @@ export class PokemonTurnData { public hitCount: integer; public hitsLeft: integer; public damageDealt: integer = 0; + public currDamageDealt: integer = 0; public damageTaken: integer = 0; public attacksReceived: AttackMoveResult[] = []; } From 80f6b62d1b7732d147e1e5a04873388f8e18ad4f Mon Sep 17 00:00:00 2001 From: arColm Date: Mon, 20 May 2024 08:02:17 +0900 Subject: [PATCH 08/12] Implement Revival Blessing (#343) --- src/data/move.ts | 66 ++++++++++++++++++++++++++++++++++++-- src/field/pokemon.ts | 38 +++++++++++++++++++++- src/phases.ts | 4 +++ src/ui/party-ui-handler.ts | 15 +++++++-- 4 files changed, 118 insertions(+), 5 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 59691f39de7..2d27afcbe47 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1,6 +1,6 @@ import { Moves } from "./enums/moves"; import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; -import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; +import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase, ToggleDoublePositionPhase } from "../phases"; import { BattleStat, getBattleStatName } from "./battle-stat"; import { EncoreTag } from "./battler-tags"; import { BattlerTagType } from "./enums/battler-tag-type"; @@ -3694,6 +3694,67 @@ export class RemoveScreensAttr extends MoveEffectAttr { } } +/** + * Attribute used for Revival Blessing. + * @extends MoveEffectAttr + * @see {@linkcode apply} + */ +export class RevivalBlessingAttr extends MoveEffectAttr { + constructor(user?: boolean) { + super(true); + } + + /** + * + * @param user {@linkcode Pokemon} using this move + * @param target {@linkcode Pokemon} target of this move + * @param move {@linkcode Move} being used + * @param args N/A + * @returns Promise, true if function succeeds. + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { + return new Promise(resolve => { + // If user is player, checks if the user has fainted pokemon + if(user instanceof PlayerPokemon + && user.scene.getParty().findIndex(p => p.isFainted())>-1) { + (user as PlayerPokemon).revivalBlessing().then(() => { + resolve(true) + }); + // If user is enemy, checks that it is a trainer, and it has fainted non-boss pokemon in party + } else if(user instanceof EnemyPokemon + && user.hasTrainer() + && user.scene.getEnemyParty().findIndex(p => p.isFainted() && !p.isBoss()) > -1) { + // Selects a random fainted pokemon + const faintedPokemon = user.scene.getEnemyParty().filter(p => p.isFainted() && !p.isBoss()); + const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length)]; + const slotIndex = user.scene.getEnemyParty().findIndex(p => pokemon.id === p.id); + pokemon.resetStatus(); + pokemon.heal(Math.min(Math.max(Math.ceil(Math.floor(0.5 * pokemon.getMaxHp())), 1), pokemon.getMaxHp())); + user.scene.queueMessage(`${pokemon.name} was revived!`,0,true); + + if(user.scene.currentBattle.double && user.scene.getEnemyParty().length > 1) { + const allyPokemon = user.getAlly(); + if(slotIndex<=1) { + user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, pokemon.getFieldIndex(), slotIndex, false, false, false)); + } else if(allyPokemon.isFainted()){ + user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, allyPokemon.getFieldIndex(), slotIndex, false, false,false)); + } + } + resolve(true); + } else { + user.scene.queueMessage(`But it failed!`); + resolve(false); + } + }) + } + + getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { + if(user.hasTrainer() && user.scene.getEnemyParty().findIndex(p => p.isFainted() && !p.isBoss()) > -1) + return 20; + + return -20; + } +} export class ForceSwitchOutAttr extends MoveEffectAttr { private user: boolean; @@ -7235,7 +7296,8 @@ export function initMoves() { .partial(), new StatusMove(Moves.REVIVAL_BLESSING, Type.NORMAL, -1, 1, -1, 0, 9) .triageMove() - .unimplemented(), + .attr(RevivalBlessingAttr) + .target(MoveTarget.USER), new AttackMove(Moves.SALT_CURE, Type.ROCK, MoveCategory.PHYSICAL, 40, 100, 15, -1, 0, 9) .attr(AddBattlerTagAttr, BattlerTagType.SALT_CURED) .makesContact(false), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index e8a63635448..8e56d163141 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -17,7 +17,7 @@ import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims'; import { Status, StatusEffect, getRandomStatus } from '../data/status-effect'; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from '../data/pokemon-evolutions'; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms'; -import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchSummonPhase } from '../phases'; +import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchPhase, SwitchSummonPhase, ToggleDoublePositionPhase } from '../phases'; import { BattleStat } from '../data/battle-stat'; import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; import { BattlerTagType } from "../data/enums/battler-tag-type"; @@ -2681,6 +2681,42 @@ export class PlayerPokemon extends Pokemon { sd.friendship = Math.max((sd.friendship || 0) + starterAmount.value, 0); } } + /** + * Handles Revival Blessing when used by player. + * @returns Promise to revive a pokemon. + * @see {@linkcode RevivalBlessingAttr} + */ + revivalBlessing(): Promise { + return new Promise(resolve => { + this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => { + if(slotIndex >= 0 && slotIndex<6) { + const pokemon = this.scene.getParty()[slotIndex]; + if(!pokemon || !pokemon.isFainted()) + resolve(); + + pokemon.resetTurnData(); + pokemon.resetStatus(); + pokemon.heal(Math.min(Math.max(Math.ceil(Math.floor(0.5 * pokemon.getMaxHp())), 1), pokemon.getMaxHp())); + this.scene.queueMessage(`${pokemon.name} was revived!`,0,true); + + if(this.scene.currentBattle.double && this.scene.getParty().length > 1) { + const allyPokemon = this.getAlly(); + if(slotIndex<=1) { + // Revived ally pokemon + this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, pokemon.getFieldIndex(), slotIndex, false, false, true)); + this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true)); + } else if(allyPokemon.isFainted()) { + // Revived party pokemon, and ally pokemon is fainted + this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, allyPokemon.getFieldIndex(), slotIndex, false, false, true)); + this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true)); + } + } + + } + this.scene.ui.setMode(Mode.MESSAGE).then(() => resolve()); + }, PartyUiHandler.FilterFainted) + }) + } getPossibleEvolution(evolution: SpeciesFormEvolution): Promise { return new Promise(resolve => { diff --git a/src/phases.ts b/src/phases.ts index 99308a20941..de40e1abe6b 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -3844,6 +3844,10 @@ export class SwitchPhase extends BattlePhase { if (this.isModal && !this.scene.getParty().filter(p => !p.isFainted() && !p.isActive(true)).length) return super.end(); + // Check if there is any space still in field + if (this.isModal && this.scene.getPlayerField().filter(p => !p.isFainted() && p.isActive(true)).length >= this.scene.currentBattle.getBattlerCount()) + return super.end(); + // Override field index to 0 in case of double battle where 2/3 remaining party members fainted at once const fieldIndex = this.scene.currentBattle.getBattlerCount() === 1 || this.scene.getParty().filter(p => !p.isFainted()).length > 1 ? this.fieldIndex : 0; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 8b497655a17..253ed8b4b72 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -24,6 +24,7 @@ export enum PartyUiMode { SWITCH, FAINT_SWITCH, POST_BATTLE_SWITCH, + REVIVAL_BLESSING, MODIFIER, MOVE_MODIFIER, TM_MODIFIER, @@ -37,6 +38,7 @@ export enum PartyOption { CANCEL = -1, SEND_OUT, PASS_BATON, + REVIVE, APPLY, TEACH, TRANSFER, @@ -103,6 +105,12 @@ export default class PartyUiHandler extends MessageUiHandler { return null; }; + public static FilterFainted = (pokemon: PlayerPokemon) => { + if(!pokemon.isFainted()) + return `${pokemon.name} still has energy\nto battle!`; + return null; + } + private static FilterAllMoves = (_pokemonMove: PokemonMove) => null; public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => { @@ -361,7 +369,7 @@ export default class PartyUiHandler extends MessageUiHandler { if (this.cursor < 6) { this.showOptions(); ui.playSelect(); - } else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH) + } else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING) ui.playError(); else return this.processInput(Button.CANCEL); @@ -370,7 +378,7 @@ export default class PartyUiHandler extends MessageUiHandler { if ((this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.SPLICE) && this.transferMode) { this.clearTransfer(); ui.playSelect(); - } else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH) { + } else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH && this.partyUiMode !== PartyUiMode.REVIVAL_BLESSING) { if (this.selectCallback) { const selectCallback = this.selectCallback; this.selectCallback = null; @@ -580,6 +588,9 @@ export default class PartyUiHandler extends MessageUiHandler { this.options.push(PartyOption.FORM_CHANGE_ITEM + i); } break; + case PartyUiMode.REVIVAL_BLESSING: + this.options.push(PartyOption.REVIVE); + break; case PartyUiMode.MODIFIER: this.options.push(PartyOption.APPLY); break; From 3671fe4c2f81b8efe097819079408fd4432d699c Mon Sep 17 00:00:00 2001 From: Adrian Torrano <68144167+torranx@users.noreply.github.com> Date: Mon, 20 May 2024 07:04:32 +0800 Subject: [PATCH 09/12] Prevent spamming of requests when going over scoreboard pages (#1130) * prevent spamming of requests * add documentations --- src/ui/daily-run-scoreboard.ts | 70 ++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index 8b258b3a702..139a6d60cd7 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -30,13 +30,34 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { private pageCount: integer; private page: integer; private category: ScoreboardCategory; + + private _isUpdating: boolean; constructor(scene: BattleScene, x: number, y: number) { super(scene, x, y); + this._isUpdating = false; this.setup(); } + /** + * Sets the updating state and updates button states accordingly. + * If value is true (updating), disables the buttons; if false, enables the buttons. + * @param {boolean} value - The new updating state. + */ + set isUpdating(value) { + this._isUpdating = value; + this.setButtonsState(!value); + } + + /** + * Gets the current updating state. + * @returns {boolean} - The current updating state. + */ + get isUpdating() { + return this._isUpdating; + } + setup() { const titleWindow = addWindow(this.scene, 0, 0, 114, 18, false, false, null, null, WindowVariant.THIN); this.add(titleWindow); @@ -140,7 +161,24 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { }); } + /** + * Updates the scoreboard rankings based on the selected category and page. + * + * If the update process is already ongoing, the method exits early. Otherwise, it begins the update process by clearing + * the current rankings and showing a loading label. If the category changes, the page is reset to 1. + * + * The method fetches the total page count if necessary, followed by fetching the rankings for the specified category + * and page. It updates the UI with the fetched rankings or shows an appropriate message if no rankings are found. + * + * @param {ScoreboardCategory} [category=this.category] - The category to fetch rankings for. Defaults to the current category. + * @param {number} [page=this.page] - The page number to fetch. Defaults to the current page. + */ update(category: ScoreboardCategory = this.category, page: integer = this.page) { + if (this.isUpdating) { + return; + } + + this.isUpdating = true; this.rankingsContainer.removeAll(true); this.loadingLabel.setText(i18next.t('menu:loading')); @@ -150,7 +188,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { this.page = page = 1; Utils.executeIf(category !== this.category || this.pageCount === undefined, - () => Utils.apiFetch(`daily/rankingpagecount?category=${category}`).then(response => response.json()).then(count => this.pageCount = count) + () => Utils.apiFetch(`daily/rankingpagecount?category=${category}`).then(response => response.json()).then(count => this.pageCount = count) ).then(() => { Utils.apiFetch(`daily/rankings?category=${category}&page=${page}`) .then(response => response.json()) @@ -158,16 +196,40 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { this.page = page; this.category = category; this.titleLabel.setText(`${i18next.t(`menu:${ScoreboardCategory[category].toLowerCase()}Rankings`)}`); - this.prevPageButton.setAlpha(page > 1 ? 1 : 0.5); - this.nextPageButton.setAlpha(page < this.pageCount ? 1 : 0.5); this.pageNumberLabel.setText(page.toString()); if (jsonResponse) { this.loadingLabel.setVisible(false); this.updateRankings(jsonResponse); } else this.loadingLabel.setText(i18next.t('menu:noRankings')); + }).finally(() => { + this.isUpdating = false; }); - }).catch(err => { console.error("Failed to load daily rankings:\n", err) }); + }).catch(err => { + console.error("Failed to load daily rankings:\n", err) + }) + } + + /** + * Sets the state of the navigation buttons. + * @param {boolean} [enabled=true] - Whether the buttons should be enabled or disabled. + */ + setButtonsState(enabled: boolean = true) { + const buttons = [ + { button: this.prevPageButton, alphaValue: enabled ? (this.page > 1 ? 1 : 0.5) : 0.5 }, + { button: this.nextPageButton, alphaValue: enabled ? (this.page < this.pageCount ? 1 : 0.5) : 0.5 }, + { button: this.nextCategoryButton, alphaValue: enabled ? 1 : 0.5 }, + { button: this.prevCategoryButton, alphaValue: enabled ? 1 : 0.5 } + ]; + + buttons.forEach(({ button, alphaValue }) => { + if (enabled) { + button.setInteractive(); + } else { + button.disableInteractive(); + } + button.setAlpha(alphaValue); + }); } } From ca1ae4b55621a38b6e72778f57be506f0c9f7c3c Mon Sep 17 00:00:00 2001 From: Matthew Olker Date: Sun, 19 May 2024 21:40:58 -0400 Subject: [PATCH 10/12] cleanup language and candy in starter select ui handler --- src/ui/starter-select-ui-handler.ts | 153 ++++++++++++---------------- 1 file changed, 63 insertions(+), 90 deletions(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index c3681651964..264062c20fd 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -42,48 +42,69 @@ export interface Starter { pokerus: boolean; } +interface LanguageSetting { + starterInfoTextSize: string, + instructionTextSize: string, + starterInfoXPosition: integer +} + +const languageSettings: { [key: string]: LanguageSetting } = { + "en":{ + starterInfoTextSize: '56px', + instructionTextSize: '42px', + starterInfoXPosition: 31 + }, + "de":{ + starterInfoTextSize: '56px', + instructionTextSize: '35px', + starterInfoXPosition: 31 + }, + "es":{ + starterInfoTextSize: '56px', + instructionTextSize: '35px', + starterInfoXPosition: 31 + }, + "it":{ + starterInfoTextSize: '56px', + instructionTextSize: '38px', + starterInfoXPosition: 31 + }, + "fr":{ + starterInfoTextSize: '54px', + instructionTextSize: '42px', + starterInfoXPosition: 31 + }, + "zh_CN":{ + starterInfoTextSize: '56px', + instructionTextSize: '42px', + starterInfoXPosition: 31 + }, + "pt_BR":{ + starterInfoTextSize: '47px', + instructionTextSize: '38px', + starterInfoXPosition: 32 + }, +} + +const starterCandyCosts: { passive: integer, costReduction: [integer, integer] }[] = [ + { passive: 50, costReduction: [30, 75] }, // 1 + { passive: 45, costReduction: [25, 60] }, // 2 + { passive: 30, costReduction: [20, 50] }, // 3 + { passive: 25, costReduction: [15, 40] }, // 4 + { passive: 20, costReduction: [12, 35] }, // 5 + { passive: 15, costReduction: [10, 30] }, // 6 + { passive: 10, costReduction: [8, 20] }, // 7 + { passive: 10, costReduction: [5, 15] }, // 8 + { passive: 10, costReduction: [3, 10] }, // 9 + { passive: 10, costReduction: [3, 10] }, // 10 +] + function getPassiveCandyCount(baseValue: integer): integer { - switch (baseValue) { - case 1: - return 50; - case 2: - return 45; - case 3: - return 40; - case 4: - return 30; - case 5: - return 25; - case 6: - return 20; - case 7: - return 15; - default: - return 10; - } + return starterCandyCosts[baseValue - 1].passive; } function getValueReductionCandyCounts(baseValue: integer): [integer, integer] { - switch (baseValue) { - case 1: - return [ 30, 75]; - case 2: - return [ 25, 60 ]; - case 3: - return [ 20, 50 ]; - case 4: - return [ 15, 40 ]; - case 5: - return [ 12, 35 ]; - case 6: - return [ 10, 30 ]; - case 7: - return [ 8, 20 ]; - case 8: - return [ 5, 15 ]; - default: - return [ 3, 10 ]; - } + return starterCandyCosts[baseValue - 1].costReduction; } const gens = [ @@ -255,32 +276,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonUncaughtText.setOrigin(0, 0); this.starterSelectContainer.add(this.pokemonUncaughtText); - let starterInfoXPosition = 31; // Only text - // The position should be set per language const currentLanguage = i18next.language; - switch (currentLanguage) { - case 'pt_BR': - starterInfoXPosition = 32; - break; - default: - starterInfoXPosition = 31; - break - } + // The position should be set per language + let starterInfoXPosition = languageSettings[currentLanguage].starterInfoXPosition; - let starterInfoTextSize = '56px'; // Labels and text // The font size should be set per language - // currentLanguage is already defined - switch (currentLanguage) { - case 'fr': - starterInfoTextSize = '54px'; - break; - case 'pt_BR': - starterInfoTextSize = '47px'; - break; - default: - starterInfoTextSize = '56px'; - break - } + let starterInfoTextSize = languageSettings[currentLanguage].starterInfoTextSize; this.pokemonAbilityLabelText = addTextObject(this.scene, 6, 127, i18next.t("starterSelectUiHandler:ability"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonAbilityLabelText.setOrigin(0, 0); @@ -589,36 +590,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.add(this.pokemonEggMovesContainer); - - - let instructionTextSize = '42px'; // The font size should be set per language - // currentLanguage is already defined in the previous code block - switch (currentLanguage) { - case 'de': - instructionTextSize = '35px'; - break; - case 'en': - instructionTextSize = '42px'; - break; - case 'es': - instructionTextSize = '35px'; - break; - case 'fr': - instructionTextSize = '42px'; - break; - case 'it': - instructionTextSize = '38px'; - break; - case 'pt_BR': - instructionTextSize = '38px'; - break; - case 'zh_CN': - instructionTextSize = '42px'; - break; - - } - + let instructionTextSize = languageSettings[currentLanguage].instructionTextSize; this.instructionsText = addTextObject(this.scene, 4, 156, '', TextStyle.PARTY, { fontSize: instructionTextSize }); this.starterSelectContainer.add(this.instructionsText); From a32f61fbf7fce840bbdff676698ba230ed27b30d Mon Sep 17 00:00:00 2001 From: Somod1 <160222354+Somod1@users.noreply.github.com> Date: Mon, 20 May 2024 11:05:14 +0800 Subject: [PATCH 11/12] update zh_CN voucher locales (#1145) * Add files via upload * Update zh_CN voucher locales --- src/locales/zh_CN/voucher.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/locales/zh_CN/voucher.ts b/src/locales/zh_CN/voucher.ts index 7af569e88cb..7d0f8d2b2dd 100644 --- a/src/locales/zh_CN/voucher.ts +++ b/src/locales/zh_CN/voucher.ts @@ -1,11 +1,11 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const voucher: SimpleTranslationEntries = { - "vouchers": "Vouchers", - "eggVoucher": "Egg Voucher", - "eggVoucherPlus": "Egg Voucher Plus", - "eggVoucherPremium": "Egg Voucher Premium", - "eggVoucherGold": "Egg Voucher Gold", - "locked": "Locked", - "defeatTrainer": "Defeat {{trainerName}}" + "vouchers": "兑换券", + "eggVoucher": "初级扭蛋券", + "eggVoucherPlus": "中级扭蛋券", + "eggVoucherPremium": "高级扭蛋券", + "eggVoucherGold": "黄金扭蛋券", + "locked": "锁定", + "defeatTrainer": "你打败了{{trainerName}}" } as const; \ No newline at end of file From b95a59c094e0755c3879beff031b922cd0a7eb3d Mon Sep 17 00:00:00 2001 From: Matthew Olker Date: Sun, 19 May 2024 23:11:07 -0400 Subject: [PATCH 12/12] setup more future language text configuration --- src/ui/starter-select-ui-handler.ts | 37 ++++++++++++++--------------- src/ui/text.ts | 31 ++++++++++++++++++++---- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 264062c20fd..b0321946e9b 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -45,44 +45,40 @@ export interface Starter { interface LanguageSetting { starterInfoTextSize: string, instructionTextSize: string, - starterInfoXPosition: integer + starterInfoXPos?: integer, + starterInfoYOffset?: integer } const languageSettings: { [key: string]: LanguageSetting } = { "en":{ starterInfoTextSize: '56px', instructionTextSize: '42px', - starterInfoXPosition: 31 }, "de":{ starterInfoTextSize: '56px', instructionTextSize: '35px', - starterInfoXPosition: 31 }, "es":{ starterInfoTextSize: '56px', instructionTextSize: '35px', - starterInfoXPosition: 31 }, "it":{ starterInfoTextSize: '56px', instructionTextSize: '38px', - starterInfoXPosition: 31 }, "fr":{ starterInfoTextSize: '54px', instructionTextSize: '42px', - starterInfoXPosition: 31 }, "zh_CN":{ - starterInfoTextSize: '56px', + starterInfoTextSize: '40px', instructionTextSize: '42px', - starterInfoXPosition: 31 + starterInfoYOffset: 2 }, "pt_BR":{ starterInfoTextSize: '47px', instructionTextSize: '38px', - starterInfoXPosition: 32 + starterInfoXPos: 32, }, } @@ -220,6 +216,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { setup() { const ui = this.getUi(); + const currentLanguage = i18next.language; + const textSettings = languageSettings[currentLanguage]; this.starterSelectContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6); this.starterSelectContainer.setVisible(false); @@ -276,37 +274,38 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonUncaughtText.setOrigin(0, 0); this.starterSelectContainer.add(this.pokemonUncaughtText); - const currentLanguage = i18next.language; + // The position should be set per language - let starterInfoXPosition = languageSettings[currentLanguage].starterInfoXPosition; + let starterInfoXPos = textSettings?.starterInfoXPos || 31; + let starterInfoYOffset = textSettings?.starterInfoYOffset || 0; // The font size should be set per language - let starterInfoTextSize = languageSettings[currentLanguage].starterInfoTextSize; + let starterInfoTextSize = textSettings.starterInfoTextSize; - this.pokemonAbilityLabelText = addTextObject(this.scene, 6, 127, i18next.t("starterSelectUiHandler:ability"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonAbilityLabelText = addTextObject(this.scene, 6, 127 + starterInfoYOffset, i18next.t("starterSelectUiHandler:ability"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonAbilityLabelText.setOrigin(0, 0); this.pokemonAbilityLabelText.setVisible(false); this.starterSelectContainer.add(this.pokemonAbilityLabelText); - this.pokemonAbilityText = addTextObject(this.scene, starterInfoXPosition, 127, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonAbilityText = addTextObject(this.scene, starterInfoXPos, 127 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonAbilityText.setOrigin(0, 0); this.starterSelectContainer.add(this.pokemonAbilityText); - this.pokemonPassiveLabelText = addTextObject(this.scene, 6, 136, i18next.t("starterSelectUiHandler:passive"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonPassiveLabelText = addTextObject(this.scene, 6, 136 + starterInfoYOffset, i18next.t("starterSelectUiHandler:passive"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonPassiveLabelText.setOrigin(0, 0); this.pokemonPassiveLabelText.setVisible(false); this.starterSelectContainer.add(this.pokemonPassiveLabelText); - this.pokemonPassiveText = addTextObject(this.scene, starterInfoXPosition, 136, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonPassiveText = addTextObject(this.scene, starterInfoXPos, 136 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonPassiveText.setOrigin(0, 0); this.starterSelectContainer.add(this.pokemonPassiveText); - this.pokemonNatureLabelText = addTextObject(this.scene, 6, 145, i18next.t("starterSelectUiHandler:nature"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonNatureLabelText = addTextObject(this.scene, 6, 145 + starterInfoYOffset, i18next.t("starterSelectUiHandler:nature"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonNatureLabelText.setOrigin(0, 0); this.pokemonNatureLabelText.setVisible(false); this.starterSelectContainer.add(this.pokemonNatureLabelText); - this.pokemonNatureText = addBBCodeTextObject(this.scene, starterInfoXPosition, 145, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); + this.pokemonNatureText = addBBCodeTextObject(this.scene, starterInfoXPos, 145 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize }); this.pokemonNatureText.setOrigin(0, 0); this.starterSelectContainer.add(this.pokemonNatureText); @@ -591,7 +590,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.add(this.pokemonEggMovesContainer); // The font size should be set per language - let instructionTextSize = languageSettings[currentLanguage].instructionTextSize; + let instructionTextSize = textSettings.instructionTextSize; this.instructionsText = addTextObject(this.scene, 4, 156, '', TextStyle.PARTY, { fontSize: instructionTextSize }); this.starterSelectContainer.add(this.instructionsText); diff --git a/src/ui/text.ts b/src/ui/text.ts index d7ecd3b2526..8be46b1b238 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -4,6 +4,7 @@ import { ModifierTier } from "../modifier/modifier-tier"; import { EggTier } from "../data/enums/egg-type"; import BattleScene from "../battle-scene"; import { UiTheme } from "../enums/ui-theme"; +import i18next from "i18next"; export enum TextStyle { MESSAGE, @@ -28,6 +29,25 @@ export enum TextStyle { MOVE_INFO_CONTENT }; +interface LanguageSetting { + summaryFontSize?: string, + battleInfoFontSize?: string, + partyFontSize?: string, + tooltipContentFontSize?: string, + moveInfoFontSize?: string, + textScale?: number +} + +const languageSettings: { [key: string]: LanguageSetting } = { + "en":{}, + "de":{}, + "es":{}, + "it":{}, + "fr":{}, + "zh_CN":{}, + "pt_BR":{}, +} + export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text { const [ styleOptions, shadowColor, shadowSize ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions); @@ -64,6 +84,7 @@ export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, wi } function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, integer ] { + const lang = i18next.language; let shadowColor: string; let shadowSize = 6; @@ -90,25 +111,25 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio case TextStyle.MESSAGE: case TextStyle.SETTINGS_LABEL: case TextStyle.SETTINGS_SELECTED: - styleOptions.fontSize = '96px'; + styleOptions.fontSize = languageSettings[lang]?.summaryFontSize || '96px'; break; case TextStyle.BATTLE_INFO: case TextStyle.MONEY: case TextStyle.TOOLTIP_TITLE: - styleOptions.fontSize = '72px'; + styleOptions.fontSize = languageSettings[lang]?.battleInfoFontSize || '72px'; shadowSize = 4.5; break; case TextStyle.PARTY: case TextStyle.PARTY_RED: + styleOptions.fontSize = languageSettings[lang]?.partyFontSize || '66px'; styleOptions.fontFamily = 'pkmnems'; - styleOptions.fontSize = '66px'; break; case TextStyle.TOOLTIP_CONTENT: - styleOptions.fontSize = '64px'; + styleOptions.fontSize = languageSettings[lang]?.tooltipContentFontSize || '64px'; shadowSize = 4; break; case TextStyle.MOVE_INFO_CONTENT: - styleOptions.fontSize = '56px'; + styleOptions.fontSize = languageSettings[lang]?.moveInfoFontSize || '56px'; shadowSize = 3; break; }