From eba1920ee6193d1d7de39919cdaf4efbd36b0dc2 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Thu, 26 Sep 2024 17:01:24 +0200 Subject: [PATCH 01/65] [Bug] [Localization] Formes key correction (#4447) * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json * Update pokemon-form.json --- src/locales/de/pokemon-form.json | 6 +- src/locales/en/pokemon-form.json | 6 +- src/locales/es/pokemon-form.json | 6 +- src/locales/fr/pokemon-form.json | 6 +- src/locales/it/pokemon-form.json | 6 +- src/locales/ja/pokemon-form.json | 6 +- src/locales/ko/pokemon-form.json | 6 +- src/locales/pt_BR/pokemon-form.json | 6 +- src/locales/zh_CN/pokemon-form.json | 6 +- src/locales/zh_TW/pokemon-form.json | 116 ---------------------------- 10 files changed, 27 insertions(+), 143 deletions(-) diff --git a/src/locales/de/pokemon-form.json b/src/locales/de/pokemon-form.json index 16efc3af653..b4e62d3e4ee 100644 --- a/src/locales/de/pokemon-form.json +++ b/src/locales/de/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Ofenmaske (Terakristallisiert)", "ogerponCornerstoneMask": "Fundamentmaske", "ogerponCornerstoneMaskTera": "Fundamentmaske (Terakristallisiert)", - "terpagos": "Normalform", - "terpagosTerastal": "Terakristall-Form", - "terpagosStellar": "Stellarform", + "terapagos": "Normalform", + "terapagosTerastal": "Terakristall-Form", + "terapagosStellar": "Stellarform", "galarDarumaka": "Normalmodus", "galarDarumakaZen": "Trance-Modus", "paldeaTaurosCombat": "Gefechtsvariante", diff --git a/src/locales/en/pokemon-form.json b/src/locales/en/pokemon-form.json index 642d31a2a20..86e7c5dc1bc 100644 --- a/src/locales/en/pokemon-form.json +++ b/src/locales/en/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Hearthflame Mask Terastallized", "ogerponCornerstoneMask": "Cornerstone Mask", "ogerponCornerstoneMaskTera": "Cornerstone Mask Terastallized", - "terpagos": "Normal Form", - "terpagosTerastal": "Terastal Form", - "terpagosStellar": "Stellar Form", + "terapagos": "Normal Form", + "terapagosTerastal": "Terastal Form", + "terapagosStellar": "Stellar Form", "galarDarumaka": "Standard Mode", "galarDarumakaZen": "Zen Mode", "paldeaTaurosCombat": "Combat Breed", diff --git a/src/locales/es/pokemon-form.json b/src/locales/es/pokemon-form.json index b6008357d89..73aace57148 100644 --- a/src/locales/es/pokemon-form.json +++ b/src/locales/es/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Máscara Horno Teracristal", "ogerponCornerstoneMask": "Máscara Cimiento", "ogerponCornerstoneMaskTera": "Máscara Cimiento Teracristal", - "terpagos": "Normal", - "terpagosTerastal": "Teracristal", - "terpagosStellar": "Astral", + "terapagos": "Normal", + "terapagosTerastal": "Teracristal", + "terapagosStellar": "Astral", "galarDarumaka": "Modo Normal", "galarDarumakaZen": "Modo Daruma", "paldeaTaurosCombat": "Combatiente", diff --git a/src/locales/fr/pokemon-form.json b/src/locales/fr/pokemon-form.json index b1201ae0dc9..56ad2ff766b 100644 --- a/src/locales/fr/pokemon-form.json +++ b/src/locales/fr/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Masque du Fourneau Téracristal", "ogerponCornerstoneMask": "Masque de la Pierre", "ogerponCornerstoneMaskTera": "Masque de la Pierre Téracristal", - "terpagos": "Normal", - "terpagosTerastal": "Téracristal", - "terpagosStellar": "Stellaire", + "terapagos": "Normal", + "terapagosTerastal": "Téracristal", + "terapagosStellar": "Stellaire", "galarDarumaka": "Mode Normal", "galarDarumakaZen": "Mode Transe", "paldeaTaurosCombat": "Combatif", diff --git a/src/locales/it/pokemon-form.json b/src/locales/it/pokemon-form.json index e1ecb708b89..0cdd545e00d 100644 --- a/src/locales/it/pokemon-form.json +++ b/src/locales/it/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Maschera Focolare Teracristal", "ogerponCornerstoneMask": "Maschera Fondamenta", "ogerponCornerstoneMaskTera": "Maschera Fondamenta Teracristal", - "terpagos": "Normale", - "terpagosTerastal": "Teracristal", - "terpagosStellar": "Astrale", + "terapagos": "Normale", + "terapagosTerastal": "Teracristal", + "terapagosStellar": "Astrale", "galarDarumaka": "Normale", "galarDarumakaZen": "Stato Zen", "paldeaTaurosCombat": "Combattiva", diff --git a/src/locales/ja/pokemon-form.json b/src/locales/ja/pokemon-form.json index 8ef61ec2c14..b94bedc4f0b 100644 --- a/src/locales/ja/pokemon-form.json +++ b/src/locales/ja/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "かまどのめん テラスタル", "ogerponCornerstoneMask": "いしずえのめん", "ogerponCornerstoneMaskTera": "いしずえのめん テラスタル", - "terpagos": "ノーマルフォルム", - "terpagosTerastal": "テラスタルフォルム", - "terpagosStellar": "ステラフォルム", + "terapagos": "ノーマルフォルム", + "terapagosTerastal": "テラスタルフォルム", + "terapagosStellar": "ステラフォルム", "galarDarumaka": "ノーマルモード", "galarDarumakaZen": "ダルマモード", "paldeaTaurosCombat": "コンバット", diff --git a/src/locales/ko/pokemon-form.json b/src/locales/ko/pokemon-form.json index dce2fcd35cf..8175fc9549e 100644 --- a/src/locales/ko/pokemon-form.json +++ b/src/locales/ko/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "화덕의가면 테라스탈", "ogerponCornerstoneMask": "주춧돌의가면", "ogerponCornerstoneMaskTera": "주춧돌의가면 테라스탈", - "terpagos": "노말폼", - "terpagosTerastal": "테라스탈폼", - "terpagosStellar": "스텔라폼", + "terapagos": "노말폼", + "terapagosTerastal": "테라스탈폼", + "terapagosStellar": "스텔라폼", "galarDarumaka": "노말모드", "galarDarumakaZen": "달마모드", "paldeaTaurosCombat": "컴뱃종", diff --git a/src/locales/pt_BR/pokemon-form.json b/src/locales/pt_BR/pokemon-form.json index 416f09c97bf..a0b9e98fbaa 100644 --- a/src/locales/pt_BR/pokemon-form.json +++ b/src/locales/pt_BR/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "Máscara Fornalha Terastalizada", "ogerponCornerstoneMask": "Máscara Alicerce", "ogerponCornerstoneMaskTera": "Máscara Alicerce Terastalizada", - "terpagos": "Normal", - "terpagosTerastal": "Teracristal", - "terpagosStellar": "Astral", + "terapagos": "Normal", + "terapagosTerastal": "Teracristal", + "terapagosStellar": "Astral", "galarDarumaka": "Padrão", "galarDarumakaZen": "Zen", "paldeaTaurosCombat": "Combate", diff --git a/src/locales/zh_CN/pokemon-form.json b/src/locales/zh_CN/pokemon-form.json index f10c21e8851..b02fbc54dbf 100644 --- a/src/locales/zh_CN/pokemon-form.json +++ b/src/locales/zh_CN/pokemon-form.json @@ -279,9 +279,9 @@ "ogerponHearthflameMaskTera": "火灶面具太晶化", "ogerponCornerstoneMask": "础石面具", "ogerponCornerstoneMaskTera": "础石面具太晶化", - "terpagos": "普通", - "terpagosTerastal": "太晶", - "terpagosStellar": "星晶", + "terapagos": "普通", + "terapagosTerastal": "太晶", + "terapagosStellar": "星晶", "galarDarumaka": "通常", "galarDarumakaZen": "达摩", "paldeaTaurosCombat": "斗战种", diff --git a/src/locales/zh_TW/pokemon-form.json b/src/locales/zh_TW/pokemon-form.json index 104f8f5ea49..bde2840cbdc 100644 --- a/src/locales/zh_TW/pokemon-form.json +++ b/src/locales/zh_TW/pokemon-form.json @@ -1,5 +1,4 @@ { - "pikachu": "Normal", "pikachuCosplay": "換裝", "pikachuCoolCosplay": "搖滾巨星", "pikachuBeautyCosplay": "貴婦", @@ -7,9 +6,7 @@ "pikachuSmartCosplay": "博士", "pikachuToughCosplay": "面罩摔跤手", "pikachuPartner": "搭檔", - "eevee": "Normal", "eeveePartner": "搭檔", - "pichu": "Normal", "pichuSpiky": "刺刺耳", "unownA": "A", "unownB": "B", @@ -39,19 +36,13 @@ "unownZ": "Z", "unownExclamation": "!", "unownQuestion": "?", - "castform": "Normal Form", "castformSunny": "晴天", "castformRainy": "雨天", "castformSnowy": "雪天", "deoxysNormal": "普通", - "deoxysAttack": "Attack", - "deoxysDefense": "Defense", - "deoxysSpeed": "Speed", "burmyPlant": "草木蓑衣", "burmySandy": "砂土蓑衣", "burmyTrash": "垃圾蓑衣", - "cherubiOvercast": "Overcast", - "cherubiSunshine": "Sunshine", "shellosEast": "東海", "shellosWest": "西海", "rotom": "Normal", @@ -60,44 +51,22 @@ "rotomFrost": "結冰", "rotomFan": "旋轉", "rotomMow": "切割", - "dialga": "Normal", - "dialgaOrigin": "Origin", - "palkia": "Normal", - "palkiaOrigin": "Origin", "giratinaAltered": "別種", - "giratinaOrigin": "Origin", "shayminLand": "陸上", - "shayminSky": "Sky", "basculinRedStriped": "紅條紋", "basculinBlueStriped": "藍條紋", "basculinWhiteStriped": "白條紋", - "darumaka": "Standard Mode", - "darumakaZen": "Zen", "deerlingSpring": "春天", "deerlingSummer": "夏天", "deerlingAutumn": "秋天", "deerlingWinter": "冬天", "tornadusIncarnate": "化身", - "tornadusTherian": "Therian", "thundurusIncarnate": "化身", - "thundurusTherian": "Therian", "landorusIncarnate": "化身", - "landorusTherian": "Therian", - "kyurem": "Normal", - "kyuremBlack": "Black", - "kyuremWhite": "White", "keldeoOrdinary": "通常", - "keldeoResolute": "Resolute", "meloettaAria": "歌聲", "meloettaPirouette": "舞步形態", - "genesect": "Normal", - "genesectShock": "Shock Drive", - "genesectBurn": "Burn Drive", - "genesectChill": "Chill Drive", - "genesectDouse": "Douse Drive", - "froakie": "Normal", "froakieBattleBond": "牽絆變身", - "froakieAsh": "Ash", "scatterbugMeadow": "花園花紋", "scatterbugIcySnow": "冰雪花紋", "scatterbugPolar": "雪國花紋", @@ -123,7 +92,6 @@ "flabebeOrange": "橙花", "flabebeBlue": "藍花", "flabebeWhite": "白花", - "furfrou": "Natural Form", "furfrouHeart": "心形造型", "furfrouStar": "星形造型", "furfrouDiamond": "菱形造型", @@ -133,11 +101,6 @@ "furfrouLaReine": "女王造型", "furfrouKabuki": "歌舞伎造型", "furfrouPharaoh": "國王造型", - "espurrMale": "Male", - "espurrFemale": "Female", - "honedgeShiled": "Shield", - "honedgeBlade": "Blade", - "pumpkaboo": "Average Size", "pumpkabooSmall": "小尺寸", "pumpkabooLarge": "大尺寸", "pumpkabooSuper": "特大尺寸", @@ -156,29 +119,6 @@ "oricorioSensu": "輕盈輕盈風格", "rockruff": "Normal", "rockruffOwnTempo": "特殊岩狗狗", - "rockruffMidday": "Midday", - "rockruffMidnight": "Midnight", - "rockruffDusk": "Dusk", - "wishiwashi": "Solo Form", - "wishiwashiSchool": "School", - "typeNullNormal": "Type: Normal", - "typeNullFighting": "Type: Fighting", - "typeNullFlying": "Type: Flying", - "typeNullPoison": "Type: Poison", - "typeNullGround": "Type: Ground", - "typeNullRock": "Type: Rock", - "typeNullBug": "Type: Bug", - "typeNullGhost": "Type: Ghost", - "typeNullSteel": "Type: Steel", - "typeNullFire": "Type: Fire", - "typeNullWater": "Type: Water", - "typeNullGrass": "Type: Grass", - "typeNullElectric": "Type: Electric", - "typeNullPsychic": "Type: Psychic", - "typeNullIce": "Type: Ice", - "typeNullDragon": "Type: Dragon", - "typeNullDark": "Type: Dark", - "typeNullFairy": "Type: Fairy", "miniorRedMeteor": "紅色核心", "miniorOrangeMeteor": "橙色核心", "miniorYellowMeteor": "黃色核心", @@ -195,66 +135,25 @@ "miniorViolet": "紫色", "mimikyuDisguised": "化形", "mimikyuBusted": "現形", - "necrozma": "Normal", - "necrozmaDuskMane": "Dusk Mane", - "necrozmaDawnWings": "Dawn Wings", - "necrozmaUltra": "Ultra", - "magearna": "Normal", "magearnaOriginal": "500年前的顔色", - "marshadow": "Normal", "marshadowZenith": "全力", - "cramorant": "Normal", - "cramorantGulping": "Gulping Form", - "cramorantGorging": "Gorging Form", - "toxelAmped": "Amped Form", - "toxelLowkey": "Low-Key Form", "sinisteaPhony": "赝品", "sinisteaAntique": "真品", - "milceryVanillaCream": "Vanilla Cream", - "milceryRubyCream": "Ruby Cream", - "milceryMatchaCream": "Matcha Cream", - "milceryMintCream": "Mint Cream", - "milceryLemonCream": "Lemon Cream", - "milcerySaltedCream": "Salted Cream", - "milceryRubySwirl": "Ruby Swirl", - "milceryCaramelSwirl": "Caramel Swirl", - "milceryRainbowSwirl": "Rainbow Swirl", - "eiscue": "Ice Face", "eiscueNoIce": "解凍頭", "indeedeeMale": "雄性", "indeedeeFemale": "雌性", "morpekoFullBelly": "滿腹花紋", - "morpekoHangry": "Hangry", "zacianHeroOfManyBattles": "百戰勇者", - "zacianCrowned": "Crowned", "zamazentaHeroOfManyBattles": "百戰勇者", - "zamazentaCrowned": "Crowned", - "kubfuSingleStrike": "Single Strike", - "kubfuRapidStrike": "Rapid Strike", - "zarude": "Normal", "zarudeDada": "老爹", - "calyrex": "Normal", - "calyrexIce": "Ice Rider", - "calyrexShadow": "Shadow Rider", - "basculinMale": "Male", - "basculinFemale": "Female", "enamorusIncarnate": "化身", - "enamorusTherian": "Therian", - "lechonkMale": "Male", - "lechonkFemale": "Female", - "tandemausFour": "Family of Four", - "tandemausThree": "Family of Three", "squawkabillyGreenPlumage": "綠羽毛", "squawkabillyBluePlumage": "藍羽毛", "squawkabillyYellowPlumage": "黃羽毛", "squawkabillyWhitePlumage": "白羽毛", - "finizenZero": "Zero", - "finizenHero": "Hero", "tatsugiriCurly": "上弓姿勢", "tatsugiriDroopy": "下垂姿勢", "tatsugiriStretchy": "平挺姿勢", - "dunsparceTwo": "Two-Segment", - "dunsparceThree": "Three-Segment", "gimmighoulChest": "寶箱形態", "gimmighoulRoaming": "徒步形態", "koraidonApexBuild": "頂尖形態", @@ -269,21 +168,6 @@ "miraidonGlideMode":"滑翔模式", "poltchageistCounterfeit": "冒牌貨", "poltchageistArtisan": "高檔貨", - "poltchageistUnremarkable": "Unremarkable", - "poltchageistMasterpiece": "Masterpiece", - "ogerponTealMask": "Teal Mask", - "ogerponTealMaskTera": "Teal Mask Terastallized", - "ogerponWellspringMask": "Wellspring Mask", - "ogerponWellspringMaskTera": "Wellspring Mask Terastallized", - "ogerponHearthflameMask": "Hearthflame Mask", - "ogerponHearthflameMaskTera": "Hearthflame Mask Terastallized", - "ogerponCornerstoneMask": "Cornerstone Mask", - "ogerponCornerstoneMaskTera": "Cornerstone Mask Terastallized", - "terpagos": "Normal Form", - "terpagosTerastal": "Terastal", - "terpagosStellar": "Stellar", - "galarDarumaka": "Standard Mode", - "galarDarumakaZen": "Zen", "paldeaTaurosCombat": "鬥戰種", "paldeaTaurosBlaze": "火熾種", "paldeaTaurosAqua": "水瀾種" From 8044c76e71f334f4fab750dfe0b2cbaf49fda775 Mon Sep 17 00:00:00 2001 From: damocleas Date: Thu, 26 Sep 2024 12:31:04 -0400 Subject: [PATCH 02/65] [Localization] Fix for English 'Battles Won', updated tutorial # of Pokerus mons from 3 -> 5 (#4449) * Fixed 'count, number' on 'Battles Won' splash text * english tutorial * German tutorial * Spanish tutorial * French tutorial * Italian Tutorial * Japanese tutorial, needs fix * Korean Tutorial, needs fix * PT / Brazil Tutorial * zh_cn tutorial, needs check * zh_tw tutorial, needs check --- src/locales/de/tutorial.json | 4 ++-- src/locales/en/splash-messages.json | 2 +- src/locales/en/tutorial.json | 4 ++-- src/locales/es/tutorial.json | 2 +- src/locales/fr/tutorial.json | 2 +- src/locales/it/tutorial.json | 4 ++-- src/locales/ja/tutorial.json | 2 +- src/locales/ko/tutorial.json | 4 ++-- src/locales/pt_BR/tutorial.json | 2 +- src/locales/zh_CN/tutorial.json | 4 ++-- src/locales/zh_TW/tutorial.json | 4 ++-- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/locales/de/tutorial.json b/src/locales/de/tutorial.json index 9cdb94b2cac..9aa40a2d7da 100644 --- a/src/locales/de/tutorial.json +++ b/src/locales/de/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.", "menu": "In diesem Menü hast du Zugriff auf die Einstellungen.\n$Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern.\n$Das Menü verbirgt noch andere Funktionen - probier' sie gerne aus!", "starterSelect": "In diesem Bildschirm kannst du mit Z oder Leertaste deine\nStarter auswählen.\n$Sie begleiten dich am Anfang deines Abenteuers.\n$Jeder Starter hat einen Preis. Dein Team kann bis zu sechs\nMitglieder haben, solange der Gesamtpreis max. 10 beträgt.\n$Du kannst Geschlecht, Fähigkeit und Form beliebig auswählen,\nsobald du sie mindestens einmal gefangen hast.\n$Die DVs ergeben sich aus den Höchstwerten aller Pokémon,\ndie du bereits gefangen hast. \n$Es lohnt sich also, das selbe Pokémon mehrmals zu fangen!", - "pokerus": "Jeden Tag haben drei zufällige Pokémon einen lila Rahmen.\n$Wenn du eins von ihnen besitzt,\n$nimm es doch mal mit und sieh dir seinen Bericht an!", + "pokerus": "Jeden Tag haben fünf zufällige Pokémon einen lila Rahmen.\n$Wenn du eins von ihnen besitzt,\n$nimm es doch mal mit und sieh dir seinen Bericht an!", "statChange": "Statuswertveränderungen halten solange an, wie dein Pokémon auf dem Feld bleibt.\n$Pokémon werden am Anfang eines Trainerkampfes oder bei einem Arealwechsel automatisch zurückgerufen.\n$Nutze C oder Shift, um aktuelle Statuswertveränderungen anzuzeigen.", "selectItem": "Nach jedem Kampf kannst du aus 3 zufälligen Items exakt eines auswählen.\n$Es gibt u. A. Heilitems, tragbare Items und Basis-Items, die dir einen permanenten Vorteil verschaffen.\n$Die meisten tragbaren und permanenten Items werden stärker, wenn du sie mehrfach sammelst.\n$Manche Items, wie Entwicklungssteine, tauchen nur auf, wenn du sie auch nutzen kannst.\n$Mithilfe der \"Transfer\"-Option kannst du Items zwischen deinen Pokémon verschieben.\n$Sie erscheint rechts unten, sobald du einem deiner Pokémon dein Item zum Tragen gegeben hast.\n$Du kannst Heilitems auch gegen Geld erwerben. Je weiter du kommst, desto mehr stehen dir zur Auswahl.\n$Erledige deine Einkäufe als erstes, denn sobald du dein zufälliges Item auswählst, beginnt der nächste Kampf.", "eggGacha": "Hier kannst du deine Gutscheine gegen Pokémon-Eier\ntauschen.\n$Eier schlüpfen, nachdem du eine gewisse Anzahl Kämpfe\nabsolviert hast. Je seltener das Ei, desto länger dauert es.\n$Geschlüpfte Pokémon werden nicht deinem Team hinzugefügt,\nsondern deinen verfügbaren Startern.\n$In der Regel haben sie bessere DVs als in der Wildnis\ngefangene Pokémon.\n$Es gibt sogar Pokémon, die du nur aus Eiern erhalten kannst.\n$Es gibt drei Gacha-Maschinen mit je unterschiedlichen Boni,\nalso such' dir die aus, die dir am besten gefällt!" -} \ No newline at end of file +} diff --git a/src/locales/en/splash-messages.json b/src/locales/en/splash-messages.json index b7f7c737344..7397669b57d 100644 --- a/src/locales/en/splash-messages.json +++ b/src/locales/en/splash-messages.json @@ -1,5 +1,5 @@ { - "battlesWon": "Battles Won!", + "battlesWon": "{{count, number}} Battles Won!", "joinTheDiscord": "Join the Discord!", "infiniteLevels": "Infinite Levels!", "everythingIsStackable": "Everything Is Stackable*!", diff --git a/src/locales/en/tutorial.json b/src/locales/en/tutorial.json index 4c43f1fd896..b25ca777f7c 100644 --- a/src/locales/en/tutorial.json +++ b/src/locales/en/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.", "menu": "From this menu you can access the settings.\n$From the settings you can change game speed, window style, and other options.\n$There are also various other features here, so be sure to check them all!", "starterSelect": "From this screen, you can select your starters by pressing\nZ or the Space bar. These are your initial party members.\n$Each starter has a value. Your party can have up to\n6 members as long as the total does not exceed 10.\n$You can also select gender, ability, and form depending on\nthe variants you've caught or hatched.\n$The IVs for a species are also the best of every one you've\ncaught or hatched, so try to get lots of the same species!", - "pokerus": "A daily random 3 selectable starters have a purple border.\n$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!", + "pokerus": "A daily random 5 selectable starters have a purple border.\n$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!", "statChange": "Stat changes persist across battles as long as your Pokémon aren't recalled.\n$Your Pokémon are recalled before a trainer battle and before entering a new biome.\n$You can view the stat changes for any Pokémon on the field by holding C or Shift.\n$You can also view the moveset for an enemy Pokémon by holding V.\n$This only reveals moves that you've seen the Pokémon use this battle.", "selectItem": "After every battle, you are given a choice of 3 random items.\nYou may only pick one.\n$These range from consumables, to Pokémon held items, to passive permanent items.\n$Most non-consumable item effects will stack in various ways.\n$Some items will only show up if they can be used, such as evolution items.\n$You can also transfer held items between Pokémon using the transfer option.\n$The transfer option will appear in the bottom right once you have obtained a held item.\n$You may purchase consumable items with money, and a larger variety will be available the further you get.\n$Be sure to buy these before you pick your random item, as it will progress to the next battle once you do.", "eggGacha": "From this screen, you can redeem your vouchers for\nPokémon eggs.\n$Eggs have to be hatched and get closer to hatching after\nevery battle. Rarer eggs take longer to hatch.\n$Hatched Pokémon also won't be added to your party, they will\nbe added to your starters.\n$Pokémon hatched from eggs generally have better IVs than\nwild Pokémon.\n$Some Pokémon can only even be obtained from eggs.\n$There are 3 different machines to pull from with different\nbonuses, so pick the one that suits you best!" -} \ No newline at end of file +} diff --git a/src/locales/es/tutorial.json b/src/locales/es/tutorial.json index f03d1e216e4..6b8952e7ab0 100644 --- a/src/locales/es/tutorial.json +++ b/src/locales/es/tutorial.json @@ -3,7 +3,7 @@ "accessMenu": "Para acceder al menú, pulsa M o Escape cuando\ntengas el control.\n$El menú contiene los ajustes y otras funciones.", "menu": "Desde este menú podrás acceder a los ajustes.\n$Podrás cambiar la velocidad del juego, el estilo de la ventana y demás.\n$Hay más opciones, ¡así que pruébalas todas!", "starterSelect": "En esta pantalla, podrás elegir tus iniciales presionando Z\no Espacio. Estos serán tus miembros de equipo al comenzar.\n$Cada inicial tiene un valor. Tu equipo puede contener hasta 6\nmiembros mientras el valor total no pase de 10.\n$También puedes elegir su género, habilidad y forma\ndependiendo de las variantes que hayas conseguido.\n$Los IVs de los iniciales corresponderán al valor más alto de\nlos Pokémon de la misma especie que hayas obtenido.\n$¡Así que intenta conseguir muchos Pokémon de la misma\nespecie!", - "pokerus": "Cada día, 3 iniciales aleatorios tendrán un borde morado.\n$Si ves un inicial que tengas con este borde, prueba a\nañadirlo a tu equipo. ¡No olvides revisar sus datos!", + "pokerus": "Cada día, 5 iniciales aleatorios tendrán un borde morado.\n$Si ves un inicial que tengas con este borde, prueba a\nañadirlo a tu equipo. ¡No olvides revisar sus datos!", "statChange": "Los cambios de estadísticas se mantienen entre combates\nmientras que el Pokémon no vuelva a su Poké Ball.\n$Tus Pokémon vuelven a sus Poké Balls antes de combates contra entrenadores y de entrar a un nuevo bioma.\n$También puedes ver los cambios de estadísticas del Pokémon en campo manteniendo pulsado C o Shift.\n$También puedes ver los movimientos de un Pokémon enemigo manteniendo presionada la V.\n$Esto solo revela los movimientos que has visto usar al Pokémon en esta combate.", "selectItem": "Tras cada combate, tendrás la opción de elegir entre tres objetos aleatorios. Solo podrás escoger uno.\n$Estos objetos pueden ser consumibles, objetos equipables u objetos pasivos permanentes (hasta acabar la partida).\n$La mayoría de los efectos de objetos no consumibles se acumularán de varias maneras.\n$Algunos objetos solo aparecerán si pueden ser utilizados, como las piedras evolutivas.\n$También puedes transferir objetos equipados entre Pokémon, utilizando la opción de transferir.\n$La opción de transferir aparecerá en la parte inferior derecha una vez hayas obtenido un objeto equipable.\n$También puedes comprar objetos consumibles con dinero y su variedad irá aumentando según tu avance.\n$Asegúrate de comprar antes de escoger una recompensa, ya que se avanzará automáticamente al siguiente combate.", "eggGacha": "En esta pantalla podrás canjear tus vales por huevos\nde Pokémon.\n$Los huevos deben eclosionar y estarán más cerca de\nhacerlo tras cada combate.\n$Los huevos más raros tardarán más en eclosionar.\n$Los Pokémon que hayan salido del huevo no se\nañadirán a tu equipo, pero sí a tus iniciales.\n$Los Pokémon salidos de un huevo suelen tener mejores\nIVs que los Pokémon salvajes.\n$Algunos Pokémon solo pueden ser obtenidos de huevos.\n$Hay 3 máquinas diferentes entre las que elegir, cada\nuna con diferentes bonificaciones.\n$¡Así que escoge la que más te interese!" diff --git a/src/locales/fr/tutorial.json b/src/locales/fr/tutorial.json index 3236bdafea2..60fcd475b52 100644 --- a/src/locales/fr/tutorial.json +++ b/src/locales/fr/tutorial.json @@ -3,7 +3,7 @@ "accessMenu": "Accédez au menu avec M ou Échap lors de l’attente d’une\naction.\n$Il contient les paramètres et diverses fonctionnalités.", "menu": "Vous pouvez accéder aux paramètres depuis ce menu.\n$Vous pouvez entre autres y changer la vitesse du jeu ou le style de fenêtre…\n$Mais également des tonnes d’autres fonctionnalités, jetez-y un œil !", "starterSelect": "Choisissez vos starters depuis cet écran avec Z ou Espace.\nIls formeront votre équipe de départ.\n$Chacun possède une valeur. Votre équipe peut avoir\njusqu’à 6 membres, sans dépasser un cout de 10.\n$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.\n$Les IV d’un starter sont les meilleurs de tous ceux de\nson espèce déjà possédés. Obtenez-en plusieurs !", - "pokerus": "Chaque jour, 3 starters tirés aléatoirement ont un contour violet.\n$Si un starter que vous possédez l’a, essayez de l’ajouter à votre équipe. Vérifiez bien son résumé !", + "pokerus": "Chaque jour, 5 starters tirés aléatoirement ont un contour violet.\n$Si un starter que vous possédez l’a, essayez de l’ajouter à votre équipe. Vérifiez bien son résumé !", "statChange": "Les changements de stats persistent à travers\nles combats tant que le Pokémon n’est pas rappelé.\n$Vos Pokémon sont rappelés avant un combat de\nDresseur et avant d’entrer dans un nouveau biome.\n$Vous pouvez voir en combat les changements de stats\nd’un Pokémon en maintenant C ou Maj.\n$Vous pouvez également voir les capacités de l’adversaire\nen maintenant V.\n$Seules les capacités que le Pokémon a utilisées dans\nce combat sont consultables.", "selectItem": "Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre qu’un.\n$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.\n$La plupart des effets des objets non-consommables se cumuleront de diverses manières.\n$Certains objets n’apparaitront que s’ils ont une utilité immédiate, comme les objets d’évolution.\n$Vous pouvez aussi transférer des objets tenus entre\nPokémon en utilisant l’option de transfert.\n$L’option de transfert apparait en bas à droite dès\nqu’un Pokémon de l’équipe porte un objet.\n$Vous pouvez acheter des consommables avec de\nl’argent. Plus vous progressez, plus le choix sera large.\n$Choisir un des objets gratuits déclenchera le prochain\ncombat, donc faites bien tous vos achats avant.", "eggGacha": "Depuis cet écran, vous pouvez utiliser vos coupons\npour recevoir Œufs de Pokémon au hasard.\n$Les Œufs éclosent après avoir remporté un certain nombre de combats.\n$Plus ils sont rares, plus ils mettent de temps.\n$Les Pokémon éclos ne rejoindront pas votre équipe, mais seront ajoutés à vos starters.\n$Les Pokémon issus d’Œufs ont généralement de meilleurs IV que les Pokémon sauvages.\n$Certains Pokémon ne peuvent être obtenus que dans des Œufs.\n$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !" diff --git a/src/locales/it/tutorial.json b/src/locales/it/tutorial.json index 6937d59408e..0a749563a75 100644 --- a/src/locales/it/tutorial.json +++ b/src/locales/it/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "Per accedere al menu, premi M o esc.\nDal menu puoi modificare le impostazioni, controllare la wiki ed accedere a varie features.", "menu": "Da questo menu puoi accedere alle impostazioni.\n$Esse ti permettono di cambiare velocità di gioco, stile delle finestre ed altre opzioni.\n$Ci sono varie funzionalità: controlla bene e non perderti nulla!", "starterSelect": "Da questa schermata puoi selezionare il tuo starter.\nQuesti sono i membri iniziali della tua squadra.\n$Ogni starter ha un valore. Puoi avere fino a \n6 Pokèmon, avendo a disposizione un massimo di 10 punti.\n$Puoi anche selezionare genere, abilità, e forma a seconda delle\nvarianti che hai catturato o schiuso.\n$Le IVs di una specie sono le migliori rispetto a tutte quelle che hai\ncatturato o schiuso, quindi prova a catturarne il piu possibile!", - "pokerus": "Giornalmente 3 starter casuali disponibili avranno il bordo viola.\n$Se possiedi uno di questi starter,\nprova ad aggiungerlo alla squadra. Ricorda di controllarne le info!", + "pokerus": "Giornalmente 5 starter casuali disponibili avranno il bordo viola.\n$Se possiedi uno di questi starter,\nprova ad aggiungerlo alla squadra. Ricorda di controllarne le info!", "statChange": "I cambiamenti alle statistiche persistono fintanto che i tuoi pokèmon restano in campo.\n$I tuoi pokemon verranno richiamati quando incontrerai un allenatore o al cambiamento di bioma.\n$Puoi anche vedere i cambiamenti alle statistiche in corso tenendo premuto C o Shift", "selectItem": "Dopo ogni battaglia potrai scegliere tra 3 oggetti.\nPotrai prenderne solo uno.\n$Questi spaziano tra consumabili, oggetti tenuti da Pokèmon o con un effetto passivo permanente.\n$La maggior parte degli oggetti non consumabili possono accumulare i loro effetti in diversi modi.\n$Alcuni risulteranno inoltre disponibili solo se possono essere usati, come ad esempio gli oggetti evolutivi.\n$Puoi anche passare un oggetto tenuto da un Pokèmon a un altro attraverso l'opzione 'trasferisci strumento'.\n$Quest'ultima sarà disponibile solo dopo aver assegnato uno strumento ad un Pokèmon.\n$Puoi acquistare consumabili con le monete; progredendo saranno poi disponibili ulteriori oggetti.\n$Assicurati di fare un acquisto prima di selezionare un item casuale, poichè dopo aver fatto ciò passerai subito alla lotta successiva.", "eggGacha": "Da questa schermata puoi riscattare i tuoi vouchers in cambio di\nuova Pokèmon.\n$Le uova vanno schiuse, e saranno sempre più vicine alla schiusura dopo\nogni battaglia. Le uova più rare impiegheranno più battaglie per la schiusura.\n$I Pokémon schiusi non verranno aggiunti alla tua squadra, ma saranno\ninvece aggiunti ai tuoi starters.\n$I Pokémon schiusi hanno (generalmente) IVs migliori rispetto ai\n Pokémon selvatici.\n$Inoltre, alcuni Pokémon possono essere ottenuti solo tramite uova.\n$Ci sono 3 diversi macchinari con differenti\nbonus, scegli quello che preferisci!" -} \ No newline at end of file +} diff --git a/src/locales/ja/tutorial.json b/src/locales/ja/tutorial.json index a9018a53144..537076def0e 100644 --- a/src/locales/ja/tutorial.json +++ b/src/locales/ja/tutorial.json @@ -3,7 +3,7 @@ "accessMenu": "メニューを開くには 入力待ちの間に Mキー/Escを 押してください。\nメニューには 設定や 様々な機能が 含まれています。", "menu": "このメニューから 設定が 開けます。\n$設定では、ゲームの速さや ウィンドウタイプなどの オプションを 変更できます。\n$ここには 様々な機能が ありますので、\nぜひ 確認してみてください!", "starterSelect": "この画面では Zキー/空白キーを押して ポケモンが 選択できます。\n選んだポケモンは 最初の手持ちに なります。\n$各ポケモンは ポイントが ある。最大6つを 選べますが\nポケモンのポイントが 合計10を超えては いけません。\n$ポケモンを 捕まえたり タマゴからふかしたり することで\n選択できる 性別、特性、フォルムなどの 幅を広げられます。\n$個体値も 徐々に 累積して 高くなるから\n同じポケモンを たくさん 捕まえて みてください!", - "pokerus": "毎日、無作為に スターターの\n3種類には 紫色の枠が 表示されます。\n$登録された スターターの 中に いれば、\n手持ちに加えて 強さを 確認してみましょう!", + "pokerus": "毎日、無作為に スターターの\n5種類には 紫色の枠が 表示されます。\n$登録された スターターの 中に いれば、\n手持ちに加えて 強さを 確認してみましょう!", "statChange": "ポケモンを 入れ替えない限り、\n次のバトルでも 能力変化は なくなりません。\n$その代わりに、トレーナーバトルや 新しいバイオームに\n入る直前に 能力変化は 自動的に 元に戻ります。\n$Cキー/Shiftキーを 押し続けると、\n場にいるポケモンの 能力変化を 確認できます。\n$Vキーを 押し続けると、\n相手が出した技と 場の効果を 確認できます。\n$ただし 現在のバトルでの 相手ポケモンが\nすでに 使った 技のみ 表示されます。", "selectItem": "バトルが 終わるたびには、「ショップ」という\n画面で 3つのご褒美から 1つが選べます。\n$種類は 消耗品、ポケモンの持ち物や道具、\n永続的な パッシブアイテムなど 様々です。\n$ほとんどの 消耗しない 道具は\n効果が 累積されます。\n$例えば 進化アイテムなどの ご褒美は\n使用できる 場合のみに 登場します。\n$持ち物や 道具が\n手持ちポケモン画面に 移動できます。\n$持ち物や 道具が あれば、 ショップ画面の\n右下に「アイテム移行」が 表示されます。\n$ショップ画面で お金で 消耗品を 買えます。\nラウンドが進むにつれて 買えるアイテムが 増えます。\n$ご褒美を 選択すると 次の ラウンドに 進むから\nまずは 金で買える 消耗品を 買ってください。", "eggGacha": "この画面では、「タマゴクーポン」で\nポケモンのタマゴを 取得できます。\n$タマゴは ラウンドが進めるうちに ふかします。\nタマゴのふかは レア度によって 時間が かかります。\n$ふかしたポケモンは 手持ちに 加えられずに\nスターターに 登録されます。\n$ふかしたポケモンは 一般的に\n野生ポケモンよりも 高い個体値が あります。\n$あるポケモンは タマゴからしか 手に入りません。\n$各ガチャマシンは 個性的な ボーナスが あるから\n好きな方から 引いてみてください!," diff --git a/src/locales/ko/tutorial.json b/src/locales/ko/tutorial.json index b5304f43098..748b8abba52 100644 --- a/src/locales/ko/tutorial.json +++ b/src/locales/ko/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "메뉴에 액세스하려면 입력을 기다리는 동안 M 또는 Esc를 누릅니다.\n메뉴에는 설정과 다양한 기능이 포함되어 있습니다.", "menu": "이 메뉴에서 설정에 액세스할 수 있습니다.\n$설정에서 게임 속도, 윈도우 스타일 및 기타 옵션을 변경할 수 있습니다.\n$여기에는 다양한 다른 기능도 있으니 꼭 확인해보세요!", "starterSelect": "이 화면에서 Z나 스페이스바로 스타팅을 선택할 수 있습니다.\n이들은 당신의 첫 번째 파티 멤버들입니다.\n$최대 6마리의 파티로 시작할 수 있지만\n포켓몬에 따라 코스트가 있어 총합 10을 넘겨선 안 됩니다.\n$계속 잡거나 부화시켜서\n선택할 수 있는 성별, 특성, 폼 등의 폭을 넓힐 수 있습니다.\n$개체값도 점점 누적되어 높아지므로,\n같은 포켓몬을 많이 잡아보세요!", - "pokerus": "매일 랜덤 스타팅 세 종류에 보라색 테두리가 쳐집니다.\n$등록된 스타팅 중에 있다면,\n파티에 추가해서 능력치 화면을 확인해봅시다!", + "pokerus": "매일 랜덤 스타팅 다섯 종류에 보라색 테두리가 쳐집니다.\n$등록된 스타팅 중에 있다면,\n파티에 추가해서 능력치 화면을 확인해봅시다!", "statChange": "포켓몬은 교체하지 않으면 다음 전투에서도 능력치 변화가 유지됩니다.\n$대신 트레이너 배틀이나 새로운 바이옴 입장 직전에 자동으로 들여보내지게 됩니다.\n$C 또는 Shift를 꾹 눌러 현재 포켓몬의 능력치 변화를 볼 수도 있습니다.\n$V를 눌러 상대방이 사용했던 기술도 확인할 수 있습니다.\n$단, 이번 배틀에서 상대 포켓몬이 이미 사용한 기술만 나타납니다.", "selectItem": "전투가 끝날때마다 무작위 아이템 3개 중 하나를 선택하여 얻습니다.\n$종류는 소모품, 포켓몬의 지닌 도구, 영구적 패시브 아이템에 이르기까지 다양합니다.\n$대부분의 소모되지 않는 도구는 효과가 누적됩니다.\n$진화용과 같은 일부분의 아이템은 사용할 수 있는 경우에만 등장합니다.\n$지닌 도구 건네주기 기능을 사용해 포켓몬끼리 도구를 옮겨 지닐 수도 있습니다.\n$지닌 도구가 있다면 아이템 선택 화면 오른쪽 하단에 건네주기 기능이 표시됩니다.\n$돈으로 소모품을 구입할 수도 있으며, 웨이브 진행에 따라 구입 가능한 종류가 늘어납니다.\n$아이템을 선택하면 다음 웨이브로 넘어가므로, 소모품 구입을 먼저 해 주세요.", "eggGacha": "이 화면에서 포켓몬 알 바우처를\n사용해 뽑기를 할 수 있습니다.\n$알은 전투를 반복하다 보면 부화합니다.\n희귀할 수록 더 오래 걸립니다.\n$부화시킨 포켓몬은 파티에 추가되지 않고\n스타팅에 등록될 것입니다.\n$알에서 부화한 포켓몬은 일반적으로\n야생에서 잡은 포켓몬보다 더 높은 개체값을 지닙니다.\n$일부 포켓몬은 알에서만 얻을 수 있습니다.\n$각 뽑기 기계가 각각 다른 보너스를 가지고 있으므로,\n원하는 쪽을 사용해보세요!" -} \ No newline at end of file +} diff --git a/src/locales/pt_BR/tutorial.json b/src/locales/pt_BR/tutorial.json index 09199a9e31c..6c70d61e4c8 100644 --- a/src/locales/pt_BR/tutorial.json +++ b/src/locales/pt_BR/tutorial.json @@ -3,7 +3,7 @@ "accessMenu": "Para acessar o menu, pressione M ou Esc.\n$O menu contém configurações e diversas funções.", "menu": "A partir deste menu, você pode\nacessar as configurações.\n$A partir das configurações, você\npode alterar a velocidade do jogo,\n$o estilo da janela e outras opções.\n$Há também vários outros recursos aqui.\nCertifique-se de verificar todos eles!", "starterSelect": "Nesta tela, você pode selecionar seus iniciais\npressionando Z ou a barra de espaço.\n$Esses serão os primeiros membros da sua equipe.\n$Cada inicial tem um custo. Sua equipe pode ter até 6 membros,\ndesde que desde que o custo total não exceda 10.\n$Você pode escolher o gênero, a habilidade\ne até a forma do seu inicial.\n$Essas opções dependem das variantes dessa\nespécie que você já capturou ou chocou.\n$Os IVs de cada inicial são os melhores de todos os Pokémon\ndaquela espécie que você já capturou ou chocou.\n$Sempre capture vários Pokémon de todas as espécies!", - "pokerus": "Todo dia, 3 Pokémon iniciais ficam com uma borda roxa.\n$Caso veja um inicial que você possui com uma dessa, tente\nadicioná-lo a sua equipe. Lembre-se de olhar seu sumário!", + "pokerus": "Todo dia, 5 Pokémon iniciais ficam com uma borda roxa.\n$Caso veja um inicial que você possui com uma dessa, tente\nadicioná-lo a sua equipe. Lembre-se de olhar seu sumário!", "statChange": "As mudanças de atributos se mantém após a batalha desde que o Pokémon não seja trocado.\n$Seus Pokémon voltam a suas Poké Bolas antes de batalhas contra treinadores e de entrar em um novo bioma.\n$Para ver as mudanças de atributos dos Pokémon em campo, mantena C ou Shift pressionado durante a batalha.", "selectItem": "Após cada batalha, você pode escolher entre 3 itens aleatórios.\n$Você pode escolher apenas um deles.\n$Esses itens variam entre consumíveis, itens de segurar e itens passivos permanentes.\n$A maioria dos efeitos de itens não consumíveis podem ser acumulados.\n$Alguns itens só aparecerão se puderem ser usados, como os itens de evolução.\n$Você também pode transferir itens de segurar entre os Pokémon utilizando a opção \"Alterar\".\n$A opção de transferir irá aparecer no canto inferior direito assim que você obter um item de segurar.\n$Você pode comprar itens consumíveis com dinheiro, e sua variedade aumentará conforme você for mais longe.\n$Certifique-se de comprá-los antes de escolher seu item aleatório. Ao escolhê-lo, a próxima batalha começará.", "eggGacha": "Nesta tela, você pode trocar seus vouchers por ovos\nde Pokémon.\n$Ovos ficam mais próximos de chocar após cada batalha.\nOvos mais raros demoram mais tempo para chocar.\n$Pokémon chocados não serão adicionados a sua equipe,\nmas sim aos seus iniciais.\n$Pokémon chocados de ovos geralmente têm IVs melhores\ndo que Pokémon selvagens.\n$Alguns Pokémon só podem ser obtidos através de ovos.\n$Existem 3 máquinas para usar com diferentes bônus, então\nescolha a que mais lhe convém!" diff --git a/src/locales/zh_CN/tutorial.json b/src/locales/zh_CN/tutorial.json index 2f76b2ba2b5..7e6163c80e8 100644 --- a/src/locales/zh_CN/tutorial.json +++ b/src/locales/zh_CN/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "在等待输入时,按 M 或 Escape 键可访\n问菜单。菜单包含设置和各种功能。", "menu": "在此菜单中,您可以访问设置。\n$在设置中,您可以更改游戏速度、窗口样式\n和其他选项。\n$这里还有各种其他功能,请务必全部查看!", "starterSelect": "在此页面中,您可以通过按Z或空格键选择\n您的初始宝可梦。这些是您最初的队伍成员。\n$每个初始宝可梦都有一个费用值。您的队伍\n最多可以拥有6名成员,只要总费用不超过10。\n$您还可以根据您捕获或孵化的变种选择性别\n、特性和形态。\n$一个物种个体值是您捕获或孵化的所有宝可\n梦中最好的,所以尽量获得更多同种宝可梦!", - "pokerus": "每天随机3个可选的初始宝可梦会有紫色边\n框。\n$如果您看到您拥有的初始宝可梦带有紫色边\n框,请尝试将其添加到您的队伍中。请务必\n$查看其概况!", + "pokerus": "每天随机5个可选的初始宝可梦会有紫色边\n框。\n$如果您看到您拥有的初始宝可梦带有紫色边\n框,请尝试将其添加到您的队伍中。请务必\n$查看其概况!", "statChange": "只要您的宝可梦没有被召回,属性变化就会\n在战斗中持续存在。\n$在训练家战斗之前和进入新的宝可梦群落之\n前,您的宝可梦会被召回。\n$您还可以通过按住C或Shift键来查看\n场上宝可梦的能力变化。", "selectItem": "每次战斗后,您都可以从多个随机物品中\n选择其中一个。\n$这些物品包括消耗品、宝可梦携带物品和永\n久被动道具。\n$大多数非消耗品的效果会以各种方式叠加。\n$某些物品只有在可以使用时才会出现,例如\n进化物品。\n$您还可以使用转移选项在宝可梦之间转移携\n带物品。\n$一旦您获得了携带物品,转移选项就会出现\n在右下角。\n$您可以用金钱购买消耗品,并且随着您游戏\n的深入,将会有更多种类的消耗品可供选择。\n$请务必在选择随机物品之前购买这些消耗品\n因为一旦您选择,游戏就会进入下一场战斗。", "eggGacha": "在此页面中,您可以使用您的兑换券兑换宝\n可梦蛋。\n$蛋需要孵化,并且在每场战斗后都会减少孵\n化周期。稀有蛋需要更长时间才能孵化。\n$孵化的宝可梦不会被添加到您的队伍中,它\n们将被添加到您的初始宝可梦中。\n$从蛋中孵化的宝可梦通常比野生宝可梦具有\n更好的个体值。\n$有些宝可梦只能从蛋中获得。\n$有 3 种不同的扭蛋机可供选择,每种扭蛋机\n都有不同的奖励,请选择最适合您的!" -} \ No newline at end of file +} diff --git a/src/locales/zh_TW/tutorial.json b/src/locales/zh_TW/tutorial.json index 5e6e3d0ba9c..581aea5b8ca 100644 --- a/src/locales/zh_TW/tutorial.json +++ b/src/locales/zh_TW/tutorial.json @@ -3,8 +3,8 @@ "accessMenu": "在等待輸入時,按 M 或 Escape 鍵可訪\n問菜單。菜單包含設置和各種功能。", "menu": "在此菜單中,您可以訪問設置。 \n$在設置中,您可以更改遊戲速度、窗口樣式\n和其他選項。 \n$這裏還有各種其他功能,請務必全部查看!", "starterSelect": "在此頁面中,您可以選擇您的初始寶可夢。\n這些是您最初的隊伍成員。 \n$每個初始寶可夢都有一個費用值。您的隊伍\n最多可以擁有6名成員,只要總費用不超過10。 \n$您還可以根據您捕獲或孵化的變種選擇性別\n、特性和形態。 \n$一個物種個體值是您捕獲或孵化的所有寶可\n夢中最好的,所以儘量獲得更多同種寶可夢!", - "pokerus": "每天隨機3個可選的初始寶可夢會有紫色邊\n框。 \n$如果您看到您擁有的初始寶可夢帶有紫色邊\n框,請嘗試將其添加到您的隊伍中。請務必 \n$查看其概況!", + "pokerus": "每天隨機5個可選的初始寶可夢會有紫色邊\n框。 \n$如果您看到您擁有的初始寶可夢帶有紫色邊\n框,請嘗試將其添加到您的隊伍中。請務必 \n$查看其概況!", "statChange": "只要您的寶可夢沒有被召回,屬性變化就會\n在戰鬥中持續存在。 \n$在訓練家戰鬥之前和進入新的寶可夢羣落之\n前,您的寶可夢會被召回。 \n$您還可以通過按住C或Shift鍵來查看\n場上寶可夢的能力變化。", "selectItem": "每次戰鬥後,您都可以選擇 3 個隨機物品。\n您只能選擇其中一個。 \n$這些物品包括消耗品、寶可夢攜帶物品和永\n久被動道具。 \n$大多數非消耗品的效果會以各種方式疊加。 \n$某些物品只有在可以使用時纔會出現,例如\n進化物品。 \n$您還可以使用轉移選項在寶可夢之間轉移攜\n帶物品。 \n$一旦您獲得了攜帶物品,轉移選項就會出現\n在右下角。 \n$您可以用金錢購買消耗品,並且隨着您遊戲\n的深入,將會有更多種類的消耗品可供選擇。 \n$請務必在選擇隨機物品之前購買這些消耗品\n因爲一旦您選擇,遊戲就會進入下一場戰鬥。", "eggGacha": "在此頁面中,您可以使用您的兌換券兌換寶\n可夢蛋。 \n$蛋需要孵化,並且在每場戰鬥後都會減少孵\n化週期。稀有蛋需要更長時間才能孵化。 \n$孵化的寶可夢不會被添加到您的隊伍中,它\n們將被添加到您的初始寶可夢中。 \n$從蛋中孵化的寶可夢通常比野生寶可夢具有\n更好的個體值。 \n$有些寶可夢只能從蛋中獲得。 \n$有 3 種不同的扭蛋機可供選擇,每種扭蛋機\n都有不同的獎勵,請選擇最適合您的!" -} \ No newline at end of file +} From 909be8ed722090db007f4f11b3a2e83750ba8af7 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Thu, 26 Sep 2024 18:34:20 +0200 Subject: [PATCH 03/65] [Localization] Splash texts Updates (#4424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Apply suggestions from code review * Update splash-messages.json * Update splash-messages.json * Update splash-messages.json * Update src/locales/pt_BR/splash-messages.json * Update src/locales/pt_BR/splash-messages.json * Update src/locales/pt_BR/splash-messages.json * Update src/locales/pt_BR/splash-messages.json * Update src/locales/pt_BR/splash-messages.json * Apply suggestions from code review Co-authored-by: José Ricardo * Update splash-messages.json [localization] italian localization * Apply suggestions from code review Readded count * Apply suggestions from code review Removed non translated text from spanish * Removed non translated splash messages from all other languages * I missed simplified chinese * Update src/locales/es/splash-messages.json * Update src/locales/ja/splash-messages.json * Update src/locales/es/splash-messages.json * Update src/locales/ko/splash-messages.json * Update src/locales/zh_TW/splash-messages.json * Update src/locales/zh_CN/splash-messages.json --------- Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Co-authored-by: José Ricardo Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com> --- src/locales/de/splash-messages.json | 126 +++++++++++++++++++++-- src/locales/es/splash-messages.json | 11 +-- src/locales/fr/splash-messages.json | 126 +++++++++++++++++++++-- src/locales/it/splash-messages.json | 126 +++++++++++++++++++++-- src/locales/ja/splash-messages.json | 35 +------ src/locales/ko/splash-messages.json | 13 +-- src/locales/pt_BR/splash-messages.json | 132 ++++++++++++++++++++++--- src/locales/zh_CN/splash-messages.json | 8 +- src/locales/zh_TW/splash-messages.json | 8 +- 9 files changed, 478 insertions(+), 107 deletions(-) diff --git a/src/locales/de/splash-messages.json b/src/locales/de/splash-messages.json index ba126393ccb..0794d89f8ea 100644 --- a/src/locales/de/splash-messages.json +++ b/src/locales/de/splash-messages.json @@ -2,9 +2,9 @@ "battlesWon": "{{count, number}} Kämpfe gewonnen!", "joinTheDiscord": "Tritt dem Discord bei!", "infiniteLevels": "Unendliche Level!", - "everythingStacks": "Alles stapelt sich!", + "everythingIsStackable": "Alles ist stapelbar*!", "optionalSaveScumming": "Optionales Save Scumming!", - "biomes": "35 Biome!", + "biomes": "38 Biome!", "openSource": "Open Source!", "playWithSpeed": "Spiele mit fünffacher Geschwindigkeit!", "liveBugTesting": "Live-Bug-Tests!", @@ -14,9 +14,9 @@ "infiniteFusionAtHome": "Wir haben Infinite Fusionen zu Hause!", "brokenEggMoves": "Übermächtige Ei-Attacken!", "magnificent": "Herrlich!", - "mubstitute": "Melegator!", + "doPeopleReadThis": "Liest das jemand?", "thatsCrazy": "Das ist verrückt!", - "oranceJuice": "Orangensaft!", + "gottaCatchEmAll": "Komm' und schnapp sie dir!", "questionableBalancing": "Fragwürdiges Balancing!", "coolShaders": "Coole Shader!", "aiFree": "Ohne KI!", @@ -25,12 +25,120 @@ "moreAddictiveThanIntended": "Süchtig machender als beabsichtigt!", "mostlyConsistentSeeds": "Meistens konsistente Seeds!", "achievementPointsDontDoAnything": "Errungenschaftspunkte tun nichts!", - "youDoNotStartAtLevel": "Du startest nicht auf Level 2000!", - "dontTalkAboutTheManaphyEggIncident": "Wir reden nicht über den Manaphy-Ei-Vorfall!", + "nothingBeatsAJellyFilledDonut": "Donuts mit Marmelade, es gibt nicht besseres auf der Welt!", + "dontTalkAboutTheTinkatonIncident": "Wir reden nicht über den Granforgita-Vorfallt!", "alsoTryPokengine": "Versuche auch Pokéngine!", "alsoTryEmeraldRogue": "Versuche auch Emerald Rogue!", "alsoTryRadicalRed": "Versuche auch Radical Red!", "eeveeExpo": "Evoli-Expo!", - "ynoproject": "YNO-Projekt!", - "breedersInSpace": "Züchter im Weltall!" -} \ No newline at end of file + "checkOutYnoproject": "Schau dir YNOproject an!", + "breedersInSpace": "Züchter im Weltall!", + "alsoTryPokemonUnbound": "Verusch mal Pokemon Unbound!", + "tryTheJohtoDragonChallenge": "Versuch die Johto Mono-Drache Herausforderung!", + "basicReadingAbilityRecommended": "Grundlegendes Leseverständnis empfohlen!", + "shoutoutsToTheArtists": "Shoutout an die Künstler!", + "gamblingNotEncouraged": "Glücksspiel wird nicht gefördert!", + "dontForgetToTakeABreak": "Vergiss nicht eine Pause einzulegen!", + "wEvent": "Geiles Event", + "ifItsNotAccurateItsAccurate": "Hat es keine 100%ige Genauigkeit trifft es nur in 50% der Fälle.", + "everyLossIsProgressMade": "Jede Niederlage ist Fortschritt!", + "liveWoChienReaction": "Live Chongjian Reaktion:", + "itsAFeatureNotABug": "Es ist ein Feature und kein Fehler!", + "theEggsAreNotForEating": "Die Eier sind nicht zum Essen da!", + "7.8outOf10TooManyWaterBiomes": "7.8/10, Zu viel Wasser!", + "butNothingHappened": "Nichts geschieht!", + "thePowerOfScienceIsAmazing": "Die Wissenschaft kennt keine Grenzen!", + "freeToPlay": "Free To Play!", + "theresATimeAndPlaceForEverything": "Dies ist weder der rechte Ort noch die rechte Zeit dafür", + "nowWithShinierShinies": "Mit schillerenden schillernden Pokémon!", + "smilesGoForMiles": "Mit einem Lachen werden wir es machen!", + "certainlyNotDragonFree": "Sicherlich nicht ohne Drachen!", + "haveANiceDay": "Hab einen schönen Tag!", + "redacted": "[ZENSIERT]", + "hi": "hi", + "transRights": "Transrechte!", + "shinyOddsHigherThanYouThink": "Die Chance für schillernde Pokémon ist höher als du denkst!", + "noFalseTrades": "Keine falschen Pokémon-Täusche!", + "notForProfit": "Nicht profitorientiert!", + "timeForYourDailyRun": "Zeit für deinen Täglichen Durchlauf!", + "moreEggsThanADaycare": "Mehr Eier als der Pokémon-Hort!", + "disclaimerHarshSunDoesNotGiveVitaminD": "Warnung: Gleißendes Sonnenlicht liefert KEIN Vitamin D!!", + "whoNeedsAMap": "Wer braucht schon eine Karte?", + "luxrayIsNotADarkType": "Luxtra ist nicht vom Typ Unlicht!", + "selfDestructiveEncounters": "Gegner mit Selbstzerstörungstendenzen!", + "mostOptionsAreViable": "Die meisten Pokémon sind praktikable Optionen!", + "pokerogueMorse": ".--. --- -.- . .-. --- --. ..- .", + "smiley": ":)", + "beAwareOfPassives": "Achte auf passive Fähigkeiten!", + "asSeenOnTheWorldWideWeb": "Wie Im Internet zu sehen!", + "vaultinVeluzas": "Mein lieber Scholli!", + "tooManyStarters": "Zu viele Starter!", + "checkTheWiki": "Schau ins Wiki!", + "winWithYourFavorites": "Gewinne mit deinen Favoriten!", + "alsoTryPokerogueWait": "Probiere auch PokéRogue! Warte mal...", + "theWayISeeItKyogreIsSurrounded": "So wie ich das sehe ist Kyogre umzingelt...", + "tryOutHoneyGather": "Probiere es mal mit Honigmaul!", + "notForTheFaintOfHeart": "Nichts für Zartbesaitete!", + "p": "(P)", + "flipYourDeviceToEvolveInkay": "Dreh dein Gerät auf den Kopf um Iscalar zu entwickeln!", + "inArceusWeTrust": "Wir vertrauen auf Arceus", + "whyDidTheTorchicCrossTheRoad": "Warum überquerte das Flemmli die Straße?", + "goodLuck": "Viel Glück!", + "fuseWisely": "Fusioniere weise!", + "compensation": "Entschädigung?", + "prepareForTroubleAndMakeItDouble": "Jetzt gibt es Ärger...und es kommt noch härter!", + "anEggForYourTroubles": "Ein Ei für deine Mühen?", + "regirock": "ÜN ÜN ÜN", + "hereForAGoodTime": "Hier für eine gute Zeit!", + "getGoodOrDont": "Werd gut! Oder lass es!", + "checkTheSubreddit": "Schau dir das Subreddit an!", + "betterNerfGreninja": "Schwäche Quajutsu lieber ab!", + "inCaseOfUpdateClearYourCache": "Update? Cache leeren!", + "insertTextHere": "*hier Text einfügen*", + "endingEndlessNotFound": "ending_endless nicht gefunden", + "iLikeMyEggsVouchered": "Ich mag meine Eier mit Gutscheinen!", + "YOU": "DU!", + "noAddedSugar": "Ohne Zucker!", + "notSponsored": "Nicht gesponsert!", + "notRated": "Nicht eingestuft!", + "justOneMoreWaveMom": "Nur noch eine Welle, Mama!", + "saltCured": "Gepökelsalzt!", + "onlyOnPokerogueNet": "Nur auf pokerogue.net!", + "pixelPerfection": "Pixel Perfektion!", + "openSource": "Open Source!", + "probablyGood": "Wahrscheinlich ganz gut!", + "itsAMonsterHouse": "Ein Monster-Raum!", + "dontForgetYourPassword": "Vergiss dein Passwort nicht!", + "tripleTripleTripleAxel": "Dreifach- Dreifach- Dreifach-Axel!", + "questionExclamation": "?!", + "clownEncounters": "Clown Begegnungen!", + "fullOfBerries": "Voll mit Beeren!", + "limitsAreMeantToBeBrokenSometimes": "Regeln sind dazu da, gebrochen zu werden, manchmal!", + "keepItCasual": "Lässig bleiben!", + "serversProbablyWorking": "Server funktionieren wahrscheinlich!", + "mew": "Mew ist wahrscheinlich nicht unter dem LKW!", + "makeItRainAndYourProblemsGoAway": "Goldrausch und deine Probleme sind vergessen!", + "customMusicTracks": "Eigene Musiktitel!", + "youAreValid": "Du bist wertvoll!", + "number591IsLookingOff": "Nummer 591 sieht ein bisschen...", + "timeForYourDeliDelivery": "Zeit für deine Botogel-Lieferung!", + "goodFirstImpression": "Hoffe wir haben einen guten ersten Eindruck hinterlassen!", + "iPreferRarerCandies": "Ich bevorzuge Supersonderbonbons!", + "halloween": { + "pumpkabooAbout": "Irrbis überall!", + "mayContainSpiders": "Könnte Spuren von Spinnen enthalten!", + "spookyScarySkeledirge": "Gespenstisch gruselige Skelokrok!", + "gourgeistUsedTrickOrTreat": "Pumpdjinn setzt Halloween ein!", + "letsSnuggleForever": "Herzliche Knuddelkloppe!" + }, + "xmas": { + "happyHolidays": "Fröhliche Feiertage!", + "delibirdSeason": "Botogel-Saison!", + "unaffilicatedWithDelibirdServices": "Kein Zusammenhang mit Botogel-Diensten!", + "diamondsFromTheSky": "Diamantregen vom Himmel!", + "holidayStylePikachuNotIncluded": "Festtags-Pikachu nicht enthalten!" + }, + "newYears": { + "happyNewYear": "Frohes neues Jahr!" + } +} diff --git a/src/locales/es/splash-messages.json b/src/locales/es/splash-messages.json index da31d394c0f..e6d84b3aaf8 100644 --- a/src/locales/es/splash-messages.json +++ b/src/locales/es/splash-messages.json @@ -2,9 +2,8 @@ "battlesWon": "¡{{count, number}} Batallas ganadas!", "joinTheDiscord": "¡Únete al Discord!", "infiniteLevels": "¡Niveles infinitos!", - "everythingStacks": "¡Todo se acumula!", "optionalSaveScumming": "¡Trampas de guardado opcionales!", - "biomes": "¡35 biomas!", + "biomes": "¡38 biomas!", "openSource": "¡Código abierto!", "playWithSpeed": "¡Juega a velocidad 5x!", "liveBugTesting": "¡Testeo de bugs en directo!", @@ -14,9 +13,7 @@ "infiniteFusionAtHome": "¡Infinite Fusion en casa!", "brokenEggMoves": "¡Movimientos Huevo rotos!", "magnificent": "¡Magnífico!", - "mubstitute": "¡Mubstituto!", "thatsCrazy": "¡De locos!", - "oranceJuice": "¡Zumo de narancia!", "questionableBalancing": "¡Cambios en balance cuestionables!", "coolShaders": "¡Shaders impresionantes!", "aiFree": "¡Libre de IA!", @@ -25,12 +22,8 @@ "moreAddictiveThanIntended": "¡Más adictivo de lo previsto!", "mostlyConsistentSeeds": "¡Semillas CASI consistentes!", "achievementPointsDontDoAnything": "¡Los Puntos de Logro no hacen nada!", - "youDoNotStartAtLevel": "¡No empiezas al nivel 2000!", - "dontTalkAboutTheManaphyEggIncident": "¡No se habla del Incidente Manaphy!", "alsoTryPokengine": "¡Prueba también Pokéngine!", "alsoTryEmeraldRogue": "¡Prueba también Emerald Rogue!", "alsoTryRadicalRed": "¡Prueba también Radical Red!", - "eeveeExpo": "¡Eevee Expo!", - "ynoproject": "¡YNOproject!", - "breedersInSpace": "Criadores... ¡EN EL ESPACIO!" + "eeveeExpo": "¡Eevee Expo!" } diff --git a/src/locales/fr/splash-messages.json b/src/locales/fr/splash-messages.json index 2ac85680e58..a4f65896f5e 100644 --- a/src/locales/fr/splash-messages.json +++ b/src/locales/fr/splash-messages.json @@ -2,9 +2,9 @@ "battlesWon": "{{count, number}} combats gagnés !", "joinTheDiscord": "Rejoins le Discord !", "infiniteLevels": "Niveaux infinis !", - "everythingStacks": "Tout se cumule !", + "everythingIsStackable": "Tout est cumulable*!", "optionalSaveScumming": "Optional Save Scumming !", - "biomes": "35 biomes !", + "biomes": "38 biomes !", "openSource": "Open Source !", "playWithSpeed": "Joue en vitesse x5 !", "liveBugTesting": "Tests de bugs en direct !", @@ -14,9 +14,9 @@ "infiniteFusionAtHome": "Infinite Fusion, chez vous !", "brokenEggMoves": "Des Capacités Œuf craquées !", "magnificent": "Magnifique !", - "mubstitute": "Mubstitute !", + "doPeopleReadThis": "Y’a vraiment des gens qui lisent ça ?", "thatsCrazy": "C’est une dinguerie !", - "oranceJuice": "Jus d’orange !", + "gottaCatchEmAll": "Attrapez-les tous !", "questionableBalancing": "Équilibrage douteux !", "coolShaders": "Cool shaders !", "aiFree": "Garanti sans IA !", @@ -25,12 +25,120 @@ "moreAddictiveThanIntended": "Plus addictif que prévu !", "mostlyConsistentSeeds": "Des seeds à peu près stables !", "achievementPointsDontDoAnything": "Les Points de Succès servent à rien !", - "youDoNotStartAtLevel": "Ne commence pas au Niveau 2000 !", - "dontTalkAboutTheManaphyEggIncident": "Ne parle pas de l’incident de l’Œuf de Manaphy !", + "nothingBeatsAJellyFilledDonut": "Les beignets à la confiture, il n’y a que ça de vrai !", + "dontTalkAboutTheTinkatonIncident": "Ne parle pas de l’incident de Forgelina !", "alsoTryPokengine": "Essaye aussi Pokéngine !", - "alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue!", + "alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue !", "alsoTryRadicalRed": "Essaye aussi Radical Red !", "eeveeExpo": "Eevee Expo !", - "ynoproject": "YNOproject !", - "breedersInSpace": "Des Éleveurs dans l’espace !" + "checkOutYnoproject": "Jette un œil au YNOproject !", + "breedersInSpace": "Des Éleveurs dans l’espace !", + "alsoTryPokemonUnbound": "Essaye aussi Pokémon Unbound !", + "tryTheJohtoDragonChallenge": "Essaye un challenge Dragon de Johto !", + "basicReadingAbilityRecommended": "Un niveau de lecture basique est nécessaire !", + "shoutoutsToTheArtists": "S/O aux artistes !", + "gamblingNotEncouraged": "Les jeux de hasard ne sont du tout encouragés !", + "dontForgetToTakeABreak": "N’oublie pas de faire des pauses !", + "wEvent": "W Event", + "ifItsNotAccurateItsAccurate": "Loi de la précision : Si inférieure à 100, alors 50.", + "everyLossIsProgressMade": "Chaque échec est une étape !", + "liveWoChienReaction": "Réaction en direct de Chongjian :", + "itsAFeatureNotABug": "C’est pas un bug, mais une feature !", + "theEggsAreNotForEating": "Merci de ne pas graille les Œufs !", + "7.8outOf10TooManyWaterBiomes": "7,8/10, Too Many Biomes aquatiques.", + "butNothingHappened": "Mais rien ne se passe !", + "thePowerOfScienceIsAmazing": "La technologie, c’est un truc de dingue !", + "freeToPlay": "Free to Play !", + "theresATimeAndPlaceForEverything": "Ce n’est pas le moment pour ça !", + "nowWithShinierShinies": "Avec des chormatiques encore plus chromatiques !", + "smilesGoForMiles": "Sans travail, pas de médaille !", + "certainlyNotDragonFree": "Plein de Dragon !", + "haveANiceDay": "Passe une bonne journée !", + "redacted": "[SUPPRIMÉ]", + "hi": "slt", + "transRights": "Trans Rights !", + "shinyOddsHigherThanYouThink": "Le taux des chromatiques est plus haut que tu le penses !", + "noFalseTrades": "Aucun écgane frauduleux !", + "notForProfit": "Aucun profit !", + "timeForYourDailyRun": "P’tit Défi du jour ?", + "moreEggsThanADaycare": "Plus qu’une Pension Pokémon !", + "disclaimerHarshSunDoesNotGiveVitaminD": "Avetissement : Un fort soleil NE donne PAS de Vitamine D !", + "whoNeedsAMap": "Une Carte ? Là où on va on a pas besoin… de Carte", + "luxrayIsNotADarkType": "Luxray n’est pas de type Ténèbres !", + "selfDestructiveEncounters": "Des rencontres Destructrices !", + "mostOptionsAreViable": "Presque tous les choix sont viables !", + "pokerogueMorse": ".--. --- -.- . .-. --- --. ..- .", + "smiley": ":)", + "beAwareOfPassives": "Ne sois pas passif, attention aux Passifs !", + "asSeenOnTheWorldWideWeb": "Vu sur les Internets !", + "vaultinVeluzas": "Mouah ha ha !", + "tooManyStarters": "Trop de starters !", + "checkTheWiki": "Jette un œil au Wiki !", + "winWithYourFavorites": "Gagnez avec vos Favoris !", + "alsoTryPokerogueWait": "Essaye aussi PokéRogue ! Oh, attends…", + "theWayISeeItKyogreIsSurrounded": "Tout ce que je vois, c’est que Kyogre est foutu…", + "tryOutHoneyGather": "Essaye Cherche Miel !", + "notForTheFaintOfHeart": "Pas pour les âmes sensibles !", + "p": "(P)", + "flipYourDeviceToEvolveInkay": "Retournez votre appareil pour faire évoluer Sepiatop !", + "inArceusWeTrust": "En Arceus nous croyons", + "whyDidTheTorchicCrossTheRoad": "Pourquoi le Poussifeu a-t-il traversé la route ?", + "goodLuck": "Bonne chance !", + "fuseWisely": "Fusionne avec sagesse !", + "compensation": "Dédomagement ?", + "prepareForTroubleAndMakeItDouble": "Nous sommes de retour ! Pour vous jouer un mauvais tour !", + "anEggForYourTroubles": "Un Œuf pour le dérangement ?", + "regirock": "ÜN ÜN ÜN", + "hereForAGoodTime": "Ici pour passer du bon temps ", + "getGoodOrDont": "Sois doué·e ! Ou pas !", + "checkTheSubreddit": "Jette un œil au Subreddit !", + "betterNerfGreninja": "Nerf Amphinobi !", + "inCaseOfUpdateClearYourCache": "En cas de MàJ, videz votre cache !", + "insertTextHere": "insérer texte ici", + "endingEndlessNotFound": "ending_endless not found", + "iLikeMyEggsVouchered": "J’aime les Œufs couponisés !", + "YOU": "TOI !", + "noAddedSugar": "Sans sucres ajoutés !", + "notSponsored": "Non-sponsorisé !", + "notRated": "Non évalué !", + "justOneMoreWaveMom": "Allez maman, encore une vague !", + "saltCured": "Salaisoné !", + "onlyOnPokerogueNet": "Seulement sur pokerogue.net !", + "pixelPerfection": "Pixel Perfect !", + "openSource": "Open Source !", + "probablyGood": "Plutôt OK !", + "itsAMonsterHouse": "C’est une Maison de monstres !", + "dontForgetYourPassword": "Oublie pas ton mot de passe !", + "tripleTripleTripleAxel": "Triple- Triple- Triple Axel !", + "questionExclamation": "?!", + "clownEncounters": "Rencontres de Clowns !", + "fullOfBerries": "Chargé en Baies !", + "limitsAreMeantToBeBrokenSometimes": "Les limites sont fait pour être dépassées !… Parfois…", + "keepItCasual": "Mets-toi à l’aise !", + "serversProbablyWorking": "Les serveurs fonctionnent probablement !", + "mew": "Mew n’est probablement pas sous le camion !", + "makeItRainAndYourProblemsGoAway": "Ruée d’Or pour résoudre tes problèmes !", + "customMusicTracks": "Quelques musiques originales !", + "youAreValid": "Tu es VALIDE !", + "number591IsLookingOff": "N° 591 s’est fait…", + "timeForYourDeliDelivery": "Cas d’oiseaux !", + "goodFirstImpression": "On a pas dit notre Dernier Mot !", + "iPreferRarerCandies": "Je préfère les Hyper Bonbons !", + "halloween": { + "pumpkabooAbout": "Pitrouill-ard !", + "mayContainSpiders": "TW Araignées !", + "spookyScarySkeledirge": "Spooky, Scary Skelénox !", + "gourgeistUsedTrickOrTreat": "Banshitrouye utilise Halloween !", + "letsSnuggleForever": "Patati-Patattrape !" + }, + "xmas": { + "happyHolidays": "Bonne fêtes !", + "delibirdSeason": "Saison du Cadoizo !", + "unaffilicatedWithDelibirdServices": "Non, on a rien à voir avec Cadoi-zon !", + "diamondsFromTheSky": "Diamonds from the sky !", + "holidayStylePikachuNotIncluded": "Pikachu Papa Noël non-inclus !" + }, + "newYears": { + "happyNewYear": "Bonne année !" + } } diff --git a/src/locales/it/splash-messages.json b/src/locales/it/splash-messages.json index d4b411241b6..77db51d80da 100644 --- a/src/locales/it/splash-messages.json +++ b/src/locales/it/splash-messages.json @@ -2,9 +2,9 @@ "battlesWon": "{{count, number}} Battaglie Vinte!", "joinTheDiscord": "Entra nel Discord!", "infiniteLevels": "Livelli Infiniti!", - "everythingStacks": "Tutto si impila!", + "everythingIsStackable": "Tutto si impila!", "optionalSaveScumming": "Salvataggi Facoltativi!", - "biomes": "35 Biomi!", + "biomes": "38 Biomi!", "openSource": "Open Source!", "playWithSpeed": "Gioca con la velocità aumentata di 5 volte!", "liveBugTesting": "Test dei Bug in Tempo Reale!", @@ -14,9 +14,9 @@ "infiniteFusionAtHome": "Fusioni Infinite a Casa!", "brokenEggMoves": "Mosse delle Uova Rotte!", "magnificent": "Magnifico!", - "mubstitute": "Mubstitute!", + "doPeopleReadThis": "Qualcuno legge sta roba?", "thatsCrazy": "È Pazzesco!", - "oranceJuice": "Succo d'Arancia!", + "gottaCatchEmAll": "Acchiappali tutti!", "questionableBalancing": "Bilanciamento Discutibile!", "coolShaders": "Shader fantastici!", "aiFree": "Senza Intelligenza Artificiale!", @@ -25,12 +25,120 @@ "moreAddictiveThanIntended": "Crea Dipendeza più del Dovuto!", "mostlyConsistentSeeds": "Seeds Consistenti!", "achievementPointsDontDoAnything": "I Punti Obiettivo non Fanno Nulla!", - "youDoNotStartAtLevel": "Non Cominci dal Livello 2000!", - "dontTalkAboutTheManaphyEggIncident": "Non Parlare dell'Incidente dell'Uovo di Manaphy!", + "nothingBeatsAJellyFilledDonut": "Niente di meglio delle polpette di riso!", + "dontTalkAboutTheTinkatonIncident": "Non si parla dell'incidente Tinkaton!", "alsoTryPokengine": "Prova anche Pokéngine!", "alsoTryEmeraldRogue": "Prova anche Emerald Rogue!", "alsoTryRadicalRed": "Prova anche Radical Red!", "eeveeExpo": "Eevee Expo!", - "ynoproject": "YNOproject!", - "breedersInSpace": "Allevapokémon nello spazio!" -} \ No newline at end of file + "checkOutYnoproject": "Dai un'occhiata a YNOproject!", + "breedersInSpace": "Allevapokémon nello spazio!", + "alsoTryPokemonUnbound": "Prova anche Pokemon Unbound!", + "tryTheJohtoDragonChallenge": "Tenta la sfida monotipo Drago Johto!", + "basicReadingAbilityRecommended": "Competenze basilari nella lettura consigliate!", + "shoutoutsToTheArtists": "Complimenti agli artisti!", + "gamblingNotEncouraged": "Non incoraggiamo al gioco d'azzardo!", + "dontForgetToTakeABreak": "Non dimenticarti di fare una pausa!", + "wEvent": "Bell'evento", + "ifItsNotAccurateItsAccurate": "Se non ha il 100% di precisione, ne ha il 50%.", + "everyLossIsProgressMade": "Ogni sconfitta è un insegnamento!", + "liveWoChienReaction": "Live Wo-Chien Reaction:", + "itsAFeatureNotABug": "È una meccanica, non un bug!", + "theEggsAreNotForEating": "Le uova non vanno mangiate!", + "7.8outOf10TooManyWaterBiomes": "7.8 su 10, troppi biomi acquatici.", + "butNothingHappened": "Ma non succede nulla!", + "thePowerOfScienceIsAmazing": "Il potere della scienza è incredibile!", + "freeToPlay": "Free To Play!", + "theresATimeAndPlaceForEverything": "C’è un luogo e un tempo per ogni cosa!", + "nowWithShinierShinies": "Ora con shiny cromatici!", + "smilesGoForMiles": "Smiles Go for Miles!", + "certainlyNotDragonFree": "Draghi inclusi!", + "haveANiceDay": "Buona giornata!", + "redacted": "[CENSURATO]", + "hi": "ciao", + "transRights": "Diritti trans!", + "shinyOddsHigherThanYouThink": "Tasso di shiny maggiore di quello che pensi!", + "noFalseTrades": "Senza scambi farlocchi!", + "notForProfit": "Senza profitto!", + "timeForYourDailyRun": "È l'ora della run giornaliera!", + "moreEggsThanADaycare": "Più uova di una pensione!", + "disclaimerHarshSunDoesNotGiveVitaminD": "Attenzione: la luce solare accecante NON dà vitamina C!", + "whoNeedsAMap": "Chi vuole una mappa?", + "luxrayIsNotADarkType": "Luxray non è un tipo buio!", + "selfDestructiveEncounters": "Incontri autodistruggenti!", + "mostOptionsAreViable": "Ci sono tante impostazioni!", + "pokerogueMorse": ".--. --- -.- . .-. --- --. ..- .", + "smiley": ":)", + "beAwareOfPassives": "Occhio alle passive!", + "asSeenOnTheWorldWideWeb": "Proprio come sul World-Wide Web!", + "vaultinVeluzas": "Blublub!", + "tooManyStarters": "Troppi starters!", + "checkTheWiki": "Dai un'occhiata alla Wiki!", + "winWithYourFavorites": "Vinci coi tuoi preferiti!", + "alsoTryPokerogueWait": "Prova anche PokéRogue! Aspe...", + "theWayISeeItKyogreIsSurrounded": "Per come la vedo io, Kyogre è circondato...", + "tryOutHoneyGather": "Prova Mielincetta!", + "notForTheFaintOfHeart": "Sconsigliato ai deboli di cuore!", + "p": "(P)", + "flipYourDeviceToEvolveInkay": "Gira il tuo dispositivo per evolvere Inkay!", + "inArceusWeTrust": "Rendiamo grazie ad Arceus", + "whyDidTheTorchicCrossTheRoad": "Perché un Torchic attraversa la strada?", + "goodLuck": "Buona fortuna!", + "fuseWisely": "Fondi saggiamente!", + "compensation": "Ricompensa?", + "prepareForTroubleAndMakeItDouble": "Preparatevi a passare dei guai! Dei guai molto grossi!", + "anEggForYourTroubles": "Vuoi un ovetto?", + "regirock": "ÜN ÜN ÜN", + "hereForAGoodTime": "Siamo qui per divertirci!", + "getGoodOrDont": "Impara a giocare! O non farlo!", + "checkTheSubreddit": "Dai un'occhiata al subreddit!", + "betterNerfGreninja": "Nerfate Greninja!", + "inCaseOfUpdateClearYourCache": "In caso di aggiornamento, ripulite la cache!", + "insertTextHere": "inserire testo", + "endingEndlessNotFound": "ending_endless not found", + "iLikeMyEggsVouchered": "Le uova le gradisco bigliettizzate!", + "YOU": "TU!", + "noAddedSugar": "Senza zuccheri aggiunti!", + "notSponsored": "Non sponsorizzato!", + "notRated": "Non valutato!", + "justOneMoreWaveMom": "Dai mamma, solo un'altra onda!", + "saltCured": "Sotto sale!", + "onlyOnPokerogueNet": "Solo su pokerogue.net!", + "pixelPerfection": "Perfezione Pixel!", + "openSource": "Open Source!", + "probablyGood": "Probabilmente bello!", + "itsAMonsterHouse": "Covo di Pokémon!", + "dontForgetYourPassword": "Non dimenticarti la password!", + "tripleTripleTripleAxel": "Triplo- Triplo- Triplo Axel!", + "questionExclamation": "?!", + "clownEncounters": "Incontri coi pagliacci!", + "fullOfBerries": "Pieno di bacche!", + "limitsAreMeantToBeBrokenSometimes": "I limiti vanno infranti, a volte!", + "keepItCasual": "Rimani casual!", + "serversProbablyWorking": "Servers potenzialmente funzionanti!", + "mew": "Mew NON è sotto al camion!", + "makeItRainAndYourProblemsGoAway": "Corsa all'oro, alla faccia loro!", + "customMusicTracks": "Musiche custom!", + "youAreValid": "Sei valido!", + "number591IsLookingOff": "Il numero 591 non me la dice giusta...", + "timeForYourDeliDelivery": "Ora della coco-consegna!", + "goodFirstImpression": "Pronto alla Schermaglia!", + "iPreferRarerCandies": "Preferisco le caramelle più rare!", + "halloween": { + "pumpkabooAbout": "Evviva i Pumpkaboo!", + "mayContainSpiders": "Potrebbe contenere traccia di ragni!", + "spookyScarySkeledirge": "Skeledirge, spaventosi ed inquietanti!", + "gourgeistUsedTrickOrTreat": "Gourgeist usa dolcetto o scherzetto!", + "letsSnuggleForever": "Dolcesacco di botte!" + }, + "xmas": { + "happyHolidays": "Buone vacanze!", + "delibirdSeason": "La stagione di Delibird!", + "unaffilicatedWithDelibirdServices": "Non affiliati a Delibird Services!", + "diamondsFromTheSky": "Diamanti dal cielo!", + "holidayStylePikachuNotIncluded": "Pikachu stile vacanziero non incluso!" + }, + "newYears": { + "happyNewYear": "Buon anno!" + } +} diff --git a/src/locales/ja/splash-messages.json b/src/locales/ja/splash-messages.json index db3948fa2f1..552faab1f68 100644 --- a/src/locales/ja/splash-messages.json +++ b/src/locales/ja/splash-messages.json @@ -1,36 +1,3 @@ { - "battlesWon": "勝ったバトル:{{count, number}}回!", - "joinTheDiscord": "Join the Discord!", - "infiniteLevels": "Infinite Levels!", - "everythingStacks": "Everything Stacks!", - "optionalSaveScumming": "Optional Save Scumming!", - "biomes": "35 Biomes!", - "openSource": "Open Source!", - "playWithSpeed": "Play with 5x Speed!", - "liveBugTesting": "Live Bug Testing!", - "heavyInfluence": "Heavy RoR2 Influence!", - "pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!", - "nowWithMoreSalt": "Now with 33% More Salt!", - "infiniteFusionAtHome": "Infinite Fusion at Home!", - "brokenEggMoves": "Broken Egg Moves!", - "magnificent": "Magnificent!", - "mubstitute": "Mubstitute!", - "thatsCrazy": "That's Crazy!", - "oranceJuice": "Orance Juice!", - "questionableBalancing": "Questionable Balancing!", - "coolShaders": "Cool Shaders!", - "aiFree": "AI-Free!", - "suddenDifficultySpikes": "Sudden Difficulty Spikes!", - "basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!", - "moreAddictiveThanIntended": "More Addictive than Intended!", - "mostlyConsistentSeeds": "Mostly Consistent Seeds!", - "achievementPointsDontDoAnything": "Achievement Points Don't Do Anything!", - "youDoNotStartAtLevel": "You Do Not Start at Level 2000!", - "dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!", - "alsoTryPokengine": "Also Try Pokéngine!", - "alsoTryEmeraldRogue": "Also Try Emerald Rogue!", - "alsoTryRadicalRed": "Also Try Radical Red!", - "eeveeExpo": "Eevee Expo!", - "ynoproject": "YNOproject!", - "breedersInSpace": "Breeders in space!" + "battlesWon": "勝ったバトル:{{count, number}}回!" } diff --git a/src/locales/ko/splash-messages.json b/src/locales/ko/splash-messages.json index 1e89713ccde..3748ba214d9 100644 --- a/src/locales/ko/splash-messages.json +++ b/src/locales/ko/splash-messages.json @@ -2,9 +2,8 @@ "battlesWon": "{{count, number}} 전투에서 승리하세요!", "joinTheDiscord": "디스코드에 가입하세요!", "infiniteLevels": "무한한 레벨!", - "everythingStacks": "모든 것이 누적됩니다!", "optionalSaveScumming": "원한다면 세이브 노가다를!", - "biomes": "35개의 지역!", + "biomes": "38개의 지역!", "openSource": "오픈소스!", "playWithSpeed": "5배속으로 플레이해봐요!", "liveBugTesting": "라이브 버그 테스트!", @@ -13,24 +12,16 @@ "nowWithMoreSalt": "이제 33% 더 과몰입 가능!", "infiniteFusionAtHome": "집에서 인피니트 퓨전을 즐겨보세요!", "brokenEggMoves": "알기술까기!", - "magnificent": "Magnificent!", - "mubstitute": "Mubstitute!", "thatsCrazy": "미쳤습니다!", - "oranceJuice": "오렌지 쥬스!", "questionableBalancing": "의심스러운 밸런싱!", "coolShaders": "쿨한 셰이더!", - "aiFree": "AI-Free!", "suddenDifficultySpikes": "돌연사 가능!", "basedOnAnUnfinishedFlashGame": "무한 플래시게임 기반!", "moreAddictiveThanIntended": "기획보다 중독적이에요!", "mostlyConsistentSeeds": "일관성있는 랜덤 시드!", "achievementPointsDontDoAnything": "업적 포인트는 아무것도 하지 않습니다!", - "youDoNotStartAtLevel": "레벨 2000에서 시작하지 않아요!", - "dontTalkAboutTheManaphyEggIncident": "마나피 알 사건에 대해선 이야기하지 맙시다!", "alsoTryPokengine": "Pokéngine도 해봐요!", "alsoTryEmeraldRogue": "Emerald Rogue도 해봐요!", "alsoTryRadicalRed": "Radical Red도 해봐요!", - "eeveeExpo": "Eevee Expo!", - "ynoproject": "YNOproject!", "breedersInSpace": "충격!우주에 브리더 진짜 계심ㄷㄷ" -} \ No newline at end of file +} diff --git a/src/locales/pt_BR/splash-messages.json b/src/locales/pt_BR/splash-messages.json index 174dc5e4092..e586e1e5216 100644 --- a/src/locales/pt_BR/splash-messages.json +++ b/src/locales/pt_BR/splash-messages.json @@ -2,9 +2,9 @@ "battlesWon": "{{count, number}} Batalhas Ganhas!", "joinTheDiscord": "Junte-se ao Discord!", "infiniteLevels": "Níveis Infinitos!", - "everythingStacks": "Tudo Acumula!", + "everythingIsStackable": "Tudo Pode Ser Acumulado*!", "optionalSaveScumming": "Você Pode Dar F5!", - "biomes": "35 Biomas!", + "biomes": "38 Biomas!", "openSource": "Código Aberto!", "playWithSpeed": "Jogue na Velocidade 5x!", "liveBugTesting": "Testamos os Bugs Ao Vivo!", @@ -12,11 +12,11 @@ "pokemonRiskAndPokemonRain": "Pokémon Risk e Pokémon Rain!", "nowWithMoreSalt": "O Choro é Livre!", "infiniteFusionAtHome": "Infinite Fusion da Shopee!", - "brokenEggMoves": "Mov. de Ovo Apelões!", + "brokenEggMoves": "Movimentos de Ovo Apelões!", "magnificent": "Magnífico!", - "mubstitute": "Mubstituto!", + "doPeopleReadThis": "As Pessoas Leem Isso?", "thatsCrazy": "Que Doidera!", - "oranceJuice": "Suco de Laranja!", + "gottaCatchEmAll": "Temos Que Pegar!", "questionableBalancing": "Balanceamento Questionável!", "coolShaders": "Shader Maneiros!", "aiFree": "Livre de IA!", @@ -25,12 +25,120 @@ "moreAddictiveThanIntended": "Mais Viciante do que Planejado!", "mostlyConsistentSeeds": "Consistente (na Maioria das Vezes)!", "achievementPointsDontDoAnything": "Pontos de Conquista Não Fazem Nada!", - "youDoNotStartAtLevel": "Você Não Começa no Nível 2000!", - "dontTalkAboutTheManaphyEggIncident": "Não Fale do Incidente do Ovo de Manaphy!", - "alsoTryPokengine": "Também Jogue Pokéngine!", - "alsoTryEmeraldRogue": "Também Jogue Emerald Rogue!", - "alsoTryRadicalRed": "Também Jogue Radical Red!", + "nothingBeatsAJellyFilledDonut": "Nada Melhor Que Um Donut Recheado Com Geleia!", + "dontTalkAboutTheTinkatonIncident": "Não Fale Sobre o Incidente do Tinkaton!", + "alsoTryPokengine": "Jogue Também Pokéngine!", + "alsoTryEmeraldRogue": "Jogue Também Emerald Rogue!", + "alsoTryRadicalRed": "Jogue Também Radical Red!", "eeveeExpo": "Eevee Expo!", - "ynoproject": "YNOproject!", - "breedersInSpace": "Criadores de Pokémon no Espaço!" + "checkOutYnoproject": "Confira o YNOproject!", + "breedersInSpace": "Criadores de Pokémon no Espaço!", + "alsoTryPokemonUnbound": "Jogue Tambénm Pokémon Unbound!", + "tryTheJohtoDragonChallenge": "Experimente o Desafio do Dragão de Johto!", + "basicReadingAbilityRecommended": "Habilidade de Leitura Básica Recomendada!", + "shoutoutsToTheArtists": "Agradecimentos aos Artistas!", + "gamblingNotEncouraged": "Não Incentivamos o Jogo do Raikouzinho!", + "dontForgetToTakeABreak": "Não Se Esqueça de Fazer uma Pausa!", + "wEvent": "Só Jogamos Nos Eventos Shiny!", + "ifItsNotAccurateItsAccurate": "Se Não For 100% de Chance, é 50%.", + "everyLossIsProgressMade": "Toda Derrota é Progresso Feito!", + "liveWoChienReaction": "Reação Ao-Vivo de Wo-Chien:", + "itsAFeatureNotABug": "É Uma Funcionalidade, Não um Bug!", + "theEggsAreNotForEating": "Os Ovos Não São Para Comer!", + "7.8outOf10TooManyWaterBiomes": "7.8 de 10, Muitos Biomas de Água.", + "butNothingHappened": "Mas Nada Aconteceu!", + "thePowerOfScienceIsAmazing": "O Poder da Ciência é Incrível!", + "freeToPlay": "Jogue de Graça!", + "theresATimeAndPlaceForEverything": "Existe Hora e Lugar Pra Tudo!", + "nowWithShinierShinies": "Agora Com Shinies Mais Shinies!", + "smilesGoForMiles": "Sorriso Maroto!", + "certainlyNotDragonFree": "Certamente Não é Livre de Dragões!", + "haveANiceDay": "Tenha um Bom dia!", + "redacted": "Nós Não Falamos Espanhol", + "hi": "oi", + "transRights": "Direitos Trans!", + "shinyOddsHigherThanYouThink": "Chances de Shiny Maiores do Que Você Pensa!", + "noFalseTrades": "Sem Falsas Trocas!", + "notForProfit": "Sem Fins Lucrativos!", + "timeForYourDailyRun": "Hora do Seu Desafio Diário!", + "moreEggsThanADaycare": "Mais Ovos do Que Uma Creche!", + "disclaimerHarshSunDoesNotGiveVitaminD": "Aviso: Sol Intenso NÃO Fornece Vitamina D!", + "whoNeedsAMap": "Quem Precisa de Um Mapa?", + "luxrayIsNotADarkType": "Luxray Não é Tipo Sombrio!", + "selfDestructiveEncounters": "Encontros Autodestrutivos!", + "mostOptionsAreViable": "A Maioria das Opções é Viável!", + "pokerogueMorse": ".--. --- -.- . .-. --- --. ..- .", + "smiley": ":)", + "beAwareOfPassives": "Cuidado Com as Passivas!", + "asSeenOnTheWorldWideWeb": "Como Visto na World-Wide Web!", + "vaultinVeluzas": "Vaultin' Veluza!", + "tooManyStarters": "Muitos Iniciais!", + "checkTheWiki": "Confira a Wiki!", + "winWithYourFavorites": "Vença Com os Seus Favoritos!", + "alsoTryPokerogueWait": "Jogue Também PokéRogue! Pera...", + "theWayISeeItKyogreIsSurrounded": "Pelo Que Vejo, Kyogre Está Cercado...", + "tryOutHoneyGather": "Teste Honey Gather!", + "notForTheFaintOfHeart": "Não Para os Fracos de Coração!", + "p": "(P)", + "flipYourDeviceToEvolveInkay": "Vire Sua Tela Para Evoluir Inkay!", + "inArceusWeTrust": "Tudo no Tempo de Arceus", + "whyDidTheTorchicCrossTheRoad": "Por que Torchic Atravessou a Rua?", + "goodLuck": "Boa Sorte!", + "fuseWisely": "Funda Com Sabedoria!", + "compensation": "Compensação?", + "prepareForTroubleAndMakeItDouble": "Prepare-se Para Encrenca! Encrenca em Dobro!", + "anEggForYourTroubles": "Um Ovo Pelos Seus Problemas?", + "regirock": "ÜN ÜN ÜN", + "hereForAGoodTime": "Aqui Para Curtir!", + "getGoodOrDont": "Melhore! Ou Não!", + "checkTheSubreddit": "Confira o Subreddit!", + "betterNerfGreninja": "É Melhor Nerfar o Greninja!", + "inCaseOfUpdateClearYourCache": "No Caso de Atualizações, Limpe Seu Cache!", + "insertTextHere": "insira texto aqui", + "endingEndlessNotFound": "fim_infinito não encontrado", + "iLikeMyEggsVouchered": "Eu Gosto dos Meus Ovos!", + "YOU": "VOCÊ!", + "noAddedSugar": "Sem Adição de Açúcar!", + "notSponsored": "Não Somos Patrocinados!", + "notRated": "Sem Classificação Indicativa!", + "justOneMoreWaveMom": "Só Mais Uma Onda, Mãe!", + "saltCured": "Curado no Sal!", + "onlyOnPokerogueNet": "Somente em pokerogue.net!", + "pixelPerfection": "Perfeição em Pixels!", + "openSource": "Código Aberto!", + "probablyGood": "Provavelmente Bom!", + "itsAMonsterHouse": "É uma Casa Monstro!", + "dontForgetYourPassword": "Não Esqueça Sua Senha!", + "tripleTripleTripleAxel": "Triple- Triple- Triple Axel!", + "questionExclamation": "?!", + "clownEncounters": "Encontre Palhaços!", + "fullOfBerries": "Cheio de Frutas!", + "limitsAreMeantToBeBrokenSometimes": "Limites São Feitos Para Serem Quebrados, Às Vezes!", + "keepItCasual": "É Só um Lance!", + "serversProbablyWorking": "Servidores Provavelmente Funcionando!", + "mew": "Mew Provavelmente Não Está Debaixo de Um Caminhão!", + "makeItRainAndYourProblemsGoAway": "Make it Rain e Seus Problemas Somem!", + "customMusicTracks": "Trilha Sonora Customizada!", + "youAreValid": "Você é Válido!", + "number591IsLookingOff": "Número 591 Está Um Pouco...", + "timeForYourDeliDelivery": "Hora da Sua Deli-Entrega!", + "goodFirstImpression": "Esperamos Ter Deixado uma Boa First Impression!", + "iPreferRarerCandies": "Eu Prefiro Doces Raríssimos!", + "halloween": { + "pumpkabooAbout": "Pumpkaboo à Vista!", + "mayContainSpiders": "Pode Conter Aranhas!", + "spookyScarySkeledirge": "Spooky, Scary Skeledirge!", + "gourgeistUsedTrickOrTreat": "Gourgeist Usou Trick-or-Treat!", + "letsSnuggleForever": "Let's Snuggle Forever!" + }, + "xmas": { + "happyHolidays": "Boas Festas!", + "delibirdSeason": "Temporada de Delibird!", + "unaffilicatedWithDelibirdServices": "Não Afiliado Com Serviços Delibird!", + "diamondsFromTheSky": "Diamantes do Céu!", + "holidayStylePikachuNotIncluded": "Pikachu no Estilo de Feriado Não Incluso!" + }, + "newYears": { + "happyNewYear": "Feliz Ano Novo!" + } } diff --git a/src/locales/zh_CN/splash-messages.json b/src/locales/zh_CN/splash-messages.json index 24981513afe..b929662718f 100644 --- a/src/locales/zh_CN/splash-messages.json +++ b/src/locales/zh_CN/splash-messages.json @@ -2,9 +2,8 @@ "battlesWon": "{{count, number}} 场胜利!", "joinTheDiscord": "加入Discord!", "infiniteLevels": "等级无限!", - "everythingStacks": "道具全部叠加!", "optionalSaveScumming": "可用SL大法!", - "biomes": "35种地区!", + "biomes": "38种地区!", "openSource": "开源!", "playWithSpeed": "请五倍速游玩!", "liveBugTesting": "随时修复BUG!", @@ -14,9 +13,7 @@ "infiniteFusionAtHome": "无限融合家庭版!", "brokenEggMoves": "超模的蛋招式!", "magnificent": "华丽!", - "mubstitute": "替身!", "thatsCrazy": "疯狂!", - "oranceJuice": "橙汁!", "questionableBalancing": "游戏平衡性存疑!", "coolShaders": "炫酷的配色!", "aiFree": "不含AI!", @@ -25,12 +22,9 @@ "moreAddictiveThanIntended": "比你想象的更上瘾!", "mostlyConsistentSeeds": "随机数种子基本固定!", "achievementPointsDontDoAnything": "成就点数没有任何用处!", - "youDoNotStartAtLevel": "你不能第一关就改个2000级!", - "dontTalkAboutTheManaphyEggIncident": "别再提玛纳霏蛋事件了!", "alsoTryPokengine": "也玩玩看Pokéngine!", "alsoTryEmeraldRogue": "也玩玩看绿宝石肉鸽!", "alsoTryRadicalRed": "也玩玩看激进红!", "eeveeExpo": "伊布博览会!", - "ynoproject": "Yume Nikki 页游项目!", "breedersInSpace": "饲养员也能上太空?" } diff --git a/src/locales/zh_TW/splash-messages.json b/src/locales/zh_TW/splash-messages.json index 60b03549c2f..8ae0f44a673 100644 --- a/src/locales/zh_TW/splash-messages.json +++ b/src/locales/zh_TW/splash-messages.json @@ -2,9 +2,8 @@ "battlesWon": "{{count, number}} 勝利場數!", "joinTheDiscord": "加入Discord!", "infiniteLevels": "無限等級!", - "everythingStacks": "所有效果都能疊加!", "optionalSaveScumming": "可選的存檔重刷!", - "biomes": "35種生態區!", + "biomes": "38種生態區!", "openSource": "開源!", "playWithSpeed": "以5倍速度遊玩!", "liveBugTesting": "即時漏洞測試!", @@ -14,9 +13,7 @@ "infiniteFusionAtHome": "在家無限融合!", "brokenEggMoves": "破損的蛋招式!", "magnificent": "壯麗!", - "mubstitute": "替補!", "thatsCrazy": "真是瘋狂!", - "oranceJuice": "橙汁!", "questionableBalancing": "值得質疑的平衡性!", "coolShaders": "酷炫的著色器!", "aiFree": "無AI!", @@ -25,12 +22,9 @@ "moreAddictiveThanIntended": "比預期更上癮!", "mostlyConsistentSeeds": "大多數情況下一致的種子!", "achievementPointsDontDoAnything": "成就點數沒有任何用處!", - "youDoNotStartAtLevel": "你不會從2000級開始!", - "dontTalkAboutTheManaphyEggIncident": "別提那個瑪納霏蛋事件!", "alsoTryPokengine": "也試試Pokéngine!", "alsoTryEmeraldRogue": "也試試翡翠流氓!", "alsoTryRadicalRed": "也試試激進紅!", "eeveeExpo": "伊布博覽會!", - "ynoproject": "YNO專案!", "breedersInSpace": "飼養員也能上太空?" } From 9f31e36d2410a665e07ad8ba9336e14957cf866f Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:43:12 +0200 Subject: [PATCH 04/65] [Beta][Bug] Rename files so it load the correct status file in languages with a - (#4450) --- .../{statuses_ca_ES.json => statuses_ca-ES.json} | 0 .../{statuses_ca_ES.png => statuses_ca-ES.png} | Bin .../{statuses_pt_BR.json => statuses_pt-BR.json} | 0 .../{statuses_pt_BR.png => statuses_pt-BR.png} | Bin .../{statuses_zh_CN.json => statuses_zh-CN.json} | 0 .../{statuses_zh_CN.png => statuses_zh-CN.png} | Bin .../{statuses_zh_TW.json => statuses_zh-TW.json} | 0 .../{statuses_zh_TW.png => statuses_zh-TW.png} | Bin 8 files changed, 0 insertions(+), 0 deletions(-) rename public/images/{statuses_ca_ES.json => statuses_ca-ES.json} (100%) rename public/images/{statuses_ca_ES.png => statuses_ca-ES.png} (100%) rename public/images/{statuses_pt_BR.json => statuses_pt-BR.json} (100%) rename public/images/{statuses_pt_BR.png => statuses_pt-BR.png} (100%) rename public/images/{statuses_zh_CN.json => statuses_zh-CN.json} (100%) rename public/images/{statuses_zh_CN.png => statuses_zh-CN.png} (100%) rename public/images/{statuses_zh_TW.json => statuses_zh-TW.json} (100%) rename public/images/{statuses_zh_TW.png => statuses_zh-TW.png} (100%) diff --git a/public/images/statuses_ca_ES.json b/public/images/statuses_ca-ES.json similarity index 100% rename from public/images/statuses_ca_ES.json rename to public/images/statuses_ca-ES.json diff --git a/public/images/statuses_ca_ES.png b/public/images/statuses_ca-ES.png similarity index 100% rename from public/images/statuses_ca_ES.png rename to public/images/statuses_ca-ES.png diff --git a/public/images/statuses_pt_BR.json b/public/images/statuses_pt-BR.json similarity index 100% rename from public/images/statuses_pt_BR.json rename to public/images/statuses_pt-BR.json diff --git a/public/images/statuses_pt_BR.png b/public/images/statuses_pt-BR.png similarity index 100% rename from public/images/statuses_pt_BR.png rename to public/images/statuses_pt-BR.png diff --git a/public/images/statuses_zh_CN.json b/public/images/statuses_zh-CN.json similarity index 100% rename from public/images/statuses_zh_CN.json rename to public/images/statuses_zh-CN.json diff --git a/public/images/statuses_zh_CN.png b/public/images/statuses_zh-CN.png similarity index 100% rename from public/images/statuses_zh_CN.png rename to public/images/statuses_zh-CN.png diff --git a/public/images/statuses_zh_TW.json b/public/images/statuses_zh-TW.json similarity index 100% rename from public/images/statuses_zh_TW.json rename to public/images/statuses_zh-TW.json diff --git a/public/images/statuses_zh_TW.png b/public/images/statuses_zh-TW.png similarity index 100% rename from public/images/statuses_zh_TW.png rename to public/images/statuses_zh-TW.png From cb27d32fe5aed247baa2056168651a80b86d7c90 Mon Sep 17 00:00:00 2001 From: Lugiad Date: Thu, 26 Sep 2024 21:34:06 +0200 Subject: [PATCH 05/65] [Localization] Tiny French typos (#4452) * Update part-timer-dialogue.json * Update an-offer-you-cant-refuse-dialogue.json --- .../mystery-encounters/an-offer-you-cant-refuse-dialogue.json | 2 +- src/locales/fr/mystery-encounters/part-timer-dialogue.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/fr/mystery-encounters/an-offer-you-cant-refuse-dialogue.json b/src/locales/fr/mystery-encounters/an-offer-you-cant-refuse-dialogue.json index 1df9288981f..0ed54bb1eed 100644 --- a/src/locales/fr/mystery-encounters/an-offer-you-cant-refuse-dialogue.json +++ b/src/locales/fr/mystery-encounters/an-offer-you-cant-refuse-dialogue.json @@ -1,7 +1,7 @@ { "intro": "Un jeune garçon aux airs très bourgeois vous arrête.", "speaker": "Richard", - "intro_dialogue": "Bonchour-haann !$Je ne puis carrément pas ignorer que votre\n{{strongestPokemon}} m’a l’air fa-bu-leux-han !$J’ai toujours désiré posséder un tel Pokémon !$Je peux vous payer grassement,\nainsi que vous donner petite babiole-han !", + "intro_dialogue": "Bonchour-haann !$Je ne puis carrément pas ignorer que votre\n{{strongestPokemon}} m’a l’air fa-bu-leux-han !$J’ai toujours désiré posséder un tel Pokémon !$Je peux vous payer grassement,\nainsi que vous donner une petite babiole-han !", "title": "L’affaire du siècle", "description": "Un fils à papa vous offre un @[TOOLTIP_TITLE]{Charme Chroma} et {{price, money}} en échange de votre {{strongestPokemon}} !\n\nÇa semble être une bonne affaire, mais pourriez-vous supporter de priver votre équipe d’un tel atout ?", "query": "Que voulez-vous faire ?", diff --git a/src/locales/fr/mystery-encounters/part-timer-dialogue.json b/src/locales/fr/mystery-encounters/part-timer-dialogue.json index 88bb68df03e..dda680e861a 100644 --- a/src/locales/fr/mystery-encounters/part-timer-dialogue.json +++ b/src/locales/fr/mystery-encounters/part-timer-dialogue.json @@ -26,6 +26,6 @@ }, "job_complete_good": "Merci pour votre aide !\nVotre {{selectedPokemon}} nous a été d’un grand renfort !$Voici votre salaire.", "job_complete_bad": "Votre {{selectedPokemon}} nous a plutôt bien aidé !$Voici votre salaire.", - "pokemon_tired": "Votre {{selectedPokemon}} est épuisé !\nLes PP de toutes ses capacités baissent de 2 !", + "pokemon_tired": "Votre {{selectedPokemon}} est épuisé !\nLes PP de toutes ses capacités baissent à 2 !", "outro": "Reviens nous aider à l’occasion !" } From 34bf0069caeb625d226fb75ae29ce5151908ef84 Mon Sep 17 00:00:00 2001 From: podar <1999688+podarsmarty@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:55:08 -0500 Subject: [PATCH 06/65] [P1] Fixing continue menu option when game finishes (#4287) * [Bug] Fixing continue error when game finishes * migrate: `GameData.tryClearSession` to async/await * install dev: msw module * add: game-data test => tryClearSession tests --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- package-lock.json | 238 ++++++++++++++++++++++++++++++ package.json | 1 + src/@types/pokerogue-api.ts | 9 ++ src/system/game-data.ts | 63 ++++---- src/test/system/game_data.test.ts | 89 +++++++++++ 5 files changed, 372 insertions(+), 28 deletions(-) create mode 100644 src/@types/pokerogue-api.ts create mode 100644 src/test/system/game_data.test.ts diff --git a/package-lock.json b/package-lock.json index 00942ee3312..316306e3299 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "inquirer": "^11.0.2", "jsdom": "^24.0.0", "lefthook": "^1.6.12", + "msw": "^2.4.9", "phaser3spectorjs": "^0.0.8", "typedoc": "^0.26.4", "typescript": "^5.5.3", @@ -486,6 +487,37 @@ "node": ">=6.9.0" } }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -1461,6 +1493,24 @@ "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", "license": "Apache-2.0" }, + "node_modules/@mswjs/interceptors": { + "version": "0.35.8", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.8.tgz", + "integrity": "sha512-PFfqpHplKa7KMdoQdj5td03uG05VK2Ng1dG0sP4pT9h0dGSX2v9txYt/AnrzPb/vAmfyBBC0NQV7VaBEX+efgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1499,6 +1549,31 @@ "node": ">= 8" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1777,6 +1852,13 @@ "eslint": ">=8.40.0" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/eslint": { "version": "8.56.11", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", @@ -1842,6 +1924,13 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -2622,6 +2711,16 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", @@ -3740,6 +3839,16 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3797,6 +3906,13 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -4072,6 +4188,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4805,6 +4928,90 @@ "dev": true, "license": "MIT" }, + "node_modules/msw": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.9.tgz", + "integrity": "sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^3.0.0", + "@mswjs/interceptors": "^0.35.8", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.3.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/@inquirer/confirm": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.2.0.tgz", + "integrity": "sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/msw/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", @@ -4983,6 +5190,13 @@ "node": ">=0.10.0" } }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5105,6 +5319,13 @@ "dev": true, "license": "ISC" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5667,6 +5888,16 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", @@ -5674,6 +5905,13 @@ "dev": true, "license": "MIT" }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index 2109604c969..37418014d93 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "inquirer": "^11.0.2", "jsdom": "^24.0.0", "lefthook": "^1.6.12", + "msw": "^2.4.9", "phaser3spectorjs": "^0.0.8", "typedoc": "^0.26.4", "typescript": "^5.5.3", diff --git a/src/@types/pokerogue-api.ts b/src/@types/pokerogue-api.ts new file mode 100644 index 00000000000..892869968bb --- /dev/null +++ b/src/@types/pokerogue-api.ts @@ -0,0 +1,9 @@ +/** + * Pokerogue API response for path: `/savedata/session/clear` + */ +export interface PokerogueApiClearSessionData { + /** Contains the error message if any occured */ + error?: string; + /** Is `true` if the request was successfully processed */ + success?: boolean; +} diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 22a793e9aca..34c4f67328d 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -48,6 +48,7 @@ import { RUN_HISTORY_LIMIT } from "#app/ui/run-history-ui-handler"; import { applySessionDataPatches, applySettingsDataPatches, applySystemDataPatches } from "./version-converter"; import { MysteryEncounterSaveData } from "../data/mystery-encounters/mystery-encounter-save-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -1186,37 +1187,43 @@ export class GameData { }); } - tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { - return new Promise<[boolean, boolean]>(resolve => { - if (bypassLogin) { - localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); - return resolve([true, true]); + + /** + * Attempt to clear session data. After session data is removed, attempt to update user info so the menu updates + */ + async tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { + let result: [boolean, boolean] = [false, false]; + + if (bypassLogin) { + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); + result = [true, true]; + } else { + const sessionData = this.getSessionSaveData(scene); + const response = await Utils.apiPost(`savedata/session/clear?slot=${slotId}&trainerId=${this.trainerId}&secretId=${this.secretId}&clientSessionId=${clientSessionId}`, JSON.stringify(sessionData), undefined, true); + + if (response.ok) { + loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? + localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); } - updateUserInfo().then(success => { - if (success !== null && !success) { - return resolve([false, false]); + const jsonResponse: PokerogueApiClearSessionData = await response.json(); + + if (!jsonResponse.error) { + result = [true, jsonResponse.success ?? false]; + } else { + if (jsonResponse && jsonResponse.error?.startsWith("session out of date")) { + this.scene.clearPhaseQueue(); + this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); } - const sessionData = this.getSessionSaveData(scene); - Utils.apiPost(`savedata/session/clear?slot=${slotId}&trainerId=${this.trainerId}&secretId=${this.secretId}&clientSessionId=${clientSessionId}`, JSON.stringify(sessionData), undefined, true).then(response => { - if (response.ok) { - loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); - } - return response.json(); - }).then(jsonResponse => { - if (!jsonResponse.error) { - return resolve([true, jsonResponse.success as boolean]); - } - if (jsonResponse && jsonResponse.error.startsWith("session out of date")) { - this.scene.clearPhaseQueue(); - this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); - } - console.error(jsonResponse); - resolve([false, false]); - }); - }); - }); + + console.error(jsonResponse); + result = [false, false]; + } + } + + await updateUserInfo(); + + return result; } parseSessionData(dataStr: string): SessionSaveData { diff --git a/src/test/system/game_data.test.ts b/src/test/system/game_data.test.ts new file mode 100644 index 00000000000..e3550e44fff --- /dev/null +++ b/src/test/system/game_data.test.ts @@ -0,0 +1,89 @@ +import * as BattleScene from "#app/battle-scene"; +import { SessionSaveData } from "#app/system/game-data"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import GameManager from "#test/utils/gameManager"; +import { http, HttpResponse } from "msw"; +import { setupServer } from "msw/node"; +import Phaser from "phaser"; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import * as account from "../../account"; + +const apiBase = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8001"; + +export const server = setupServer(); + +describe("System - Game Data", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + server.listen(); + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterAll(() => { + server.close(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.SPLASH]) + .battleType("single") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + afterEach(() => { + server.resetHandlers(); + game.phaseInterceptor.restoreOg(); + }); + + describe("tryClearSession", () => { + beforeEach(() => { + vi.spyOn(BattleScene, "bypassLogin", "get").mockReturnValue(false); + vi.spyOn(game.scene.gameData, "getSessionSaveData").mockReturnValue({} as SessionSaveData); + vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]); + }); + + it("should return [true, true] if bypassLogin is true", async () => { + vi.spyOn(BattleScene, "bypassLogin", "get").mockReturnValue(true); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, true]); + }); + + it("should return [true, true] if successful", async () => { + server.use(http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ success: true }))); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, true]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + + it("should return [true, false] if not successful", async () => { + server.use(http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ success: false }))); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, false]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + + it("should return [false, false] session is out of date", async () => { + server.use( + http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ error: "session out of date" })) + ); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([false, false]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + }); +}); From 2aeacc6de994bad378fc588af0794b066432003b Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:00:25 -0500 Subject: [PATCH 07/65] September egg move changes (#4453) --- src/data/egg-moves.ts | 180 +++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 3e58f993df2..1070b642eab 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -5,12 +5,12 @@ import { Species } from "#enums/species"; export const speciesEggMoves = { - [Species.BULBASAUR]: [ Moves.SAPPY_SEED, Moves.SLUDGE_WAVE, Moves.EARTH_POWER, Moves.MATCHA_GOTCHA ], + [Species.BULBASAUR]: [ Moves.SAPPY_SEED, Moves.MALIGNANT_CHAIN, Moves.EARTH_POWER, Moves.MATCHA_GOTCHA ], [Species.CHARMANDER]: [ Moves.DRAGON_DANCE, Moves.BITTER_BLADE, Moves.EARTH_POWER, Moves.OBLIVION_WING ], [Species.SQUIRTLE]: [ Moves.FREEZE_DRY, Moves.SHORE_UP, Moves.BOUNCY_BUBBLE, Moves.ORIGIN_PULSE ], [Species.CATERPIE]: [ Moves.SANDSEAR_STORM, Moves.SILK_TRAP, Moves.TWIN_BEAM, Moves.BLEAKWIND_STORM ], - [Species.WEEDLE]: [ Moves.THOUSAND_ARROWS, Moves.SWORDS_DANCE, Moves.ATTACK_ORDER, Moves.NOXIOUS_TORQUE ], - [Species.PIDGEY]: [ Moves.WILDBOLT_STORM, Moves.SANDSEAR_STORM, Moves.CALM_MIND, Moves.BOOMBURST ], + [Species.WEEDLE]: [ Moves.THOUSAND_ARROWS, Moves.NOXIOUS_TORQUE, Moves.ATTACK_ORDER, Moves.VICTORY_DANCE ], + [Species.PIDGEY]: [ Moves.WILDBOLT_STORM, Moves.SANDSEAR_STORM, Moves.NASTY_PLOT, Moves.BOOMBURST ], [Species.RATTATA]: [ Moves.HYPER_FANG, Moves.PSYCHIC_FANGS, Moves.FIRE_FANG, Moves.EXTREME_SPEED ], [Species.SPEAROW]: [ Moves.FLOATY_FALL, Moves.EXTREME_SPEED, Moves.TIDY_UP, Moves.TRIPLE_ARROWS ], [Species.EKANS]: [ Moves.NOXIOUS_TORQUE, Moves.DRAGON_DANCE, Moves.SLACK_OFF, Moves.SHED_TAIL ], @@ -21,46 +21,46 @@ export const speciesEggMoves = { [Species.ZUBAT]: [ Moves.FLOATY_FALL, Moves.DIRE_CLAW, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], [Species.ODDISH]: [ Moves.SLUDGE_BOMB, Moves.FIERY_DANCE, Moves.STRENGTH_SAP, Moves.SPORE ], [Species.PARAS]: [ Moves.LEECH_LIFE, Moves.HORN_LEECH, Moves.CRABHAMMER, Moves.SAPPY_SEED ], - [Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.MOONLIGHT, Moves.EARTH_POWER, Moves.MYSTICAL_POWER ], + [Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.TOXIC_THREAD, Moves.EARTH_POWER, Moves.STORED_POWER ], [Species.DIGLETT]: [ Moves.TRIPLE_DIVE, Moves.SWORDS_DANCE, Moves.TRIPLE_AXEL, Moves.HEADLONG_RUSH ], - [Species.MEOWTH]: [ Moves.COVET, Moves.SWORDS_DANCE, Moves.DOUBLE_KICK, Moves.TAIL_SLAP ], - [Species.PSYDUCK]: [ Moves.SPLISHY_SPLASH, Moves.AQUA_STEP, Moves.AURA_SPHERE, Moves.MYSTICAL_POWER ], - [Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.PLAY_ROUGH, Moves.METEOR_MASH, Moves.NO_RETREAT ], + [Species.MEOWTH]: [ Moves.HEART_STAMP, Moves.SWORDS_DANCE, Moves.SIZZLY_SLIDE, Moves.TAIL_SLAP ], + [Species.PSYDUCK]: [ Moves.FROST_BREATH, Moves.AQUA_STEP, Moves.MYSTICAL_POWER, Moves.BOUNCY_BUBBLE ], + [Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.NO_RETREAT ], [Species.GROWLITHE]: [ Moves.ZING_ZAP, Moves.PARTING_SHOT, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.POLIWAG]: [ Moves.SLACK_OFF, Moves.WILDBOLT_STORM, Moves.DRAIN_PUNCH, Moves.SURGING_STRIKES ], - [Species.ABRA]: [ Moves.AURA_SPHERE, Moves.BADDY_BAD, Moves.THUNDERBOLT, Moves.PSYSTRIKE ], + [Species.ABRA]: [ Moves.AURA_SPHERE, Moves.BADDY_BAD, Moves.ICE_BEAM, Moves.PSYSTRIKE ], [Species.MACHOP]: [ Moves.COMBAT_TORQUE, Moves.METEOR_MASH, Moves.MOUNTAIN_GALE, Moves.FISSURE ], [Species.BELLSPROUT]: [ Moves.SOLAR_BLADE, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.VICTORY_DANCE ], [Species.TENTACOOL]: [ Moves.BANEFUL_BUNKER, Moves.STRENGTH_SAP, Moves.BOUNCY_BUBBLE, Moves.MALIGNANT_CHAIN ], - [Species.GEODUDE]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.SHORE_UP, Moves.HEAD_SMASH ], + [Species.GEODUDE]: [ Moves.FLARE_BLITZ, Moves.HEAD_SMASH, Moves.SHORE_UP, Moves.SHELL_SMASH ], [Species.PONYTA]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.SWORDS_DANCE, Moves.VOLT_TACKLE ], [Species.SLOWPOKE]: [ Moves.BOUNCY_BUBBLE, Moves.FLAMETHROWER, Moves.MYSTICAL_POWER, Moves.SHED_TAIL ], - [Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.BODY_PRESS, Moves.ICE_BEAM, Moves.THUNDERCLAP ], - [Species.FARFETCHD]: [ Moves.IVY_CUDGEL, Moves.TRIPLE_ARROWS, Moves.ROOST, Moves.VICTORY_DANCE ], + [Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.FLAMETHROWER, Moves.ICE_BEAM, Moves.THUNDERCLAP ], + [Species.FARFETCHD]: [ Moves.IVY_CUDGEL, Moves.TRIPLE_ARROWS, Moves.DRILL_RUN, Moves.VICTORY_DANCE ], [Species.DODUO]: [ Moves.TRIPLE_AXEL, Moves.MULTI_ATTACK, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ], [Species.SEEL]: [ Moves.FREEZE_DRY, Moves.BOUNCY_BUBBLE, Moves.SLACK_OFF, Moves.STEAM_ERUPTION ], [Species.GRIMER]: [ Moves.SUCKER_PUNCH, Moves.CURSE, Moves.STRENGTH_SAP, Moves.NOXIOUS_TORQUE ], [Species.SHELLDER]: [ Moves.ROCK_BLAST, Moves.WATER_SHURIKEN, Moves.BANEFUL_BUNKER, Moves.BONE_RUSH ], [Species.GASTLY]: [ Moves.SLUDGE_BOMB, Moves.AURA_SPHERE, Moves.NASTY_PLOT, Moves.ASTRAL_BARRAGE ], - [Species.ONIX]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.HEAVY_SLAM, Moves.DIAMOND_STORM ], + [Species.ONIX]: [ Moves.SHORE_UP, Moves.THOUSAND_WAVES, Moves.COIL, Moves.DIAMOND_STORM ], [Species.DROWZEE]: [ Moves.BADDY_BAD, Moves.STRENGTH_SAP, Moves.LUMINA_CRASH, Moves.DARK_VOID ], - [Species.KRABBY]: [ Moves.FIRE_LASH, Moves.PLAY_ROUGH, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ], - [Species.VOLTORB]: [ Moves.NASTY_PLOT, Moves.OVERHEAT, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], + [Species.KRABBY]: [ Moves.DIRE_CLAW, Moves.JET_PUNCH, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ], + [Species.VOLTORB]: [ Moves.NASTY_PLOT, Moves.FUSION_FLARE, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], [Species.EXEGGCUTE]: [ Moves.FICKLE_BEAM, Moves.APPLE_ACID, Moves.TRICK_ROOM, Moves.LUMINA_CRASH ], [Species.CUBONE]: [ Moves.HEAD_SMASH, Moves.WOOD_HAMMER, Moves.SHADOW_SNEAK, Moves.BITTER_BLADE ], - [Species.LICKITUNG]: [ Moves.BODY_SLAM, Moves.FIRE_LASH, Moves.GRAV_APPLE, Moves.MILK_DRINK ], + [Species.LICKITUNG]: [ Moves.CRUSH_GRIP, Moves.FIRE_LASH, Moves.SLACK_OFF, Moves.MAGICAL_TORQUE ], [Species.KOFFING]: [ Moves.SCALD, Moves.RECOVER, Moves.BODY_PRESS, Moves.MALIGNANT_CHAIN ], [Species.RHYHORN]: [ Moves.SHORE_UP, Moves.ICE_HAMMER, Moves.ACCELEROCK, Moves.HEAD_SMASH ], [Species.TANGELA]: [ Moves.STRENGTH_SAP, Moves.SNAP_TRAP, Moves.PARTING_SHOT, Moves.SAPPY_SEED ], [Species.KANGASKHAN]: [ Moves.POWER_UP_PUNCH, Moves.TRAILBLAZE, Moves.FACADE, Moves.SEISMIC_TOSS ], [Species.HORSEA]: [ Moves.SNIPE_SHOT, Moves.FROST_BREATH, Moves.HURRICANE, Moves.SPACIAL_REND ], - [Species.GOLDEEN]: [ Moves.DRILL_RUN, Moves.FLIP_TURN, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ], + [Species.GOLDEEN]: [ Moves.GLACIAL_LANCE, Moves.SUPERCELL_SLAM, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ], [Species.STARYU]: [ Moves.CALM_MIND, Moves.BOUNCY_BUBBLE, Moves.MOONBLAST, Moves.MYSTICAL_POWER ], [Species.SCYTHER]: [ Moves.MIGHTY_CLEAVE, Moves.BUG_BITE, Moves.STORM_THROW, Moves.DOUBLE_IRON_BASH ], - [Species.PINSIR]: [ Moves.EARTHQUAKE, Moves.LEECH_LIFE, Moves.CLOSE_COMBAT, Moves.EXTREME_SPEED ], - [Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.BLAZING_TORQUE, Moves.LIQUIDATION, Moves.COMBAT_TORQUE ], + [Species.PINSIR]: [ Moves.HEADLONG_RUSH, Moves.LEECH_LIFE, Moves.CRUSH_GRIP, Moves.EXTREME_SPEED ], + [Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.LIQUIDATION, Moves.COMBAT_TORQUE ], [Species.MAGIKARP]: [ Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.DRAGON_ASCENT, Moves.SURGING_STRIKES ], - [Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.SHELL_SMASH, Moves.STEAM_ERUPTION ], + [Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.SCALD, Moves.SHELL_SMASH ], [Species.DITTO]: [ Moves.MIMIC, Moves.SKETCH, Moves.METRONOME, Moves.IMPRISON ], [Species.EEVEE]: [ Moves.WISH, Moves.NO_RETREAT, Moves.ZIPPY_ZAP, Moves.BOOMBURST ], [Species.PORYGON]: [ Moves.THUNDERCLAP, Moves.AURA_SPHERE, Moves.FLAMETHROWER, Moves.TECHNO_BLAST ], @@ -68,56 +68,56 @@ export const speciesEggMoves = { [Species.KABUTO]: [ Moves.CEASELESS_EDGE, Moves.HIGH_HORSEPOWER, Moves.TRIPLE_DIVE, Moves.MIGHTY_CLEAVE ], [Species.AERODACTYL]: [ Moves.FLOATY_FALL, Moves.FLARE_BLITZ, Moves.SWORDS_DANCE, Moves.MIGHTY_CLEAVE ], [Species.ARTICUNO]: [ Moves.EARTH_POWER, Moves.CALM_MIND, Moves.AURORA_VEIL, Moves.AEROBLAST ], - [Species.ZAPDOS]: [ Moves.WEATHER_BALL, Moves.CALM_MIND, Moves.SANDSEAR_STORM, Moves.ELECTRO_SHOT ], + [Species.ZAPDOS]: [ Moves.BLEAKWIND_STORM, Moves.CALM_MIND, Moves.SANDSEAR_STORM, Moves.ELECTRO_SHOT ], [Species.MOLTRES]: [ Moves.SCORCHING_SANDS, Moves.CALM_MIND, Moves.AEROBLAST, Moves.TORCH_SONG ], [Species.DRATINI]: [ Moves.DRAGON_HAMMER, Moves.CRUSH_GRIP, Moves.FIRE_LASH, Moves.GIGATON_HAMMER ], [Species.MEWTWO]: [ Moves.METEOR_MASH, Moves.MOONBLAST, Moves.THUNDEROUS_KICK, Moves.PHOTON_GEYSER ], [Species.MEW]: [ Moves.PHOTON_GEYSER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE, Moves.SHELL_SMASH ], [Species.CHIKORITA]: [ Moves.SAPPY_SEED, Moves.STONE_AXE, Moves.DRAGON_DANCE, Moves.SPORE ], - [Species.CYNDAQUIL]: [ Moves.NASTY_PLOT, Moves.SCORCHING_SANDS, Moves.FIERY_DANCE, Moves.ELECTRO_DRIFT ], + [Species.CYNDAQUIL]: [ Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.FIERY_DANCE, Moves.ELECTRO_DRIFT ], [Species.TOTODILE]: [ Moves.THUNDER_PUNCH, Moves.DRAGON_DANCE, Moves.TRIPLE_AXEL, Moves.FISHIOUS_REND ], - [Species.SENTRET]: [ Moves.TIDY_UP, Moves.THIEF, Moves.NUZZLE, Moves.EXTREME_SPEED ], + [Species.SENTRET]: [ Moves.TIDY_UP, Moves.FAKE_OUT, Moves.NUZZLE, Moves.EXTREME_SPEED ], [Species.HOOTHOOT]: [ Moves.CALM_MIND, Moves.ESPER_WING, Moves.AEROBLAST, Moves.BOOMBURST ], [Species.LEDYBA]: [ Moves.POLLEN_PUFF, Moves.THIEF, Moves.PARTING_SHOT, Moves.SPORE ], [Species.SPINARAK]: [ Moves.PARTING_SHOT, Moves.ATTACK_ORDER, Moves.GASTRO_ACID, Moves.STRENGTH_SAP ], [Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.THUNDER_CAGE, Moves.TAIL_GLOW ], - [Species.PICHU]: [ Moves.RISING_VOLTAGE, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.THUNDERCLAP ], + [Species.PICHU]: [ Moves.MOONBLAST, Moves.WAVE_CRASH, Moves.AIR_SLASH, Moves.AURA_WHEEL ], [Species.CLEFFA]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.WISH, Moves.LIGHT_OF_RUIN ], [Species.IGGLYBUFF]: [ Moves.DRAIN_PUNCH, Moves.GRAV_APPLE, Moves.SOFT_BOILED, Moves.EXTREME_SPEED ], [Species.TOGEPI]: [ Moves.SCORCHING_SANDS, Moves.ROOST, Moves.RELIC_SONG, Moves.FIERY_DANCE ], - [Species.NATU]: [ Moves.AEROBLAST, Moves.ROOST, Moves.CALM_MIND, Moves.LUMINA_CRASH ], + [Species.NATU]: [ Moves.AEROBLAST, Moves.ROOST, Moves.MOONBLAST, Moves.LUMINA_CRASH ], [Species.MAREEP]: [ Moves.ICE_BEAM, Moves.PARABOLIC_CHARGE, Moves.CORE_ENFORCER, Moves.TAIL_GLOW ], [Species.HOPPIP]: [ Moves.FLOATY_FALL, Moves.STRENGTH_SAP, Moves.SAPPY_SEED, Moves.SPORE ], [Species.AIPOM]: [ Moves.TIDY_UP, Moves.STORM_THROW, Moves.FAKE_OUT, Moves.POPULATION_BOMB ], - [Species.SUNKERN]: [ Moves.SPORE, Moves.SAPPY_SEED, Moves.FIERY_DANCE, Moves.HYDRO_STEAM ], + [Species.SUNKERN]: [ Moves.SPORE, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.HYDRO_STEAM ], [Species.YANMA]: [ Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.HEAT_WAVE, Moves.BLEAKWIND_STORM ], [Species.WOOPER]: [ Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.CURSE, Moves.SURGING_STRIKES ], [Species.MURKROW]: [ Moves.TRIPLE_ARROWS, Moves.FLOATY_FALL, Moves.TIDY_UP, Moves.WICKED_BLOW ], [Species.MISDREAVUS]: [ Moves.TAKE_HEART, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], [Species.UNOWN]: [ Moves.NATURE_POWER, Moves.COSMIC_POWER, Moves.ANCIENT_POWER, Moves.MYSTICAL_POWER ], [Species.GIRAFARIG]: [ Moves.MYSTICAL_POWER, Moves.NIGHT_DAZE, Moves.RECOVER, Moves.BOOMBURST ], - [Species.PINECO]: [ Moves.METAL_BURST, Moves.LUNGE, Moves.BODY_PRESS, Moves.SHORE_UP ], - [Species.DUNSPARCE]: [ Moves.BODY_SLAM, Moves.MAGICAL_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ], + [Species.PINECO]: [ Moves.METAL_BURST, Moves.SHORE_UP, Moves.BODY_PRESS, Moves.DIAMOND_STORM ], + [Species.DUNSPARCE]: [ Moves.WICKED_TORQUE, Moves.MAGICAL_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ], [Species.GLIGAR]: [ Moves.FLOATY_FALL, Moves.THOUSAND_WAVES, Moves.ROOST, Moves.MIGHTY_CLEAVE ], [Species.SNUBBULL]: [ Moves.FACADE, Moves.EARTHQUAKE, Moves.SWORDS_DANCE, Moves.EXTREME_SPEED ], [Species.QWILFISH]: [ Moves.BARB_BARRAGE, Moves.BANEFUL_BUNKER, Moves.KNOCK_OFF, Moves.FISHIOUS_REND ], [Species.SHUCKLE]: [ Moves.STUFF_CHEEKS, Moves.HEAL_ORDER, Moves.BODY_PRESS, Moves.SALT_CURE ], [Species.HERACROSS]: [ Moves.ROCK_BLAST, Moves.FIRST_IMPRESSION, Moves.ICICLE_SPEAR, Moves.DRAGON_DANCE ], [Species.SNEASEL]: [ Moves.DIRE_CLAW, Moves.STORM_THROW, Moves.TRIPLE_AXEL, Moves.WICKED_BLOW ], - [Species.TEDDIURSA]: [ Moves.MOUNTAIN_GALE, Moves.RAGING_BULL, Moves.SLACK_OFF, Moves.PRECIPICE_BLADES ], + [Species.TEDDIURSA]: [ Moves.MOUNTAIN_GALE, Moves.FAKE_OUT, Moves.SLACK_OFF, Moves.PRECIPICE_BLADES ], [Species.SLUGMA]: [ Moves.BURNING_BULWARK, Moves.POWER_GEM, Moves.SOLAR_BEAM, Moves.MAGMA_STORM ], [Species.SWINUB]: [ Moves.SLACK_OFF, Moves.LANDS_WRATH, Moves.MIGHTY_CLEAVE, Moves.GLACIAL_LANCE ], [Species.CORSOLA]: [ Moves.SCALD, Moves.FREEZE_DRY, Moves.STRENGTH_SAP, Moves.SALT_CURE ], [Species.REMORAID]: [ Moves.WATER_SHURIKEN, Moves.TAKE_HEART, Moves.SHELL_SIDE_ARM, Moves.BOUNCY_BUBBLE ], - [Species.DELIBIRD]: [ Moves.DRILL_RUN, Moves.FLOATY_FALL, Moves.VICTORY_DANCE, Moves.GLACIAL_LANCE ], + [Species.DELIBIRD]: [ Moves.BONEMERANG, Moves.FLOATY_FALL, Moves.VICTORY_DANCE, Moves.GLACIAL_LANCE ], [Species.SKARMORY]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.BEAK_BLAST ], - [Species.HOUNDOUR]: [ Moves.HEAT_WAVE, Moves.FIERY_WRATH, Moves.SOLAR_BEAM, Moves.HYDRO_STEAM ], + [Species.HOUNDOUR]: [ Moves.MOONLIGHT, Moves.FIERY_WRATH, Moves.SECRET_SWORD, Moves.HYDRO_STEAM ], [Species.PHANPY]: [ Moves.SHORE_UP, Moves.SWORDS_DANCE, Moves.ICICLE_CRASH, Moves.COLLISION_COURSE ], - [Species.STANTLER]: [ Moves.THUNDEROUS_KICK, Moves.HYPER_VOICE, Moves.BULK_UP, Moves.PHOTON_GEYSER ], + [Species.STANTLER]: [ Moves.THUNDEROUS_KICK, Moves.PHOTON_GEYSER, Moves.SWORDS_DANCE, Moves.BOOMBURST ], [Species.SMEARGLE]: [ Moves.CONVERSION, Moves.BURNING_BULWARK, Moves.SALT_CURE, Moves.DARK_VOID ], [Species.TYROGUE]: [ Moves.VICTORY_DANCE, Moves.THUNDEROUS_KICK, Moves.METEOR_MASH, Moves.WICKED_BLOW ], [Species.SMOOCHUM]: [ Moves.EXPANDING_FORCE, Moves.AURA_SPHERE, Moves.FREEZE_DRY, Moves.QUIVER_DANCE ], - [Species.ELEKID]: [ Moves.BLAZING_TORQUE, Moves.TIDY_UP, Moves.MOUNTAIN_GALE, Moves.ZIPPY_ZAP ], + [Species.ELEKID]: [ Moves.FIRE_LASH, Moves.ZING_ZAP, Moves.MOUNTAIN_GALE, Moves.SHIFT_GEAR ], [Species.MAGBY]: [ Moves.THUNDERCLAP, Moves.EARTH_POWER, Moves.ARMOR_CANNON, Moves.FLEUR_CANNON ], [Species.MILTANK]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.YAWN, Moves.SIZZLY_SLIDE ], [Species.RAIKOU]: [ Moves.PARABOLIC_CHARGE, Moves.NASTY_PLOT, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], @@ -125,10 +125,10 @@ export const speciesEggMoves = { [Species.SUICUNE]: [ Moves.RECOVER, Moves.NASTY_PLOT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], [Species.LARVITAR]: [ Moves.DRAGON_DANCE, Moves.MOUNTAIN_GALE, Moves.SHORE_UP, Moves.DIAMOND_STORM ], [Species.LUGIA]: [ Moves.NASTY_PLOT, Moves.LUMINA_CRASH, Moves.AURA_SPHERE, Moves.OBLIVION_WING ], - [Species.HO_OH]: [ Moves.FLOATY_FALL, Moves.PRECIPICE_BLADES, Moves.REVIVAL_BLESSING, Moves.BOLT_BEAK ], + [Species.HO_OH]: [ Moves.BRAVE_BIRD, Moves.DRAGON_DANCE, Moves.REVIVAL_BLESSING, Moves.BOLT_BEAK ], [Species.CELEBI]: [ Moves.PHOTON_GEYSER, Moves.MATCHA_GOTCHA, Moves.REVIVAL_BLESSING, Moves.QUIVER_DANCE ], [Species.TREECKO]: [ Moves.NASTY_PLOT, Moves.APPLE_ACID, Moves.SECRET_SWORD, Moves.DRAGON_ENERGY ], - [Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.V_CREATE ], + [Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.BURNING_BULWARK, Moves.V_CREATE ], [Species.MUDKIP]: [ Moves.SHORE_UP, Moves.MOUNTAIN_GALE, Moves.BULK_UP, Moves.SURGING_STRIKES ], [Species.POOCHYENA]: [ Moves.JAW_LOCK, Moves.CLOSE_COMBAT, Moves.DIRE_CLAW, Moves.NO_RETREAT ], [Species.ZIGZAGOON]: [ Moves.EXTREME_SPEED, Moves.NUZZLE, Moves.HIGH_HORSEPOWER, Moves.TIDY_UP ], @@ -154,7 +154,7 @@ export const speciesEggMoves = { [Species.ELECTRIKE]: [ Moves.RISING_VOLTAGE, Moves.FLAMETHROWER, Moves.NASTY_PLOT, Moves.ICE_BEAM ], [Species.PLUSLE]: [ Moves.FLAMETHROWER, Moves.GLITZY_GLOW, Moves.SPLISHY_SPLASH, Moves.TAIL_GLOW ], [Species.MINUN]: [ Moves.ICE_BEAM, Moves.BADDY_BAD, Moves.SPARKLY_SWIRL, Moves.TAIL_GLOW ], - [Species.VOLBEAT]: [ Moves.BATON_PASS, Moves.LUNGE, Moves.DECORATE, Moves.VICTORY_DANCE ], + [Species.VOLBEAT]: [ Moves.BATON_PASS, Moves.STICKY_WEB, Moves.DECORATE, Moves.VICTORY_DANCE ], [Species.ILLUMISE]: [ Moves.PARTING_SHOT, Moves.GLITZY_GLOW, Moves.POWDER, Moves.QUIVER_DANCE ], [Species.GULPIN]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.MALIGNANT_CHAIN ], [Species.CARVANHA]: [ Moves.THUNDER_FANG, Moves.SWORDS_DANCE, Moves.OBSTRUCT, Moves.SURGING_STRIKES ], @@ -168,7 +168,7 @@ export const speciesEggMoves = { [Species.SWABLU]: [ Moves.ROOST, Moves.NASTY_PLOT, Moves.FLOATY_FALL, Moves.BOOMBURST ], [Species.ZANGOOSE]: [ Moves.FACADE, Moves.HIGH_HORSEPOWER, Moves.EXTREME_SPEED, Moves.TIDY_UP ], [Species.SEVIPER]: [ Moves.ICE_BEAM, Moves.BITTER_BLADE, Moves.SUCKER_PUNCH, Moves.NO_RETREAT ], - [Species.LUNATONE]: [ Moves.POWER_GEM, Moves.NIGHT_DAZE, Moves.SHELL_SMASH, Moves.LUMINA_CRASH ], + [Species.LUNATONE]: [ Moves.POWER_GEM, Moves.MOONGEIST_BEAM, Moves.SHELL_SMASH, Moves.LUMINA_CRASH ], [Species.SOLROCK]: [ Moves.PSYSHIELD_BASH, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH, Moves.SACRED_FIRE ], [Species.BARBOACH]: [ Moves.DRAGON_DANCE, Moves.ZING_ZAP, Moves.ICE_SPINNER, Moves.SURGING_STRIKES ], [Species.CORPHISH]: [ Moves.CEASELESS_EDGE, Moves.JET_PUNCH, Moves.SUCKER_PUNCH, Moves.SHELL_SMASH ], @@ -177,7 +177,7 @@ export const speciesEggMoves = { [Species.ANORITH]: [ Moves.FIRST_IMPRESSION, Moves.LEECH_LIFE, Moves.DRAGON_DANCE, Moves.MIGHTY_CLEAVE ], [Species.FEEBAS]: [ Moves.CALM_MIND, Moves.FREEZE_DRY, Moves.MOONBLAST, Moves.STEAM_ERUPTION ], [Species.CASTFORM]: [ Moves.BOOMBURST, Moves.HYDRO_STEAM, Moves.ERUPTION, Moves.QUIVER_DANCE ], - [Species.KECLEON]: [ Moves.DRAIN_PUNCH, Moves.DRAGON_DANCE, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ], + [Species.KECLEON]: [ Moves.ZIPPY_ZAP, Moves.COIL, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ], [Species.SHUPPET]: [ Moves.STORM_THROW, Moves.TIDY_UP, Moves.PARTING_SHOT, Moves.SPECTRAL_THIEF ], [Species.DUSKULL]: [ Moves.BULK_UP, Moves.DRAIN_PUNCH, Moves.STRENGTH_SAP, Moves.RAGE_FIST ], [Species.TROPIUS]: [ Moves.STUFF_CHEEKS, Moves.EARTH_POWER, Moves.APPLE_ACID, Moves.SAPPY_SEED ], @@ -189,16 +189,16 @@ export const speciesEggMoves = { [Species.RELICANTH]: [ Moves.DRAGON_DANCE, Moves.SHORE_UP, Moves.WAVE_CRASH, Moves.DIAMOND_STORM ], [Species.LUVDISC]: [ Moves.BATON_PASS, Moves.HEART_SWAP, Moves.GLITZY_GLOW, Moves.REVIVAL_BLESSING ], [Species.BAGON]: [ Moves.FLOATY_FALL, Moves.FIRE_LASH, Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH ], - [Species.BELDUM]: [ Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.TRIPLE_AXEL, Moves.SHIFT_GEAR ], + [Species.BELDUM]: [ Moves.HEADLONG_RUSH, Moves.DRAIN_PUNCH, Moves.TRIPLE_AXEL, Moves.SHIFT_GEAR ], [Species.REGIROCK]: [ Moves.STONE_AXE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SALT_CURE ], [Species.REGICE]: [ Moves.EARTH_POWER, Moves.TAKE_HEART, Moves.RECOVER, Moves.FREEZE_DRY ], [Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.GIGATON_HAMMER ], [Species.LATIAS]: [ Moves.CORE_ENFORCER, Moves.FUSION_FLARE, Moves.SPARKLY_SWIRL, Moves.MYSTICAL_POWER ], [Species.LATIOS]: [ Moves.CORE_ENFORCER, Moves.BLUE_FLARE, Moves.NASTY_PLOT, Moves.TACHYON_CUTTER ], - [Species.KYOGRE]: [ Moves.BOUNCY_BUBBLE, Moves.HURRICANE, Moves.FREEZE_DRY, Moves.ELECTRO_SHOT ], + [Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FLIP_TURN, Moves.WILDBOLT_STORM ], [Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ], - [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ], + [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS, Moves.SHELL_SMASH ], [Species.DEOXYS]: [ Moves.COLLISION_COURSE, Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.LUMINA_CRASH ], [Species.TURTWIG]: [ Moves.SHELL_SMASH, Moves.MIGHTY_CLEAVE, Moves.ICE_SPINNER, Moves.SAPPY_SEED ], [Species.CHIMCHAR]: [ Moves.FIERY_DANCE, Moves.SECRET_SWORD, Moves.TRIPLE_AXEL, Moves.SACRED_FIRE ], @@ -206,7 +206,7 @@ export const speciesEggMoves = { [Species.STARLY]: [ Moves.SWORDS_DANCE, Moves.HEAD_CHARGE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ], [Species.BIDOOF]: [ Moves.EXTREME_SPEED, Moves.COSMIC_POWER, Moves.POWER_TRIP, Moves.AQUA_STEP ], [Species.KRICKETOT]: [ Moves.BONEMERANG, Moves.VICTORY_DANCE, Moves.STONE_AXE, Moves.POPULATION_BOMB ], - [Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.FACADE, Moves.BOLT_STRIKE ], + [Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.ZIPPY_ZAP, Moves.BOLT_STRIKE ], [Species.BUDEW]: [ Moves.FIERY_DANCE, Moves.ACID_SPRAY, Moves.BOUNCY_BUBBLE, Moves.QUIVER_DANCE ], [Species.CRANIDOS]: [ Moves.VOLT_TACKLE, Moves.ACCELEROCK, Moves.FLARE_BLITZ, Moves.SHIFT_GEAR ], [Species.SHIELDON]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.DIAMOND_STORM ], @@ -223,7 +223,7 @@ export const speciesEggMoves = { [Species.STUNKY]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.RECOVER, Moves.DIRE_CLAW ], [Species.BRONZOR]: [ Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.GLARE, Moves.LUMINA_CRASH ], [Species.BONSLY]: [ Moves.ACCELEROCK, Moves.SWORDS_DANCE, Moves.STRENGTH_SAP, Moves.SAPPY_SEED ], - [Species.MIME_JR]: [ Moves.CALM_MIND, Moves.MOONBLAST, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ], + [Species.MIME_JR]: [ Moves.CHILLY_RECEPTION, Moves.MOONBLAST, Moves.FROST_BREATH, Moves.LUMINA_CRASH ], [Species.HAPPINY]: [ Moves.COTTON_GUARD, Moves.SEISMIC_TOSS, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ], [Species.CHATOT]: [ Moves.SPARKLING_ARIA, Moves.TORCH_SONG, Moves.BATON_PASS, Moves.BOOMBURST ], [Species.SPIRITOMB]: [ Moves.PARTING_SHOT, Moves.BADDY_BAD, Moves.STRENGTH_SAP, Moves.SPECTRAL_THIEF ], @@ -232,7 +232,7 @@ export const speciesEggMoves = { [Species.RIOLU]: [ Moves.THUNDEROUS_KICK, Moves.TACHYON_CUTTER, Moves.TRIPLE_AXEL, Moves.DOUBLE_IRON_BASH ], [Species.HIPPOPOTAS]: [ Moves.SHORE_UP, Moves.STONE_AXE, Moves.BULK_UP, Moves.SALT_CURE ], [Species.SKORUPI]: [ Moves.COIL, Moves.DIRE_CLAW, Moves.CRABHAMMER, Moves.WICKED_BLOW ], - [Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_PUNCH, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ], + [Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_SPINNER, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ], [Species.CARNIVINE]: [ Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.COIL, Moves.SAPPY_SEED ], [Species.FINNEON]: [ Moves.QUIVER_DANCE, Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ], [Species.MANTYKE]: [ Moves.SPLISHY_SPLASH, Moves.FREEZY_FROST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ], @@ -243,7 +243,7 @@ export const speciesEggMoves = { [Species.AZELF]: [ Moves.PSYSTRIKE, Moves.ICE_BEAM, Moves.MOONBLAST, Moves.TAIL_GLOW ], [Species.DIALGA]: [ Moves.CORE_ENFORCER, Moves.TAKE_HEART, Moves.RECOVER, Moves.MAKE_IT_RAIN ], [Species.PALKIA]: [ Moves.RECOVER, Moves.TAKE_HEART, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ], - [Species.HEATRAN]: [ Moves.TORCH_SONG, Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.MATCHA_GOTCHA ], + [Species.HEATRAN]: [ Moves.MATCHA_GOTCHA, Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.TORCH_SONG ], [Species.REGIGIGAS]: [ Moves.SKILL_SWAP, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.GIGATON_HAMMER ], [Species.GIRATINA]: [ Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH, Moves.RECOVER, Moves.SPECTRAL_THIEF ], [Species.CRESSELIA]: [ Moves.COSMIC_POWER, Moves.SECRET_SWORD, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ], @@ -274,18 +274,18 @@ export const speciesEggMoves = { [Species.THROH]: [ Moves.MACH_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.RAGE_FIST ], [Species.SAWK]: [ Moves.DRAIN_PUNCH, Moves.SUCKER_PUNCH, Moves.METEOR_MASH, Moves.VICTORY_DANCE ], [Species.SEWADDLE]: [ Moves.STONE_AXE, Moves.PSYCHO_CUT, Moves.BITTER_BLADE, Moves.VICTORY_DANCE ], - [Species.VENIPEDE]: [ Moves.SWORDS_DANCE, Moves.LEECH_LIFE, Moves.NOXIOUS_TORQUE, Moves.POWER_TRIP ], + [Species.VENIPEDE]: [ Moves.BANEFUL_BUNKER, Moves.LEECH_LIFE, Moves.NOXIOUS_TORQUE, Moves.POWER_TRIP ], [Species.COTTONEE]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.SLEEP_POWDER, Moves.SEED_FLARE ], [Species.PETILIL]: [ Moves.THUNDEROUS_KICK, Moves.SPARKLING_ARIA, Moves.FIERY_DANCE, Moves.FLOWER_TRICK ], [Species.BASCULIN]: [ Moves.LAST_RESPECTS, Moves.CLOSE_COMBAT, Moves.SPLISHY_SPLASH, Moves.NO_RETREAT ], [Species.SANDILE]: [ Moves.DIRE_CLAW, Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.WICKED_BLOW ], [Species.DARUMAKA]: [ Moves.DRAIN_PUNCH, Moves.ZIPPY_ZAP, Moves.EARTHQUAKE, Moves.PYRO_BALL ], - [Species.MARACTUS]: [ Moves.SCORCHING_SANDS, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ], + [Species.MARACTUS]: [ Moves.EARTH_POWER, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ], [Species.DWEBBLE]: [ Moves.CRABHAMMER, Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.MIGHTY_CLEAVE ], - [Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ], + [Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.NOXIOUS_TORQUE, Moves.VICTORY_DANCE ], [Species.SIGILYPH]: [ Moves.MOONBLAST, Moves.CALM_MIND, Moves.FREEZING_GLARE, Moves.OBLIVION_WING ], - [Species.YAMASK]: [ Moves.STRENGTH_SAP, Moves.INFERNAL_PARADE, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], - [Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ], + [Species.YAMASK]: [ Moves.STRENGTH_SAP, Moves.GLARE, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], + [Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.AQUA_STEP, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ], [Species.ARCHEN]: [ Moves.ROOST, Moves.EARTHQUAKE, Moves.FLOATY_FALL, Moves.MIGHTY_CLEAVE ], [Species.TRUBBISH]: [ Moves.COIL, Moves.RECOVER, Moves.DIRE_CLAW, Moves.GIGATON_HAMMER ], [Species.ZORUA]: [ Moves.FLAMETHROWER, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.FIERY_WRATH ], @@ -295,19 +295,19 @@ export const speciesEggMoves = { [Species.DUCKLETT]: [ Moves.SPLISHY_SPLASH, Moves.EARTH_POWER, Moves.WILDBOLT_STORM, Moves.QUIVER_DANCE ], [Species.VANILLITE]: [ Moves.EARTH_POWER, Moves.AURORA_VEIL, Moves.CALM_MIND, Moves.SPARKLY_SWIRL ], [Species.DEERLING]: [ Moves.TIDY_UP, Moves.FLOWER_TRICK, Moves.BODY_SLAM, Moves.COMBAT_TORQUE ], - [Species.EMOLGA]: [ Moves.TRIPLE_AXEL, Moves.SPLISHY_SPLASH, Moves.TAILWIND, Moves.ZIPPY_ZAP ], - [Species.KARRABLAST]: [ Moves.LEECH_LIFE, Moves.HEAL_ORDER, Moves.HIGH_HORSEPOWER, Moves.DOUBLE_IRON_BASH ], + [Species.EMOLGA]: [ Moves.TRIPLE_AXEL, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.AURA_WHEEL ], + [Species.KARRABLAST]: [ Moves.LEECH_LIFE, Moves.BITTER_BLADE, Moves.HIGH_HORSEPOWER, Moves.DOUBLE_IRON_BASH ], [Species.FOONGUS]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.FOUL_PLAY, Moves.SAPPY_SEED ], - [Species.FRILLISH]: [ Moves.STRENGTH_SAP, Moves.INFERNAL_PARADE, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], - [Species.ALOMOMOLA]: [ Moves.FLIP_TURN, Moves.HEART_SWAP, Moves.TOXIC, Moves.GLITZY_GLOW ], - [Species.JOLTIK]: [ Moves.THUNDER, Moves.PARABOLIC_CHARGE, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], + [Species.FRILLISH]: [ Moves.STRENGTH_SAP, Moves.BUZZY_BUZZ, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], + [Species.ALOMOMOLA]: [ Moves.FLIP_TURN, Moves.HEART_SWAP, Moves.GLITZY_GLOW, Moves.REVIVAL_BLESSING ], + [Species.JOLTIK]: [ Moves.WILDBOLT_STORM, Moves.PARABOLIC_CHARGE, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], [Species.FERROSEED]: [ Moves.STRENGTH_SAP, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.SAPPY_SEED ], [Species.KLINK]: [ Moves.TRIPLE_AXEL, Moves.HIGH_HORSEPOWER, Moves.FUSION_BOLT, Moves.DOUBLE_IRON_BASH ], - [Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.PLASMA_FISTS ], - [Species.ELGYEM]: [ Moves.LUSTER_PURGE, Moves.TRICK_ROOM, Moves.AURA_SPHERE, Moves.TAIL_GLOW ], + [Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.AURA_WHEEL ], + [Species.ELGYEM]: [ Moves.LUSTER_PURGE, Moves.BADDY_BAD, Moves.AURA_SPHERE, Moves.TAIL_GLOW ], [Species.LITWICK]: [ Moves.FIERY_DANCE, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE ], [Species.AXEW]: [ Moves.STONE_AXE, Moves.DIRE_CLAW, Moves.BITTER_BLADE, Moves.GLAIVE_RUSH ], - [Species.CUBCHOO]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], + [Species.CUBCHOO]: [ Moves.MOUNTAIN_GALE, Moves.AQUA_STEP, Moves.ICE_SHARD, Moves.COLLISION_COURSE ], [Species.CRYOGONAL]: [ Moves.FREEZING_GLARE, Moves.AURORA_VEIL, Moves.NASTY_PLOT, Moves.ORIGIN_PULSE ], [Species.SHELMET]: [ Moves.POWER_GEM, Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.STEAM_ERUPTION ], [Species.STUNFISK]: [ Moves.BANEFUL_BUNKER, Moves.SANDSEAR_STORM, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ], @@ -315,24 +315,24 @@ export const speciesEggMoves = { [Species.DRUDDIGON]: [ Moves.FIRE_LASH, Moves.ROOST, Moves.DRAGON_DARTS, Moves.CLANGOROUS_SOUL ], [Species.GOLETT]: [ Moves.SHIFT_GEAR, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.RAGE_FIST ], [Species.PAWNIARD]: [ Moves.SUCKER_PUNCH, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.LAST_RESPECTS ], - [Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ], + [Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.HIGH_JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ], [Species.RUFFLET]: [ Moves.FLOATY_FALL, Moves.AURA_SPHERE, Moves.NO_RETREAT, Moves.BOLT_BEAK ], [Species.VULLABY]: [ Moves.FOUL_PLAY, Moves.BODY_PRESS, Moves.ROOST, Moves.RUINATION ], [Species.HEATMOR]: [ Moves.EARTH_POWER, Moves.OVERHEAT, Moves.THUNDERBOLT, Moves.V_CREATE ], [Species.DURANT]: [ Moves.HIGH_HORSEPOWER, Moves.FIRST_IMPRESSION, Moves.SWORDS_DANCE, Moves.BEHEMOTH_BASH ], [Species.DEINO]: [ Moves.FIERY_WRATH, Moves.ESPER_WING, Moves.SLUDGE_BOMB, Moves.FICKLE_BEAM ], [Species.LARVESTA]: [ Moves.THUNDERBOLT, Moves.MATCHA_GOTCHA, Moves.EARTH_POWER, Moves.TORCH_SONG ], - [Species.COBALION]: [ Moves.BEHEMOTH_BLADE, Moves.BODY_PRESS, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], + [Species.COBALION]: [ Moves.BEHEMOTH_BLADE, Moves.MIGHTY_CLEAVE, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.TERRAKION]: [ Moves.MIGHTY_CLEAVE, Moves.HEADLONG_RUSH, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.VIRIZION]: [ Moves.PSYBLADE, Moves.SAPPY_SEED, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.TORNADUS]: [ Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.ICE_BEAM, Moves.OBLIVION_WING ], [Species.THUNDURUS]: [ Moves.EARTH_POWER, Moves.HURRICANE, Moves.FROST_BREATH, Moves.ELECTRO_SHOT ], - [Species.RESHIRAM]: [ Moves.MORNING_SUN, Moves.TAKE_HEART, Moves.FICKLE_BEAM, Moves.ERUPTION ], - [Species.ZEKROM]: [ Moves.DRAGON_DANCE, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ], + [Species.RESHIRAM]: [ Moves.ENERGY_BALL, Moves.TAKE_HEART, Moves.FICKLE_BEAM, Moves.ERUPTION ], + [Species.ZEKROM]: [ Moves.TRIPLE_AXEL, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ], [Species.LANDORUS]: [ Moves.STONE_AXE, Moves.FLOATY_FALL, Moves.ROOST, Moves.BLEAKWIND_STORM ], - [Species.KYUREM]: [ Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.NO_RETREAT, Moves.GLACIAL_LANCE ], + [Species.KYUREM]: [ Moves.DRAGON_DARTS, Moves.GLACIAL_LANCE, Moves.NO_RETREAT, Moves.DRAGON_ENERGY ], [Species.KELDEO]: [ Moves.BOUNCY_BUBBLE, Moves.THUNDERBOLT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], - [Species.MELOETTA]: [ Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.TRIPLE_ARROWS, Moves.TORCH_SONG ], + [Species.MELOETTA]: [ Moves.BODY_SLAM, Moves.TORCH_SONG, Moves.TRIPLE_ARROWS, Moves.BOOMBURST ], [Species.GENESECT]: [ Moves.EXTREME_SPEED, Moves.U_TURN, Moves.TACHYON_CUTTER, Moves.TAIL_GLOW ], [Species.CHESPIN]: [ Moves.BODY_PRESS, Moves.SYNTHESIS, Moves.CEASELESS_EDGE, Moves.SAPPY_SEED ], [Species.FENNEKIN]: [ Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.THUNDERBOLT, Moves.TORCH_SONG ], @@ -344,13 +344,13 @@ export const speciesEggMoves = { [Species.FLABEBE]: [ Moves.GLITZY_GLOW, Moves.MYSTICAL_FIRE, Moves.TAKE_HEART, Moves.SEED_FLARE ], [Species.SKIDDO]: [ Moves.HIGH_HORSEPOWER, Moves.GRASSY_GLIDE, Moves.STONE_AXE, Moves.SAPPY_SEED ], [Species.PANCHAM]: [ Moves.DRAIN_PUNCH, Moves.SUCKER_PUNCH, Moves.METEOR_MASH, Moves.WICKED_BLOW ], - [Species.FURFROU]: [ Moves.TIDY_UP, Moves.SLACK_OFF, Moves.COVET, Moves.MULTI_ATTACK ], - [Species.ESPURR]: [ Moves.GLARE, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PSYSTRIKE ], + [Species.FURFROU]: [ Moves.TIDY_UP, Moves.SLACK_OFF, Moves.COMBAT_TORQUE, Moves.MULTI_ATTACK ], + [Species.ESPURR]: [ Moves.LUSTER_PURGE, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.DARK_VOID ], [Species.HONEDGE]: [ Moves.TACHYON_CUTTER, Moves.SHADOW_BONE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], [Species.SPRITZEE]: [ Moves.TRICK_ROOM, Moves.FOUL_PLAY, Moves.WISH, Moves.REVIVAL_BLESSING ], [Species.SWIRLIX]: [ Moves.BELLY_DRUM, Moves.HEADLONG_RUSH, Moves.MAGICAL_TORQUE, Moves.REVIVAL_BLESSING ], [Species.INKAY]: [ Moves.POWER_TRIP, Moves.SPIN_OUT, Moves.RECOVER, Moves.PSYCHO_BOOST ], - [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.ACCELEROCK, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], + [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.CRABHAMMER, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], [Species.SKRELP]: [ Moves.STRENGTH_SAP, Moves.TRICK_ROOM, Moves.CALM_MIND, Moves.CORE_ENFORCER ], [Species.CLAUNCHER]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.WATER_SHURIKEN, Moves.ORIGIN_PULSE ], [Species.HELIOPTILE]: [ Moves.WEATHER_BALL, Moves.HYDRO_STEAM, Moves.EARTH_POWER, Moves.BOOMBURST ], @@ -360,15 +360,15 @@ export const speciesEggMoves = { [Species.DEDENNE]: [ Moves.BOOMBURST, Moves.FAKE_OUT, Moves.NASTY_PLOT, Moves.REVIVAL_BLESSING ], [Species.CARBINK]: [ Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SPARKLY_SWIRL, Moves.DIAMOND_STORM ], [Species.GOOMY]: [ Moves.SCALD, Moves.RECOVER, Moves.CALM_MIND, Moves.MAKE_IT_RAIN ], - [Species.KLEFKI]: [ Moves.HEAL_BELL, Moves.ENCORE, Moves.TOPSY_TURVY, Moves.INSTRUCT ], + [Species.KLEFKI]: [ Moves.HEAL_BELL, Moves.ENCORE, Moves.INSTRUCT, Moves.TOPSY_TURVY ], [Species.PHANTUMP]: [ Moves.RAGE_FIST, Moves.TRICK_ROOM, Moves.SYNTHESIS, Moves.SAPPY_SEED ], [Species.PUMPKABOO]: [ Moves.SPIRIT_SHACKLE, Moves.FIRE_LASH, Moves.DIRE_CLAW, Moves.SAPPY_SEED ], [Species.BERGMITE]: [ Moves.STONE_AXE, Moves.METAL_BURST, Moves.BODY_PRESS, Moves.GLACIAL_LANCE ], [Species.NOIBAT]: [ Moves.AEROBLAST, Moves.OVERDRIVE, Moves.NASTY_PLOT, Moves.CLANGING_SCALES ], - [Species.XERNEAS]: [ Moves.SEARING_SHOT, Moves.LUMINA_CRASH, Moves.STRENGTH_SAP, Moves.TAIL_GLOW ], + [Species.XERNEAS]: [ Moves.EARTH_POWER, Moves.SPRINGTIDE_STORM, Moves.STRENGTH_SAP, Moves.TAIL_GLOW ], [Species.YVELTAL]: [ Moves.SHELL_SIDE_ARM, Moves.POWER_TRIP, Moves.FIERY_WRATH, Moves.CLANGOROUS_SOUL ], [Species.ZYGARDE]: [ Moves.DRAGON_DARTS, Moves.HEAL_ORDER, Moves.CLANGOROUS_SOUL, Moves.DOUBLE_IRON_BASH ], - [Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.GEOMANCY ], + [Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.AURA_SPHERE, Moves.SHORE_UP, Moves.GEOMANCY ], [Species.HOOPA]: [ Moves.PHOTON_GEYSER, Moves.SECRET_SWORD, Moves.FIERY_WRATH, Moves.SHELL_SMASH ], [Species.VOLCANION]: [ Moves.HYDRO_STEAM, Moves.CALM_MIND, Moves.ENERGY_BALL, Moves.MAGMA_STORM ], [Species.ROWLET]: [ Moves.THOUSAND_ARROWS, Moves.SHADOW_BONE, Moves.FIRST_IMPRESSION, Moves.VICTORY_DANCE ], @@ -379,7 +379,7 @@ export const speciesEggMoves = { [Species.GRUBBIN]: [ Moves.ICE_BEAM, Moves.EARTH_POWER, Moves.THUNDERCLAP, Moves.QUIVER_DANCE ], [Species.CRABRAWLER]: [ Moves.JET_PUNCH, Moves.SHORE_UP, Moves.SUCKER_PUNCH, Moves.SURGING_STRIKES ], [Species.ORICORIO]: [ Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.THUNDERCLAP, Moves.OBLIVION_WING ], - [Species.CUTIEFLY]: [ Moves.STICKY_WEB, Moves.MOONBLAST, Moves.HEAT_WAVE, Moves.SPORE ], + [Species.CUTIEFLY]: [ Moves.STICKY_WEB, Moves.SLEEP_POWDER, Moves.HEAT_WAVE, Moves.SPARKLY_SWIRL ], [Species.ROCKRUFF]: [ Moves.HIGH_HORSEPOWER, Moves.TIDY_UP, Moves.ICE_SPINNER, Moves.MIGHTY_CLEAVE ], [Species.WISHIWASHI]: [ Moves.HEAL_ORDER, Moves.ICE_SPINNER, Moves.DRAGON_DANCE, Moves.JET_PUNCH ], [Species.MAREANIE]: [ Moves.CEASELESS_EDGE, Moves.SIZZLY_SLIDE, Moves.BODY_PRESS, Moves.LEECH_SEED ], @@ -394,31 +394,31 @@ export const speciesEggMoves = { [Species.ORANGURU]: [ Moves.JUNGLE_HEALING, Moves.YAWN, Moves.FOLLOW_ME, Moves.LUMINA_CRASH ], [Species.PASSIMIAN]: [ Moves.FAKE_OUT, Moves.SUCKER_PUNCH, Moves.ZING_ZAP, Moves.PYRO_BALL ], [Species.WIMPOD]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.JET_PUNCH, Moves.SURGING_STRIKES ], - [Species.SANDYGAST]: [ Moves.SCORCHING_SANDS, Moves.SPLISHY_SPLASH, Moves.TAKE_HEART, Moves.SALT_CURE ], + [Species.SANDYGAST]: [ Moves.SANDSEAR_STORM, Moves.SPLISHY_SPLASH, Moves.TAKE_HEART, Moves.SALT_CURE ], [Species.PYUKUMUKU]: [ Moves.COMEUPPANCE, Moves.BANEFUL_BUNKER, Moves.TOXIC_SPIKES, Moves.SALT_CURE ], [Species.TYPE_NULL]: [ Moves.DIRE_CLAW, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.SHELL_SMASH ], [Species.MINIOR]: [ Moves.EARTH_POWER, Moves.FLOATY_FALL, Moves.ZING_ZAP, Moves.DIAMOND_STORM ], [Species.KOMALA]: [ Moves.SLACK_OFF, Moves.EXTREME_SPEED, Moves.KNOCK_OFF, Moves.COLLISION_COURSE ], [Species.TURTONATOR]: [ Moves.BURNING_BULWARK, Moves.MORNING_SUN, Moves.BODY_PRESS, Moves.CORE_ENFORCER ], - [Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.BOLT_STRIKE ], + [Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.AURA_WHEEL ], [Species.MIMIKYU]: [ Moves.SPIRIT_BREAK, Moves.TIDY_UP, Moves.BITTER_BLADE, Moves.SPECTRAL_THIEF ], [Species.BRUXISH]: [ Moves.PLAY_ROUGH, Moves.FIRE_FANG, Moves.DRAGON_DANCE, Moves.SURGING_STRIKES ], [Species.DRAMPA]: [ Moves.SLACK_OFF, Moves.TRICK_ROOM, Moves.CORE_ENFORCER, Moves.BOOMBURST ], [Species.DHELMISE]: [ Moves.SHADOW_BONE, Moves.STRENGTH_SAP, Moves.LIQUIDATION, Moves.SAPPY_SEED ], [Species.JANGMO_O]: [ Moves.BODY_PRESS, Moves.SHELL_SIDE_ARM, Moves.SECRET_SWORD, Moves.GLAIVE_RUSH ], - [Species.TAPU_KOKO]: [ Moves.MAGICAL_TORQUE, Moves.TRIPLE_AXEL, Moves.RISING_VOLTAGE, Moves.PLASMA_FISTS ], + [Species.TAPU_KOKO]: [ Moves.MAGICAL_TORQUE, Moves.TRIPLE_AXEL, Moves.RISING_VOLTAGE, Moves.BOLT_STRIKE ], [Species.TAPU_LELE]: [ Moves.MOONLIGHT, Moves.NASTY_PLOT, Moves.HEAT_WAVE, Moves.EXPANDING_FORCE ], [Species.TAPU_BULU]: [ Moves.SAPPY_SEED, Moves.DRAIN_PUNCH, Moves.MAGICAL_TORQUE, Moves.VICTORY_DANCE ], [Species.TAPU_FINI]: [ Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.RECOVER, Moves.QUIVER_DANCE ], [Species.COSMOG]: [ Moves.PHOTON_GEYSER, Moves.PRECIPICE_BLADES, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE ], [Species.NIHILEGO]: [ Moves.STRENGTH_SAP, Moves.MALIGNANT_CHAIN, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], [Species.BUZZWOLE]: [ Moves.FIRST_IMPRESSION, Moves.COMBAT_TORQUE, Moves.ROCK_WRECKER, Moves.DOUBLE_IRON_BASH ], - [Species.PHEROMOSA]: [ Moves.AURA_SPHERE, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.DIAMOND_STORM ], + [Species.PHEROMOSA]: [ Moves.SECRET_SWORD, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.DIAMOND_STORM ], [Species.XURKITREE]: [ Moves.FLAMETHROWER, Moves.GIGA_DRAIN, Moves.TAIL_GLOW, Moves.THUNDERCLAP ], [Species.CELESTEELA]: [ Moves.RECOVER, Moves.BUZZY_BUZZ, Moves.SANDSEAR_STORM, Moves.OBLIVION_WING ], [Species.KARTANA]: [ Moves.MIGHTY_CLEAVE, Moves.PSYBLADE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], [Species.GUZZLORD]: [ Moves.SUCKER_PUNCH, Moves.COMEUPPANCE, Moves.SLACK_OFF, Moves.SHED_TAIL ], - [Species.NECROZMA]: [ Moves.CLANGOROUS_SOUL, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.DYNAMAX_CANNON ], + [Species.NECROZMA]: [ Moves.DYNAMAX_CANNON, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.CLANGOROUS_SOUL ], [Species.MAGEARNA]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.MAKE_IT_RAIN ], [Species.MARSHADOW]: [ Moves.POWER_UP_PUNCH, Moves.TRIPLE_AXEL, Moves.METEOR_MASH, Moves.STORM_THROW ], [Species.POIPOLE]: [ Moves.CORE_ENFORCER, Moves.ICE_BEAM, Moves.SEARING_SHOT, Moves.MALIGNANT_CHAIN ], @@ -428,11 +428,11 @@ export const speciesEggMoves = { [Species.MELTAN]: [ Moves.BULLET_PUNCH, Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS ], [Species.GROOKEY]: [ Moves.HIGH_HORSEPOWER, Moves.CLANGOROUS_SOUL, Moves.GRASSY_GLIDE, Moves.SAPPY_SEED ], [Species.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.HIGH_JUMP_KICK, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE ], - [Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.SCORCHING_SANDS, Moves.NASTY_PLOT ], - [Species.SKWOVET]: [ Moves.KNOCK_OFF, Moves.SLACK_OFF, Moves.BODY_PRESS, Moves.POPULATION_BOMB ], + [Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.ENERGY_BALL, Moves.NASTY_PLOT ], + [Species.SKWOVET]: [ Moves.SUCKER_PUNCH, Moves.SLACK_OFF, Moves.COIL, Moves.POPULATION_BOMB ], [Species.ROOKIDEE]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.BEHEMOTH_BASH ], - [Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.EXPANDING_FORCE, Moves.SPORE, Moves.TAIL_GLOW ], - [Species.NICKIT]: [ Moves.BADDY_BAD, Moves.BURNING_JEALOUSY, Moves.SPARKLY_SWIRL, Moves.FIERY_WRATH ], + [Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.LUSTER_PURGE, Moves.SLEEP_POWDER, Moves.TAIL_GLOW ], + [Species.NICKIT]: [ Moves.BADDY_BAD, Moves.FLAMETHROWER, Moves.SPARKLY_SWIRL, Moves.MAKE_IT_RAIN ], [Species.GOSSIFLEUR]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.SAPPY_SEED, Moves.SEED_FLARE ], [Species.WOOLOO]: [ Moves.PSYSHIELD_BASH, Moves.MILK_DRINK, Moves.BODY_PRESS, Moves.MULTI_ATTACK ], [Species.CHEWTLE]: [ Moves.ICE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.FISHIOUS_REND ], @@ -446,25 +446,25 @@ export const speciesEggMoves = { [Species.SIZZLIPEDE]: [ Moves.BURNING_BULWARK, Moves.ZING_ZAP, Moves.FIRST_IMPRESSION, Moves.BITTER_BLADE ], [Species.CLOBBOPUS]: [ Moves.STORM_THROW, Moves.JET_PUNCH, Moves.MACH_PUNCH, Moves.SURGING_STRIKES ], [Species.SINISTEA]: [ Moves.SCALD, Moves.TAKE_HEART, Moves.SPARKLY_SWIRL, Moves.MATCHA_GOTCHA ], - [Species.HATENNA]: [ Moves.RECOVER, Moves.MOONBLAST, Moves.BUZZY_BUZZ, Moves.SEARING_SHOT ], + [Species.HATENNA]: [ Moves.RECOVER, Moves.MOONBLAST, Moves.BUZZY_BUZZ, Moves.TORCH_SONG ], [Species.IMPIDIMP]: [ Moves.ENCORE, Moves.PARTING_SHOT, Moves.TOPSY_TURVY, Moves.WICKED_BLOW ], [Species.MILCERY]: [ Moves.MOONBLAST, Moves.CHILLY_RECEPTION, Moves.EARTH_POWER, Moves.GEOMANCY ], [Species.FALINKS]: [ Moves.COMBAT_TORQUE, Moves.PSYSHIELD_BASH, Moves.HEAL_ORDER, Moves.POPULATION_BOMB ], [Species.PINCURCHIN]: [ Moves.TRICK_ROOM, Moves.RISING_VOLTAGE, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ], - [Species.SNOM]: [ Moves.MOONBLAST, Moves.SURF, Moves.EARTH_POWER, Moves.FIERY_DANCE ], + [Species.SNOM]: [ Moves.FROST_BREATH, Moves.HEAL_ORDER, Moves.EARTH_POWER, Moves.SPORE ], [Species.STONJOURNER]: [ Moves.BODY_PRESS, Moves.HELPING_HAND, Moves.ACCELEROCK, Moves.DIAMOND_STORM ], [Species.EISCUE]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.SHELL_SMASH, Moves.GLACIAL_LANCE ], [Species.INDEEDEE]: [ Moves.MATCHA_GOTCHA, Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.REVIVAL_BLESSING ], [Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], [Species.CUFANT]: [ Moves.LIQUIDATION, Moves.CURSE, Moves.COMBAT_TORQUE, Moves.GIGATON_HAMMER ], - [Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ], + [Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.SCALE_SHOT, Moves.FIRE_LASH, Moves.DRAGON_DANCE ], [Species.ARCTOZOLT]: [ Moves.MOUNTAIN_GALE, Moves.AQUA_STEP, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ], [Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ], [Species.ARCTOVISH]: [ Moves.ICE_FANG, Moves.THUNDER_FANG, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ], [Species.DURALUDON]: [ Moves.CORE_ENFORCER, Moves.BODY_PRESS, Moves.RECOVER, Moves.TACHYON_CUTTER ], - [Species.DREEPY]: [ Moves.SHADOW_BONE, Moves.POWER_UP_PUNCH, Moves.BLAZING_TORQUE, Moves.GLAIVE_RUSH ], + [Species.DREEPY]: [ Moves.SHADOW_BONE, Moves.NASTY_PLOT, Moves.FIRE_LASH, Moves.COLLISION_COURSE ], [Species.ZACIAN]: [ Moves.MAGICAL_TORQUE, Moves.MIGHTY_CLEAVE, Moves.BITTER_BLADE, Moves.PRECIPICE_BLADES ], - [Species.ZAMAZENTA]: [ Moves.PSYSHIELD_BASH, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.VICTORY_DANCE ], + [Species.ZAMAZENTA]: [ Moves.BULK_UP, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.DIAMOND_STORM ], [Species.ETERNATUS]: [ Moves.BODY_PRESS, Moves.NASTY_PLOT, Moves.MALIGNANT_CHAIN, Moves.DRAGON_ENERGY ], [Species.KUBFU]: [ Moves.METEOR_MASH, Moves.DRAIN_PUNCH, Moves.JET_PUNCH, Moves.DRAGON_DANCE ], [Species.ZARUDE]: [ Moves.SAPPY_SEED, Moves.MIGHTY_CLEAVE, Moves.WICKED_BLOW, Moves.VICTORY_DANCE ], @@ -482,7 +482,7 @@ export const speciesEggMoves = { [Species.NYMBLE]: [ Moves.KNOCK_OFF, Moves.FELL_STINGER, Moves.ATTACK_ORDER, Moves.WICKED_BLOW ], [Species.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.ICE_PUNCH, Moves.MACH_PUNCH, Moves.PLASMA_FISTS ], [Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.THIEF, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ], - [Species.FIDOUGH]: [ Moves.WISH, Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.TIDY_UP ], + [Species.FIDOUGH]: [ Moves.SOFT_BOILED, Moves.HIGH_HORSEPOWER, Moves.SIZZLY_SLIDE, Moves.TIDY_UP ], [Species.SMOLIV]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.BOOMBURST ], [Species.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ], [Species.NACLI]: [ Moves.BODY_PRESS, Moves.TOXIC, Moves.CURSE, Moves.DIAMOND_STORM ], @@ -492,7 +492,7 @@ export const speciesEggMoves = { [Species.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.CLOSE_COMBAT, Moves.PSYCHIC_FANGS, Moves.NO_RETREAT ], [Species.SHROODLE]: [ Moves.GASTRO_ACID, Moves.PARTING_SHOT, Moves.TOXIC, Moves.SKETCH ], [Species.BRAMBLIN]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.FLOWER_TRICK, Moves.LAST_RESPECTS ], - [Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SAPPY_SEED ], + [Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.SAPPY_SEED, Moves.TAIL_GLOW ], [Species.KLAWF]: [ Moves.CRABHAMMER, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH ], [Species.CAPSAKID]: [ Moves.STRENGTH_SAP, Moves.APPLE_ACID, Moves.FROST_BREATH, Moves.TORCH_SONG ], [Species.RELLOR]: [ Moves.HEAL_BLOCK, Moves.RECOVER, Moves.HEAT_WAVE, Moves.LUMINA_CRASH ], @@ -509,7 +509,7 @@ export const speciesEggMoves = { [Species.FLAMIGO]: [ Moves.THUNDEROUS_KICK, Moves.TRIPLE_AXEL, Moves.FLOATY_FALL, Moves.VICTORY_DANCE ], [Species.CETODDLE]: [ Moves.MOUNTAIN_GALE, Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.DRAGON_DANCE ], [Species.VELUZA]: [ Moves.PSYBLADE, Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.BITTER_BLADE ], - [Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.ICE_SPINNER, Moves.TOXIC, Moves.SALT_CURE ], + [Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.SIZZLY_SLIDE, Moves.TOXIC, Moves.SALT_CURE ], [Species.TATSUGIRI]: [ Moves.ICE_BEAM, Moves.FILLET_AWAY, Moves.CORE_ENFORCER, Moves.STEAM_ERUPTION ], [Species.GREAT_TUSK]: [ Moves.STONE_AXE, Moves.MORNING_SUN, Moves.COLLISION_COURSE, Moves.SHIFT_GEAR ], [Species.SCREAM_TAIL]: [ Moves.TORCH_SONG, Moves.GLITZY_GLOW, Moves.MOONLIGHT, Moves.SPARKLY_SWIRL ], @@ -521,7 +521,7 @@ export const speciesEggMoves = { [Species.IRON_BUNDLE]: [ Moves.EARTH_POWER, Moves.BOUNCY_BUBBLE, Moves.NASTY_PLOT, Moves.STEAM_ERUPTION ], [Species.IRON_HANDS]: [ Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS, Moves.ICE_HAMMER ], [Species.IRON_JUGULIS]: [ Moves.FIERY_WRATH, Moves.ROOST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ], - [Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.QUIVER_DANCE, Moves.MALIGNANT_CHAIN ], + [Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.MALIGNANT_CHAIN, Moves.QUIVER_DANCE ], [Species.IRON_THORNS]: [ Moves.DIAMOND_STORM, Moves.SHORE_UP, Moves.SHIFT_GEAR, Moves.PLASMA_FISTS ], [Species.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.GLACIAL_LANCE ], [Species.GIMMIGHOUL]: [ Moves.HAPPY_HOUR, Moves.AURA_SPHERE, Moves.SURF, Moves.ASTRAL_BARRAGE ], @@ -540,7 +540,7 @@ export const speciesEggMoves = { [Species.MUNKIDORI]: [ Moves.PSYSTRIKE, Moves.HEAT_WAVE, Moves.EARTH_POWER, Moves.MALIGNANT_CHAIN ], [Species.FEZANDIPITI]: [ Moves.BARB_BARRAGE, Moves.VICTORY_DANCE, Moves.TRIPLE_AXEL, Moves.MAGICAL_TORQUE ], [Species.OGERPON]: [ Moves.FLOWER_TRICK, Moves.BONEMERANG, Moves.TRIPLE_AXEL, Moves.GIGATON_HAMMER ], - [Species.GOUGING_FIRE]: [ Moves.SUPERCELL_SLAM, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ], + [Species.GOUGING_FIRE]: [ Moves.EXTREME_SPEED, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ], [Species.RAGING_BOLT]: [ Moves.NASTY_PLOT, Moves.FLAMETHROWER, Moves.MORNING_SUN, Moves.ELECTRO_DRIFT ], [Species.IRON_BOULDER]: [ Moves.PSYBLADE, Moves.KOWTOW_CLEAVE, Moves.STONE_AXE, Moves.BITTER_BLADE ], [Species.IRON_CROWN]: [ Moves.NASTY_PLOT, Moves.SECRET_SWORD, Moves.PSYSTRIKE, Moves.ELECTRO_DRIFT ], @@ -566,7 +566,7 @@ export const speciesEggMoves = { [Species.GALAR_DARUMAKA]: [ Moves.ICE_SPINNER, Moves.ENDURE, Moves.DRAIN_PUNCH, Moves.V_CREATE ], [Species.GALAR_YAMASK]: [ Moves.STRENGTH_SAP, Moves.DIRE_CLAW, Moves.THOUSAND_WAVES, Moves.SPECTRAL_THIEF ], [Species.GALAR_STUNFISK]: [ Moves.SPIKY_SHIELD, Moves.THOUSAND_ARROWS, Moves.STRENGTH_SAP, Moves.DOUBLE_IRON_BASH ], - [Species.HISUI_GROWLITHE]: [ Moves.WOOD_HAMMER, Moves.HEAD_SMASH, Moves.MORNING_SUN, Moves.DRAGON_DANCE ], + [Species.HISUI_GROWLITHE]: [ Moves.WAVE_CRASH, Moves.HEAD_SMASH, Moves.VOLT_TACKLE, Moves.DRAGON_DANCE ], [Species.HISUI_VOLTORB]: [ Moves.FROST_BREATH, Moves.NASTY_PLOT, Moves.APPLE_ACID, Moves.ELECTRO_DRIFT ], [Species.HISUI_QWILFISH]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.STRENGTH_SAP, Moves.FISHIOUS_REND ], [Species.HISUI_SNEASEL]: [ Moves.THUNDEROUS_KICK, Moves.KNOCK_OFF, Moves.TRIPLE_AXEL, Moves.VICTORY_DANCE ], From 69cac2342159757e21dec9f13b60cbbf1905e29b Mon Sep 17 00:00:00 2001 From: damocleas Date: Thu, 26 Sep 2024 18:07:27 -0400 Subject: [PATCH 08/65] [Balance] Various Pokemon and Move Balance Changes, labels for E-Floette and Ursaluna-BM (#4414) * Gmax Changes for Venusaur, Blastoise, Lapras, Regenerator Mega Audino, Darkrai and Cosmog upped 6 -> 7 cost * Changed Heal Order to 5pp to match other Recovery options * Updated Ursaluna-BM and Eternal-Floette to Sub-Legend for easier handling, Adjust catchrates to Metagross to match Baxcalibur line, and Iron Leaves/Walking Wake catchrate to match the other paradox legends * Actually updated catchrate for Iron Leaves and Walking Wake * Added comments for all changes * part 2 passive changes for the update, Pidgey, Lickitung, Stantler, Regigigas, Frillish, Litten, Chien Pao * fix space * Updated Meloetta Cost, Updated Krabby Passive --- src/data/move.ts | 2 +- src/data/pokemon-species.ts | 44 ++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 5320501cc0d..43f0b3be14d 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8080,7 +8080,7 @@ export function initMoves() { .makesContact(false), new SelfStatusMove(Moves.DEFEND_ORDER, Type.BUG, -1, 10, -1, 0, 4) .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, true), - new SelfStatusMove(Moves.HEAL_ORDER, Type.BUG, -1, 10, -1, 0, 4) + new SelfStatusMove(Moves.HEAL_ORDER, Type.BUG, -1, 5, -1, 0, 4) .attr(HealAttr, 0.5) .triageMove(), new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index b8ddd826035..2a1b43aa117 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -944,7 +944,7 @@ export function initSpecies() { new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), ), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -959,7 +959,7 @@ export function initSpecies() { new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 130, 115, 115, 68, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), ), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), @@ -1131,7 +1131,7 @@ export function initSpecies() { ), new PokemonSpecies(Species.LAPRAS, 1, false, false, false, "Transport Pokémon", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true, new PokemonForm("Normal", "", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ICE, 24, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 635, 170, 85, 95, 115, 110, 60, 45, 50, 187), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ICE, 24, 999.9, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, 635, 170, 85, 85, 105, 130, 60, 45, 50, 187), ), new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", Type.NORMAL, null, 0.3, 4, Abilities.LIMBER, Abilities.NONE, Abilities.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.EEVEE, 1, false, false, false, "Evolution Pokémon", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true, @@ -1492,9 +1492,9 @@ export function initSpecies() { new PokemonForm("Normal", "", Type.DRAGON, Type.FLYING, 1.5, 102.6, Abilities.INTIMIDATE, Abilities.NONE, Abilities.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.DRAGON, Type.FLYING, 1.8, 112.6, Abilities.AERILATE, Abilities.NONE, Abilities.AERILATE, 700, 95, 145, 130, 120, 90, 120, 45, 35, 300), ), - new PokemonSpecies(Species.BELDUM, 3, false, false, false, "Iron Ball Pokémon", Type.STEEL, Type.PSYCHIC, 0.6, 95.2, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 3, 35, 60, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.METANG, 3, false, false, false, "Iron Claw Pokémon", Type.STEEL, Type.PSYCHIC, 1.2, 202.5, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 3, 35, 147, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, GrowthRate.SLOW, null, false, true, + new PokemonSpecies(Species.BELDUM, 3, false, false, false, "Iron Ball Pokémon", Type.STEEL, Type.PSYCHIC, 0.6, 95.2, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 45, 35, 60, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Frigibax + new PokemonSpecies(Species.METANG, 3, false, false, false, "Iron Claw Pokémon", Type.STEEL, Type.PSYCHIC, 1.2, 202.5, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 25, 35, 147, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Arctibax + new PokemonSpecies(Species.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 10, 35, 300, GrowthRate.SLOW, null, false, true, //Custom Catchrate, matching Baxcalibur new PokemonForm("Normal", "", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.STEEL, Type.PSYCHIC, 2.5, 942.9, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 700, 80, 145, 150, 105, 110, 110, 3, 35, 300), ), @@ -1745,7 +1745,7 @@ export function initSpecies() { new PokemonSpecies(Species.EXCADRILL, 5, false, false, false, "Subterrene Pokémon", Type.GROUND, Type.STEEL, 0.7, 40.4, Abilities.SAND_RUSH, Abilities.SAND_FORCE, Abilities.MOLD_BREAKER, 508, 110, 135, 60, 50, 65, 88, 60, 50, 178, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.AUDINO, 5, false, false, false, "Hearing Pokémon", Type.NORMAL, null, 1.1, 31, Abilities.HEALER, Abilities.REGENERATOR, Abilities.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, GrowthRate.FAST, 50, false, true, new PokemonForm("Normal", "", Type.NORMAL, null, 1.1, 31, Abilities.HEALER, Abilities.REGENERATOR, Abilities.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.NORMAL, Type.FAIRY, 1.5, 32, Abilities.HEALER, Abilities.HEALER, Abilities.HEALER, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390), + new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.NORMAL, Type.FAIRY, 1.5, 32, Abilities.REGENERATOR, Abilities.REGENERATOR, Abilities.REGENERATOR, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390), //Custom Ability, base form Hidden Ability ), new PokemonSpecies(Species.TIMBURR, 5, false, false, false, "Muscular Pokémon", Type.FIGHTING, null, 0.6, 12.5, Abilities.GUTS, Abilities.SHEER_FORCE, Abilities.IRON_FIST, 305, 75, 80, 55, 25, 35, 35, 180, 70, 61, GrowthRate.MEDIUM_SLOW, 75, false), new PokemonSpecies(Species.GURDURR, 5, false, false, false, "Muscular Pokémon", Type.FIGHTING, null, 1.2, 40, Abilities.GUTS, Abilities.SHEER_FORCE, Abilities.IRON_FIST, 405, 85, 105, 85, 40, 50, 40, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), @@ -2617,8 +2617,8 @@ export function initSpecies() { new PokemonForm("Aquatic Mode", "aquatic-mode", Type.ELECTRIC, Type.DRAGON, 2.8, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true), new PokemonForm("Glide Mode", "glide-mode", Type.ELECTRIC, Type.DRAGON, 2.8, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true), ), - new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 5, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 5, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt + new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown new PokemonSpecies(Species.DIPPLIN, 9, false, false, false, "Candy Apple Pokémon", Type.GRASS, Type.DRAGON, 0.4, 9.7, Abilities.SUPERSWEET_SYRUP, Abilities.GLUTTONY, Abilities.STICKY_HOLD, 485, 80, 80, 110, 95, 80, 40, 45, 50, 170, GrowthRate.ERRATIC, 50, false), new PokemonSpecies(Species.POLTCHAGEIST, 9, false, false, false, "Matcha Pokémon", Type.GRASS, Type.GHOST, 0.1, 1.1, Abilities.HOSPITALITY, Abilities.NONE, Abilities.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.SLOW, null, false, false, new PokemonForm("Counterfeit Form", "counterfeit", Type.GRASS, Type.GHOST, 0.1, 1.1, Abilities.HOSPITALITY, Abilities.NONE, Abilities.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, true), @@ -2671,7 +2671,7 @@ export function initSpecies() { new PokemonSpecies(Species.ALOLA_MUK, 7, false, false, false, "Sludge Pokémon", Type.POISON, Type.DARK, 1, 52, Abilities.POISON_TOUCH, Abilities.GLUTTONY, Abilities.POWER_OF_ALCHEMY, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.ALOLA_EXEGGUTOR, 7, false, false, false, "Coconut Pokémon", Type.GRASS, Type.DRAGON, 10.9, 415.6, Abilities.FRISK, Abilities.NONE, Abilities.HARVEST, 530, 95, 105, 85, 125, 75, 45, 45, 50, 186, GrowthRate.SLOW, 50, false), new PokemonSpecies(Species.ALOLA_MAROWAK, 7, false, false, false, "Bone Keeper Pokémon", Type.FIRE, Type.GHOST, 1, 34, Abilities.CURSED_BODY, Abilities.LIGHTNING_ROD, Abilities.ROCK_HEAD, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(Species.ETERNAL_FLOETTE, 6, false, false, false, "Single Bloom Pokémon", Type.FAIRY, null, 0.2, 0.9, Abilities.FLOWER_VEIL, Abilities.NONE, Abilities.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(Species.ETERNAL_FLOETTE, 6, true, false, false, "Single Bloom Pokémon", Type.FAIRY, null, 0.2, 0.9, Abilities.FLOWER_VEIL, Abilities.NONE, Abilities.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false), //Marked as Sub-Legend, for casing purposes new PokemonSpecies(Species.GALAR_MEOWTH, 8, false, false, false, "Scratch Cat Pokémon", Type.STEEL, null, 0.4, 7.5, Abilities.PICKUP, Abilities.TOUGH_CLAWS, Abilities.UNNERVE, 290, 50, 65, 55, 40, 40, 40, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GALAR_PONYTA, 8, false, false, false, "Fire Horse Pokémon", Type.PSYCHIC, null, 0.8, 24, Abilities.RUN_AWAY, Abilities.PASTEL_VEIL, Abilities.ANTICIPATION, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GALAR_RAPIDASH, 8, false, false, false, "Fire Horse Pokémon", Type.PSYCHIC, Type.FAIRY, 1.7, 80, Abilities.RUN_AWAY, Abilities.PASTEL_VEIL, Abilities.ANTICIPATION, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), @@ -2716,7 +2716,7 @@ export function initSpecies() { new PokemonForm("Aqua Breed", "aqua", Type.FIGHTING, Type.WATER, 1.4, 110, Abilities.INTIMIDATE, Abilities.ANGER_POINT, Abilities.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true), ), new PokemonSpecies(Species.PALDEA_WOOPER, 9, false, false, false, "Water Fish Pokémon", Type.POISON, Type.GROUND, 0.4, 11, Abilities.POISON_POINT, Abilities.WATER_ABSORB, Abilities.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, false, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), //Marked as Sub-Legend, for casing purposes ); } @@ -2985,7 +2985,7 @@ export const speciesStarters = { [Species.CRESSELIA]: 6, [Species.PHIONE]: 4, [Species.MANAPHY]: 7, - [Species.DARKRAI]: 6, + [Species.DARKRAI]: 7, [Species.SHAYMIN]: 6, [Species.ARCEUS]: 9, @@ -3069,7 +3069,7 @@ export const speciesStarters = { [Species.LANDORUS]: 7, [Species.KYUREM]: 8, [Species.KELDEO]: 6, - [Species.MELOETTA]: 6, + [Species.MELOETTA]: 7, [Species.GENESECT]: 6, [Species.CHESPIN]: 3, @@ -3150,7 +3150,7 @@ export const speciesStarters = { [Species.TAPU_LELE]: 6, [Species.TAPU_BULU]: 6, [Species.TAPU_FINI]: 6, - [Species.COSMOG]: 6, + [Species.COSMOG]: 7, [Species.NIHILEGO]: 6, [Species.BUZZWOLE]: 6, [Species.PHEROMOSA]: 7, @@ -3383,7 +3383,7 @@ export const starterPassiveAbilities = { [Species.SQUIRTLE]: Abilities.STURDY, [Species.CATERPIE]: Abilities.MAGICIAN, [Species.WEEDLE]: Abilities.TINTED_LENS, - [Species.PIDGEY]: Abilities.FLARE_BOOST, + [Species.PIDGEY]: Abilities.SHEER_FORCE, [Species.RATTATA]: Abilities.STRONG_JAW, [Species.SPEAROW]: Abilities.MOXIE, [Species.EKANS]: Abilities.REGENERATOR, @@ -3417,11 +3417,11 @@ export const starterPassiveAbilities = { [Species.GASTLY]: Abilities.SHADOW_SHIELD, [Species.ONIX]: Abilities.ROCKY_PAYLOAD, [Species.DROWZEE]: Abilities.MAGICIAN, - [Species.KRABBY]: Abilities.UNBURDEN, + [Species.KRABBY]: Abilities.THERMAL_EXCHANGE, [Species.VOLTORB]: Abilities.TRANSISTOR, [Species.EXEGGCUTE]: Abilities.RIPEN, [Species.CUBONE]: Abilities.PARENTAL_BOND, - [Species.LICKITUNG]: Abilities.THICK_FAT, + [Species.LICKITUNG]: Abilities.CHEEK_POUCH, [Species.KOFFING]: Abilities.PARENTAL_BOND, [Species.RHYHORN]: Abilities.FILTER, [Species.TANGELA]: Abilities.SEED_SOWER, @@ -3486,7 +3486,7 @@ export const starterPassiveAbilities = { [Species.SKARMORY]: Abilities.LIGHTNING_ROD, [Species.HOUNDOUR]: Abilities.DROUGHT, [Species.PHANPY]: Abilities.SPEED_BOOST, - [Species.STANTLER]: Abilities.ANALYTIC, + [Species.STANTLER]: Abilities.SPEED_BOOST, [Species.SMEARGLE]: Abilities.PRANKSTER, [Species.TYROGUE]: Abilities.MOXIE, [Species.SMOOCHUM]: Abilities.PSYCHIC_SURGE, @@ -3617,7 +3617,7 @@ export const starterPassiveAbilities = { [Species.DIALGA]: Abilities.LEVITATE, [Species.PALKIA]: Abilities.SPEED_BOOST, [Species.HEATRAN]: Abilities.EARTH_EATER, - [Species.REGIGIGAS]: Abilities.MINDS_EYE, + [Species.REGIGIGAS]: Abilities.SCRAPPY, [Species.GIRATINA]: Abilities.SHADOW_SHIELD, [Species.CRESSELIA]: Abilities.SHADOW_SHIELD, [Species.PHIONE]: Abilities.SIMPLE, @@ -3671,7 +3671,7 @@ export const starterPassiveAbilities = { [Species.EMOLGA]: Abilities.TRANSISTOR, [Species.KARRABLAST]: Abilities.QUICK_DRAW, [Species.FOONGUS]: Abilities.THICK_FAT, - [Species.FRILLISH]: Abilities.UNAWARE, + [Species.FRILLISH]: Abilities.POISON_HEAL, [Species.ALOMOMOLA]: Abilities.MULTISCALE, [Species.JOLTIK]: Abilities.TRANSISTOR, [Species.FERROSEED]: Abilities.ROUGH_SKIN, @@ -3745,7 +3745,7 @@ export const starterPassiveAbilities = { [Species.HOOPA]: Abilities.OPPORTUNIST, [Species.VOLCANION]: Abilities.FILTER, [Species.ROWLET]: Abilities.SNIPER, - [Species.LITTEN]: Abilities.FUR_COAT, + [Species.LITTEN]: Abilities.OPPORTUNIST, [Species.POPPLIO]: Abilities.PUNK_ROCK, [Species.PIKIPEK]: Abilities.TECHNICIAN, [Species.YUNGOOS]: Abilities.TOUGH_CLAWS, @@ -3899,7 +3899,7 @@ export const starterPassiveAbilities = { [Species.FRIGIBAX]: Abilities.SNOW_WARNING, [Species.GIMMIGHOUL]: Abilities.HONEY_GATHER, [Species.WO_CHIEN]: Abilities.VESSEL_OF_RUIN, - [Species.CHIEN_PAO]: Abilities.SNOW_WARNING, + [Species.CHIEN_PAO]: Abilities.INTIMIDATE, [Species.TING_LU]: Abilities.STAMINA, [Species.CHI_YU]: Abilities.BERSERK, [Species.ROARING_MOON]: Abilities.TOUGH_CLAWS, From 59cb6539a7a6510ad235265f1fbb27adc772ec5c Mon Sep 17 00:00:00 2001 From: DanStevensonx <114961842+DanStevensonx@users.noreply.github.com> Date: Fri, 27 Sep 2024 00:33:39 +0200 Subject: [PATCH 09/65] [Localization] Minor Spanish Typo Corrections (#4454) Co-authored-by: Lugiad --- .../es/mystery-encounters/department-store-sale-dialogue.json | 4 ++-- src/locales/es/trainer-names.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locales/es/mystery-encounters/department-store-sale-dialogue.json b/src/locales/es/mystery-encounters/department-store-sale-dialogue.json index e17d57b8c3c..f3f64a9ed57 100644 --- a/src/locales/es/mystery-encounters/department-store-sale-dialogue.json +++ b/src/locales/es/mystery-encounters/department-store-sale-dialogue.json @@ -1,7 +1,7 @@ { "intro": "Es una señora con un montón de bolsas de compras.", "speaker": "Compradora", - "intro_dialogue": "¡Hola! ¿También estás aquí por las increíbles rebajas? Hay un cupón especial que puedes canjear por un artículo gratis durante la venta. ¡Tengo uno extra. ¡Aquí tienes!", + "intro_dialogue": "¡Hola! ¿También estás aquí por las increíbles rebajas?$Hay un cupón especial que puedes canjear por un artículo gratis durante la venta. ¡Tengo uno extra. ¡Aquí tienes!", "title": "¡Rebajas en el Centro Comercial!", "description": "¡Hay mercancía en todas direcciones! Parece que hay 4 mostradores donde puedes canjear el cupón por varios artículos. ¡Las posibilidades son infinitas!", "query": "¿A qué mostrador irás?", @@ -24,4 +24,4 @@ } }, "outro": "¡Qué chollo! Deberías comprar allí más a menudo." -} \ No newline at end of file +} diff --git a/src/locales/es/trainer-names.json b/src/locales/es/trainer-names.json index 14e31638d9c..2e76c24be9f 100644 --- a/src/locales/es/trainer-names.json +++ b/src/locales/es/trainer-names.json @@ -180,5 +180,5 @@ "vicky": "Vicky", "vito": "Vito", "bug_type_superfan": "Superfan de los Pokémon Bicho", - "expert_pokemon_breeder": "Criaokémon Experta" + "expert_pokemon_breeder": "Criapokémon Experta" } From 6e18c76e25a9e165fda8867f0c90aa43eecf0e4f Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:35:38 -0500 Subject: [PATCH 10/65] [Balance] [Fix] Fix accidental Jirachi revert / Update Spritzee (#4455) * Fix Jirachi / Change Spritzee * Update egg-moves.ts --- src/data/egg-moves.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 1070b642eab..813ade94020 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -198,7 +198,7 @@ export const speciesEggMoves = { [Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FLIP_TURN, Moves.WILDBOLT_STORM ], [Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ], - [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS, Moves.SHELL_SMASH ], + [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ], [Species.DEOXYS]: [ Moves.COLLISION_COURSE, Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.LUMINA_CRASH ], [Species.TURTWIG]: [ Moves.SHELL_SMASH, Moves.MIGHTY_CLEAVE, Moves.ICE_SPINNER, Moves.SAPPY_SEED ], [Species.CHIMCHAR]: [ Moves.FIERY_DANCE, Moves.SECRET_SWORD, Moves.TRIPLE_AXEL, Moves.SACRED_FIRE ], @@ -347,7 +347,7 @@ export const speciesEggMoves = { [Species.FURFROU]: [ Moves.TIDY_UP, Moves.SLACK_OFF, Moves.COMBAT_TORQUE, Moves.MULTI_ATTACK ], [Species.ESPURR]: [ Moves.LUSTER_PURGE, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.DARK_VOID ], [Species.HONEDGE]: [ Moves.TACHYON_CUTTER, Moves.SHADOW_BONE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], - [Species.SPRITZEE]: [ Moves.TRICK_ROOM, Moves.FOUL_PLAY, Moves.WISH, Moves.REVIVAL_BLESSING ], + [Species.SPRITZEE]: [ Moves.SPEED_SWAP, Moves.TORCH_SONG, Moves.ROOST, Moves.REVIVAL_BLESSING ], [Species.SWIRLIX]: [ Moves.BELLY_DRUM, Moves.HEADLONG_RUSH, Moves.MAGICAL_TORQUE, Moves.REVIVAL_BLESSING ], [Species.INKAY]: [ Moves.POWER_TRIP, Moves.SPIN_OUT, Moves.RECOVER, Moves.PSYCHO_BOOST ], [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.CRABHAMMER, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], From 5997744aa2853909170c9b04298f06fee7c09884 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:43:28 -0400 Subject: [PATCH 11/65] [Beta][Bug] Major/minor ME bug fixes (#4451) * major/minor ME bug fixes * potential fix for failed save with rental pokemon * Update src/system/game-data.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/system/game-data.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * more bug fix cleanup and PR feedback * fix Uncommon Breed ME crash * real fix to Fun and Games force switch issues * add isBattleMysteryEncounter() helper function * add isBattleMysteryEncounter() helper function * fix unintentional replace all errors * fix catches not updating dex --------- Co-authored-by: ImperialSympathizer Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- public/images/trainer/bug_type_superfan.json | 1450 +---------------- public/images/trainer/bug_type_superfan.png | Bin 4111 -> 1159 bytes src/battle-scene.ts | 7 +- src/battle.ts | 9 +- src/data/move.ts | 5 + .../encounters/absolute-avarice-encounter.ts | 6 +- .../an-offer-you-cant-refuse-encounter.ts | 2 +- .../encounters/berries-abound-encounter.ts | 1 + .../encounters/bug-type-superfan-encounter.ts | 89 +- .../encounters/clowning-around-encounter.ts | 10 +- .../encounters/dancing-lessons-encounter.ts | 1 + .../encounters/fiery-fallout-encounter.ts | 1 + .../encounters/fight-or-flight-encounter.ts | 1 + .../encounters/fun-and-games-encounter.ts | 1 + .../slumbering-snorlax-encounter.ts | 1 + .../teleporting-hijinks-encounter.ts | 1 + .../the-expert-pokemon-breeder-encounter.ts | 5 +- .../encounters/the-strong-stuff-encounter.ts | 1 + .../encounters/training-session-encounter.ts | 33 +- .../encounters/trash-to-treasure-encounter.ts | 1 + .../encounters/uncommon-breed-encounter.ts | 8 +- .../encounters/weird-dream-encounter.ts | 22 +- .../utils/encounter-phase-utils.ts | 4 +- .../utils/encounter-pokemon-utils.ts | 12 +- src/field/pokemon.ts | 2 +- .../safari-zone-dialogue.json | 2 +- src/modifier/modifier.ts | 33 +- src/phases/command-phase.ts | 4 +- src/phases/encounter-phase.ts | 22 +- src/phases/post-summon-phase.ts | 3 +- src/phases/summon-phase.ts | 2 +- src/phases/victory-phase.ts | 2 +- src/system/game-data.ts | 40 +- 33 files changed, 217 insertions(+), 1564 deletions(-) diff --git a/public/images/trainer/bug_type_superfan.json b/public/images/trainer/bug_type_superfan.json index 74dca3583d5..6a77fe69912 100644 --- a/public/images/trainer/bug_type_superfan.json +++ b/public/images/trainer/bug_type_superfan.json @@ -4,1458 +4,30 @@ "image": "bug_type_superfan.png", "format": "RGBA8888", "size": { - "w": 224, - "h": 224 + "w": 71, + "h": 71 }, "scale": 1, "frames": [ - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 52, - "h": 85 - }, - "frame": { - "x": 1, - "y": 1, - "w": 52, - "h": 85 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 52, - "h": 85 - }, - "frame": { - "x": 1, - "y": 1, - "w": 52, - "h": 85 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 60, - "h": 75 - }, - "frame": { - "x": 55, - "y": 1, - "w": 60, - "h": 75 - } - }, { "filename": "0001.png", "rotated": false, "trimmed": true, "sourceSize": { "w": 80, - "h": 86 + "h": 80 }, "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 + "x": 4, + "y": 9, + "w": 71, + "h": 71 }, "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 19, - "w": 66, - "h": 67 - }, - "frame": { - "x": 49, - "y": 88, - "w": 66, - "h": 67 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 19, - "w": 66, - "h": 67 - }, - "frame": { - "x": 49, - "y": 88, - "w": 66, - "h": 67 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 49, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 49, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 7, - "y": 19, - "w": 65, - "h": 67 - }, - "frame": { - "x": 117, - "y": 71, - "w": 65, - "h": 67 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 7, - "y": 19, - "w": 65, - "h": 67 - }, - "frame": { - "x": 117, - "y": 71, - "w": 65, - "h": 67 + "w": 71, + "h": 71 } } ] @@ -1464,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:442c13442d70348845d7f5fcdfc121b3:3b8402aa64ee8990e64c7f03ffffbc55:568199339797fd79d11ae8d741953c1c$" + "smartupdate": "$TexturePacker:SmartUpdate:d051332055512f245ae68e912a28cd81:4926ba3fd9fe432bb535d13f4df1df4e:621aca0914900a3b9e235ebf0431ce2b$" } } diff --git a/public/images/trainer/bug_type_superfan.png b/public/images/trainer/bug_type_superfan.png index 59316fe6ed898706b85c654253306dc183d9888a..0d2fd7a68aeeb55a419e8aebd4ce290f85540754 100644 GIT binary patch delta 1153 zcmV-{1b+LEAcqNmiBL{Q4GJ0x0000DNk~Le0000-0000-2m=5B0Ag;cEdT%jW>8F2 zMNDaNnX9x@EgH;kPJw)dHI!DRV@Uu20A{~M@UnhpJ2n6Q|LEf4oK7H1YB#&PyS#d3 z@trX}t2#6v5_(EmP+oo2m1G|!Gc`UtU@Q$ZLSZ5@Eps#!C|RS*_xJa+EhMwD!ls_4 zaBBcnkzE&m4#WTe4#WYKD-Ig~00X*7L_t(o!@byxmYOgS24F4;gIr?8Wd(J&?fbuE z|Cvbuttenm(~F#4`T9>X32vk4KMcd;A0Xu(zuu%6VaFT}hc_Uz_hAkPqV15Dv=?Px zZgxzmX~5u$4)k^!o~5mh&P~M(&-KJTXD^rFzJU3NkwmD(JE8K3NfO*4_ z6b4Ggxi(j2ydza@ag?c06&#MUjiLSEFtc@%DJ)eb4qhjdLl~>##@ru;t!$?7=^ZBHbJ;8hq$)>DyM^%LFsb9@K1c?V<*r$!8yGj3$*@t&} zhyfX=ljT9r>hf_2%zkX++)FyFec?nD6#AGjydSJmP1AVgd0P{)f{UqhJSGXbU*uE* zfpL7b^m6;hj~^qG@SyTsJLl*ZjO2*1XqQcY9ASA9?7Cd(N(#Q&_ONsc58 z24`EQM13!DD47lqB@$;Dlcs&oW&H&uKhyNOnBkeIdw>3g!V+h$b^Y^7#x0Li_ccuy ziy0Rix}ra0i)C9hIsL$lVO(S5*wpDYj?t2hH4EY}a}!4nW*ZwM!e89lczwC%L^T0_ z^KF?V#^|O%ASlA{B`s({Owj=OTW=iV%hwD^!zqM2y~B_?cA*oE5Hq;dS=Xo|Wr;%z zHkLx2GBGuJXxORqJkW>Vp8|DVtWG%LA3K+}ZRhqm@n-5;fv70dao%Yha)#qOx?IYy zOZzyELgE5ue8wX_ z{p-7D^ust|dM1uM1?N98&czv=fSUBEH}+%t&)_?wm|swVxhJb8(_#QkHjiVTg3ge5{V6(!G<; z#0i^S9n23EQwPv(E6?=tEo?mw3|B>7WdYc*Q_^;y+0YFdp Te~$TR00000NkvXXu0mjf$+;9I literal 4111 zcmZWscQo8h7yel#2(c`}>Kkp9=p{|`9%Yq8?CBZ6DLI|-T zh)(pfLa@=I#wYLj&iBtZ=iGVb&U2r8=G>Y4$HW*JXwlO`X#oJB*U?r-T;Tj)qb9$Y z#douYFF?{r-&ErQFNPFCRTu5#ROIi0hzr%V3=Ku2$5K-KTU$e&T3cIZi$b?&ozBNv z&(F`-e{5gB5Rg4a7?=Rcs}rsl4vmktg+BmXhWs@$AS;Ir02qRF)KyG_rZ#OZXBP@H z$&N;d;P=nZr}f$|@p?1iR=2)qVmFW8*U&Rb(+D^=Z=H|-v;XOaP(15-Zh8y1T8~1D zyU`1GnJBjRi7mM*!b4tR-8k+7TA2ZG#P1tbSKG-+2YUTbx4NTt zq8enq1K_65>w0#DNdC&-&(Q~@uG21#Y=^32hg$79DccVApzDWM*P0V@{e zXZf!VK>$P8E%nORp&Jzd(XSmQA+G(mP7S854BLrU~nI;n&vkOnXf&sIb!CP`;b6k1a;lgj) z7?#d1$9>trS5>pfqAcTIR4&~{`3Qi&F$Ilv)S8g@9Kp@s<>Zou(ZYD!S*mHOT&bC6 z^`jH*Lq4mWJ(Tx1o)5b zZD`L;mR0-E0KO=2zOv$ig!OY?EnzoSXMv>Wr`O2mTTO^S3J%O@@cOG{S7(N`w|zfI z1Xb?gCRG$#vf6uC{P1OM&O5V@(?h+|?`_QLnDUk86RNn*4l7Mc1i=fHkXOA~{IZqi z5s}rPd?g0kn`ioePAg4>79b>_nR_rVH3pM&?f?{Pn;)usM)CcV+wDVTCAB6cWL-K< zTQQ+dSLU{VPcYaktU8IRNvVu7g%s_2=zm;ZAAui&p&vVUBJwc>dB+YxOWP1WPjwpf zB#`l``V-VIV0{hCCoLr(yA~R~wY^=zrJW%wzh3lglTcs@K?HZ+UT znO8F{Pu?%rCOKJXJ<aJgq?b_?%v_T@9Yl(%0t%sUd#G*pihodZkQpw zjSRt<7_XTYY2*ynB-^S48~FT_rbDuPY}3`5bQW9dk@!@suKBAdnw|YN@B-TxPm|QL z&vGZ!(v0>* zUvr`agt&M;%p9!uAWZM;g?BA^zEtflHhl%%n9h4agZyUL%1?zk$aAxo0A=D-e*& zt^=W9go4EK^FlHuN_XkVkg^usGswv5xM%AwZTVkid z>PT?La*_Bg`wFRc&*O(_M=duQdXkN}YH;#KpuRVG<%A8OmcaW!Lf1u?*bQ7f7PA$P zjoYPh_0|!Yd&3nw`vKg*6q0&(t;A+!V!|>ZK5<{bMUXJ1NS5w)vDGfp+L|rXA5PZ{U^4Pvmi?4V9d)Z7559s{}kh?+CE# zIr7C(|49JHZdVk6V?&r=jDwU62)g7ZB*U@OybU&rJc zC%YZxadTa&ak#JFU+-HkHUPVwqS&N8*{@_(Tl=--WARn^Es?O$CxZVFY^Fz*3r_`h zzEPS^6v9>{Y^zKbmtia3{!$1@ zb+5;_o?U~vQ2L1ame$0Z=XicsGv|T8^A1;4QGEUNi4{t4gp#W}&0GYwIAo$RszON= zv6`-9)&WI-5hkW;n)6(R$FliTIvqT$zvH~`n_QFDF0J`v$n)g$`V!2=36rJ|Qs6KY z#Pw?sto;{69JdVQa}CU`VpERH=?6QzO?r_|$$oOmS2+fRaGUCcmO+f@=WeWXKrF}; zh8P1_$Jo+^vSKTapF25t2_fWx)hO_t&9B{wO39k$D}3wbFqdbFWh@KRz2z%)uj!v6 zlGCF~tzuFbP_?cj8OI_={5UAbcAZwY|Lffhf;~s_&Psb|3uT|=-dOK?*(7)V?pw3F z?HJe!WPZyz*J-UX*(}kO4nFtO=>{?Onl$DP2$KP=LUv0SH}>we!B?64O>u(XtLeY|7L=O6!PT$VjZP^=wJk zM>Y9T|IwY*E%Xd3?xt&1b2baKOul*hs@?vzf4F?W;pW5#i zp)AH93Ieb4;p zJPOyno9nr=S;MkN?kRvsv!P)n8t zj$`qmw&}z;aSQsq@|^aYdyta`TX~B3i9uo(9(;34?-iKDv`7yj3M;x#eBw+31KC1K z!p4Yoh$~62@}eB>gKn*q3evYOB_NsXlj4ZCZ315xkqKMF4a06EAiwEiP;m;(a2(xr zA7{y7<9imprZ0UXOcsCHmWIJ=xkjC%s{JjSaN}$@l&!U2P4xesOhCdS0}Mp5ODT#+ zQbB_E&UHCQQ&RQghY4pXif2+mH^TDue@SzVzDJg@Ty*8S6Nyl*mbJKYvpitbK=h*F z;+|m$jbCV+5|B3d;TLMHn$PI|I5)S`h8c-s%{fcDdJ{XcZzfsujOdoI7#b9?E2sT< zZn;tS@}-F`Dl-9jkz@cQ=3|NrunbI z>UI>{nY8fGl2i$x?}GES4Cb_Ndt+HNOsEC)I7g$g=2K5%n6%`OC8@ z3>?vw{~OmL-mkECa1&X?@t5ke%Pa^i!lVnUf0S<;8Ei&$>M_G8?F$M5D>3PU>ahFb zl6wYYq+{Zo3b>;fOd_;xBpC^JeHBJ04%Y>dI?EZbpQP}`YAxC*eI zOy;KU9{sgsVSjcujc3scID^_sCa7F8ogiZ;HT=z(wO~q2C1KQ(vi(?IZ{%DEeF)+U z@n2AQsYQnI3<~;cSH%^I46rK4wV<2fG|<^EJ_LG6?ufAzob;P3^b+pXUW*C(Rp7#6 z>wxU0w+p5(9Fk?aBZTTQhE;vZ~Q%{$n+<7uBZ4de%A@+ZS#J`HW|F1~=mpI4JO%SNt)75Tgk9eaG cdB_fVZkrZFe?2{H`TMWe(J)Z2Qniox54TLqv;Y7A diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 6b53ffd6a7f..ff0ca47bcac 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1201,7 +1201,7 @@ export default class BattleScene extends SceneBase { // Check for mystery encounter // Can only occur in place of a standard (non-boss) wild battle, waves 10-180 - if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex, mysteryEncounterType) || newBattleType === BattleType.MYSTERY_ENCOUNTER || !isNullOrUndefined(mysteryEncounterType)) { + if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex, mysteryEncounterType) || newBattleType === BattleType.MYSTERY_ENCOUNTER) { newBattleType = BattleType.MYSTERY_ENCOUNTER; // Reset base spawn weight this.mysteryEncounterSaveData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT; @@ -3002,7 +3002,7 @@ export default class BattleScene extends SceneBase { if (participantIds.size > 0) { if (this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) { expValue = Math.floor(expValue * 1.5); - } else if (this.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.currentBattle.mysteryEncounter) { + } else if (this.currentBattle.isBattleMysteryEncounter() && this.currentBattle.mysteryEncounter) { expValue = Math.floor(expValue * this.currentBattle.mysteryEncounter.expMultiplier); } for (const partyMember of nonFaintedPartyMembers) { @@ -3102,9 +3102,10 @@ export default class BattleScene extends SceneBase { // If total number of encounters is lower than expected for the run, slightly favor a new encounter spawn (reverse as well) // Reduces occurrence of runs with total encounters significantly different from AVERAGE_ENCOUNTERS_PER_RUN_TARGET + // Favored rate changes can never exceed 50%. So if base rate is 15/256 and favored rate would add 200/256, result will be (15 + 128)/256 const expectedEncountersByFloor = AVERAGE_ENCOUNTERS_PER_RUN_TARGET / (highestMysteryEncounterWave - lowestMysteryEncounterWave) * (waveIndex - lowestMysteryEncounterWave); const currentRunDiffFromAvg = expectedEncountersByFloor - encounteredEvents.length; - const favoredEncounterRate = sessionEncounterRate + currentRunDiffFromAvg * ANTI_VARIANCE_WEIGHT_MODIFIER; + const favoredEncounterRate = sessionEncounterRate + Math.min(currentRunDiffFromAvg * ANTI_VARIANCE_WEIGHT_MODIFIER, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT / 2); const successRate = isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE) ? favoredEncounterRate : Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE!; diff --git a/src/battle.ts b/src/battle.ts index f9c16d0189d..778d2467803 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -213,7 +213,7 @@ export default class Battle { getBgmOverride(scene: BattleScene): string | null { const battlers = this.enemyParty.slice(0, this.getBattlerCount()); - if (this.battleType === BattleType.MYSTERY_ENCOUNTER && this.mysteryEncounter?.encounterMode === MysteryEncounterMode.DEFAULT) { + if (this.isBattleMysteryEncounter() && this.mysteryEncounter?.encounterMode === MysteryEncounterMode.DEFAULT) { // Music is overridden for MEs during ME onInit() // Should not use any BGM overrides before swapping from DEFAULT mode return null; @@ -409,6 +409,13 @@ export default class Battle { scene.rngSeedOverride = tempSeedOverride; return ret; } + + /** + * Returns if the battle is of type {@linkcode BattleType.MYSTERY_ENCOUNTER} + */ + isBattleMysteryEncounter(): boolean { + return this.battleType === BattleType.MYSTERY_ENCOUNTER; + } } export class FixedBattle extends Battle { diff --git a/src/data/move.ts b/src/data/move.ts index 43f0b3be14d..74ecead73fa 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5290,6 +5290,11 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { return false; } + if (!player && user.scene.currentBattle.isBattleMysteryEncounter() && !user.scene.currentBattle.mysteryEncounter?.fleeAllowed) { + // Don't allow wild opponents to be force switched during MEs with flee disabled + return false; + } + const blockedByAbility = new Utils.BooleanHolder(false); applyAbAttrs(ForceSwitchOutImmunityAbAttr, target, blockedByAbility); return !blockedByAbility.value; diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index efcd41054ea..432a0b778da 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -24,6 +24,7 @@ import { BerryType } from "#enums/berry-type"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import i18next from "i18next"; /** the i18n namespace for this encounter */ const namespace = "mysteryEncounter:absoluteAvarice"; @@ -38,6 +39,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn + .withFleeAllowed(false) .withIntroSpriteConfigs([ { // This sprite has the shadow @@ -262,15 +264,13 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = // Provides 1x Reviver Seed to each party member at end of battle const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED); + encounter.setDialogueToken("foodReward", revSeed?.name ?? i18next.t("modifierType:ModifierType.REVIVER_SEED.name")); const givePartyPokemonReviverSeeds = () => { const party = scene.getParty(); party.forEach(p => { const heldItems = p.getHeldItems(); if (revSeed && !heldItems.some(item => item instanceof PokemonInstantReviveModifier)) { const seedModifier = revSeed.newModifier(p); - if (seedModifier) { - encounter.setDialogueToken("foodReward", seedModifier.type.name); - } scene.addModifier(seedModifier, false, false, false, true); } }); diff --git a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts index 919cd1df5ca..8746c387545 100644 --- a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts +++ b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts @@ -70,7 +70,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const pokemon = getHighestStatTotalPlayerPokemon(scene, true, true); - const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId(true); + const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId(); const starterValue: number = speciesStarters[baseSpecies] ?? 1; const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER); const price = scene.getWaveMoneyAmount(multiplier); diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index a112355b033..a7f8d62c233 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -46,6 +46,7 @@ export const BerriesAboundEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 35858b2e6db..3a80e92918d 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -49,6 +49,7 @@ import MoveInfoOverlay from "#app/ui/move-info-overlay"; import { allMoves } from "#app/data/move"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:bugTypeSuperfan"; @@ -177,9 +178,14 @@ const MISC_TUTOR_MOVES = [ Moves.U_TURN ]; +/** + * Wave breakpoints that determine how strong to make the Bug-Type Superfan's team + */ +const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160]; + /** * Bug Type Superfan encounter. - * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810} + * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3820 | GitHub Issue #3820} * @see For biome requirements check {@linkcode mysteryEncountersByBiome} */ export const BugTypeSuperfanEncounter: MysteryEncounter = @@ -216,11 +222,46 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = female: true, }); + let beedrillKeys: { spriteKey: string, fileRoot: string }, butterfreeKeys: { spriteKey: string, fileRoot: string }; + if (scene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) { + beedrillKeys = getSpriteKeysFromSpecies(Species.BEEDRILL, false); + butterfreeKeys = getSpriteKeysFromSpecies(Species.BUTTERFREE, false); + } else { + // Mega Beedrill/Gmax Butterfree + beedrillKeys = getSpriteKeysFromSpecies(Species.BEEDRILL, false, 1); + butterfreeKeys = getSpriteKeysFromSpecies(Species.BUTTERFREE, false, 1); + } + encounter.spriteConfigs = [ + { + spriteKey: beedrillKeys.spriteKey, + fileRoot: beedrillKeys.fileRoot, + hasShadow: true, + repeat: true, + isPokemon: true, + x: -30, + tint: 0.15, + y: -4, + yShadow: -4 + }, + { + spriteKey: butterfreeKeys.spriteKey, + fileRoot: butterfreeKeys.fileRoot, + hasShadow: true, + repeat: true, + isPokemon: true, + x: 30, + tint: 0.15, + y: -4, + yShadow: -4 + }, { spriteKey: spriteKey, fileRoot: "trainer", hasShadow: true, + x: 4, + y: 7, + yShadow: 7 }, ]; @@ -330,6 +371,10 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = if (formChangeModifier) { specialOptions.push(formChangeModifier); } + const rareFormChangeModifier = generateModifierTypeOption(scene, modifierTypes.RARE_FORM_CHANGE_ITEM); + if (rareFormChangeModifier) { + specialOptions.push(rareFormChangeModifier); + } if (specialOptions.length > 0) { modifierOptions.push(specialOptions[randSeedInt(specialOptions.length)]); } @@ -445,29 +490,29 @@ function getTrainerConfigForWave(waveIndex: number) { const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].clone(); config.name = i18next.t("trainerNames:bug_type_superfan"); - const pool3Copy = POOL_3_POKEMON.slice(0); - randSeedShuffle(pool3Copy); + let pool3Copy = POOL_3_POKEMON.slice(0); + pool3Copy = randSeedShuffle(pool3Copy); const pool3Mon = pool3Copy.pop()!; - if (waveIndex < 30) { + if (waveIndex < WAVE_LEVEL_BREAKPOINTS[0]) { // Use default template (2 AVG) config .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)); - } else if (waveIndex < 50) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[1]) { config .setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 70) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[2]) { config .setPartyTemplates(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 100) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) { config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) @@ -475,7 +520,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 120) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[4]) { config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -497,8 +542,8 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })); - } else if (waveIndex < 140) { - randSeedShuffle(pool3Copy); + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[5]) { + pool3Copy = randSeedShuffle(pool3Copy); const pool3Mon2 = pool3Copy.pop()!; config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) @@ -527,7 +572,7 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })); - } else if (waveIndex < 160) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[6]) { config .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG))) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -629,27 +674,7 @@ function doBugTypeMoveTutor(scene: BattleScene): Promise { moveInfoOverlay.setVisible(false); } - // TODO: add menu to confirm player doesn't want to teach a move - // while (!result && !forceExit) { - // // Didn't teach a move, ask the player to confirm they don't want to teach a move - // await showEncounterDialogue(scene, `${namespace}.confirm_no_teach`, `${namespace}.speaker`); - // const confirm = await new Promise(confirmResolve => { - // scene.ui.setMode(Mode.CONFIRM, () => confirmResolve(true), () => confirmResolve(false)); - // }); - // scene.ui.clearText(); - // await scene.ui.setMode(Mode.MESSAGE); - // if (confirm) { - // // No teach, break out of loop - // forceExit = true; - // } else { - // // Re-show learn menu - // result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel); - // if (!result) { - // moveInfoOverlay.active = false; - // moveInfoOverlay.setVisible(false); - // } - // } - // } + // TODO: add menu to confirm player doesn't want to teach a move? // Option select complete, handle if they are learning a move if (result && result.selectedOptionIndex < moveOptions.length) { diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index e1e681e95dd..7e846b42ea4 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -336,8 +336,8 @@ export const ClowningAroundEncounter: MysteryEncounter = .filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS) .map(move => move!.getMove().type); if (priorityTypes?.length > 0) { - priorityTypes = [...new Set(priorityTypes)]; - randSeedShuffle(priorityTypes); + priorityTypes = [...new Set(priorityTypes)].sort(); + priorityTypes = randSeedShuffle(priorityTypes); } const newTypes = [originalTypes[0]]; @@ -494,9 +494,13 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem } for (let i = 0; i < numItems; i++) { + if (pool.length === 0) { + // Stop generating new items if somehow runs out of items to spawn + return; + } const randIndex = randSeedInt(pool.length); const newItemType = pool[randIndex]; - let newMod; + let newMod: PokemonHeldItemModifierType; if (tier === "Berries") { newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType; } else { diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index 1ceb14a7372..a99395726c8 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -90,6 +90,7 @@ export const DancingLessonsEncounter: MysteryEncounter = .withHideWildIntroMessage(true) .withAutoHideIntroVisuals(false) .withCatchAllowed(true) + .withFleeAllowed(false) .withOnVisualsStart((scene: BattleScene) => { const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getParty()[0]); danceAnim.play(scene); diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 13f9d926345..6775aee6b30 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -46,6 +46,7 @@ export const FieryFalloutEncounter: MysteryEncounter = .withIntroSpriteConfigs([]) // Set in onInit() .withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT) .withAutoHideIntroVisuals(false) + .withFleeAllowed(false) .withIntroDialogue([ { text: `${namespace}.intro`, diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index 349984f1958..b3afdaf5f17 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -44,6 +44,7 @@ export const FightOrFlightEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { diff --git a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts index a144aa88299..1d8bf42528b 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -44,6 +44,7 @@ export const FunAndGamesEncounter: MysteryEncounter = .withSkipEnemyBattleTurns(true) // Will skip COMMAND selection menu and go straight to FIGHT (move select) menu .withSkipToFightInput(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "fun_and_games_game", diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index bfccc46ee0f..fe61766a888 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -34,6 +34,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: Species.SNORLAX.toString(), diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index abea725f113..386f4170156 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -42,6 +42,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = .withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost .withAutoHideIntroVisuals(false) .withCatchAllowed(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "teleporting_hijinks_teleporter", diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index 91aeea79111..e41b3ab03ef 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -437,8 +437,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { } function getSpeciesFromPool(speciesPool: (Species | BreederSpeciesEvolution)[][], waveIndex: number): Species { - const poolCopy = speciesPool.slice(0); - randSeedShuffle(poolCopy); + const poolCopy = randSeedShuffle(speciesPool.slice(0)); const speciesEvolutions = poolCopy.pop()!.slice(0); let speciesObject = speciesEvolutions.pop()!; while (speciesObject instanceof BreederSpeciesEvolution && speciesObject.evolution > waveIndex) { @@ -452,7 +451,7 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number] // 1 point for every 20 points below 680 BST the pokemon is, (max 18, min 1) const pointsFromBst = Math.min(Math.max(Math.floor((680 - bst) / 20), 1), 18); - const rootSpecies = pokemon.species.getRootSpeciesId(true); + const rootSpecies = pokemon.species.getRootSpeciesId(); let pointsFromStarterTier = 0; // 2 points for every 1 below 7 that the pokemon's starter tier is (max 12, min 0) if (speciesStarters.hasOwnProperty(rootSpecies)) { diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index 56328695128..10537cbe200 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -39,6 +39,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = .withMaxAllowedEncounters(1) .withHideWildIntroMessage(true) .withAutoHideIntroVisuals(false) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "berry_juice", diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 33864c00143..ea59b8003f5 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -101,7 +101,7 @@ export const TrainingSessionEncounter: MysteryEncounter = encounter.setDialogueToken("stat1", "-"); encounter.setDialogueToken("stat2", "-"); // Add the pokemon back to party with IV boost - const ivIndexes: any[] = []; + let ivIndexes: any[] = []; playerPokemon.ivs.forEach((iv, index) => { if (iv < 31) { ivIndexes.push({ iv: iv, index: index }); @@ -117,7 +117,7 @@ export const TrainingSessionEncounter: MysteryEncounter = // 25-27 starting IV caps in 2 encounters let improvedCount = 0; while (ivIndexes.length > 0 && improvedCount < 2) { - randSeedShuffle(ivIndexes); + ivIndexes = randSeedShuffle(ivIndexes); const ivToChange = ivIndexes.pop(); let newVal = ivToChange.iv; if (improvedCount === 0) { @@ -145,10 +145,7 @@ export const TrainingSessionEncounter: MysteryEncounter = if (improvedCount > 0) { playerPokemon.calculateStats(); - scene.gameData.updateSpeciesDexIvs( - playerPokemon.species.getRootSpeciesId(true), - playerPokemon.ivs - ); + scene.gameData.updateSpeciesDexIvs(playerPokemon.species.getRootSpeciesId(true), playerPokemon.ivs); scene.gameData.setPokemonCaught(playerPokemon, false); } @@ -322,27 +319,23 @@ export const TrainingSessionEncounter: MysteryEncounter = queueEncounterMessage(scene, `${namespace}.option.3.finished`); // Add the pokemon back to party with ability change const abilityIndex = encounter.misc.abilityIndex; + if (!!playerPokemon.getFusionSpeciesForm()) { playerPokemon.fusionAbilityIndex = abilityIndex; - if (!isNullOrUndefined(playerPokemon.fusionSpecies?.speciesId) && speciesStarters.hasOwnProperty(playerPokemon.fusionSpecies.speciesId)) { - scene.gameData.starterData[playerPokemon.fusionSpecies.speciesId] - .abilityAttr |= - abilityIndex !== 1 || playerPokemon.fusionSpecies.ability2 - ? Math.pow(2, playerPokemon.fusionAbilityIndex) - : AbilityAttr.ABILITY_HIDDEN; + + // Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals) + const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId(); + if (!isNullOrUndefined(rootFusionSpecies) + && speciesStarters.hasOwnProperty(rootFusionSpecies) + && !!scene.gameData.dexData[rootFusionSpecies].caughtAttr) { + scene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2 + ? 1 << playerPokemon.fusionAbilityIndex + : AbilityAttr.ABILITY_HIDDEN; } } else { playerPokemon.abilityIndex = abilityIndex; - if (speciesStarters.hasOwnProperty(playerPokemon.species.speciesId)) { - scene.gameData.starterData[playerPokemon.species.speciesId] - .abilityAttr |= - abilityIndex !== 1 || playerPokemon.species.ability2 - ? Math.pow(2, playerPokemon.abilityIndex) - : AbilityAttr.ABILITY_HIDDEN; - } } - playerPokemon.getAbility(); playerPokemon.calculateStats(); scene.gameData.setPokemonCaught(playerPokemon, false); diff --git a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts index 98aa90c0818..4b2333297c0 100644 --- a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts +++ b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts @@ -36,6 +36,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.ULTRA) .withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1]) .withMaxAllowedEncounters(1) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: Species.GARBODOR.toString() + "-gigantamax", diff --git a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts index 24298a633df..14ba7895434 100644 --- a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts +++ b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts @@ -38,6 +38,7 @@ export const UncommonBreedEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { @@ -59,17 +60,18 @@ export const UncommonBreedEncounter: MysteryEncounter = const eggMoveIndex = randSeedInt(4); const randomEggMove: Moves = eggMoves[eggMoveIndex]; encounter.misc = { - eggMove: randomEggMove + eggMove: randomEggMove, + pokemon: pokemon }; if (pokemon.moveset.length < 4) { pokemon.moveset.push(new PokemonMove(randomEggMove)); } else { pokemon.moveset[0] = new PokemonMove(randomEggMove); } + } else { + encounter.misc.pokemon = pokemon; } - encounter.misc.pokemon = pokemon; - // Defense/Spd buffs below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? [Stat.DEF, Stat.SPDEF, Stat.SPD] : diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 8fa60774a72..71e8491df69 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -368,7 +368,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon const newEggMoveIndex = await addEggMoveToNewPokemonMoveset(scene, newPokemon, speciesRootForm); // Try to add a favored STAB move (might fail if Pokemon already knows a bunch of moves from newPokemonGeneratedMoveset) - addFavoredMoveToNewPokemonMoveset(scene, newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); + addFavoredMoveToNewPokemonMoveset(newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); // Randomize the second type of the pokemon // If the pokemon does not normally have a second type, it will gain 1 @@ -553,8 +553,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla let eggMoveIndex: null | number = null; const eggMoves = newPokemon.getEggMoves()?.slice(0); if (eggMoves) { - const eggMoveIndices = [0, 1, 2, 3]; - randSeedShuffle(eggMoveIndices); + const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]); let randomEggMoveIndex = eggMoveIndices.pop(); let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; let retries = 0; @@ -587,12 +586,11 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla /** * Returns index of the new egg move within the Pokemon's moveset (not the index of the move in `speciesEggMoves`) - * @param scene * @param newPokemon * @param newPokemonGeneratedMoveset * @param newEggMoveIndex */ -function addFavoredMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: PlayerPokemon, newPokemonGeneratedMoveset: (PokemonMove | null)[], newEggMoveIndex: number | null) { +function addFavoredMoveToNewPokemonMoveset(newPokemon: PlayerPokemon, newPokemonGeneratedMoveset: (PokemonMove | null)[], newEggMoveIndex: number | null) { let favoredMove: PokemonMove | null = null; for (const move of newPokemonGeneratedMoveset) { // Needs to match first type, second type will be replaced @@ -614,11 +612,15 @@ function addFavoredMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Playe } // Finally, assign favored move to random index that isn't the new egg move index if (favoredMove) { - let favoredMoveIndex = randSeedInt(4); - while (newEggMoveIndex !== null && favoredMoveIndex === newEggMoveIndex) { - favoredMoveIndex = randSeedInt(4); - } + if (newPokemon.moveset.length < 4) { + newPokemon.moveset.push(favoredMove); + } else { + let favoredMoveIndex = randSeedInt(4); + while (newEggMoveIndex !== null && favoredMoveIndex === newEggMoveIndex) { + favoredMoveIndex = randSeedInt(4); + } - newPokemon.moveset[favoredMoveIndex] = favoredMove; + newPokemon.moveset[favoredMoveIndex] = favoredMove; + } } } diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index ea04241e663..ca02c8bdfd6 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -832,7 +832,7 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide: */ export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter; - if (scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) { + if (scene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) { const effects = encounter.startOfBattleEffects; effects.forEach(effect => { let source; @@ -871,7 +871,7 @@ export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) { */ export function handleMysteryEncounterTurnStartEffects(scene: BattleScene): boolean { const encounter = scene.currentBattle.mysteryEncounter; - if (scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && encounter && encounter.onTurnStart) { + if (scene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.onTurnStart) { return encounter.onTurnStart(scene); } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index d7e596af879..c9b30415299 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -210,10 +210,10 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu .map(s => [parseInt(s) as Species, speciesStarters[s] as number]) .filter(s => { const pokemonSpecies = getPokemonSpecies(s[0]); - return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]) + return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0])) && (allowSubLegendary || !pokemonSpecies.subLegendary) && (allowLegendary || !pokemonSpecies.legendary) - && (allowMythical || !pokemonSpecies.mythical)); + && (allowMythical || !pokemonSpecies.mythical); }) .map(s => [getPokemonSpecies(s[0]), s[1]]); @@ -757,9 +757,10 @@ const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [ ]; /** - * Will randomly return one of the species from GOLDEN_BUG_NET_SPECIES_POOL, based on their weights + * Will randomly return one of the species from GOLDEN_BUG_NET_SPECIES_POOL, based on their weights. + * Will also check for and evolve pokemon based on level. */ -export function getGoldenBugNetSpecies(): PokemonSpecies { +export function getGoldenBugNetSpecies(level: number): PokemonSpecies { const totalWeight = GOLDEN_BUG_NET_SPECIES_POOL.reduce((a, b) => a + b[1], 0); const roll = randSeedInt(totalWeight); @@ -767,7 +768,8 @@ export function getGoldenBugNetSpecies(): PokemonSpecies { for (const speciesWeightPair of GOLDEN_BUG_NET_SPECIES_POOL) { w += speciesWeightPair[1]; if (roll < w) { - return getPokemonSpecies(speciesWeightPair[0]); + const initialSpecies = getPokemonSpecies(speciesWeightPair[0]); + return getPokemonSpecies(initialSpecies.getSpeciesForLevel(level, true)); } } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index fda4d2226c0..0fda3d075be 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1801,7 +1801,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns list of egg moves */ getEggMoves() : Moves[] | undefined { - return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId(true)]; + return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId()]; } setMove(moveIndex: integer, moveId: Moves): void { diff --git a/src/locales/en/mystery-encounters/safari-zone-dialogue.json b/src/locales/en/mystery-encounters/safari-zone-dialogue.json index b96e3b5beb8..c1e4dd30852 100644 --- a/src/locales/en/mystery-encounters/safari-zone-dialogue.json +++ b/src/locales/en/mystery-encounters/safari-zone-dialogue.json @@ -1,7 +1,7 @@ { "intro": "It's a safari zone!", "title": "The Safari Zone", - "description": "There are all kinds of rare and special Pokémon that can be found here!\nIf you choose to enter, you'll have a time limit of @[TOOLTIP_TITLE]{{{numEncounters}} wild encounters} where you can try to catch these special Pokémon.\n\nBeware, though. These Pokémon may flee before you're able to catch them!", + "description": "There are all kinds of rare and special Pokémon that can be found here!\nIf you choose to enter, you'll have a time limit of@[TOOLTIP_TITLE]{ {{numEncounters}} wild encounters} where you can try to catch these special Pokémon.\n\nBeware, though. These Pokémon may flee before you're able to catch them!", "query": "Would you like to enter?", "option": { "1": { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 6c998105c1d..f53a07e8e21 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,4 +1,5 @@ import * as ModifierTypes from "./modifier-type"; +import { ModifierType, modifierTypes } from "./modifier-type"; import BattleScene from "../battle-scene"; import { getLevelTotalExp } from "../data/exp"; import { MAX_PER_TYPE_POKEBALLS, PokeballType } from "../data/pokeball"; @@ -12,16 +13,15 @@ import * as Utils from "../utils"; import { getBerryEffectFunc, getBerryPredicate } from "../data/berry"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; -import { StatusEffect, getStatusEffectHealText } from "../data/status-effect"; +import { getStatusEffectHealText, StatusEffect } from "#app/data/status-effect"; import { achvs } from "../system/achv"; import { VoucherType } from "../system/voucher"; import { FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "../data/pokemon-forms"; import { Nature } from "#app/data/nature"; import Overrides from "#app/overrides"; -import { ModifierType, modifierTypes } from "./modifier-type"; import { Command } from "#app/ui/command-ui-handler"; import { Species } from "#enums/species"; -import { Stat, type PermanentStat, type TempBattleStat, BATTLE_STATS, TEMP_BATTLE_STATS } from "#app/enums/stat"; +import { BATTLE_STATS, type PermanentStat, Stat, TEMP_BATTLE_STATS, type TempBattleStat } from "#app/enums/stat"; import i18next from "i18next"; import { allMoves } from "#app/data/move"; @@ -882,7 +882,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { private statModifier: integer; public isTransferable: boolean = false; - constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: integer, statModifier: integer, stackCount?: integer) { + constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: number, statModifier: number, stackCount?: integer) { super(type, pokemonId, stackCount); this.statModifier = statModifier; } @@ -927,11 +927,11 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { * Currently used by Old Gateau item */ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { - private statModifier: integer; + private statModifier: number; private stats: Stat[]; public isTransferable: boolean = false; - constructor (type: ModifierType, pokemonId: integer, statModifier: integer, stats: Stat[], stackCount?: integer) { + constructor (type: ModifierType, pokemonId: number, statModifier: number, stats: Stat[], stackCount?: number) { super(type, pokemonId, stackCount); this.statModifier = statModifier; @@ -947,7 +947,7 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { } override getArgs(): any[] { - return super.getArgs().concat(this.statModifier, this.stats); + return [ ...super.getArgs(), this.statModifier, this.stats ]; } override shouldApply(args: any[]): boolean { @@ -989,8 +989,8 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { return modifier instanceof PokemonIncrementingStatModifier; } - clone(): PersistentModifier { - return new PokemonIncrementingStatModifier(this.type, this.pokemonId); + clone(): PokemonIncrementingStatModifier { + return new PokemonIncrementingStatModifier(this.type, this.pokemonId, this.stackCount); } getArgs(): any[] { @@ -1004,14 +1004,19 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { apply(args: any[]): boolean { // Modifies the passed in stats[] array by +1 per stack for HP, +2 per stack for other stats // If the Macho Brace is at max stacks (50), adds additional 5% to total HP and 10% to other stats + const targetToApply = args[0] as Pokemon; + args[1].forEach((v, i) => { const isHp = i === 0; - let mult = 1; - if (this.stackCount === this.getMaxHeldItemCount()) { - mult = isHp ? 1.05 : 1.1; + // Doesn't modify HP if holder has Wonder Guard + if (!isHp || !targetToApply.hasAbility(Abilities.WONDER_GUARD)) { + let mult = 1; + if (this.stackCount === this.getMaxHeldItemCount()) { + mult = isHp ? 1.05 : 1.1; + } + const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult); + args[1][i] = Math.min(Math.max(newVal, 1), 999999); } - const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult); - args[1][i] = Math.min(Math.max(newVal, 1), 999999); }); return true; diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 66e39cf98a5..a374f885d3f 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -70,7 +70,7 @@ export class CommandPhase extends FieldPhase { } } } else { - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.scene.currentBattle.mysteryEncounter?.skipToFightInput) { + if (this.scene.currentBattle.isBattleMysteryEncounter() && this.scene.currentBattle.mysteryEncounter?.skipToFightInput) { this.scene.ui.clearText(); this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); } else { @@ -141,7 +141,7 @@ export class CommandPhase extends FieldPhase { this.scene.ui.showText("", 0); this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); }, null, true); - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter() && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => { diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 25b4398025f..798ee3dca3c 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -34,6 +34,7 @@ import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encount import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { Biome } from "#enums/biome"; export class EncounterPhase extends BattlePhase { private loaded: boolean; @@ -63,7 +64,7 @@ export class EncounterPhase extends BattlePhase { const battle = this.scene.currentBattle; // Generate and Init Mystery Encounter - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER && !battle.mysteryEncounter) { + if (battle.isBattleMysteryEncounter() && !battle.mysteryEncounter) { this.scene.executeWithSeedOffset(() => { const currentSessionEncounterType = battle.mysteryEncounterType; battle.mysteryEncounter = this.scene.getMysteryEncounter(currentSessionEncounterType); @@ -79,7 +80,7 @@ export class EncounterPhase extends BattlePhase { mysteryEncounter.onInit(this.scene); } mysteryEncounter.populateDialogueTokensFromRequirements(this.scene); - }, this.scene.currentBattle.waveIndex); + }, battle.waveIndex); // Add any special encounter animations to load if (mysteryEncounter.encounterAnimations && mysteryEncounter.encounterAnimations.length > 0) { @@ -94,7 +95,7 @@ export class EncounterPhase extends BattlePhase { let totalBst = 0; battle.enemyLevels?.every((level, e) => { - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (battle.isBattleMysteryEncounter()) { // Skip enemy loading for MEs, those are loaded elsewhere return false; } @@ -103,9 +104,12 @@ export class EncounterPhase extends BattlePhase { battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? } else { let enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true); - // If player has golden bug net, rolls 10% chance to replace with species from the golden bug net bug pool - if (this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) && randSeedInt(10) === 0) { - enemySpecies = getGoldenBugNetSpecies(); + // If player has golden bug net, rolls 10% chance to replace non-boss wave wild species from the golden bug net bug pool + if (this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) + && !this.scene.gameMode.isBoss(battle.waveIndex) + && this.scene.arena.biomeType !== Biome.END + && randSeedInt(10) === 0) { + enemySpecies = getGoldenBugNetSpecies(level); } battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies)); if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { @@ -157,7 +161,7 @@ export class EncounterPhase extends BattlePhase { if (battle.battleType === BattleType.TRAINER) { loadEnemyAssets.push(battle.trainer?.loadAssets().then(() => battle.trainer?.initSprite())!); // TODO: is this bang correct? - } else if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + } else if (battle.isBattleMysteryEncounter()) { if (battle.mysteryEncounter?.introVisuals) { loadEnemyAssets.push(battle.mysteryEncounter.introVisuals.loadAssets().then(() => battle.mysteryEncounter!.introVisuals!.initSprite())); } @@ -189,7 +193,7 @@ export class EncounterPhase extends BattlePhase { Promise.all(loadEnemyAssets).then(() => { battle.enemyParty.every((enemyPokemon, e) => { - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (battle.isBattleMysteryEncounter()) { return false; } if (e < (battle.double ? 2 : 1)) { @@ -363,7 +367,7 @@ export class EncounterPhase extends BattlePhase { showDialogueAndSummon(); } } - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.scene.currentBattle.mysteryEncounter) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter() && this.scene.currentBattle.mysteryEncounter) { const encounter = this.scene.currentBattle.mysteryEncounter; const introVisuals = encounter.introVisuals; introVisuals?.playAnim(); diff --git a/src/phases/post-summon-phase.ts b/src/phases/post-summon-phase.ts index e7f6c6ea3db..b99c0b90fd8 100644 --- a/src/phases/post-summon-phase.ts +++ b/src/phases/post-summon-phase.ts @@ -6,7 +6,6 @@ import { StatusEffect } from "#app/enums/status-effect"; import { PokemonPhase } from "./pokemon-phase"; import { MysteryEncounterPostSummonTag } from "#app/data/battler-tags"; import { BattlerTagType } from "#enums/battler-tag-type"; -import { BattleType } from "#app/battle"; export class PostSummonPhase extends PokemonPhase { constructor(scene: BattleScene, battlerIndex: BattlerIndex) { @@ -24,7 +23,7 @@ export class PostSummonPhase extends PokemonPhase { this.scene.arena.applyTags(ArenaTrapTag, pokemon); // If this is mystery encounter and has post summon phase tag, apply post summon effects - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { + if (this.scene.currentBattle.isBattleMysteryEncounter() && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { pokemon.lapseTag(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON); } diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index d909c5c3501..dfa374307d5 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -87,7 +87,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.scene.pbTrayEnemy.hide(); this.scene.ui.showText(message, null, () => this.summon()); - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter()) { this.scene.pbTrayEnemy.hide(); this.summonWild(); } diff --git a/src/phases/victory-phase.ts b/src/phases/victory-phase.ts index c10adc5683d..e900ff97fc6 100644 --- a/src/phases/victory-phase.ts +++ b/src/phases/victory-phase.ts @@ -30,7 +30,7 @@ export class VictoryPhase extends PokemonPhase { const expValue = this.getPokemon().getExpValue(); this.scene.applyPartyExp(expValue, true); - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (this.scene.currentBattle.isBattleMysteryEncounter()) { handleMysteryEncounterVictory(this.scene, false, this.isExpOnly); return this.end(); } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 34c4f67328d..63c7cb1b13a 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1,5 +1,5 @@ import i18next from "i18next"; -import BattleScene, { PokeballCounts, bypassLogin } from "../battle-scene"; +import BattleScene, { bypassLogin, PokeballCounts } from "../battle-scene"; import Pokemon, { EnemyPokemon, PlayerPokemon } from "../field/pokemon"; import { pokemonPrevolutions } from "../data/pokemon-evolutions"; import PokemonSpecies, { allSpecies, getPokemonSpecies, noStarterFormKeys, speciesStarters } from "../data/pokemon-species"; @@ -13,11 +13,11 @@ import { GameModes, getGameMode } from "../game-mode"; import { BattleType } from "../battle"; import TrainerData from "./trainer-data"; import { trainerConfigs } from "../data/trainer-config"; -import { SettingKeys, resetSettings, setSetting } from "./settings/settings"; +import { resetSettings, setSetting, SettingKeys } from "./settings/settings"; import { achvs } from "./achv"; import EggData from "./egg-data"; import { Egg } from "../data/egg"; -import { VoucherType, vouchers } from "./voucher"; +import { vouchers, VoucherType } from "./voucher"; import { AES, enc } from "crypto-js"; import { Mode } from "../ui/ui"; import { clientSessionId, loggedInUser, updateUserInfo } from "../account"; @@ -28,8 +28,8 @@ import { speciesEggMoves } from "../data/egg-moves"; import { allMoves } from "../data/move"; import { TrainerVariant } from "../field/trainer"; import { Variant } from "#app/data/variant"; -import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./settings/settings-gamepad"; -import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "./settings/settings-gamepad"; +import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard"; import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; import * as Modifier from "../modifier/modifier"; import { StatusEffect } from "#app/data/status-effect"; @@ -1583,12 +1583,20 @@ export class GameData { * @returns `true` if Pokemon catch unlocked a new starter, `false` if Pokemon catch did not unlock a starter */ setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise { - return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage); + // If incrementCount === false (not a catch scenario), only update the pokemon's dex data if the Pokemon has already been marked as caught in dex + // Prevents form changes, nature changes, etc. from unintentionally updating the dex data of a "rental" pokemon + const speciesRootForm = pokemon.species.getRootSpeciesId(); + if (!incrementCount && !this.scene.gameData.dexData[speciesRootForm].caughtAttr) { + return Promise.resolve(false); + } else { + return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage); + } } /** * * @param pokemon + * @param species * @param incrementCount * @param fromEgg * @param showMessage @@ -1604,12 +1612,18 @@ export class GameData { } const dexAttr = pokemon.getDexAttr(); pokemon.formIndex = formIndex; + + // Mark as caught dexEntry.caughtAttr |= dexAttr; + + // Unlock ability if (speciesStarters.hasOwnProperty(species.speciesId)) { this.starterData[species.speciesId].abilityAttr |= pokemon.abilityIndex !== 1 || pokemon.species.ability2 ? 1 << pokemon.abilityIndex : AbilityAttr.ABILITY_HIDDEN; } + + // Unlock nature dexEntry.natureAttr |= 1 << (pokemon.nature + 1); const hasPrevolution = pokemonPrevolutions.hasOwnProperty(species.speciesId); @@ -1704,9 +1718,19 @@ export class GameData { return ++this.starterData[speciesIdToIncrement].classicWinCount; } + /** + * Adds a candy to the player's game data for a given {@linkcode PokemonSpecies}. + * Will do nothing if the player does not have the Pokemon owned in their system save data. + * @param species + * @param count + */ addStarterCandy(species: PokemonSpecies, count: integer): void { - this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count); - this.starterData[species.speciesId].candyCount += count; + // Only gain candies if the Pokemon has already been marked as caught in dex (ignore "rental" pokemon) + const speciesRootForm = species.getRootSpeciesId(); + if (this.scene.gameData.dexData[speciesRootForm].caughtAttr) { + this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count); + this.starterData[species.speciesId].candyCount += count; + } } /** From c7f00d0a4d07c38b07143ad5f8a4c302ab253b72 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Thu, 26 Sep 2024 22:13:15 -0400 Subject: [PATCH 12/65] Reinstate temporary evolution delay fix (#4458) --- src/data/pokemon-species.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 2a1b43aa117..94dbba958b5 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -762,6 +762,13 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali } } + //TODO: Adjust templates and delays so we don't have to hardcode it + /* TEMPORARY! (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */ + if (currentWave >= 80 && forTrainer && strength > PartyMemberStrength.WEAKER) { + evolutionChance = 1; + noEvolutionChance = 0; + } + if (evolutionChance > 0) { if (isRegionalEvolution) { evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4); From 933309cd000b43923f2865fd69a1effa5bf47a2b Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 26 Sep 2024 21:48:57 -0700 Subject: [PATCH 13/65] Fix Meloetta-related bugs in mono-type challenges (#4460) Remove Meloetta from the `TYPE_OVERRIDES` array so wrong-form Meloetta can't be sent into battle. This was missed when Meloetta was changed in a previous PR Also disallow Meloetta from being added to the party in starter select if it's in the wrong form for the current mono-type challenge --- src/data/challenge.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 1afbfc932dc..4cdaef7b1b3 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -527,18 +527,19 @@ interface monotypeOverride { */ export class SingleTypeChallenge extends Challenge { private static TYPE_OVERRIDES: monotypeOverride[] = [ - {species: Species.MELOETTA, type: Type.PSYCHIC, fusion: true}, {species: Species.CASTFORM, type: Type.NORMAL, fusion: false}, ]; + // TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy + private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA]; constructor() { super(Challenges.SINGLE_TYPE, 18); } - applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { + override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); const types = [speciesForm.type1, speciesForm.type2]; - if (soft) { + if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) { const speciesToCheck = [pokemon.speciesId]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); From b2df7d785bb9376f31d3602a5fd97c57ff8a21bf Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Fri, 27 Sep 2024 00:49:12 -0400 Subject: [PATCH 14/65] fix bug-type superfan's team on waves 160+ (#4459) Co-authored-by: ImperialSympathizer --- .../encounters/bug-type-superfan-encounter.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 3a80e92918d..827b2c12478 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -595,6 +595,8 @@ function getTrainerConfigForWave(waveIndex: number) { })) .setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true)); } else { + pool3Copy = randSeedShuffle(pool3Copy); + const pool3Mon2 = pool3Copy.pop()!; config .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG))) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -616,9 +618,9 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { - p.formIndex = pool3Mon.formIndex; + .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { + if (!isNullOrUndefined(pool3Mon2.formIndex)) { + p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); p.generateName(); } From a99ec0c6c55fbea33619fc7d0bac07c81770e001 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:23:41 +0800 Subject: [PATCH 15/65] [localization] Zh_cn ME parameters hotfix (#4462) * Update mysterious-chest-dialogue.json * Update shady-vitamin-dealer-dialogue.json * Update slumbering-snorlax-dialogue.json * Update training-session-dialogue.json --- .../zh_CN/mystery-encounters/mysterious-chest-dialogue.json | 2 +- .../zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json | 2 +- .../zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json | 2 +- .../zh_CN/mystery-encounters/training-session-dialogue.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json b/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json index ff01386ca59..b26c5d38c03 100644 --- a/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json @@ -12,7 +12,7 @@ "good": "一些不错的工具和物品!", "great": "一些很稀有的工具和物品!!", "amazing": "哇!金色传说!", - "bad": "哦不!@d{32}\n这个箱子实际上是一个伪装的{{gimmighoul Name}}!$你的{{pokeName}}跳到了你面前\n但为了保护你被打倒了!" + "bad": "哦不!@d{32}\n这个箱子实际上是一个伪装的{{gimmighoulName}}!$你的{{pokeName}}跳到了你面前\n但为了保护你被打倒了!" }, "2": { "label": "有诈,走了", diff --git a/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json b/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json index 359376eca3d..9412426d794 100644 --- a/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json @@ -20,7 +20,7 @@ "tooltip": "(-)无奖励", "selected": "呵呵,没想到你竟然是个懦夫。" }, - "selected": "那人递给你两瓶东西后\n然后很快就消失了。${{selected Pokemon}}获得了{{boost}}和{{boost 2}}提升!" + "selected": "那人递给你两瓶东西后\n然后很快就消失了。${{selectedPokemon}}获得了{{boost1}}和{{boost2}}提升!" }, "cheap_side_effects": "但是药物有一些副作用!$你的{{selectedPokemon}}受到一些伤害,\n并且它的性格变为{{newNature}}!", "no_bad_effects": "看来药物完全没有副作用!" diff --git a/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json b/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json index ee3109e3a1f..8ab03382477 100644 --- a/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json @@ -13,7 +13,7 @@ "label": "干等", "tooltip": "(-)漫长的等待\n(+)回复队伍", "selected": ".@d{32}.@d{32}.@d{32}$您等待了好一段时间,但是\n{{snorlaxName}}的哈欠让你的队伍昏昏欲睡…………", - "rest_result": "当你们醒来时,{{snorlax Name}}已无处可寻。\n但你所有的宝可梦都痊愈了!" + "rest_result": "当你们醒来时,{{snorlaxName}}已无处可寻。\n但你所有的宝可梦都痊愈了!" }, "3": { "label": "偷摸", diff --git a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json index dab52bef1db..7bb6229d330 100644 --- a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json @@ -27,7 +27,7 @@ "tooltip": "(-)无奖励", "selected": "你无暇训练\n该动身了。" }, - "selected": "{{selected Pokemon}}穿过空地来到你面前……" + "selected": "{{selectedPokemon}}穿过空地来到你面前……" }, "outro": "这次训练成果不错!" } From b426340aee1feef2fde08bb5f5aa500f5e970eee Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:10:16 +0200 Subject: [PATCH 16/65] [Localization][DE] Fix BattlerTags typo (#4464) --- src/locales/de/battler-tags.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/de/battler-tags.json b/src/locales/de/battler-tags.json index f4b9d71eb49..3a2f1b84e49 100644 --- a/src/locales/de/battler-tags.json +++ b/src/locales/de/battler-tags.json @@ -75,5 +75,5 @@ "substituteOnAdd": "Ein Delegator von {{pokemonNameWithAffix}} ist erschienen!", "substituteOnHit": "Der Delegator steckt den Schlag für {{pokemonNameWithAffix}} ein!", "substituteOnRemove": "Der Delegator von {{pokemonNameWithAffix}} hört auf zu wirken!", - "autotomizeOnAdd": "{{pokemonNameWIthAffix}} ist leichter geworden!" + "autotomizeOnAdd": "{{pokemonNameWithAffix}} ist leichter geworden!" } From edbb09f4d6f78af31b2ee68b4685fa93d7a21b5f Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Sat, 28 Sep 2024 03:11:08 +1000 Subject: [PATCH 17/65] [Beta][P2 Bug] Fix macho brace stat calculation for HP (#4467) --- src/field/pokemon.ts | 25 ++++++++++++++----------- src/modifier/modifier.ts | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0fda3d075be..07525e92157 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -952,32 +952,35 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const baseStats = this.calculateBaseStats(); // Using base stats, calculate and store stats one by one for (const s of PERMANENT_STATS) { - let value = Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01); + const statHolder = new Utils.IntegerHolder(Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01)); if (s === Stat.HP) { - value = value + this.level + 10; + statHolder.value = statHolder.value + this.level + 10; + this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); if (this.hasAbility(Abilities.WONDER_GUARD, false, true)) { - value = 1; + statHolder.value = 1; } - if (this.hp > value || this.hp === undefined) { - this.hp = value; + if (this.hp > statHolder.value || this.hp === undefined) { + this.hp = statHolder.value; } else if (this.hp) { const lastMaxHp = this.getMaxHp(); - if (lastMaxHp && value > lastMaxHp) { - this.hp += value - lastMaxHp; + if (lastMaxHp && statHolder.value > lastMaxHp) { + this.hp += statHolder.value - lastMaxHp; } } } else { - value += 5; + statHolder.value += 5; const natureStatMultiplier = new Utils.NumberHolder(getNatureStatMultiplier(this.getNature(), s)); this.scene.applyModifier(PokemonNatureWeightModifier, this.isPlayer(), this, natureStatMultiplier); if (natureStatMultiplier.value !== 1) { - value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](value * natureStatMultiplier.value), 1); + statHolder.value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](statHolder.value * natureStatMultiplier.value), 1); } + this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); } - this.setStat(s, value); + statHolder.value = Utils.clampInt(statHolder.value, 1, Number.MAX_SAFE_INTEGER); + + this.setStat(s, statHolder.value); } - this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, this.stats); } calculateBaseStats(): number[] { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index f53a07e8e21..cf9cf78225e 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -998,26 +998,26 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { } shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + return super.shouldApply(args) && args.length === 3 && args[2] instanceof Utils.IntegerHolder; } apply(args: any[]): boolean { - // Modifies the passed in stats[] array by +1 per stack for HP, +2 per stack for other stats + // Modifies the passed in stat integer holder by +1 per stack for HP, +2 per stack for other stats // If the Macho Brace is at max stacks (50), adds additional 5% to total HP and 10% to other stats - const targetToApply = args[0] as Pokemon; + const isHp = args[1] === Stat.HP; + const statHolder = args[2] as Utils.IntegerHolder; - args[1].forEach((v, i) => { - const isHp = i === 0; - // Doesn't modify HP if holder has Wonder Guard - if (!isHp || !targetToApply.hasAbility(Abilities.WONDER_GUARD)) { - let mult = 1; - if (this.stackCount === this.getMaxHeldItemCount()) { - mult = isHp ? 1.05 : 1.1; - } - const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult); - args[1][i] = Math.min(Math.max(newVal, 1), 999999); + if (isHp) { + statHolder.value += this.stackCount; + if (this.stackCount === this.getMaxHeldItemCount()) { + statHolder.value = Math.floor(statHolder.value * 1.05); } - }); + } else { + statHolder.value += 2 * this.stackCount; + if (this.stackCount === this.getMaxHeldItemCount()) { + statHolder.value = Math.floor(statHolder.value * 1.1); + } + } return true; } From d28c77db21befeb5b0fe14a2c69b667aa178fb4e Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:56:40 +0200 Subject: [PATCH 18/65] [Localization] Missing items translations (#4470) * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update src/locales/ko/modifier-type.json * Update src/locales/ko/modifier-type.json * Update modifier-type.json * Update src/locales/it/modifier-type.json * Update src/locales/it/modifier-type.json * Update src/locales/ko/modifier-type.json * Update modifier-type.json * Update src/locales/es/modifier-type.json * Update src/locales/ja/modifier-type.json * Update src/locales/ko/modifier-type.json Co-authored-by: returntoice <171243264+returntoice@users.noreply.github.com> * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update modifier-type.json * Update battler-tags.json * Update modifier-type.json * Update battler-tags.json * Update battler-tags.json --------- Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Co-authored-by: returntoice <171243264+returntoice@users.noreply.github.com> --- src/locales/es/modifier-type.json | 20 ++++++++++++++++++++ src/locales/fr/modifier-type.json | 17 +++++++++++++++++ src/locales/it/modifier-type.json | 20 ++++++++++++++++++++ src/locales/ja/modifier-type.json | 20 ++++++++++++++++++++ src/locales/ko/modifier-type.json | 22 +++++++++++++++++++++- src/locales/pt_BR/modifier-type.json | 20 ++++++++++++++++++++ src/locales/zh_CN/modifier-type.json | 20 ++++++++++++++++++++ src/locales/zh_TW/modifier-type.json | 20 ++++++++++++++++++++ 8 files changed, 158 insertions(+), 1 deletion(-) diff --git a/src/locales/es/modifier-type.json b/src/locales/es/modifier-type.json index 365a8d9bfed..668f08e443d 100644 --- a/src/locales/es/modifier-type.json +++ b/src/locales/es/modifier-type.json @@ -358,6 +358,10 @@ "name": "Llamasfera", "description": "Extraña esfera que causa quemaduras a quien la usa en combate." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "Tesoros", + "description": "¡A este Pokémon le encantan los tesoros! ¡Sigue coleccionandólos y tal vez pase algo!" + }, "BATON": { "name": "Testigo", "description": "Permite pasar los efectos al cambiar de Pokémon, también evita las trampas." @@ -495,6 +499,22 @@ "TART_APPLE": "Manzana ácida", "STRAWBERRY_SWEET": "Confite fresa", "UNREMARKABLE_TEACUP": "Cuenco mediocre", + "UPGRADE": "Mejora", + "DUBIOUS_DISC": "Disco Extraño", + "DRAGON_SCALE": "Escama Dragón", + "PRISM_SCALE": "Escama Bella", + "RAZOR_CLAW": "Garra Afilada", + "RAZOR_FANG": "Colmillo Agudo", + "REAPER_CLOTH": "Tela Terrible", + "ELECTIRIZER": "Electrizador", + "MAGMARIZER": "Magmatizador", + "PROTECTOR": "Protector", + "SACHET": "Saquito Fragante", + "WHIPPED_DREAM": "Dulce de Nata", + "LEADERS_CREST": "Distintivo de Líder", + "SUN_FLUTE": "Flauta Solar", + "MOON_FLUTE": "Flauta Lunar", + "CHIPPED_POT": "Tetera rota", "BLACK_AUGURITE": "Mineral negro", "GALARICA_CUFF": "Brazal galanuez", diff --git a/src/locales/fr/modifier-type.json b/src/locales/fr/modifier-type.json index 74c7599fea7..465ffc82572 100644 --- a/src/locales/fr/modifier-type.json +++ b/src/locales/fr/modifier-type.json @@ -240,6 +240,8 @@ "TOXIC_ORB": { "name": "Orbe Toxique", "description": "Empoisonne gravement son porteur à la fin du tour s’il n’a pas déjà de problème de statut." }, "FLAME_ORB": { "name": "Orbe Flamme", "description": "Brule son porteur à la fin du tour s’il n’a pas déjà de problème de statut." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { "name": "Trésors", "description": "Ce Pokémon adore les trésors ! Ramassez-en le plus possible et voyez ce qu’il se passe !"}, + "BATON": { "name": "Témoin", "description": "Permet de transmettre les effets en cas de changement de Pokémon. Ignore les pièges." }, "SHINY_CHARM": { "name": "Charme Chroma", "description": "Augmente énormément les chances de rencontrer un Pokémon sauvage chromatique." }, @@ -330,6 +332,21 @@ "TART_APPLE": "Pomme Acidulée", "STRAWBERRY_SWEET": "Fraise en Sucre", "UNREMARKABLE_TEACUP": "Bol Médiocre", + "UPGRADE": "Améliorator", + "DUBIOUS_DISC": "CD Douteux", + "DRAGON_SCALE": "Écaille Draco", + "PRISM_SCALE": "Bel’Écaille", + "RAZOR_CLAW": "Griffe Rasoir", + "RAZOR_FANG": "Croc Rasoir", + "REAPER_CLOTH": "Tissu Fauche", + "ELECTIRIZER": "Électriseur", + "MAGMARIZER": "Magmariseur", + "PROTECTOR": "Protecteur", + "SACHET": "Sachet Senteur", + "WHIPPED_DREAM": "Chantibonbon", + "LEADERS_CREST": "Emblème du Général", + "SUN_FLUTE": "Flute du Soleil", + "MOON_FLUTE": "Flute de la Lune", "CHIPPED_POT": "Théière Ébréchée", "BLACK_AUGURITE": "Obsidienne", diff --git a/src/locales/it/modifier-type.json b/src/locales/it/modifier-type.json index 9edf6e5a53a..13b8a62e917 100644 --- a/src/locales/it/modifier-type.json +++ b/src/locales/it/modifier-type.json @@ -358,6 +358,10 @@ "name": "Fiammosfera", "description": "Sfera bizzarra che procura una scottatura a chi l’ha con sé in una lotta." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "Tesori", + "description": "Questo Pokémon adora i tesori! Continua a collezionare i tesori e potrebbe accadere qualcosa!" + }, "BATON": { "name": "Staffetta", "description": "Permette di trasmettere gli effetti quando si cambia Pokémon, aggirando anche le trappole." @@ -495,6 +499,22 @@ "TART_APPLE": "Aspropomo", "STRAWBERRY_SWEET": "Bonbonfragola", "UNREMARKABLE_TEACUP": "Tazza dozzinale", + "UPGRADE": "Upgrade", + "DUBIOUS_DISC": "Dubbiodisco", + "DRAGON_SCALE": "Squama drago", + "PRISM_SCALE": "Squama bella", + "RAZOR_CLAW": "Affilartiglio", + "RAZOR_FANG": "Affilodente", + "REAPER_CLOTH": "Terrorpanno", + "ELECTIRIZER": "Elettritore", + "MAGMARIZER": "Magmatore", + "PROTECTOR": "Copertura", + "SACHET": "Bustina aromi", + "WHIPPED_DREAM": "Dolcespuma", + "LEADERS_CREST": "Simbolo del capo", + "SUN_FLUTE": "Flauto solare", + "MOON_FLUTE": "Flauto lunare", + "CHIPPED_POT": "Teiera crepata", "BLACK_AUGURITE": "Augite nera", "GALARICA_CUFF": "Fascia Galarnoce", diff --git a/src/locales/ja/modifier-type.json b/src/locales/ja/modifier-type.json index b217ab054b7..5562a25f96f 100644 --- a/src/locales/ja/modifier-type.json +++ b/src/locales/ja/modifier-type.json @@ -240,6 +240,11 @@ "TOXIC_ORB": { "name": "どくどくだま", "description": "触ると 毒をだす 不思議な玉。\n持たせると 戦闘中に 猛毒の状態に なる" }, "FLAME_ORB": { "name": "かえんだま", "description": "触ると 熱をだす 不思議な玉。\n持たせると 戦闘中に やけどの状態に なる。" }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "宝物", + "description": "このポケモンは 宝物が 大好き! 宝物を 集め続けると 良いことが 起こる かもしれません!" + }, + "BATON": { "name": "バトン", "description": "持たせると 入れ替えるとき 控えのポケモンが\n能力変化を 受けつげる (逃げられなくする 技や 特性も 回避する)" }, "SHINY_CHARM": { "name": "ひかるおまもり", "description": "色違いの ポケモンと 大きく 出会いやすくなる" }, @@ -330,6 +335,21 @@ "TART_APPLE": "すっぱいりんご", "STRAWBERRY_SWEET": "いちごアメざいく", "UNREMARKABLE_TEACUP": "ボンサクのちゃわん", + "UPGRADE": "アップグレード", + "DUBIOUS_DISC": "あやしいパッチ", + "DRAGON_SCALE": "りゅうのウロコ", + "PRISM_SCALE": "きれいなウロコ", + "RAZOR_CLAW": "するどいツメ", + "RAZOR_FANG": "するどいキバ", + "REAPER_CLOTH": "れいかいのぬの", + "ELECTIRIZER": "エレキブースター", + "MAGMARIZER": "マグマブースター", + "PROTECTOR": "プロテクター", + "SACHET": "においぶくろ", + "WHIPPED_DREAM": "ホイップポップ", + "LEADERS_CREST": "かしらのしるし", + "SUN_FLUTE": "たいようのふえ", + "MOON_FLUTE": "つきのふえ", "CHIPPED_POT": "かけたポット", "BLACK_AUGURITE": "くろのきせき", diff --git a/src/locales/ko/modifier-type.json b/src/locales/ko/modifier-type.json index f9d8fd1a861..d770b5fb068 100644 --- a/src/locales/ko/modifier-type.json +++ b/src/locales/ko/modifier-type.json @@ -358,9 +358,13 @@ "name": "화염구슬", "description": "이 도구를 지닌 포켓몬은 턴이 끝나는 시점에 상태이상에 걸리지 않았다면 화상 상태가 된다." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "보물", + "description": "이 포켓몬은 보물을 좋아한다. 보물을 모으다 보면 어떤 일이 일어날 지도 모른다!" + }, "BATON": { "name": "배턴", - "description": "포켓몬을 교체할 때 효과를 넘겨줄 수 있으며, 함정의 영향을 받지 않게 함" + "description": "포켓몬을 교체할 때 효과를 넘겨줄 수 있으며, 함정의 영향을 받지 않게 한다." }, "SHINY_CHARM": { "name": "빛나는부적", @@ -495,6 +499,22 @@ "TART_APPLE": "새콤한사과", "STRAWBERRY_SWEET": "딸기사탕공예", "UNREMARKABLE_TEACUP": "범작찻잔", + "UPGRADE": "업그레이드", + "DUBIOUS_DISC": "괴상한패치", + "DRAGON_SCALE": "용의비늘", + "PRISM_SCALE": "고운비늘", + "RAZOR_CLAW": "예리한손톱", + "RAZOR_FANG": "예리한이빨", + "REAPER_CLOTH": "영계의천", + "ELECTIRIZER": "에레키부스터", + "MAGMARIZER": "마그마부스터", + "PROTECTOR": "프로텍터", + "SACHET": "향기주머니", + "WHIPPED_DREAM": "휘핑크림", + "LEADERS_CREST": "대장의징표", + "SUN_FLUTE": "태양의피리", + "MOON_FLUTE": "달의피리", + "CHIPPED_POT": "이빠진포트", "BLACK_AUGURITE": "검은휘석", "GALARICA_CUFF": "가라두구팔찌", diff --git a/src/locales/pt_BR/modifier-type.json b/src/locales/pt_BR/modifier-type.json index ae7a2cba93e..a4b27b19fb7 100644 --- a/src/locales/pt_BR/modifier-type.json +++ b/src/locales/pt_BR/modifier-type.json @@ -358,6 +358,10 @@ "name": "Esfera da Chama", "description": "Uma esfera estranha que aquece quando tocada e queima quem a segurar." }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "Treasures", + "description": "This Pokémon loves treasure! Keep collecting treasure and something might happen!" + }, "BATON": { "name": "Bastão", "description": "Permite passar mudanças de atributo ao trocar Pokémon, ignorando armadilhas." @@ -507,6 +511,22 @@ "TART_APPLE": "Maçã Azeda", "STRAWBERRY_SWEET": "Doce de Morango", "UNREMARKABLE_TEACUP": "Xícara Comum", + "UPGRADE": "Melhora", + "DUBIOUS_DISC": "Dubious Disc", + "DRAGON_SCALE": "Escama de Dragão", + "PRISM_SCALE": "Prism Scale", + "RAZOR_CLAW": "Garra de Navalha", + "RAZOR_FANG": "Presa Afiada", + "REAPER_CLOTH": "Capa do Ceifador", + "ELECTIRIZER": "Electirizer", + "MAGMARIZER": "Magmarizer", + "PROTECTOR": "Protector", + "SACHET": "Sachet", + "WHIPPED_DREAM": "Whipped Dream", + "LEADERS_CREST": "Leader's Crest", + "SUN_FLUTE": "Sun Flute", + "MOON_FLUTE": "Moon Flute", + "CHIPPED_POT": "Pote Lascado", "BLACK_AUGURITE": "Mineral Negro", "GALARICA_CUFF": "Bracelete de Galar", diff --git a/src/locales/zh_CN/modifier-type.json b/src/locales/zh_CN/modifier-type.json index 61c36078369..b02d74eadb5 100644 --- a/src/locales/zh_CN/modifier-type.json +++ b/src/locales/zh_CN/modifier-type.json @@ -358,6 +358,10 @@ "name": "火焰宝珠", "description": "触碰后会放出热量的神奇宝珠。\n携带后,在战斗时会变成灼伤状态。" }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "金子宝物", + "description": "这个小精靈爱金子! 继续挑金子然后谁知道什么会发生!" + }, "BATON": { "name": "接力棒", "description": "允许在切换宝可梦时保留能力变化, 对陷阱\n同样生效。" @@ -495,6 +499,22 @@ "TART_APPLE": "酸酸苹果", "STRAWBERRY_SWEET": "草莓糖饰", "UNREMARKABLE_TEACUP": "凡作茶碗", + "UPGRADE": "升级数据", + "DUBIOUS_DISC": "可疑补丁", + "DRAGON_SCALE": "龙之鳞片", + "PRISM_SCALE": "美丽鳞片", + "RAZOR_CLAW": "锐利之爪", + "RAZOR_FANG": "锐利之牙", + "REAPER_CLOTH": "灵界之布", + "ELECTIRIZER": "电力增幅器", + "MAGMARIZER": "熔岩增幅器", + "PROTECTOR": "护具", + "SACHET": "香袋", + "WHIPPED_DREAM": "泡沫奶油", + "LEADERS_CREST": "头领凭证", + "SUN_FLUTE": "太阳之笛", + "MOON_FLUTE": "月亮之笛", + "CHIPPED_POT": "缺损的茶壶", "BLACK_AUGURITE": "黑奇石", "GALARICA_CUFF": "伽勒豆蔻手环", diff --git a/src/locales/zh_TW/modifier-type.json b/src/locales/zh_TW/modifier-type.json index f305c0e2d62..25c79af821b 100644 --- a/src/locales/zh_TW/modifier-type.json +++ b/src/locales/zh_TW/modifier-type.json @@ -358,6 +358,10 @@ "name": "火焰寶珠", "description": "觸碰後會放出熱量的神奇寶珠。\n攜帶後,在戰鬥時會變成灼傷狀態。" }, + "EVOLUTION_TRACKER_GIMMIGHOUL": { + "name": "金子寶物", + "description": "這個小精靈愛金子! 繼續挑金子然後誰知道什麼會發生!" + }, "BATON": { "name": "接力棒", "description": "允許在切換寶可夢時保留能力變化, 對陷阱\n同樣生效。" @@ -495,6 +499,22 @@ "TART_APPLE": "酸酸蘋果", "STRAWBERRY_SWEET": "草莓糖飾", "UNREMARKABLE_TEACUP": "凡作茶碗", + "UPGRADE": "升級資料", + "DUBIOUS_DISC": "可疑修正檔", + "DRAGON_SCALE": "龍之鱗片", + "PRISM_SCALE": "美麗鱗片", + "RAZOR_CLAW": "銳利之爪", + "RAZOR_FANG": "銳利之牙", + "REAPER_CLOTH": "靈界之布", + "ELECTIRIZER": "電力增幅器", + "MAGMARIZER": "熔岩增幅器", + "PROTECTOR": "護具", + "SACHET": "香袋", + "WHIPPED_DREAM": "泡沫奶油", + "LEADERS_CREST": "頭領憑證", + "SUN_FLUTE": "太陽之笛", + "MOON_FLUTE": "月亮之笛", + "CHIPPED_POT": "缺損的茶壺", "BLACK_AUGURITE": "黑奇石", "GALARICA_CUFF": "伽勒豆蔻手環", From 1a19065a45e29f166dc29886715a9e9f174573b9 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:57:46 -0400 Subject: [PATCH 19/65] [Bug] [Balance] Gimmighoul evolution adjustments/fixes (#4463) * Fix Gimmighoul evolution * Fix counter * Less janky maxStack check --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- src/data/pokemon-evolutions.ts | 5 +++-- src/modifier/modifier.ts | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index f9602d1386a..a262b84b18a 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -11,6 +11,7 @@ import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; +import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier } from "#app/modifier/modifier"; export enum SpeciesWildEvolutionDelay { NONE, @@ -1647,8 +1648,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GIMMIGHOUL]: [ - new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 - p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length ), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 - p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length ), SpeciesWildEvolutionDelay.VERY_LONG) ] }; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index cf9cf78225e..0a683ca8d27 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -859,7 +859,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.stackCount); + return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.required, this.stackCount); } getArgs(): any[] { @@ -870,8 +870,9 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { return true; } - getMaxHeldItemCount(_pokemon: Pokemon): integer { - return this.required; + getMaxHeldItemCount(pokemon: Pokemon): integer { + this.stackCount = pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length; + return this.stackCount < this.required ? this.required : this.stackCount + 1; } } From 4364ab36b9c1af8c6cec8b5e8bc470f237c06eac Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Sat, 28 Sep 2024 07:35:26 +1000 Subject: [PATCH 20/65] Revert "[Bug] [Balance] Gimmighoul evolution adjustments/fixes (#4463)" (#4472) This reverts commit 1a19065a45e29f166dc29886715a9e9f174573b9. --- src/data/pokemon-evolutions.ts | 5 ++--- src/modifier/modifier.ts | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index a262b84b18a..f9602d1386a 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -11,7 +11,6 @@ import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; -import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier } from "#app/modifier/modifier"; export enum SpeciesWildEvolutionDelay { NONE, @@ -1648,8 +1647,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GIMMIGHOUL]: [ - new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 - p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length ), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 - p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length ), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG) ] }; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 0a683ca8d27..cf9cf78225e 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -859,7 +859,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.required, this.stackCount); + return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.stackCount); } getArgs(): any[] { @@ -870,9 +870,8 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { - this.stackCount = pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length; - return this.stackCount < this.required ? this.required : this.stackCount + 1; + getMaxHeldItemCount(_pokemon: Pokemon): integer { + return this.required; } } From 2e7f6a2f4f3e68bd58a1af35a16a4ca9b517d973 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Fri, 27 Sep 2024 20:07:47 -0400 Subject: [PATCH 21/65] [Hotfix] hotfix for expert breeder ME crashing if player loses with queued enemy stat changes (#4476) Co-authored-by: ImperialSympathizer --- .../encounters/the-expert-pokemon-breeder-encounter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index e41b3ab03ef..e75e7e9f580 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -558,6 +558,10 @@ function onGameOver(scene: BattleScene) { // Revert BGM scene.playBgm(scene.arena.bgm); + // Clear any leftover battle phases + scene.clearPhaseQueue(); + scene.clearPhaseQueueSplice(); + // Return enemy Pokemon const pokemon = scene.getEnemyPokemon(); if (pokemon) { From c9664b66d360961284e7a99c19fda00faa7e6fab Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 27 Sep 2024 18:26:19 -0700 Subject: [PATCH 22/65] [Hotfix] Prevent bosses from being forced to flee by Dragon Tail/etc (#4478) --- src/data/move.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/data/move.ts b/src/data/move.ts index 74ecead73fa..59417f52e02 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5244,6 +5244,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { false, false), MoveEndPhase); } } else { + if (switchOutTarget.isBoss()) { + return false; + } // Switch out logic for everything else (eg: WILD battles) switchOutTarget.leaveField(false); From 1b6593d24274596f48c92a1f21c16c08f4203bb4 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:38:15 -0400 Subject: [PATCH 23/65] [Hotfix] Fix ME lapsing non flinch or endure battler tags (#4479) * Fix tag lapsing on battle start in MEs with free enemy moves * lapse endure tag as well --------- Co-authored-by: ImperialSympathizer --- src/phases/mystery-encounter-phases.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index 60755095cca..0efaf1bf4ca 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -25,6 +25,7 @@ import { GameOverPhase } from "#app/phases/game-over-phase"; import { SwitchPhase } from "#app/phases/switch-phase"; import { SeenEncounterData } from "#app/data/mystery-encounters/mystery-encounter-save-data"; import { SwitchType } from "#enums/switch-type"; +import { BattlerTagType } from "#enums/battler-tag-type"; /** * Will handle (in order): @@ -218,9 +219,17 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase { start() { super.start(); + // Lapse any residual flinches/endures but ignore all other turn-end battle tags + const includedLapseTags = [BattlerTagType.FLINCHED, BattlerTagType.ENDURING]; const field = this.scene.getField(true).filter(p => p.summonData); field.forEach(pokemon => { - pokemon.lapseTags(BattlerTagLapseType.TURN_END); + const tags = pokemon.summonData.tags; + tags.filter(t => includedLapseTags.includes(t.tagType) + && t.lapseTypes.includes(BattlerTagLapseType.TURN_END) + && !(t.lapse(pokemon, BattlerTagLapseType.TURN_END))).forEach(t => { + t.onRemove(pokemon); + tags.splice(tags.indexOf(t), 1); + }); }); // Remove any status tick phases From 7eb755ca9c9949626bb34bc4b418032005c29307 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:07:42 -0700 Subject: [PATCH 24/65] Prevent the last valid pokemon from being forced to switch (#4481) --- src/data/move.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/data/move.ts b/src/data/move.ts index 59417f52e02..494cffbc677 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5226,6 +5226,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { */ const switchOutTarget = this.selfSwitch ? user : target; if (switchOutTarget instanceof PlayerPokemon) { + if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { + return false; + } switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); if (switchOutTarget.hp > 0) { @@ -5234,6 +5237,9 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { } return false; } else if (user.scene.currentBattle.battleType !== BattleType.WILD) { + if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { + return false; + } // Switch out logic for trainer battles switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); From 2b3dbcc72fb61372d832752b90fa4b2a6c03aec4 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:34:25 -0400 Subject: [PATCH 25/65] [Hotfix] Fix black sludge ME causing non-integer money (#4482) * Fix tag lapsing on battle start in MEs with free enemy moves * lapse endure tag as well * fix black sludge item money calculation * Update src/modifier/modifier.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: ImperialSympathizer Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/modifier/modifier.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index cf9cf78225e..fd738060506 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -2598,7 +2598,8 @@ export class HealShopCostModifier extends PersistentModifier { } apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value *= this.shopMultiplier; + const moneyCost = args[0] as Utils.NumberHolder; + moneyCost.value = Math.floor(moneyCost.value * this.shopMultiplier); return true; } From 3def9fc15ddb04ec50c5bb360246f01d20fe8645 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:51:32 -0700 Subject: [PATCH 26/65] [Hotfix] Swap force switch out check from `isBoss` to `wave % 10` (#4484) --- src/data/move.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index 494cffbc677..e3cb5d935d5 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5250,7 +5250,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { false, false), MoveEndPhase); } } else { - if (switchOutTarget.isBoss()) { + if (user.scene.currentBattle.waveIndex % 10 === 0) { return false; } // Switch out logic for everything else (eg: WILD battles) From 5d819aacf2a9b4054ec028bd80d4187512e1201f Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Fri, 27 Sep 2024 23:48:15 -0400 Subject: [PATCH 27/65] sanitize all money when saving session data to server (#4485) * sanitize all money when saving session data to server * update money sanitization --------- Co-authored-by: ImperialSympathizer --- src/phases/game-over-phase.ts | 2 +- src/system/game-data.ts | 4 ++-- src/system/version-converter.ts | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index b0cfa5c55e2..8ecf1478b99 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -238,7 +238,7 @@ export class GameOverPhase extends BattlePhase { enemyModifiers: this.scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), arena: new ArenaData(this.scene.arena), pokeballCounts: this.scene.pokeballCounts, - money: this.scene.money, + money: Math.floor(this.scene.money), score: this.scene.score, waveIndex: this.scene.currentBattle.waveIndex, battleType: this.scene.currentBattle.battleType, diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 63c7cb1b13a..af5e717c17b 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -957,7 +957,7 @@ export class GameData { enemyModifiers: scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), arena: new ArenaData(scene.arena), pokeballCounts: scene.pokeballCounts, - money: scene.money, + money: Math.floor(scene.money), score: scene.score, waveIndex: scene.currentBattle.waveIndex, battleType: scene.currentBattle.battleType, @@ -1047,7 +1047,7 @@ export class GameData { scene.pokeballCounts = Overrides.POKEBALL_OVERRIDE.pokeballs; } - scene.money = sessionData.money || 0; + scene.money = Math.floor(sessionData.money || 0); scene.updateMoneyText(); if (scene.money > this.gameStats.highestMoney) { diff --git a/src/system/version-converter.ts b/src/system/version-converter.ts index 0591647aeaa..3a4416a975e 100644 --- a/src/system/version-converter.ts +++ b/src/system/version-converter.ts @@ -6,6 +6,10 @@ const LATEST_VERSION = "1.0.5"; export function applySessionDataPatches(data: SessionSaveData) { const curVersion = data.gameVersion; + + // Always sanitize money as a safeguard + data.money = Math.floor(data.money); + if (curVersion !== LATEST_VERSION) { switch (curVersion) { case "1.0.0": From f460f9a0e868d7800d235267597c7de7c64e4059 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Sat, 28 Sep 2024 08:59:15 +0200 Subject: [PATCH 28/65] [Localization] [P3 Bug] Incorrect French hotfix (#4483) * Update uncommon-breed-dialogue.json * Update bug-type-superfan-dialogue.json * Update settings.json * Update uncommon-breed-dialogue.json * Update settings.json --- .../fr/mystery-encounters/bug-type-superfan-dialogue.json | 2 +- .../fr/mystery-encounters/uncommon-breed-dialogue.json | 4 ++-- src/locales/fr/settings.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locales/fr/mystery-encounters/bug-type-superfan-dialogue.json b/src/locales/fr/mystery-encounters/bug-type-superfan-dialogue.json index 63195e37062..7e81b99c739 100644 --- a/src/locales/fr/mystery-encounters/bug-type-superfan-dialogue.json +++ b/src/locales/fr/mystery-encounters/bug-type-superfan-dialogue.json @@ -28,7 +28,7 @@ "select_prompt": "Choisissez un objet à donner.", "invalid_selection": "Ce Pokémon ne porte pas ce genre d’objet.", "selected": "Vous remettez l’objet {{selectedItem}} au Dresseur.", - "selected_dialogue": "Sérieux ? {{selectedItem}}, comme ça en cadeau ?\nC’est très générieux !$En guise de ma reconnaissance, laisse-moi\nte faire un cadeau un peu spécial !$Il est dans ma famille depusi des générations, et ça me ferait plaisir de te l’offrir !" + "selected_dialogue": "Sérieux ? {{selectedItem}}, comme ça en cadeau ?\nC’est très générieux !$En guise de ma reconnaissance, laisse-moi\nte faire un cadeau un peu spécial !$Il est dans ma famille depuis des générations, et ça me ferait plaisir de te l’offrir !" } }, "battle_won": "Tes connaissances et tes capacités ont totalement exploité nos faiblesses !$En remerciement de cette leçon, permets-moi\nd’apprendre une capacité Insecte à un de tes Pokémon !", diff --git a/src/locales/fr/mystery-encounters/uncommon-breed-dialogue.json b/src/locales/fr/mystery-encounters/uncommon-breed-dialogue.json index d5f5e7e336f..9d70d532f0a 100644 --- a/src/locales/fr/mystery-encounters/uncommon-breed-dialogue.json +++ b/src/locales/fr/mystery-encounters/uncommon-breed-dialogue.json @@ -14,13 +14,13 @@ "label": "Le nourrir", "disabled_tooltip": "Vous avez besoin de 4 Baies pour choisir cette option", "tooltip": "(-) Donner 4 Baies\n(+) Le {{enemyPokemon}} vous apprécie", - "selected": "Vous lancer quelques Baies\nau {{enemyPokemon}} !$Il les engloutit avec joie !$Le {{enemyPokemon}} veut se joindre\nà votre équipe !" + "selected": "Vous lancez quelques Baies\nau {{enemyPokemon}} !$Il les engloutit avec joie !$Le {{enemyPokemon}} veut se joindre\nà votre équipe !" }, "3": { "label": "Devenir amis", "disabled_tooltip": "Votre Pokémon doit connaitre certaines capacités pour choisir cette option", "tooltip": "(+) {{option3PrimaryName}} utilise {{option3PrimaryMove}}\n(+) Le {{enemyPokemon}} vous apprécie", - "selected": "Votre {{option3PrimaryName}} utilise {{option3PrimaryMove}} pour charmer le {{enemyPokemon}} !$The {{enemyPokemon}} veut se joindre\nà votre équipe !" + "selected": "Votre {{option3PrimaryName}} utilise {{option3PrimaryMove}} pour charmer le {{enemyPokemon}} !$Le {{enemyPokemon}} veut se joindre\nà votre équipe !" } } } diff --git a/src/locales/fr/settings.json b/src/locales/fr/settings.json index e310f5d5733..2dd150eed13 100644 --- a/src/locales/fr/settings.json +++ b/src/locales/fr/settings.json @@ -11,7 +11,7 @@ "expGainsSpeed": "Vit. barre d’Exp", "expPartyDisplay": "Afficher Exp équipe", "skipSeenDialogues": "Passer dialogues connus", - "eggSkip": "Animation d’éclosion", + "eggSkip": "Passer les éclosions", "never": "Jamais", "always": "Toujours", "ask": "Demander", From 0464d8f6664cf2b07a908df0cdabb7c67e7f6ce2 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:24:57 +0200 Subject: [PATCH 29/65] Update modifier-type.json (#4492) --- src/locales/zh_CN/modifier-type.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/zh_CN/modifier-type.json b/src/locales/zh_CN/modifier-type.json index b02d74eadb5..eb394baf577 100644 --- a/src/locales/zh_CN/modifier-type.json +++ b/src/locales/zh_CN/modifier-type.json @@ -360,7 +360,7 @@ }, "EVOLUTION_TRACKER_GIMMIGHOUL": { "name": "金子宝物", - "description": "这个小精靈爱金子! 继续挑金子然后谁知道什么会发生!" + "description": "这个宝可梦最爱金币!多收集点金币的话会发生什么呢?" }, "BATON": { "name": "接力棒", From 3a5f3c39cda4a55df93517819a009bf328aacc17 Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:24:03 +0200 Subject: [PATCH 30/65] Fixing Placeholder in afterYou (#4493) --- src/locales/en/move-trigger.json | 2 +- src/locales/es/move-trigger.json | 2 +- src/locales/fr/move-trigger.json | 2 +- src/locales/it/move-trigger.json | 2 +- src/locales/ja/move-trigger.json | 2 +- src/locales/ko/move-trigger.json | 2 +- src/locales/pt_BR/move-trigger.json | 2 +- src/locales/zh_CN/move-trigger.json | 2 +- src/locales/zh_TW/move-trigger.json | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/locales/en/move-trigger.json b/src/locales/en/move-trigger.json index 93d25e506ba..7ea5fe82fc2 100644 --- a/src/locales/en/move-trigger.json +++ b/src/locales/en/move-trigger.json @@ -71,5 +71,5 @@ "safeguard": "{{targetName}} is protected by Safeguard!", "substituteOnOverlap": "{{pokemonName}} already\nhas a substitute!", "substituteNotEnoughHp": "But it does not have enough HP\nleft to make a substitute!", - "afterYou": "{{pokemonName}} took the kind offer!" + "afterYou": "{{targetName}} took the kind offer!" } \ No newline at end of file diff --git a/src/locales/es/move-trigger.json b/src/locales/es/move-trigger.json index b49a64ac42a..2e394dd72a7 100644 --- a/src/locales/es/move-trigger.json +++ b/src/locales/es/move-trigger.json @@ -67,5 +67,5 @@ "swapArenaTags": "¡{{pokemonName}} ha intercambiado los efectos del terreno de combate!", "exposedMove": "¡{{pokemonName}} ha identificado\n{{targetPokemonName}}!", "safeguard": "¡{{targetName}} está protegido por Velo Sagrado!", - "afterYou": "¡{{pokemonName}} ha decidido aprovechar la oportunidad!" + "afterYou": "¡{{targetName}} ha decidido aprovechar la oportunidad!" } diff --git a/src/locales/fr/move-trigger.json b/src/locales/fr/move-trigger.json index 7564718e7ce..458b7ed8c4f 100644 --- a/src/locales/fr/move-trigger.json +++ b/src/locales/fr/move-trigger.json @@ -71,5 +71,5 @@ "safeguard": "{{targetName}} est protégé\npar la capacité Rune Protect !", "substituteOnOverlap": "{{pokemonName}} a déjà\nun clone !", "substituteNotEnoughHp": "Mais il est trop faible\npour créer un clone !", - "afterYou": "{{pokemonName}} accepte\navec joie !" + "afterYou": "{{targetName}} accepte\navec joie !" } diff --git a/src/locales/it/move-trigger.json b/src/locales/it/move-trigger.json index fba671a6813..04870015f2b 100644 --- a/src/locales/it/move-trigger.json +++ b/src/locales/it/move-trigger.json @@ -68,5 +68,5 @@ "exposedMove": "{{pokemonName}} ha identificato\n{{targetPokemonName}}!", "chillyReception": "{{pokemonName}} sta per fare una battuta!", "safeguard": "Salvaguardia protegge {{targetName}}!", - "afterYou": "{{pokemonName}} approfitta della cortesia!" + "afterYou": "{{targetName}} approfitta della cortesia!" } diff --git a/src/locales/ja/move-trigger.json b/src/locales/ja/move-trigger.json index afede7edfb3..4c3d19240f6 100644 --- a/src/locales/ja/move-trigger.json +++ b/src/locales/ja/move-trigger.json @@ -68,5 +68,5 @@ "chillyReception": "{{pokemonName}}は\n寒い ギャグを かました!", "swapArenaTags": "{{pokemonName}}は\nお互いの 場の 効果を 入れ替えた!", "exposedMove": "{{pokemonName}}は {{targetPokemonName}}の\n正体を 見破った!", - "afterYou": "{{pokemonName}}は\nお言葉に 甘えることにした!" + "afterYou": "{{targetName}}は\nお言葉に 甘えることにした!" } diff --git a/src/locales/ko/move-trigger.json b/src/locales/ko/move-trigger.json index 12a126baf9d..4b994f315bf 100644 --- a/src/locales/ko/move-trigger.json +++ b/src/locales/ko/move-trigger.json @@ -69,5 +69,5 @@ "chillyReception": "{{pokemonName}}[[는]] 썰렁한 개그를 선보였다!", "exposedMove": "{{pokemonName}}[[는]]\n{{targetPokemonName}}의 정체를 꿰뚫어 보았다!", "safeguard": "{{targetName}}[[는]] 신비의 베일이 지켜 주고 있다!", - "afterYou": "{{pokemonName}}[[는]]\n배려를 받아들이기로 했다!" + "afterYou": "{{targetName}}[[는]]\n배려를 받아들이기로 했다!" } diff --git a/src/locales/pt_BR/move-trigger.json b/src/locales/pt_BR/move-trigger.json index 307364e1b55..9a4d0b9e8b1 100644 --- a/src/locales/pt_BR/move-trigger.json +++ b/src/locales/pt_BR/move-trigger.json @@ -64,5 +64,5 @@ "chillyReception": "{{pokemonName}} está prestes a contar uma piada gelada!", "exposedMove": "{{pokemonName}} identificou\n{{targetPokemonName}}!", "safeguard": "{{targetName}} está protegido por Safeguard!", - "afterYou": "{{pokemonName}} aceitou a gentil oferta!" + "afterYou": "{{targetName}} aceitou a gentil oferta!" } diff --git a/src/locales/zh_CN/move-trigger.json b/src/locales/zh_CN/move-trigger.json index 60de3591915..32a4d0b4a7d 100644 --- a/src/locales/zh_CN/move-trigger.json +++ b/src/locales/zh_CN/move-trigger.json @@ -68,5 +68,5 @@ "chillyReception": "{{pokemonName}}\n说出了冷笑话!", "exposedMove": "{{pokemonName}}识破了\n{{targetPokemonName}}的原型!", "safeguard": "{{targetName}}\n正受到神秘之幕的保护!", - "afterYou": "{{pokemonName}}\n接受了对手的好意!" + "afterYou": "{{targetName}}\n接受了对手的好意!" } diff --git a/src/locales/zh_TW/move-trigger.json b/src/locales/zh_TW/move-trigger.json index 2cd33a3a416..6b80196f166 100644 --- a/src/locales/zh_TW/move-trigger.json +++ b/src/locales/zh_TW/move-trigger.json @@ -68,5 +68,5 @@ "chillyReception": "{{pokemonName}}\n說了冷笑話!", "exposedMove": "{{pokemonName}}識破了\n{{targetPokemonName}}的原形!", "safeguard": "{{targetName}}\n正受到神秘之幕的保護!", - "afterYou": "{{pokemonName}}\n接受了對手的好意!" + "afterYou": "{{targetName}}\n接受了對手的好意!" } From d87234504c696da5eb4566f6cf3288b340bad800 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Sat, 28 Sep 2024 12:59:48 -0400 Subject: [PATCH 31/65] prevent MEs incorrectly spawning on existing session saves (#4494) Co-authored-by: ImperialSympathizer --- src/battle-scene.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index ff0ca47bcac..8e299dd8e06 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -3091,11 +3091,6 @@ export default class BattleScene extends SceneBase { private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean { const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves(); if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) { - // If ME type is already defined in session data, no need to roll RNG check - if (!isNullOrUndefined(sessionDataEncounterType)) { - return true; - } - // Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance; const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents; From 8ce5de6d454da6159bfbabb55ec5e85bd293597a Mon Sep 17 00:00:00 2001 From: Pancakes Date: Sat, 28 Sep 2024 13:13:18 -0400 Subject: [PATCH 32/65] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 180c7af1240..8c724cda762 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: patapancakes +github: pagefaultgames From b1194cdfb62a42409343e6dcdd959c88fcca1590 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:44:22 +0200 Subject: [PATCH 33/65] Update training-session-dialogue.json (#4495) --- .../fr/mystery-encounters/training-session-dialogue.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/fr/mystery-encounters/training-session-dialogue.json b/src/locales/fr/mystery-encounters/training-session-dialogue.json index 9b06651eb59..9de246d3b6f 100644 --- a/src/locales/fr/mystery-encounters/training-session-dialogue.json +++ b/src/locales/fr/mystery-encounters/training-session-dialogue.json @@ -1,7 +1,7 @@ { "intro": "Vous tombez sur du matériel d’entrainement.", "title": "Session d’entrainement", - "description": "Ce matériel semble pouvoir être utilisé pour entrainer un membre de votre équipe ! Il existe plusieurs moyens avec lesquels vous pourriez entrainer un Pokémon, comme @[TOOLTIP_TITLE]{en le faisant combattre et vaincre le reste de votre équipe}.", + "description": "Ce matériel semble pouvoir être utilisé pour entrainer un membre de votre équipe ! Il existe plusieurs moyens avec lesquels vous pourriez entrainer un Pokémon, comme @[TOOLTIP_TITLE]{en le combattant et le vainquant avec le reste de votre équipe}.", "query": "Quel entrainement choisir ?", "invalid_selection": "Le Pokémon doit être en bonne santé.", "option": { From 357056ebebf8893c797cd72ef36877756b89a28b Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Sat, 28 Sep 2024 13:18:21 -0500 Subject: [PATCH 34/65] [Balance] Change Kyogre / Pichu eggmoves (#4491) --- src/data/egg-moves.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 813ade94020..741b707af2f 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -81,7 +81,7 @@ export const speciesEggMoves = { [Species.LEDYBA]: [ Moves.POLLEN_PUFF, Moves.THIEF, Moves.PARTING_SHOT, Moves.SPORE ], [Species.SPINARAK]: [ Moves.PARTING_SHOT, Moves.ATTACK_ORDER, Moves.GASTRO_ACID, Moves.STRENGTH_SAP ], [Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.THUNDER_CAGE, Moves.TAIL_GLOW ], - [Species.PICHU]: [ Moves.MOONBLAST, Moves.WAVE_CRASH, Moves.AIR_SLASH, Moves.AURA_WHEEL ], + [Species.PICHU]: [ Moves.MOONBLAST, Moves.TRIPLE_AXEL, Moves.FIERY_DANCE, Moves.AURA_WHEEL ], [Species.CLEFFA]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.WISH, Moves.LIGHT_OF_RUIN ], [Species.IGGLYBUFF]: [ Moves.DRAIN_PUNCH, Moves.GRAV_APPLE, Moves.SOFT_BOILED, Moves.EXTREME_SPEED ], [Species.TOGEPI]: [ Moves.SCORCHING_SANDS, Moves.ROOST, Moves.RELIC_SONG, Moves.FIERY_DANCE ], @@ -195,7 +195,7 @@ export const speciesEggMoves = { [Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.GIGATON_HAMMER ], [Species.LATIAS]: [ Moves.CORE_ENFORCER, Moves.FUSION_FLARE, Moves.SPARKLY_SWIRL, Moves.MYSTICAL_POWER ], [Species.LATIOS]: [ Moves.CORE_ENFORCER, Moves.BLUE_FLARE, Moves.NASTY_PLOT, Moves.TACHYON_CUTTER ], - [Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FLIP_TURN, Moves.WILDBOLT_STORM ], + [Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FREEZY_FROST, Moves.WILDBOLT_STORM ], [Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ], [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ], From 771b0edcb08b9794fe7c0b4868d23872fedb5cc3 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:21:42 -0400 Subject: [PATCH 35/65] [Hotfix] Fix Black Sludge disappearing on session reload (#4496) Co-authored-by: ImperialSympathizer --- src/modifier/modifier.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index fd738060506..5a813d8cbb2 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -2586,7 +2586,7 @@ export class HealShopCostModifier extends PersistentModifier { constructor(type: ModifierType, shopMultiplier: number, stackCount?: integer) { super(type, stackCount); - this.shopMultiplier = shopMultiplier; + this.shopMultiplier = shopMultiplier ?? 2.5; } match(modifier: Modifier): boolean { @@ -2604,6 +2604,10 @@ export class HealShopCostModifier extends PersistentModifier { return true; } + getArgs(): any[] { + return super.getArgs().concat(this.shopMultiplier); + } + getMaxStackCount(scene: BattleScene): integer { return 1; } From a69da4bc06457882e183cacbd00f7de655fec519 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Sat, 28 Sep 2024 13:40:42 -0700 Subject: [PATCH 36/65] Remove potential desync from `PokemonHealPhase` (#4497) --- src/phases/pokemon-heal-phase.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/phases/pokemon-heal-phase.ts b/src/phases/pokemon-heal-phase.ts index 813d15ae87e..dc0bd235bb5 100644 --- a/src/phases/pokemon-heal-phase.ts +++ b/src/phases/pokemon-heal-phase.ts @@ -46,8 +46,7 @@ export class PokemonHealPhase extends CommonAnimPhase { const pokemon = this.getPokemon(); if (!pokemon.isOnField() || (!this.revive && !pokemon.isActive())) { - super.end(); - return; + return super.end(); } const hasMessage = !!this.message; @@ -58,7 +57,7 @@ export class PokemonHealPhase extends CommonAnimPhase { if (healBlock && this.hpHealed > 0) { this.scene.queueMessage(healBlock.onActivation(pokemon)); this.message = null; - super.end(); + return super.end(); } else if (healOrDamage) { const hpRestoreMultiplier = new Utils.IntegerHolder(1); if (!this.revive) { From 000b8d9b2b80f6c1aa4a009cf0963e414549db29 Mon Sep 17 00:00:00 2001 From: Pancakes Date: Sat, 28 Sep 2024 17:35:13 -0400 Subject: [PATCH 37/65] Update .env.beta --- .env.beta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.beta b/.env.beta index 88147215258..38888ec3d97 100644 --- a/.env.beta +++ b/.env.beta @@ -1,6 +1,6 @@ VITE_BYPASS_LOGIN=0 VITE_BYPASS_TUTORIAL=0 -VITE_SERVER_URL=https://api.beta.pokerogue.net +VITE_SERVER_URL=https://apibeta.pokerogue.net VITE_DISCORD_CLIENT_ID=1248062921129459756 VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com VITE_I18N_DEBUG=1 From 7bb49a3199277be4915da6189b721e8aff6df4db Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Sat, 28 Sep 2024 22:11:02 -0400 Subject: [PATCH 38/65] [Hotfix] Fix Gimmighoul evolution (#4473) * Fix Gimmighoul evolution * Fix counter * Stack text fix * Fix Treasure tracker not saving * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/pokemon-evolutions.ts | 11 +++++++-- src/modifier/modifier-type.ts | 3 ++- src/modifier/modifier.ts | 44 ++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index f9602d1386a..698bbb8e9c9 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -11,6 +11,7 @@ import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; +import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier } from "#app/modifier/modifier"; export enum SpeciesWildEvolutionDelay { NONE, @@ -1647,8 +1648,14 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GIMMIGHOUL]: [ - new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition( p => p.evoCounter > 9 ), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter + + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + + p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier + || m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter + + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + + p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier + || m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG) ] }; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 9ce555a617e..fb69a96448a 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1387,7 +1387,8 @@ export const modifierTypes = { FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(false), RARE_FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(true), - EVOLUTION_TRACKER_GIMMIGHOUL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVOLUTION_TRACKER_GIMMIGHOUL", "relic_gold", (type, _args) => new Modifiers.EvoTrackerModifier(type, (_args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)), + EVOLUTION_TRACKER_GIMMIGHOUL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVOLUTION_TRACKER_GIMMIGHOUL", "relic_gold", + (type, args) => new Modifiers.EvoTrackerModifier(type, (args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)), MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)), DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new Modifiers.GigantamaxAccessModifier(type)), diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 5a813d8cbb2..537e2327a21 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,5 +1,5 @@ import * as ModifierTypes from "./modifier-type"; -import { ModifierType, modifierTypes } from "./modifier-type"; +import { getModifierType, ModifierType, modifierTypes } from "./modifier-type"; import BattleScene from "../battle-scene"; import { getLevelTotalExp } from "../data/exp"; import { MAX_PER_TYPE_POKEBALLS, PokeballType } from "../data/pokeball"; @@ -852,26 +852,47 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { } matchType(modifier: Modifier): boolean { - if (modifier instanceof EvoTrackerModifier) { - return (modifier as EvoTrackerModifier).species === this.species; - } - return false; + return modifier instanceof EvoTrackerModifier && modifier.species === this.species && modifier.required === this.required; } clone(): PersistentModifier { - return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.stackCount); + return new EvoTrackerModifier(this.type, this.pokemonId, this.species, this.required, this.stackCount); } getArgs(): any[] { - return super.getArgs().concat(this.species); + return super.getArgs().concat([this.species, this.required]); } apply(args: any[]): boolean { return true; } - getMaxHeldItemCount(_pokemon: Pokemon): integer { - return this.required; + getIconStackText(scene: BattleScene, virtual?: boolean): Phaser.GameObjects.BitmapText | null { + if (this.getMaxStackCount(scene) === 1 || (virtual && !this.virtualStackCount)) { + return null; + } + + const pokemon = scene.getPokemonById(this.pokemonId); + + this.stackCount = pokemon + ? pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length + : this.stackCount; + + const text = scene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11); + text.letterSpacing = -0.5; + if (this.getStackCount() >= this.required) { + text.setTint(0xf89890); + } + text.setOrigin(0, 0); + + return text; + } + + getMaxHeldItemCount(pokemon: Pokemon): integer { + this.stackCount = pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length; + return 999; } } @@ -2414,9 +2435,8 @@ export class MoneyRewardModifier extends ConsumableModifier { scene.getParty().map(p => { if (p.species?.speciesId === Species.GIMMIGHOUL || p.fusionSpecies?.speciesId === Species.GIMMIGHOUL) { - p.evoCounter++; - const modifierType: ModifierType = modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL(); - const modifier = modifierType!.newModifier(p); + p.evoCounter ? p.evoCounter++ : p.evoCounter = 1; + const modifier = getModifierType(modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL).newModifier(p) as EvoTrackerModifier; scene.addModifier(modifier); } }); From 3e8b3930a8911e849d6e0153b9f6112214aee690 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Sat, 28 Sep 2024 22:59:23 -0400 Subject: [PATCH 39/65] [Hotfix] Change early exit on Dark Deal species calc (#4500) Co-authored-by: ImperialSympathizer --- src/data/mystery-encounters/utils/encounter-pokemon-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index c9b30415299..fb67305c78d 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -224,7 +224,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu // If no filtered mons exist at specified starter tiers, will expand starter search range until there are // Starts by decrementing starter tier min until it is 0, then increments tier max up to 10 let tryFilterStarterTiers: [PokemonSpecies, number][] = filteredSpecies.filter(s => (s[1] >= min && s[1] <= max)); - while (tryFilterStarterTiers.length === 0 && (min !== 0 && max !== 10)) { + while (tryFilterStarterTiers.length === 0 && !(min === 0 && max === 10)) { if (min > 0) { min--; } else { From 6187830de77a8f3d2949e979171723850b2b811e Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 29 Sep 2024 00:47:45 -0700 Subject: [PATCH 40/65] [Hotfix] Fix crash in GTS ME: replace `pokemon` with `tradePokemon` (#4503) --- .../encounters/global-trade-system-encounter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index f3765c9acba..6d6b5d9f71e 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -159,7 +159,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = return true; }, onHover: () => { - const formName = tradePokemon.species.forms && tradePokemon.species.forms.length > tradePokemon.formIndex ? tradePokemon.species.forms[pokemon.formIndex].formName : null; + const formName = tradePokemon.species.forms && tradePokemon.species.forms.length > tradePokemon.formIndex ? tradePokemon.species.forms[tradePokemon.formIndex].formName : null; const line1 = i18next.t("pokemonInfoContainer:ability") + " " + tradePokemon.getAbility().name + (tradePokemon.getGender() !== Gender.GENDERLESS ? " | " + i18next.t("pokemonInfoContainer:gender") + " " + getGenderSymbol(tradePokemon.getGender()) : ""); const line2 = i18next.t("pokemonInfoContainer:nature") + " " + getNatureName(tradePokemon.getNature()) + (formName ? " | " + i18next.t("pokemonInfoContainer:form") + " " + formName : ""); showEncounterText(scene, `${line1}\n${line2}`, 0, 0, false); From b43620b8c518e239f856a375048f7138b4fe2683 Mon Sep 17 00:00:00 2001 From: Leo Kim <47556641+KimJeongSun@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:18:07 +0900 Subject: [PATCH 41/65] [Refactor] Optimize trick room ordering code (#4468) --- src/phases/turn-start-phase.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index b070abb390a..95d55986185 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -43,20 +43,17 @@ export class TurnStartPhase extends FieldPhase { orderedTargets = Utils.randSeedShuffle(orderedTargets); }, this.scene.currentBattle.turn, this.scene.waveSeed); - orderedTargets.sort((a: Pokemon, b: Pokemon) => { - const aSpeed = a?.getEffectiveStat(Stat.SPD) || 0; - const bSpeed = b?.getEffectiveStat(Stat.SPD) || 0; - - return bSpeed - aSpeed; - }); - - // Next, a check for Trick Room is applied. If Trick Room is present, the order is reversed. + // Next, a check for Trick Room is applied to determine sort order. const speedReversed = new Utils.BooleanHolder(false); this.scene.arena.applyTags(TrickRoomTag, speedReversed); - if (speedReversed.value) { - orderedTargets = orderedTargets.reverse(); - } + // Adjust the sort function based on whether Trick Room is active. + orderedTargets.sort((a: Pokemon, b: Pokemon) => { + const aSpeed = a?.getEffectiveStat(Stat.SPD) ?? 0; + const bSpeed = b?.getEffectiveStat(Stat.SPD) ?? 0; + + return speedReversed.value ? aSpeed - bSpeed : bSpeed - aSpeed; + }); return orderedTargets.map(t => t.getFieldIndex() + (!t.isPlayer() ? BattlerIndex.ENEMY : BattlerIndex.PLAYER)); } From 4160aefd9398fd73cad9bf66e9e80f9aa9f8ad17 Mon Sep 17 00:00:00 2001 From: fransdhinta <37843020+fransdhinta@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:18:52 +0700 Subject: [PATCH 42/65] [Feature] Show app version on title screen (#4344) * feat: show app version on title screen * fix: adjust app version positions * update app version text --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- src/ui/title-ui-handler.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 4087b397ff7..79baf407fb6 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -6,6 +6,7 @@ import { TextStyle, addTextObject, getTextStyleOptions } from "./text"; import { getSplashMessages } from "../data/splash-messages"; import i18next from "i18next"; import { TimedEventDisplay } from "#app/timed-event-manager"; +import { version } from "../../package.json"; export default class TitleUiHandler extends OptionSelectUiHandler { /** If the stats can not be retrieved, use this fallback value */ @@ -16,6 +17,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler { private splashMessage: string; private splashMessageText: Phaser.GameObjects.Text; private eventDisplay: TimedEventDisplay; + private appVersionText: Phaser.GameObjects.Text; private titleStatsTimer: NodeJS.Timeout | null; @@ -68,6 +70,11 @@ export default class TitleUiHandler extends OptionSelectUiHandler { loop: -1, yoyo: true, }); + + this.appVersionText = addTextObject(this.scene, logo.x - 60, logo.y + logo.displayHeight + 4, "", TextStyle.MONEY, { fontSize: "54px" }); + this.appVersionText.setOrigin(0.5, 0.5); + this.appVersionText.setAngle(0); + this.titleContainer.add(this.appVersionText); } updateTitleStats(): void { @@ -91,6 +98,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler { this.splashMessage = Utils.randItem(getSplashMessages()); this.splashMessageText.setText(i18next.t(this.splashMessage, { count: TitleUiHandler.BATTLES_WON_FALLBACK })); + this.appVersionText.setText("v"+version); + const ui = this.getUi(); if (this.scene.eventManager.isEventActive()) { From 2488bf805be818603f8bcb68a643ad716e76c786 Mon Sep 17 00:00:00 2001 From: Chapybara-jp Date: Mon, 30 Sep 2024 03:46:54 +0200 Subject: [PATCH 43/65] [Localization] [JA] Fixing typos in ability-trigger.json * Update ability-trigger.json * Update ability-trigger.json --------- Co-authored-by: Lugiad <2070109+Adri1@users.noreply.github.com> --- src/locales/ja/ability-trigger.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locales/ja/ability-trigger.json b/src/locales/ja/ability-trigger.json index 26d27701aef..6897b466195 100644 --- a/src/locales/ja/ability-trigger.json +++ b/src/locales/ja/ability-trigger.json @@ -2,11 +2,11 @@ "blockRecoilDamage": "{{pokemonName}}は {{abilityName}}で 反動ダメージを 受けない!", "badDreams": "{{pokemonName}}は ナイトメアに うなされている!", "costar": "{{pokemonName}}は {{allyName}}の\n能力変化を コピーした!", - "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}}は\n{{abilityName}}で ダメージを 受けない!", + "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} は\n{{abilityName}}で ダメージを 受けない!", "perishBody": "{{pokemonName}}の {{abilityName}}で\nおたがいは 3ターン後に ほろびいてしまう!", "poisonHeal": "{{pokemonName}}は {{abilityName}}で 回復した!", "trace": "{{pokemonName}}は 相手の {{targetName}}の\n{{abilityName}}を トレースした!", - "windPowerCharged": "{{pokemonNameWithAffix}}は\n{{moveName}}を 受けて じゅうでんした!", + "windPowerCharged": "{{pokemonName}} は\n{{moveName}}を 受けて じゅうでんした!", "quickDraw": "{{pokemonName}}は クイックドロウで\n行動が はやくなった!", "disguiseAvoidedDamage": "{{pokemonNameWithAffix}}の\nばけのかわが はがれた!", "blockItemTheft": "{{pokemonNameWithAffix}}の {{abilityName}}で\n道具を うばわれない!", @@ -48,8 +48,8 @@ "weatherEffectDisappeared": "天候の影響が なくなった!", "postSummonMoldBreaker": "{{pokemonNameWithAffix}}は\nかたやぶりだ!", "postSummonAnticipation": "{{pokemonNameWithAffix}}は\nみぶるいした!", - "postSummonTurboblaze": "{{pokemonNameWithAffix}}は\n燃え盛(もえさか)る オーラを 放っている!", - "postSummonTeravolt": "{{pokemonNameWithAffix}}は\n弾(はじ)ける オーラを 放っている!", + "postSummonTurboblaze": "{{pokemonNameWithAffix}}は\n燃え盛る オーラを 放っている!", + "postSummonTeravolt": "{{pokemonNameWithAffix}}は\n弾ける オーラを 放っている!", "postSummonDarkAura": "{{pokemonNameWithAffix}}は\nダークオーラを 放っている!", "postSummonFairyAura": "{{pokemonNameWithAffix}}は\nフェアリーオーラを 放っている!", "postSummonAuraBreak": "{{pokemonNameWithAffix}}は\nすべての オーラを 制圧する!", From fd67096a6aa92fa68ba0d41e5981c0b32b37c827 Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Mon, 30 Sep 2024 03:48:29 +0200 Subject: [PATCH 44/65] [P3 Bug][UI] Fix egg summary not displaying 1st mon properly (#4507) --- src/ui/egg-summary-ui-handler.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/egg-summary-ui-handler.ts b/src/ui/egg-summary-ui-handler.ts index f4c3e056360..519722b1505 100644 --- a/src/ui/egg-summary-ui-handler.ts +++ b/src/ui/egg-summary-ui-handler.ts @@ -99,8 +99,9 @@ export default class EggSummaryUiHandler extends MessageUiHandler { clear() { super.clear(); - this.cursor = -1; this.scrollGridHandler.reset(); + this.cursor = -1; + this.summaryContainer.setVisible(false); this.pokemonIconsContainer.removeAll(true); this.pokemonContainers = []; @@ -164,8 +165,8 @@ export default class EggSummaryUiHandler extends MessageUiHandler { this.scrollGridHandler.setTotalElements(this.eggHatchData.length); this.updatePokemonIcons(); - this.setCursor(0); + this.scene.playSoundWithoutBgm("evolution_fanfare"); return true; } From d0600125dd23fcdea6d1c9ebc157e50435e6af36 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:49:37 -0700 Subject: [PATCH 45/65] [P2] Fix Zippy Zap being boosted by Sheer Force (#4469) --- src/data/move.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index e3cb5d935d5..75799bdf2cd 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8937,7 +8937,7 @@ export function initMoves() { .partial() .ignoresVirtual(), /* End Unused */ - new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, 100, 2, 7) //LGPE Implementation + new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) //LGPE Implementation .attr(CritOnlyAttr), new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) From bcec819fa91d96ef81cfffd7c716940052f3d395 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:50:11 -0700 Subject: [PATCH 46/65] [Move] Fully Implement Syrup Bomb (#4441) * Syrup Bomb + Tests * Fix typo on import * Documentation * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Removed unnecessary overlap check * Removed obsolete comment * learned how forceHit works * added custom lapse message --------- Co-authored-by: frutescens Co-authored-by: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/battler-tags.ts | 39 +++++++++++++++ src/data/move.ts | 5 +- src/enums/battler-tag-type.ts | 1 + src/locales/en/battler-tags.json | 4 +- src/test/moves/syrup_bomb.test.ts | 82 +++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 src/test/moves/syrup_bomb.test.ts diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 4e688251147..6758dc1fada 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2589,6 +2589,43 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { } } +/** + * Battler Tag that applies the effects of Syrup Bomb to the target Pokemon. + * For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1. + * The tag can also expire by taking the target Pokemon off the field. + */ +export class SyrupBombTag extends BattlerTag { + constructor() { + super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB); + } + + /** + * Adds the Syrup Bomb battler tag to the target Pokemon. + * @param {Pokemon} pokemon the target Pokemon + */ + override onAdd(pokemon: Pokemon) { + super.onAdd(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + + /** + * Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count + * @param {Pokemon} pokemon the target Pokemon + * @param {BattlerTagLapseType} _lapseType + * @returns `true` if the turnCount is still greater than 0 | `false` if the turnCount is 0 or the target Pokemon has been removed from the field + */ + override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { + if (!pokemon.isActive(true)) { + return false; + } + pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline + pokemon.scene.unshiftPhase(new StatStageChangePhase( + pokemon.scene, pokemon.getBattlerIndex(), true, + [Stat.SPD], -1, true, false, true + )); + return --this.turnCount > 0; + } +} /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. @@ -2763,6 +2800,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new TauntTag(); case BattlerTagType.IMPRISON: return new ImprisonTag(sourceId); + case BattlerTagType.SYRUP_BOMB: + return new SyrupBombTag(); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/move.ts b/src/data/move.ts index 75799bdf2cd..59db7495754 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -9622,9 +9622,8 @@ export function initMoves() { .target(MoveTarget.ALL_NEAR_ENEMIES) .triageMove(), new AttackMove(Moves.SYRUP_BOMB, Type.GRASS, MoveCategory.SPECIAL, 60, 85, 10, -1, 0, 9) - .attr(StatStageChangeAttr, [ Stat.SPD ], -1) //Temporary - .ballBombMove() - .partial(), + .attr(AddBattlerTagAttr, BattlerTagType.SYRUP_BOMB, false, false, 3) + .ballBombMove(), new AttackMove(Moves.IVY_CUDGEL, Type.GRASS, MoveCategory.PHYSICAL, 100, 100, 10, -1, 0, 9) .attr(IvyCudgelTypeAttr) .attr(HighCritAttr) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 9ed3b629746..209d36316f9 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -85,4 +85,5 @@ export enum BattlerTagType { TORMENT = "TORMENT", TAUNT = "TAUNT", IMPRISON = "IMPRISON", + SYRUP_BOMB = "SYRUP_BOMB", } diff --git a/src/locales/en/battler-tags.json b/src/locales/en/battler-tags.json index 520ac2a6202..bb4b708b25f 100644 --- a/src/locales/en/battler-tags.json +++ b/src/locales/en/battler-tags.json @@ -78,5 +78,7 @@ "tormentOnAdd": "{{pokemonNameWithAffix}} was subjected to torment!", "tauntOnAdd": "{{pokemonNameWithAffix}} fell for the taunt!", "imprisonOnAdd": "{{pokemonNameWithAffix}} sealed the opponents move(s)!", - "autotomizeOnAdd": "{{pokemonNameWithAffix}} became nimble!" + "autotomizeOnAdd": "{{pokemonNameWithAffix}} became nimble!", + "syrupBombOnAdd": "{{pokemonNameWithAffix}} got covered in sticky, candy syrup!", + "syrupBombLapse": "The sticky syrup slowed down {{pokemonNameWithAffix}}!" } diff --git a/src/test/moves/syrup_bomb.test.ts b/src/test/moves/syrup_bomb.test.ts new file mode 100644 index 00000000000..20cd590e457 --- /dev/null +++ b/src/test/moves/syrup_bomb.test.ts @@ -0,0 +1,82 @@ +import { allMoves } from "#app/data/move"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Stat } from "#enums/stat"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { BattlerIndex } from "#app/battle"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - SYRUP BOMB", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .starterSpecies(Species.MAGIKARP) + .enemySpecies(Species.SNORLAX) + .startingLevel(30) + .enemyLevel(100) + .moveset([Moves.SYRUP_BOMB, Moves.SPLASH]) + .enemyMoveset(Moves.SPLASH); + vi.spyOn(allMoves[Moves.SYRUP_BOMB], "accuracy", "get").mockReturnValue(100); + }); + + //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move) + + it("decreases the target Pokemon's speed stat once per turn for 3 turns", + async () => { + await game.startBattle([Species.MAGIKARP]); + + const targetPokemon = game.scene.getEnemyPokemon()!; + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SYRUP_BOMB); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.move.forceHit(); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeDefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-1); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeDefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-2); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeUndefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-3); + } + ); + + it("does not affect Pokemon with the ability Bulletproof", + async () => { + game.override.enemyAbility(Abilities.BULLETPROOF); + await game.startBattle([Species.MAGIKARP]); + + const targetPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SYRUP_BOMB); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.move.forceHit(); + await game.toNextTurn(); + expect(targetPokemon.isFullHp()).toBe(true); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeUndefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); + } + ); +}); From 6d89ad95699a3c380cb01e69da02395b76d2daa7 Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Mon, 30 Sep 2024 03:52:13 +0200 Subject: [PATCH 47/65] [P2] Fix duplicate mon ID / RNG not properly resetting after game over (#4505) --- src/battle-scene.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 8e299dd8e06..c5283b091d4 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1040,10 +1040,6 @@ export default class BattleScene extends SceneBase { this.gameMode = getGameMode(GameModes.CLASSIC); - this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24)); - console.log("Seed:", this.seed); - this.resetSeed(); // Properly resets RNG after saving and quitting a session - this.disableMenu = false; this.score = 0; @@ -1078,6 +1074,12 @@ export default class BattleScene extends SceneBase { //@ts-ignore - allowing `null` for currentBattle causes a lot of trouble this.currentBattle = null; // TODO: resolve ts-ignore + // Reset RNG after end of game or save & quit. + // This needs to happen after clearing this.currentBattle or the seed will be affected by the last wave played + this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24)); + console.log("Seed:", this.seed); + this.resetSeed(); + this.biomeWaveText.setText(startingWave.toString()); this.biomeWaveText.setVisible(false); From 7339facae139a86fb8a5af7be3cc1979a7f28e81 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:54:49 -0700 Subject: [PATCH 48/65] [Ability] Remove (P) from Super Luck (#4498) --- src/data/ability.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 3ace872de3c..6ec4ac0e02c 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -5210,8 +5210,7 @@ export function initAbilities() { .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonMoldBreaker", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .attr(MoveAbilityBypassAbAttr), new Ability(Abilities.SUPER_LUCK, 4) - .attr(BonusCritAbAttr) - .partial(), + .attr(BonusCritAbAttr), new Ability(Abilities.AFTERMATH, 4) .attr(PostFaintContactDamageAbAttr, 4) .bypassFaint(), From 82111bc62dbb078628bce4835d333c44b951b29d Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Sun, 29 Sep 2024 20:55:17 -0500 Subject: [PATCH 49/65] [Enhancement] Gen 7+ grunts can now be in double battles (#4489) --- src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 778d2467803..412fd1b5184 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -497,7 +497,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand } /* 1/3 chance for evil team grunts to be double battles */ - const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT]; + const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT]; const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]); if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) { From d620b5c7fae912ddaed5b6ccb2d0d865aeda2084 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Sun, 29 Sep 2024 21:56:05 -0400 Subject: [PATCH 50/65] [Refactor] Move base shiny/HA chance to constants outside functions (#4407) --- src/field/pokemon.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 07525e92157..d47cbedbade 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -63,6 +63,12 @@ import { PLAYER_PARTY_MAX_SIZE } from "#app/constants"; import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; import { SwitchType } from "#enums/switch-type"; +/** `64/65536 -> 1/1024` */ +const BASE_SHINY_CHANCE = 64; + +/** `1/256` */ +const BASE_HIDDEN_ABILITY_CHANCE = 256; + export enum FieldPosition { CENTER, LEFT, @@ -139,7 +145,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`; } - const hiddenAbilityChance = new Utils.IntegerHolder(256); + const hiddenAbilityChance = new Utils.IntegerHolder(BASE_HIDDEN_ABILITY_CHANCE); if (!this.hasTrainer()) { this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); } @@ -1822,7 +1828,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * The exact mechanic is that it calculates E as the XOR of the player's trainer ID and secret ID. * F is calculated as the XOR of the first 16 bits of the Pokemon's ID with the last 16 bits. * The XOR of E and F are then compared to the {@linkcode shinyThreshold} (or {@linkcode thresholdOverride} if set) to see whether or not to generate a shiny. - * The base shiny odds are {@linkcode baseShinyChance} / 65536 + * The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / 65536 * @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm) * @returns true if the Pokemon has been set as a shiny, false otherwise */ @@ -1838,9 +1844,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId; const F = rand1 ^ rand2; - /** `64/65536 -> 1/1024` */ - const baseShinyChance = 64; - const shinyThreshold = new Utils.IntegerHolder(baseShinyChance); + const shinyThreshold = new Utils.IntegerHolder(BASE_SHINY_CHANCE); if (thresholdOverride === undefined) { if (this.scene.eventManager.isEventActive()) { shinyThreshold.value *= this.scene.eventManager.getShinyMultiplier(); @@ -1865,15 +1869,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Function that tries to set a Pokemon shiny based on seed. * For manual use only, usually to roll a Pokemon's shiny chance a second time. * - * The base shiny odds are {@linkcode baseShinyChance} / 65536 + * The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / 65536 * @param thresholdOverride number that is divided by 2^16 (65536) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm) * @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride} * @returns true if the Pokemon has been set as a shiny, false otherwise */ trySetShinySeed(thresholdOverride?: integer, applyModifiersToOverride?: boolean): boolean { - /** `64/65536 -> 1/1024` */ - const baseShinyChance = 64; - const shinyThreshold = new Utils.IntegerHolder(baseShinyChance); + const shinyThreshold = new Utils.IntegerHolder(BASE_SHINY_CHANCE); if (thresholdOverride === undefined || applyModifiersToOverride) { if (thresholdOverride !== undefined && applyModifiersToOverride) { shinyThreshold.value = thresholdOverride; @@ -1931,7 +1933,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } generateFusionSpecies(forStarter?: boolean): void { - const hiddenAbilityChance = new Utils.IntegerHolder(256); + const hiddenAbilityChance = new Utils.IntegerHolder(BASE_HIDDEN_ABILITY_CHANCE); if (!this.hasTrainer()) { this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); } From 4c327e9e63537935e3401fdfe50c65d66bfbe889 Mon Sep 17 00:00:00 2001 From: "Adrian T." <68144167+torranx@users.noreply.github.com> Date: Mon, 30 Sep 2024 09:57:50 +0800 Subject: [PATCH 51/65] [Ability] Refactor Gulp Missile and make it trigger when Cramorant faints (#4428) * reimplement gulp missile * cleanup + docs * more cleanup * add override * update paths --- src/data/ability.ts | 57 ++----------- src/data/battler-tags.ts | 31 ++++++- src/test/abilities/gulp_missile.test.ts | 104 +++++++++++++----------- 3 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 6ec4ac0e02c..041d90ac4c0 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -4,7 +4,7 @@ import { Constructor } from "#app/utils"; import * as Utils from "../utils"; import { getPokemonNameWithAffix } from "../messages"; import { Weather, WeatherType } from "./weather"; -import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags"; +import { BattlerTag, GroundedTag } from "./battler-tags"; import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { Gender } from "./gender"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; @@ -536,53 +536,6 @@ export class PostDefendAbAttr extends AbAttr { } } -/** - * Applies the effects of Gulp Missile when the user is hit by an attack. - * @extends PostDefendAbAttr - */ -export class PostDefendGulpMissileAbAttr extends PostDefendAbAttr { - constructor() { - super(true); - } - - /** - * Damages the attacker and triggers the secondary effect based on the form or the BattlerTagType. - * @param {Pokemon} pokemon - The defending Pokemon. - * @param passive - n/a - * @param {Pokemon} attacker - The attacking Pokemon. - * @param {Move} move - The move being used. - * @param {HitResult} hitResult - n/a - * @param {any[]} args - n/a - * @returns Whether the effects of the ability are applied. - */ - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise { - const battlerTag = pokemon.getTag(GulpMissileTag); - if (!battlerTag || move.category === MoveCategory.STATUS || pokemon.getTag(SemiInvulnerableTag)) { - return false; - } - - if (simulated) { - return true; - } - - const cancelled = new Utils.BooleanHolder(false); - applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); - - if (!cancelled.value) { - attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER); - } - - if (battlerTag.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) { - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ Stat.DEF ], -1)); - } else { - attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon); - } - - pokemon.removeTag(battlerTag.tagType); - return true; - } -} - export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { const attackPriority = new Utils.IntegerHolder(move.priority); @@ -5668,13 +5621,19 @@ export function initAbilities() { new Ability(Abilities.MIRROR_ARMOR, 8) .ignorable() .unimplemented(), + /** + * Right now, the logic is attached to Surf and Dive moves. Ideally, the post-defend/hit should be an + * ability attribute but the current implementation of move effects for BattlerTag does not support this- in the case + * where Cramorant is fainted. + * @see {@linkcode GulpMissileTagAttr} and {@linkcode GulpMissileTag} for Gulp Missile implementation + */ new Ability(Abilities.GULP_MISSILE, 8) .attr(UnsuppressableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(PostDefendGulpMissileAbAttr), + .bypassFaint(), new Ability(Abilities.STALWART, 8) .attr(BlockRedirectAbAttr), new Ability(Abilities.STEAM_ENGINE, 8) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 6758dc1fada..d8094f96368 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2123,7 +2123,36 @@ export class StockpilingTag extends BattlerTag { */ export class GulpMissileTag extends BattlerTag { constructor(tagType: BattlerTagType, sourceMove: Moves) { - super(tagType, BattlerTagLapseType.CUSTOM, 0, sourceMove); + super(tagType, BattlerTagLapseType.HIT, 0, sourceMove); + } + + override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + if (pokemon.getTag(BattlerTagType.UNDERWATER)) { + return true; + } + + const moveEffectPhase = pokemon.scene.getCurrentPhase(); + if (moveEffectPhase instanceof MoveEffectPhase) { + const attacker = moveEffectPhase.getUserPokemon(); + + if (!attacker) { + return false; + } + + const cancelled = new Utils.BooleanHolder(false); + applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); + + if (!cancelled.value) { + attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER); + } + + if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) { + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ Stat.DEF ], -1)); + } else { + attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon); + } + } + return false; } /** diff --git a/src/test/abilities/gulp_missile.test.ts b/src/test/abilities/gulp_missile.test.ts index ac0efd8e8d1..d981f009974 100644 --- a/src/test/abilities/gulp_missile.test.ts +++ b/src/test/abilities/gulp_missile.test.ts @@ -1,11 +1,7 @@ -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import { StatusEffect } from "#app/enums/status-effect"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatusEffect } from "#enums/status-effect"; import Pokemon from "#app/field/pokemon"; -import { BerryPhase } from "#app/phases/berry-phase"; -import { MoveEndPhase } from "#app/phases/move-end-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; -import { TurnStartPhase } from "#app/phases/turn-start-phase"; -import GameManager from "#app/test/utils/gameManager"; +import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -53,13 +49,13 @@ describe("Abilities - Gulp Missile", () => { }); it("changes to Gulping Form if HP is over half when Surf or Dive is used", async () => { - await game.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.DIVE); await game.toNextTurn(); game.move.select(Moves.DIVE); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getHpRatio()).toBeGreaterThanOrEqual(.5); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); @@ -67,21 +63,21 @@ describe("Abilities - Gulp Missile", () => { }); it("changes to Gorging Form if HP is under half when Surf or Dive is used", async () => { - await game.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.49); expect(cramorant.getHpRatio()).toBe(.49); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined(); expect(cramorant.formIndex).toBe(GORGING_FORM); }); it("changes to base form when switched out after Surf or Dive is used", async () => { - await game.startBattle([Species.CRAMORANT, Species.MAGIKARP]); + await game.classicMode.startBattle([Species.CRAMORANT, Species.MAGIKARP]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.SURF); @@ -96,51 +92,51 @@ describe("Abilities - Gulp Missile", () => { }); it("changes form during Dive's charge turn", async () => { - await game.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.DIVE); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); }); it("deals 1/4 of the attacker's maximum HP when hit by a damaging attack", async () => { - game.override.enemyMoveset([Moves.TACKLE]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.CRAMORANT]); const enemy = game.scene.getEnemyPokemon()!; vi.spyOn(enemy, "damageAndUpdate"); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy)); }); it("does not have any effect when hit by non-damaging attack", async () => { - game.override.enemyMoveset([Moves.TAIL_WHIP]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.TAIL_WHIP); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); }); it("lowers attacker's DEF stat stage by 1 when hit in Gulping form", async () => { - game.override.enemyMoveset([Moves.TACKLE]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -149,12 +145,12 @@ describe("Abilities - Gulp Missile", () => { vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy)); expect(enemy.getStatStage(Stat.DEF)).toBe(-1); @@ -163,8 +159,8 @@ describe("Abilities - Gulp Missile", () => { }); it("paralyzes the enemy when hit in Gorging form", async () => { - game.override.enemyMoveset([Moves.TACKLE]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -173,12 +169,12 @@ describe("Abilities - Gulp Missile", () => { vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.45); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined(); expect(cramorant.formIndex).toBe(GORGING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy)); expect(enemy.status?.effect).toBe(StatusEffect.PARALYSIS); @@ -187,21 +183,21 @@ describe("Abilities - Gulp Missile", () => { }); it("does not activate the ability when underwater", async () => { - game.override.enemyMoveset([Moves.SURF]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.SURF); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.DIVE); - await game.phaseInterceptor.to(BerryPhase, false); + await game.phaseInterceptor.to("BerryPhase", false); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); }); it("prevents effect damage but inflicts secondary effect on attacker with Magic Guard", async () => { - game.override.enemyMoveset([Moves.TACKLE]).enemyAbility(Abilities.MAGIC_GUARD); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.TACKLE).enemyAbility(Abilities.MAGIC_GUARD); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -209,13 +205,13 @@ describe("Abilities - Gulp Missile", () => { vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); const enemyHpPreEffect = enemy.hp; expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(enemy.hp).toBe(enemyHpPreEffect); expect(enemy.getStatStage(Stat.DEF)).toBe(-1); @@ -223,20 +219,36 @@ describe("Abilities - Gulp Missile", () => { expect(cramorant.formIndex).toBe(NORMAL_FORM); }); + it("activates on faint", async () => { + game.override.enemyMoveset(Moves.THUNDERBOLT); + await game.classicMode.startBattle([Species.CRAMORANT]); + + const cramorant = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.SURF); + await game.phaseInterceptor.to("FaintPhase"); + + expect(cramorant.hp).toBe(0); + expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeUndefined(); + expect(cramorant.formIndex).toBe(NORMAL_FORM); + expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(-1); + }); + + it("cannot be suppressed", async () => { - game.override.enemyMoveset([Moves.GASTRO_ACID]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.GASTRO_ACID); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(cramorant.hasAbility(Abilities.GULP_MISSILE)).toBe(true); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); @@ -244,19 +256,19 @@ describe("Abilities - Gulp Missile", () => { }); it("cannot be swapped with another ability", async () => { - game.override.enemyMoveset([Moves.SKILL_SWAP]); - await game.startBattle([Species.CRAMORANT]); + game.override.enemyMoveset(Moves.SKILL_SWAP); + await game.classicMode.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); game.move.select(Moves.SURF); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.formIndex).toBe(GULPING_FORM); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(cramorant.hasAbility(Abilities.GULP_MISSILE)).toBe(true); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); @@ -266,9 +278,9 @@ describe("Abilities - Gulp Missile", () => { it("cannot be copied", async () => { game.override.enemyAbility(Abilities.TRACE); - await game.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([Species.CRAMORANT]); game.move.select(Moves.SPLASH); - await game.phaseInterceptor.to(TurnStartPhase); + await game.phaseInterceptor.to("TurnStartPhase"); expect(game.scene.getEnemyPokemon()?.hasAbility(Abilities.GULP_MISSILE)).toBe(false); }); From d99dbf495568ede0eb440742c918b7aa759444c2 Mon Sep 17 00:00:00 2001 From: PrabbyDD <147005742+PrabbyDD@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:00:29 -0700 Subject: [PATCH 52/65] [P2] Fix for Pokemon Forms have Access to Other Forms' TM Movepools (#4398) * fixing form issues generating tms pokemon shouldnt have * cleaning up some code * fixing tests and allowing rotom unique moves to be learned as tms for that rotom form * Update src/test/field/pokemon.test.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * making tests simpler --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- src/field/pokemon.ts | 3 ++- src/test/field/pokemon.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index d47cbedbade..58396c59fa6 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3981,7 +3981,8 @@ export class PlayerPokemon extends Pokemon { let compatible = false; for (const p of tmSpecies[tm]) { if (Array.isArray(p)) { - if (p[0] === this.species.speciesId || (this.fusionSpecies && p[0] === this.fusionSpecies.speciesId) && p.slice(1).indexOf(this.species.forms[this.formIndex]) > -1) { + const [pkm, form] = p; + if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) { compatible = true; break; } diff --git a/src/test/field/pokemon.test.ts b/src/test/field/pokemon.test.ts index f7c1cf8bc3d..225f302ff0c 100644 --- a/src/test/field/pokemon.test.ts +++ b/src/test/field/pokemon.test.ts @@ -3,6 +3,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import GameManager from "../utils/gameManager"; import { PokeballType } from "#app/enums/pokeball"; import BattleScene from "#app/battle-scene"; +import { Moves } from "#app/enums/moves"; describe("Spec - Pokemon", () => { let phaserGame: Phaser.Game; @@ -63,4 +64,15 @@ describe("Spec - Pokemon", () => { }); }); }); + + it("should not share tms between different forms", async () => { + game.override.starterForms({ [Species.ROTOM]: 4 }); + + await game.classicMode.startBattle([Species.ROTOM]); + + const fanRotom = game.scene.getPlayerPokemon()!; + + expect(fanRotom.compatibleTms).not.toContain(Moves.BLIZZARD); + expect(fanRotom.compatibleTms).toContain(Moves.AIR_SLASH); + }); }); From 79e172176d1aefa2b4679aa48efc041738b51169 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Sep 2024 22:03:09 -0400 Subject: [PATCH 53/65] Bump rollup from 4.18.1 to 4.22.4 (#4439) Bumps [rollup](https://github.com/rollup/rollup) from 4.18.1 to 4.22.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.18.1...v4.22.4) --- updated-dependencies: - dependency-name: rollup dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From d8ee8ad82190660b66ddfb8a2f5beed5ab82592d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Sep 2024 22:04:31 -0400 Subject: [PATCH 54/65] Bump vite from 5.3.5 to 5.4.8 (#4413) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.3.5 to 5.4.8. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.8/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.8/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- package-lock.json | 43 ++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 316306e3299..568a57d3589 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "typedoc": "^0.26.4", "typescript": "^5.5.3", "typescript-eslint": "^8.0.0-alpha.54", - "vite": "^5.3.5", + "vite": "^5.4.8", "vite-tsconfig-paths": "^4.3.2", "vitest": "^2.0.4", "vitest-canvas-mock": "^0.3.3" @@ -3650,7 +3650,6 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -5042,7 +5041,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -5441,9 +5439,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -5459,16 +5457,21 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss/node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5865,11 +5868,10 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6469,15 +6471,14 @@ } }, "node_modules/vite": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", - "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -6496,6 +6497,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -6513,6 +6515,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, diff --git a/package.json b/package.json index 37418014d93..480934899cc 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "typedoc": "^0.26.4", "typescript": "^5.5.3", "typescript-eslint": "^8.0.0-alpha.54", - "vite": "^5.3.5", + "vite": "^5.4.8", "vite-tsconfig-paths": "^4.3.2", "vitest": "^2.0.4", "vitest-canvas-mock": "^0.3.3" From 1bae87fa56b2d4abb3b2134432f4695880ae99fa Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:30:33 -0700 Subject: [PATCH 55/65] [Move] Fully Implement Plasma Fists (#4446) * Implement Plasma Fists * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json --------- Co-authored-by: Lugiad --- src/data/arena-tag.ts | 35 +++++++++++ src/data/move.ts | 4 +- src/enums/arena-tag-type.ts | 1 + src/field/pokemon.ts | 2 + src/locales/de/arena-tag.json | 3 +- src/locales/en/arena-tag.json | 1 + src/locales/es/arena-tag.json | 3 +- src/locales/fr/arena-tag.json | 1 + src/locales/it/arena-tag.json | 3 +- src/locales/ja/arena-tag.json | 1 + src/locales/ko/arena-tag.json | 3 +- src/locales/pt_BR/arena-tag.json | 1 + src/locales/zh_CN/arena-tag.json | 3 +- src/locales/zh_TW/arena-tag.json | 1 + src/test/moves/plasma_fists.test.ts | 98 +++++++++++++++++++++++++++++ src/test/utils/gameManager.ts | 2 +- 16 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 src/test/moves/plasma_fists.test.ts diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index d783ea51056..9e121b81fea 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -511,6 +511,39 @@ class WaterSportTag extends WeakenMoveTypeTag { } } +/** + * Arena Tag class for the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}. + * Converts Normal-type moves to Electric type for the rest of the turn. + */ +export class PlasmaFistsTag extends ArenaTag { + constructor() { + super(ArenaTagType.PLASMA_FISTS, 1, Moves.PLASMA_FISTS); + } + + /** Queues Plasma Fists' on-add message */ + onAdd(arena: Arena): void { + arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd")); + } + + onRemove(arena: Arena): void { } // Removes default on-remove message + + /** + * Converts Normal-type moves to Electric type + * @param arena n/a + * @param args + * - `[0]` {@linkcode Utils.NumberHolder} A container with a move's {@linkcode Type} + * @returns `true` if the given move type changed; `false` otherwise. + */ + apply(arena: Arena, args: any[]): boolean { + const moveType = args[0]; + if (moveType instanceof Utils.NumberHolder && moveType.value === Type.NORMAL) { + moveType.value = Type.ELECTRIC; + return true; + } + return false; + } +} + /** * Abstract class to implement arena traps. */ @@ -1010,6 +1043,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov return new MudSportTag(turnCount, sourceId); case ArenaTagType.WATER_SPORT: return new WaterSportTag(turnCount, sourceId); + case ArenaTagType.PLASMA_FISTS: + return new PlasmaFistsTag(); case ArenaTagType.SPIKES: return new SpikesTag(sourceId, side); case ArenaTagType.TOXIC_SPIKES: diff --git a/src/data/move.ts b/src/data/move.ts index 59db7495754..7c5962abb22 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8906,8 +8906,8 @@ export function initMoves() { .attr(HalfSacrificialAttr) .target(MoveTarget.ALL_NEAR_OTHERS), new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7) - .punchingMove() - .partial(), + .attr(AddArenaTagAttr, ArenaTagType.PLASMA_FISTS, 1) + .punchingMove(), new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) .ignoresAbilities() diff --git a/src/enums/arena-tag-type.ts b/src/enums/arena-tag-type.ts index c6f911cb493..123d70b64fa 100644 --- a/src/enums/arena-tag-type.ts +++ b/src/enums/arena-tag-type.ts @@ -25,4 +25,5 @@ export enum ArenaTagType { SAFEGUARD = "SAFEGUARD", NO_CRIT = "NO_CRIT", IMPRISON = "IMPRISON", + PLASMA_FISTS = "PLASMA_FISTS", } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 58396c59fa6..a318d3ffdeb 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1518,6 +1518,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder); applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder); + this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder); + return moveTypeHolder.value as Type; } diff --git a/src/locales/de/arena-tag.json b/src/locales/de/arena-tag.json index 3bed4fefbd0..93ceb06f308 100644 --- a/src/locales/de/arena-tag.json +++ b/src/locales/de/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "Lehmsuhler hört auf zu wirken!", "waterSportOnAdd": "Die Stärke aller Feuer-Attacken wurde reduziert!", "waterSportOnRemove": "Nassmacher hört auf zu wirken!", + "plasmaFistsOnAdd": "Ein elektrisch geladener Niederschlag regnet auf das Kampffeld herab!", "spikesOnAdd": "Die {{opponentDesc}} sind von Stacheln umgeben!", "spikesActivateTrap": "Die {{pokemonNameWithAffix}} wurde durch Stachler verletzt!!", "toxicSpikesOnAdd": "Die {{opponentDesc}} sind überall von giftigen Stacheln umgeben", @@ -54,4 +55,4 @@ "safeguardOnRemove": "Der mystische Schleier, der das ganze Feld umgab, hat sich gelüftet!", "safeguardOnRemovePlayer": "Der mystische Schleier, der dein Team umgab, hat sich gelüftet!", "safeguardOnRemoveEnemy": "Der mystische Schleier, der das gegnerische Team umgab, hat sich gelüftet!" -} \ No newline at end of file +} diff --git a/src/locales/en/arena-tag.json b/src/locales/en/arena-tag.json index d8fed386b24..df79693c7bb 100644 --- a/src/locales/en/arena-tag.json +++ b/src/locales/en/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "The effects of Mud Sport\nhave faded.", "waterSportOnAdd": "Fire's power was weakened!", "waterSportOnRemove": "The effects of Water Sport\nhave faded.", + "plasmaFistsOnAdd": "A deluge of ions showers the battlefield!", "spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", "spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!", "toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", diff --git a/src/locales/es/arena-tag.json b/src/locales/es/arena-tag.json index 0f63b62e784..9aa37654c62 100644 --- a/src/locales/es/arena-tag.json +++ b/src/locales/es/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "Chapoteo Lodo ha dejado de surtir efecto.", "waterSportOnAdd": "¡Se han debilitado los ataques\nde tipo Fuego!", "waterSportOnRemove": "Hidrochorro ha dejado de surtir efecto.", + "plasmaFistsOnAdd": "¡Una lluvia de electrones cae sobre\nel terreno de combate!", "spikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!", "spikesActivateTrap": "¡Las púas han herido a {{pokemonNameWithAffix}}!", "toxicSpikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!", @@ -54,4 +55,4 @@ "safeguardOnRemove": "¡Velo Sagrado dejó de hacer efecto!", "safeguardOnRemovePlayer": "El efecto de Velo Sagrado en tu equipo se ha disipado.", "safeguardOnRemoveEnemy": "El efecto de Velo Sagrado en el equipo enemigo se ha disipado." -} \ No newline at end of file +} diff --git a/src/locales/fr/arena-tag.json b/src/locales/fr/arena-tag.json index 9cb2f342068..95e38cdbe9d 100644 --- a/src/locales/fr/arena-tag.json +++ b/src/locales/fr/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "L’effet de Lance-Boue se dissipe !", "waterSportOnAdd": "La puissance des capacités\nde type Feu diminue !", "waterSportOnRemove": "L’effet de Tourniquet se dissipe !", + "plasmaFistsOnAdd": "Un déluge de plasma s’abat sur le terrain !", "spikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !", "spikesActivateTrap": "{{pokemonNameWithAffix}} est blessé\npar les picots !", "toxicSpikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !", diff --git a/src/locales/it/arena-tag.json b/src/locales/it/arena-tag.json index a1c5ee5b3c9..be2a06eb898 100644 --- a/src/locales/it/arena-tag.json +++ b/src/locales/it/arena-tag.json @@ -1,8 +1,9 @@ { + "plasmaFistsOnAdd": "Una pioggia di elettroni si rovescia sui Pokémon!", "safeguardOnAdd": "Un velo mistico ricopre il campo!", "safeguardOnAddPlayer": "Un velo mistico ricopre la tua squadra!", "safeguardOnAddEnemy": "Un velo mistico ricopre la squadra avversaria!", "safeguardOnRemove": "Il campo non è più protetto da Salvaguardia!", "safeguardOnRemovePlayer": "La tua squadra non è più protetta da Salvaguardia!", "safeguardOnRemoveEnemy": "La squadra avversaria non è più protetta da Salvaguardia!" -} \ No newline at end of file +} diff --git a/src/locales/ja/arena-tag.json b/src/locales/ja/arena-tag.json index a81942338fd..0da759884a5 100644 --- a/src/locales/ja/arena-tag.json +++ b/src/locales/ja/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "どろあそびの 効果が なくなった!", "waterSportOnAdd": "炎の威力が 弱まった!", "waterSportOnRemove": "みずあそびの 効果が なくなった!", + "plasmaFistsOnAdd": "電子のシャワーが 降りそそいだ!", "spikesOnAdd": "{{opponentDesc}}の 足下に\n{{moveName}}が 散らばった!", "spikesActivateTrap": "{{pokemonNameWithAffix}}は\nまきびしの ダメージを 受けた!", "toxicSpikesOnAdd": "{{opponentDesc}}の 足下に\n{{moveName}}が 散らばった!", diff --git a/src/locales/ko/arena-tag.json b/src/locales/ko/arena-tag.json index ce9922ab3bf..c1a7b1ca7ca 100644 --- a/src/locales/ko/arena-tag.json +++ b/src/locales/ko/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "흙놀이의 효과가\n없어졌다!", "waterSportOnAdd": "불꽃의 위력이 약해졌다!", "waterSportOnRemove": "물놀이의 효과가\n없어졌다!", + "plasmaFistsOnAdd": "전기 입자가 쏟아졌다!", "spikesOnAdd": "{{opponentDesc}}의 발밑에\n압정이 뿌려졌다!", "spikesActivateTrap": "{{pokemonNameWithAffix}}[[는]]\n압정뿌리기의 데미지를 입었다!", "toxicSpikesOnAdd": "{{opponentDesc}}의 발밑에\n독압정이 뿌려졌다!", @@ -54,4 +55,4 @@ "safeguardOnRemove": "필드를 감싸던 신비의 베일이 없어졌다!", "safeguardOnRemovePlayer": "우리 편을 감싸던 신비의 베일이 없어졌다!", "safeguardOnRemoveEnemy": "상대 편을 감싸던 신비의 베일이 없어졌다!" -} \ No newline at end of file +} diff --git a/src/locales/pt_BR/arena-tag.json b/src/locales/pt_BR/arena-tag.json index 3a1476dcef6..5fb8b49565f 100644 --- a/src/locales/pt_BR/arena-tag.json +++ b/src/locales/pt_BR/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "Os efeitos de Mud Sport\nsumiram.", "waterSportOnAdd": "O poder de movimentos de fogo foi enfraquecido!", "waterSportOnRemove": "Os efeitos de Water Sport\nsumiram.", + "plasmaFistsOnAdd": "Um dilúvio de íons chove sobre o campo de batalha!", "spikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!", "spikesActivateTrap": "{{pokemonNameWithAffix}} foi ferido\npelos espinhos!", "toxicSpikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!", diff --git a/src/locales/zh_CN/arena-tag.json b/src/locales/zh_CN/arena-tag.json index 74ad38ba9bf..d7ac1b9b04b 100644 --- a/src/locales/zh_CN/arena-tag.json +++ b/src/locales/zh_CN/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "玩泥巴的效果消失了!", "waterSportOnAdd": "火焰的威力减弱了!", "waterSportOnRemove": "玩水的效果消失了!", + "plasmaFistsOnAdd": "等离子雨倾盆而下!", "spikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!", "spikesActivateTrap": "{{pokemonNameWithAffix}}\n受到了撒菱的伤害!", "toxicSpikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!", @@ -54,4 +55,4 @@ "safeguardOnRemove": "包围整个场地的\n神秘之幕消失了!", "safeguardOnRemovePlayer": "包围我方的\n神秘之幕消失了!", "safeguardOnRemoveEnemy": "包围对手的\n神秘之幕消失了!" -} \ No newline at end of file +} diff --git a/src/locales/zh_TW/arena-tag.json b/src/locales/zh_TW/arena-tag.json index a6224f300a3..4a08d268e20 100644 --- a/src/locales/zh_TW/arena-tag.json +++ b/src/locales/zh_TW/arena-tag.json @@ -28,6 +28,7 @@ "mudSportOnRemove": "玩泥巴的效果消失了!", "waterSportOnAdd": "火焰的威力減弱了!", "waterSportOnRemove": "玩水的效果消失了!", + "plasmaFistsOnAdd": "等離子雨傾盆而下!", "spikesOnAdd": "{{opponentDesc}}腳下\n散落著{{moveName}}!", "spikesActivateTrap": "{{pokemonNameWithAffix}}\n受到了撒菱的傷害!", "toxicSpikesOnAdd": "{{opponentDesc}}腳下\n散落著{{moveName}}!", diff --git a/src/test/moves/plasma_fists.test.ts b/src/test/moves/plasma_fists.test.ts new file mode 100644 index 00000000000..a9bd7660dfd --- /dev/null +++ b/src/test/moves/plasma_fists.test.ts @@ -0,0 +1,98 @@ +import { BattlerIndex } from "#app/battle"; +import { Type } from "#app/data/type"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Plasma Fists", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.PLASMA_FISTS, Moves.TACKLE]) + .battleType("double") + .startingLevel(100) + .enemySpecies(Species.DUSCLOPS) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE) + .enemyLevel(100); + }); + + it("should convert all subsequent Normal-type attacks to Electric-type", async () => { + await game.classicMode.startBattle([Species.DUSCLOPS, Species.BLASTOISE]); + + const field = game.scene.getField(true); + field.forEach(p => vi.spyOn(p, "getMoveType")); + + game.move.select(Moves.PLASMA_FISTS, 0, BattlerIndex.ENEMY); + game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY_2); + + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); + + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + + await game.phaseInterceptor.to("BerryPhase", false); + + field.forEach(p => { + expect(p.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(p.hp).toBeLessThan(p.getMaxHp()); + }); + }); + + it("should not affect Normal-type attacks boosted by Pixilate", async () => { + game.override + .battleType("single") + .enemyAbility(Abilities.PIXILATE); + + await game.classicMode.startBattle([Species.ONIX]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.PLASMA_FISTS); + + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.FAIRY); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + }); + + it("should affect moves that become Normal type due to Normalize", async () => { + game.override + .battleType("single") + .enemyAbility(Abilities.NORMALIZE) + .enemyMoveset(Moves.WATER_GUN); + + await game.classicMode.startBattle([Species.DUSCLOPS]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.PLASMA_FISTS); + + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + }); +}); diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index 6fad87df182..a2403de7e18 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -303,7 +303,7 @@ export default class GameManager { vi.spyOn(enemy, "getNextMove").mockReturnValueOnce({ move: moveId, - targets: (target && !legalTargets.multiple && legalTargets.targets.includes(target)) + targets: (target !== undefined && !legalTargets.multiple && legalTargets.targets.includes(target)) ? [target] : enemy.getNextTargets(moveId) }); From 3d3460888a37432cc84a8ea4e6a3a2ae534fdeca Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 29 Sep 2024 23:04:32 -0700 Subject: [PATCH 56/65] Add scoring for the Glaive Rush `BattlerTag`s (#4514) --- src/data/move.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/data/move.ts b/src/data/move.ts index 7c5962abb22..9b1fa44071a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4544,6 +4544,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { case BattlerTagType.DROWSY: case BattlerTagType.DISABLED: case BattlerTagType.HEAL_BLOCK: + case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: return -5; case BattlerTagType.SEEDED: case BattlerTagType.SALT_CURED: @@ -4564,6 +4565,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { case BattlerTagType.ENCORE: return -2; case BattlerTagType.MINIMIZED: + case BattlerTagType.ALWAYS_GET_HIT: return 0; case BattlerTagType.INGRAIN: case BattlerTagType.IGNORE_ACCURACY: From 7d2df53c51fdc12d26c755f0f931754470a40111 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sun, 29 Sep 2024 23:45:44 -0700 Subject: [PATCH 57/65] Add `waveTurnCount` to `PokemonBattleData` (#4168) Swap `FirstMoveCondition` to use the new `waveTurnCount` field --- src/data/move.ts | 2 +- src/field/pokemon.ts | 2 ++ src/phases/battle-end-phase.ts | 6 ++++++ src/phases/switch-summon-phase.ts | 1 + src/phases/turn-end-phase.ts | 1 + src/test/moves/fake_out.test.ts | 36 +++++++++++++++++++++++-------- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 9b1fa44071a..e163e89a272 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -6591,7 +6591,7 @@ export class MoveCondition { export class FirstMoveCondition extends MoveCondition { constructor() { - super((user, target, move) => user.battleSummonData?.turnCount === 1); + super((user, target, move) => user.battleSummonData?.waveTurnCount === 1); } getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a318d3ffdeb..c66da0572ad 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5000,6 +5000,8 @@ export class PokemonBattleData { export class PokemonBattleSummonData { /** The number of turns the pokemon has passed since entering the battle */ public turnCount: number = 1; + /** The number of turns the pokemon has passed since the start of the wave */ + public waveTurnCount: number = 1; /** The list of moves the pokemon has used since entering the battle */ public moveHistory: TurnMove[] = []; } diff --git a/src/phases/battle-end-phase.ts b/src/phases/battle-end-phase.ts index 902a85325ad..eaa458af904 100644 --- a/src/phases/battle-end-phase.ts +++ b/src/phases/battle-end-phase.ts @@ -35,6 +35,12 @@ export class BattleEndPhase extends BattlePhase { this.scene.unshiftPhase(new GameOverPhase(this.scene, true)); } + for (const pokemon of this.scene.getField()) { + if (pokemon && pokemon.battleSummonData) { + pokemon.battleSummonData.waveTurnCount = 1; + } + } + for (const pokemon of this.scene.getParty().filter(p => p.isAllowedInBattle())) { applyPostBattleAbAttrs(PostBattleAbAttr, pokemon); } diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index eb1e089543b..07761b10d6e 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -173,6 +173,7 @@ export class SwitchSummonPhase extends SummonPhase { // Or compensate for force switch move if switched out pokemon is not fainted if (currentCommand === Command.POKEMON || lastPokemonIsForceSwitchedAndNotFainted) { pokemon.battleSummonData.turnCount--; + pokemon.battleSummonData.waveTurnCount--; } if (this.switchType === SwitchType.BATON_PASS && pokemon) { diff --git a/src/phases/turn-end-phase.ts b/src/phases/turn-end-phase.ts index 724a5206d74..60a2e6600db 100644 --- a/src/phases/turn-end-phase.ts +++ b/src/phases/turn-end-phase.ts @@ -44,6 +44,7 @@ export class TurnEndPhase extends FieldPhase { this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon); pokemon.battleSummonData.turnCount++; + pokemon.battleSummonData.waveTurnCount++; }; this.executeForAll(handlePokemon); diff --git a/src/test/moves/fake_out.test.ts b/src/test/moves/fake_out.test.ts index 04d6216b952..e306ab12a3f 100644 --- a/src/test/moves/fake_out.test.ts +++ b/src/test/moves/fake_out.test.ts @@ -23,14 +23,15 @@ describe("Moves - Fake Out", () => { game.override .battleType("single") .enemySpecies(Species.CORVIKNIGHT) - .starterSpecies(Species.FEEBAS) .moveset([Moves.FAKE_OUT, Moves.SPLASH]) .enemyMoveset(Moves.SPLASH) + .enemyLevel(10) + .startingLevel(10) // prevent LevelUpPhase from happening .disableCrits(); }); - it("can only be used on the first turn a pokemon is sent out", async() => { - await game.classicMode.startBattle(); + it("can only be used on the first turn a pokemon is sent out in a battle", async() => { + await game.classicMode.startBattle([Species.FEEBAS]); const enemy = game.scene.getEnemyPokemon()!; @@ -44,22 +45,27 @@ describe("Moves - Fake Out", () => { await game.toNextTurn(); expect(enemy.hp).toBe(postTurnOneHp); + }, 20000); - game.move.select(Moves.SPLASH); - await game.doKillOpponents(); + // This is a PokeRogue buff to Fake Out + it("can be used at the start of every wave even if the pokemon wasn't recalled", async() => { + await game.classicMode.startBattle([Species.FEEBAS]); + + const enemy = game.scene.getEnemyPokemon()!; + enemy.damageAndUpdate(enemy.getMaxHp() - 1); + + game.move.select(Moves.FAKE_OUT); await game.toNextWave(); - const newEnemy = game.scene.getEnemyPokemon()!; - game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - expect(newEnemy.hp).toBe(newEnemy.getMaxHp()); + expect(game.scene.getEnemyPokemon()!.isFullHp()).toBe(false); }, 20000); it("can be used again if recalled and sent back out", async() => { game.override.startingWave(4); - await game.classicMode.startBattle(); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyPokemon()!; @@ -76,6 +82,18 @@ describe("Moves - Fake Out", () => { const enemy2 = game.scene.getEnemyPokemon()!; + expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); + enemy2.hp = enemy2.getMaxHp(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + game.move.select(Moves.FAKE_OUT); + await game.toNextTurn(); + expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); }, 20000); }); From bab5b31476a3cc2303ede70b56a9db19ca76ba63 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:02:37 +0200 Subject: [PATCH 58/65] [Localization] Expert Breeder ME - Egg bug in locales (#4524) * Update the-expert-pokemon-breeder-dialogue.json * Update the-expert-pokemon-breeder-dialogue.json * Update the-expert-pokemon-breeder-dialogue.json * Update the-expert-pokemon-breeder-dialogue.json * Update the-expert-pokemon-breeder-dialogue.json --- .../mystery-encounters/the-expert-pokemon-breeder-dialogue.json | 2 +- .../mystery-encounters/the-expert-pokemon-breeder-dialogue.json | 2 +- .../mystery-encounters/the-expert-pokemon-breeder-dialogue.json | 2 +- .../mystery-encounters/the-expert-pokemon-breeder-dialogue.json | 2 +- .../mystery-encounters/the-expert-pokemon-breeder-dialogue.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/locales/de/mystery-encounters/the-expert-pokemon-breeder-dialogue.json b/src/locales/de/mystery-encounters/the-expert-pokemon-breeder-dialogue.json index 191fdaaf783..d2fcc91d153 100644 --- a/src/locales/de/mystery-encounters/the-expert-pokemon-breeder-dialogue.json +++ b/src/locales/de/mystery-encounters/the-expert-pokemon-breeder-dialogue.json @@ -25,7 +25,7 @@ "outro": "Schau wie glücklich dein {{chosenPokemon}} nun ist!$Hier, diese Pokémon-Eier kannst du auch haben.", "outro_failed": "Wie enttäuschend...$Es sieht so aus, als hättest du noch einen langen Weg vor dir, um das Vertrauen deines Pokémon zu gewinnen!", "gained_eggs": "@s{item_fanfare}Du erhählst {{numEggs}}!", - "eggs_tooltip": "\n(+) Erhalte @[TOOLTIP_TITLE]{{{eggs}}}", + "eggs_tooltip": "\n(+) Erhalte {{eggs}}", "numEggs_one": "{{count}} Ei der Stufe {{rarity}}", "numEggs_other": "{{count}} Eier der Stufe {{rarity}}" } diff --git a/src/locales/fr/mystery-encounters/the-expert-pokemon-breeder-dialogue.json b/src/locales/fr/mystery-encounters/the-expert-pokemon-breeder-dialogue.json index c587a575887..ebd450730d6 100644 --- a/src/locales/fr/mystery-encounters/the-expert-pokemon-breeder-dialogue.json +++ b/src/locales/fr/mystery-encounters/the-expert-pokemon-breeder-dialogue.json @@ -25,7 +25,7 @@ "outro": "Ton {{chosenPokemon}} et toi avez\nl’air très heureux !$Tiens, prends ça aussi.", "outro_failed": "Voilà qui est bien décevant…$T’as encore visiblement bien du chemin à faire\npour acquérir la confiance de tes Pokémon !", "gained_eggs": "@s{item_fanfare}Vous recevez\n{{numEggs}} !", - "eggs_tooltip": "\n(+) Recevez @[TOOLTIP_TITLE]{{{eggs}}}", + "eggs_tooltip": "\n(+) Recevez {{eggs}}", "numEggs_one": "{{count}} Œuf {{rarity}}", "numEggs_other": "{{count}} Œufs {{rarity}}s" } diff --git a/src/locales/ja/mystery-encounters/the-expert-pokemon-breeder-dialogue.json b/src/locales/ja/mystery-encounters/the-expert-pokemon-breeder-dialogue.json index a59cf55694e..12eaebfb33c 100644 --- a/src/locales/ja/mystery-encounters/the-expert-pokemon-breeder-dialogue.json +++ b/src/locales/ja/mystery-encounters/the-expert-pokemon-breeder-dialogue.json @@ -25,7 +25,7 @@ "outro": "ねえ、 {{chosenPokemon}} すごく 嬉しくなったわ!$そして、 これらも どうぞ!", "outro_failed": "なんか ガッカリ ね……$手持ち ポケモンの 信用を 得るまで\nまだまだ みたいんだわ!", "gained_eggs": "@s{item_fanfare}{{numEggs}}を もらいました!", - "eggs_tooltip": "\n(+) @[TOOLTIP_TITLE]{{{eggs}}}を得る", + "eggs_tooltip": "\n(+) {{eggs}}を得る", "numEggs_one": "{{count}} {{rarity}} タマゴ", "numEggs_other": "{{count}} {{rarity}} タマゴ" } diff --git a/src/locales/ko/mystery-encounters/the-expert-pokemon-breeder-dialogue.json b/src/locales/ko/mystery-encounters/the-expert-pokemon-breeder-dialogue.json index 8c93868b4b4..e226741c60a 100644 --- a/src/locales/ko/mystery-encounters/the-expert-pokemon-breeder-dialogue.json +++ b/src/locales/ko/mystery-encounters/the-expert-pokemon-breeder-dialogue.json @@ -26,7 +26,7 @@ "outro": "{{chosenPokemon}}[[가]] 정말 행복해 보이네요!$여기, 이것도 드릴게요.", "outro_failed": "실망이네요….$포켓몬의 신뢰를 얻으려면 아직 멀었어요!", "gained_eggs": "@s{item_fanfare}{{numEggs}}[[를]] 받았습니다!", - "eggs_tooltip": "\n(+) @[TOOLTIP_TITLE]{{{eggs}}} 획득", + "eggs_tooltip": "\n(+) {{eggs}} 획득", "numEggs_one": "{{rarity}}알 {{count}}개", "numEggs_other": "{{rarity}}알 {{count}}개" } diff --git a/src/locales/pt_BR/mystery-encounters/the-expert-pokemon-breeder-dialogue.json b/src/locales/pt_BR/mystery-encounters/the-expert-pokemon-breeder-dialogue.json index 7e48c9552da..d84c6c07273 100644 --- a/src/locales/pt_BR/mystery-encounters/the-expert-pokemon-breeder-dialogue.json +++ b/src/locales/pt_BR/mystery-encounters/the-expert-pokemon-breeder-dialogue.json @@ -25,7 +25,7 @@ "outro": "Veja como seu {{chosenPokemon}} está feliz agora!$Aqui, você também pode ficar com isso.", "outro_failed": "Que decepção...$Parece que você ainda tem um longo caminho\na percorrer para ganhar a confiança dos seus Pokémon!", "gained_eggs": "@s{item_fanfare}Você recebeu {{numEggs}}!", - "eggs_tooltip": "\n(+) Ganhe @[TOOLTIP_TITLE]{{{eggs}}}", + "eggs_tooltip": "\n(+) Ganhe {{eggs}}", "numEggs_one": "{{count}} Ovo {{rarity}}", "numEggs_other": "{{count}} Ovos {{rarity}}" } From 814aceebc9ec4b064ef6592c90a2bcefa2940e48 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:03:13 +0800 Subject: [PATCH 59/65] [Localization] Zh-cn fix 9-30 (#4517) * Update modifier-type.json * Update delibirdy-dialogue.json * Update department-store-sale-dialogue.json * Update global-trade-system-dialogue.json * Update modifier-type.json * Update party-ui-handler.json * Update settings.json * Update trash-to-treasure-dialogue.json * Update uncommon-breed-dialogue.json * Update training-session-dialogue.json * Update egg.json * Update battle.json * Update dialogue.json --- src/locales/zh_CN/battle.json | 8 ++++ src/locales/zh_CN/dialogue.json | 22 +++++++++++ src/locales/zh_CN/egg.json | 2 +- src/locales/zh_CN/modifier-type.json | 38 +++++++++---------- .../delibirdy-dialogue.json | 2 +- .../department-store-sale-dialogue.json | 4 +- .../global-trade-system-dialogue.json | 6 +-- .../training-session-dialogue.json | 6 +-- .../trash-to-treasure-dialogue.json | 2 +- .../uncommon-breed-dialogue.json | 2 +- src/locales/zh_CN/party-ui-handler.json | 1 + src/locales/zh_CN/settings.json | 9 ++++- 12 files changed, 69 insertions(+), 33 deletions(-) diff --git a/src/locales/zh_CN/battle.json b/src/locales/zh_CN/battle.json index ef716b0893a..4b31de41f9a 100644 --- a/src/locales/zh_CN/battle.json +++ b/src/locales/zh_CN/battle.json @@ -88,6 +88,14 @@ "statHarshlyFell_other": "{{pokemonNameWithAffix}}的{{stats}}大幅降低了!", "statSeverelyFell_other": "{{pokemonNameWithAffix}}的{{stats}}极大幅降低了!", "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}的{{stats}}已经无法再降低了!", + "statRose_one": "{{pokemonNameWithAffix}}的{{stats}}提高了!", + "statSharplyRose_one": "{{pokemonNameWithAffix}}的{{stats}}大幅提高了!", + "statRoseDrastically_one": "{{pokemonNameWithAffix}}的{{stats}}极大幅提高了!", + "statWontGoAnyHigher_one": "{{pokemonNameWithAffix}}的{{stats}}已经无法再提高了!", + "statFell_one": "{{pokemonNameWithAffix}}的{{stats}}降低了!", + "statHarshlyFell_one": "{{pokemonNameWithAffix}}的{{stats}}大幅降低了!", + "statSeverelyFell_one": "{{pokemonNameWithAffix}}的{{stats}}极大幅降低了!", + "statWontGoAnyLower_one": "{{pokemonNameWithAffix}}的{{stats}}已经无法再降低了!", "transformedIntoType": "{{pokemonName}}变成了\n{{type}}属性!", "ppReduced": "降低了{{targetName}}的\n{{moveName}}的PP{{reduction}}点!", "retryBattle": "你要从对战开始时重试么?", diff --git a/src/locales/zh_CN/dialogue.json b/src/locales/zh_CN/dialogue.json index 78f0845b436..f2382299179 100644 --- a/src/locales/zh_CN/dialogue.json +++ b/src/locales/zh_CN/dialogue.json @@ -299,6 +299,28 @@ "1": "真奇怪…怎么会这样…我不应该被打败的。" } }, + "snow_worker": { + "encounter": { + "1": "天冷了,便要添衣。\n只有人类会有这么聪明的想法!" + }, + "victory": { + "1": "即使是徒劳的挣扎,\n到头来也还是展示了人类的智慧啊!" + }, + "defeat": { + "1": "我来告诉你一个小技巧。\n如果你对着冻住的宝可梦用火系技能,冰就化啦!" + } + }, + "snow_worker_double": { + "encounter": { + "1": "……\n……准……准备好战……战斗了吗?" + }, + "victory": { + "1": "……\n……我冻得直,直打哆嗦!" + }, + "defeat": { + "1": "……\n……知……知道吗?\n...这……这地方蛮冷。" + } + }, "hex_maniac": { "encounter": { "1": "我通常只听古典音乐,但如果我输了,$我想我应该试试新时代的音乐!", diff --git a/src/locales/zh_CN/egg.json b/src/locales/zh_CN/egg.json index f2b95bd40cb..3691749a971 100644 --- a/src/locales/zh_CN/egg.json +++ b/src/locales/zh_CN/egg.json @@ -11,7 +11,7 @@ "gachaTypeLegendary": "传说概率上升", "gachaTypeMove": "稀有概率上升", "gachaTypeShiny": "闪光概率上升", - "eventType": "Mystery Event", + "eventType": "神秘事件", "selectMachine": "选择一个机器。", "notEnoughVouchers": "你没有足够的兑换券!", "tooManyEggs": "你的蛋太多啦!", diff --git a/src/locales/zh_CN/modifier-type.json b/src/locales/zh_CN/modifier-type.json index eb394baf577..2dc44f0fb34 100644 --- a/src/locales/zh_CN/modifier-type.json +++ b/src/locales/zh_CN/modifier-type.json @@ -2,7 +2,7 @@ "ModifierType": { "AddPokeballModifierType": { "name": "{{modifierCount}}x {{pokeballName}}", - "description": "获得 {{pokeballName}} x{{modifierCount}} (已有:{{pokeballAmount}}) \n捕捉倍率:{{catchRate}}。" + "description": "获得 {{pokeballName}}x {{modifierCount}} (已有:{{pokeballAmount}}) \n捕捉倍率:{{catchRate}}。" }, "AddVoucherModifierType": { "name": "{{modifierCount}}x {{voucherTypeName}}", @@ -50,7 +50,7 @@ "description": "遭遇双打概率提升四倍,持续{{battleCount}}场战斗。" }, "TempStatStageBoosterModifierType": { - "description": "提升全队的{{stat}}{{amount}}级,持续5场战斗。", + "description": "提升全队的{{stat}}{{amount}},持续5场战斗。", "extra": { "stage": "1阶", "percentage": "30%" @@ -63,24 +63,24 @@ "description": "使一只宝可梦的等级提升{{levels}}级。" }, "AllPokemonLevelIncrementModifierType": { - "description": "使一只寶可夢的等級提升{{levels}}級。" + "description": "使所有宝可梦的等级提升{{levels}}级。" }, "BaseStatBoosterModifierType": { "description": "增加10%持有者的{{stat}},\n个体值越高堆叠上限越高。" }, "PokemonBaseStatTotalModifierType": { - "name": "Shuckle Juice", - "description": "{{increaseDecrease}} all of the holder's base stats by {{statValue}}. You were {{blessCurse}} by the Shuckle.", + "name": "壶壶果汁", + "description": "{{increaseDecrease}}持有者的所有基础属性{{statValue}}级。你被壶壶{{blessCurse}}了。", "extra": { - "increase": "Increases", - "decrease": "Decreases", - "blessed": "blessed", - "cursed": "cursed" + "increase": "提升", + "decrease": "降低", + "blessed": "强化", + "cursed": "诅咒" } }, "PokemonBaseStatFlatModifierType": { - "name": "Old Gateau", - "description": "Increases the holder's {{stats}} base stats by {{statValue}}. Found after a strange dream." + "name": "森之羊羹", + "description": "增加持有者{{stats}}的基础属性{{statValue}},来自于一场怪梦。" }, "AllPokemonFullHpRestoreModifierType": { "description": "所有宝可梦完全回复HP。" @@ -109,7 +109,7 @@ "description": "招式命中率增加{{accuracyAmount}}(最大100)。" }, "PokemonMultiHitModifierType": { - "description": "攻击以60/75/82.5%的伤害造成2/3/4次伤害。" + "description": "伤害降低60/75/82.5%的同时造成2/3/4次伤害。" }, "TmModifierType": { "name": "招式学习器\n{{moveId}} - {{moveName}}", @@ -126,7 +126,7 @@ "description": "使某些宝可梦更改形态。" }, "FusePokemonModifierType": { - "description": "融合两只宝可梦 (改变特性, 平分基础点数\n和属性, 共享招式池)。" + "description": "融合两只宝可梦(改变特性, 平分基础点数\n和属性, 共享招式池)。" }, "TerastallizeModifierType": { "name": "{{teraType}}太晶碎块", @@ -359,7 +359,7 @@ "description": "触碰后会放出热量的神奇宝珠。\n携带后,在战斗时会变成灼伤状态。" }, "EVOLUTION_TRACKER_GIMMIGHOUL": { - "name": "金子宝物", + "name": "宝藏金币", "description": "这个宝可梦最爱金币!多收集点金币的话会发生什么呢?" }, "BATON": { @@ -421,11 +421,11 @@ "description": "增加1%野生融合宝可梦出现概率。" }, - "MYSTERY_ENCOUNTER_SHUCKLE_JUICE": { "name": "Shuckle Juice" }, - "MYSTERY_ENCOUNTER_BLACK_SLUDGE": { "name": "Black Sludge", "description": "The stench is so powerful that shops will only sell you items at a steep cost increase." }, - "MYSTERY_ENCOUNTER_MACHO_BRACE": { "name": "Macho Brace", "description": "Defeating a Pokémon grants the holder a Macho Brace stack. Each stack slightly boosts stats, with an extra bonus at max stacks." }, - "MYSTERY_ENCOUNTER_OLD_GATEAU": { "name": "Old Gateau", "description": "Increases the holder's {{stats}} stats by {{statValue}}." }, - "MYSTERY_ENCOUNTER_GOLDEN_BUG_NET": { "name": "Golden Bug Net", "description": "Imbues the owner with luck to find Bug Type Pokémon more often. Has a strange heft to it." } + "MYSTERY_ENCOUNTER_SHUCKLE_JUICE": { "name": "壶壶果汁" }, + "MYSTERY_ENCOUNTER_BLACK_SLUDGE": { "name": "黑色污泥", "description": "由于恶臭扑鼻,商店会以非常高昂的价格向您出售商品。" }, + "MYSTERY_ENCOUNTER_MACHO_BRACE": { "name": "强制锻炼器", "description": "击败对手后获得一层锻炼等级。每层会略微提升属性,\n达到最大层数时还会获得额外奖励。" }, + "MYSTERY_ENCOUNTER_OLD_GATEAU": { "name": "森之羊羔", "description": "提升持有者的{{stats}}的{{statValue}}。" }, + "MYSTERY_ENCOUNTER_GOLDEN_BUG_NET": { "name": "金捕虫网", "description": "赋予主人好运,使其更容易\n找到虫属性宝可梦,手感很奇妙。" } }, "SpeciesBoosterItem": { "LIGHT_BALL": { diff --git a/src/locales/zh_CN/mystery-encounters/delibirdy-dialogue.json b/src/locales/zh_CN/mystery-encounters/delibirdy-dialogue.json index 3a15f5f98be..6c43a95c782 100644 --- a/src/locales/zh_CN/mystery-encounters/delibirdy-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/delibirdy-dialogue.json @@ -3,7 +3,7 @@ { "intro": "一伙{{delibirdName}}出现了!", "title": "信使鸟快递", - "description": "{{delibirdName}}满怀期待地看着你,\n它们好像想要什么东西。\n\n也许给它们一件道具或一些钱能让它们满意?", + "description": "{{delibirdName}}满怀期待地看着你,\n它们好像想要什么东西。\n\n给它们一件道具或一些钱的话\n会不会让它们满意呢?", "query": "你要给它们什么?", "invalid_selection": "宝可梦身上并没有那种道具。", "option": { diff --git a/src/locales/zh_CN/mystery-encounters/department-store-sale-dialogue.json b/src/locales/zh_CN/mystery-encounters/department-store-sale-dialogue.json index 09c23762ea9..1d6adb28776 100644 --- a/src/locales/zh_CN/mystery-encounters/department-store-sale-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/department-store-sale-dialogue.json @@ -1,9 +1,9 @@ { "intro": "一位提着一大堆购物袋的女士。", "speaker": "大促销", - "intro_dialogue": "你好!你也是来参加促销活动的吗?\n在促销期间,可以领取一张特别优惠券,用于购买免费商品!\n我这有一张多余的优惠券。送你了!", + "intro_dialogue": "你好!你也是来参加促销活动的吗?\n在促销期间,可以领取一张特别优惠券!\n可以用于免费兑换商品哦!\n我这有一张多余的优惠券。送你了!", "title": "百货公司促销", - "description": "到处都是商品!\n好像有4个柜台可以让你用优惠券兑换商品。\n无尽可能!", + "description": "到处都是商品!\n共有4个柜台可以用优惠券兑换商品。\n好礼多多!", "query": "你要去哪里?", "option": { "1": { diff --git a/src/locales/zh_CN/mystery-encounters/global-trade-system-dialogue.json b/src/locales/zh_CN/mystery-encounters/global-trade-system-dialogue.json index 4b0d2e84edc..76748b8e71c 100644 --- a/src/locales/zh_CN/mystery-encounters/global-trade-system-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/global-trade-system-dialogue.json @@ -1,7 +1,7 @@ { "intro": "是GTS系统的交互面板!", "title": "全球交换系统(GTS)", - "description": "啊,GTS!科学的奇迹,\\nn你可以与世界各地的任何人联系,\n与他们交换宝可梦!\n今天你的交换会有好运吗?", + "description": "啊,GTS!科学的奇迹,\n你可以与世界各地的任何人联系,\n并与他们交换宝可梦!\n今天你的交换运会如何呢?", "query": "你要怎么做?", "option": { "1": { @@ -11,13 +11,13 @@ }, "2": { "label": "奇迹交换", - "tooltip": "(+)将一只宝可梦送至GTS,\n并获得一只随机宝可梦" + "tooltip": "(+)发送一只宝可梦,\n并获得一只随机宝可梦" }, "3": { "label": "道具交换", "trade_options_prompt": "选择要发送的道具", "invalid_selection": "这只宝可梦没有合法道具\n可以被交换。", - "tooltip": "(+)将你的一件道具发送到GTS并获得一件随机新道具" + "tooltip": "(+)发送一件道具\n并获得一件随机新道具" }, "4": { "label": "离开", diff --git a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json index 7bb6229d330..ba853f80b4d 100644 --- a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json @@ -8,19 +8,19 @@ "1": { "label": "轻量训练", "tooltip": "(-)轻松战斗\n(+)提升随机2只\n宝可梦的个体", - "finished": "{{selectedPokemon}}回来了,感觉\n虽然疲惫不堪,但很有成就!$它的{{stat1}}和{{stat2}}的个体得到了改善!" + "finished": "{{selectedPokemon}}回来了,感觉虽然疲惫不堪,\n但很有成就感!$它的{{stat1}}和{{stat2}}的个体得到了改善!" }, "2": { "label": "适度训练", "tooltip": "(-)适中的战斗\n(+)改变宝可梦的性格", "select_prompt": "选择一种想要的性格\n来训练你的神奇宝贝。", - "finished": "{{selectedPokemon}}回来了,感觉\n虽然疲惫不堪,但很有成就!$它的性格变成了{{nature}}!" + "finished": "{{selectedPokemon}}回来了,感觉虽然疲惫不堪,\n但很有成就感!$它的性格变成了{{nature}}!" }, "3": { "label": "重磅训练", "tooltip": "(-)艰苦的战斗\n(+)改变宝可梦的特性", "select_prompt": "选择一种想要的特性\n来训练你的神奇宝贝。", - "finished": "{{selectedPokemon}}回来了,感觉\n虽然疲惫不堪,但很有成就!$它的特性变成了{{nature}}!" + "finished": "{{selectedPokemon}}回来了,感觉虽然疲惫不堪,\n但很有成就感!$它的特性变成了{{ability}}!" }, "4": { "label": "离开", diff --git a/src/locales/zh_CN/mystery-encounters/trash-to-treasure-dialogue.json b/src/locales/zh_CN/mystery-encounters/trash-to-treasure-dialogue.json index 29e7817923b..9de9b30cbd9 100644 --- a/src/locales/zh_CN/mystery-encounters/trash-to-treasure-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/trash-to-treasure-dialogue.json @@ -12,7 +12,7 @@ "2": { "label": "探究来源", "tooltip": "(?)找到垃圾的来源", - "selected": "你在这堆东西周围徘徊,寻找表明这东西可能出现在这里的任何迹象……", + "selected": "你在这堆东西周围徘徊,\n寻找表明这东西可能出现在这里的任何迹象……", "selected_2": "突然,垃圾动了!那不是垃圾,是一只宝可梦!" } } diff --git a/src/locales/zh_CN/mystery-encounters/uncommon-breed-dialogue.json b/src/locales/zh_CN/mystery-encounters/uncommon-breed-dialogue.json index f844cae5908..1d01b894e27 100644 --- a/src/locales/zh_CN/mystery-encounters/uncommon-breed-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/uncommon-breed-dialogue.json @@ -1,7 +1,7 @@ { "intro": "这可不是一只普通的宝可梦!", "title": "罕见物种", - "description": "{{enemyPokemon}}看起来与其他同种宝可梦大相径庭。\n@[TOOLTIP_TITLE]{也许它会特殊招式?}\n你可以直接进行战斗并尝试捕获它,\n但可能也有办法和它交朋友。", + "description": "{{enemyPokemon}}看起来\n与其他同种宝可梦大相径庭。\n@[TOOLTIP_TITLE]{也许它会特殊招式?}\n你可以直接进行战斗并尝试捕获它,\n但可能也有办法和它交朋友。", "query": "你要怎么做?", "option": { "1": { diff --git a/src/locales/zh_CN/party-ui-handler.json b/src/locales/zh_CN/party-ui-handler.json index 2bc74991824..079fc551a40 100644 --- a/src/locales/zh_CN/party-ui-handler.json +++ b/src/locales/zh_CN/party-ui-handler.json @@ -13,6 +13,7 @@ "ALL": "全部道具", "PASS_BATON": "接棒", "UNPAUSE_EVOLUTION": "解除进化暂停", + "PAUSE_EVOLUTION": "暂停进化", "REVIVE": "复活", "RENAME": "起名", "SELECT": "选择", diff --git a/src/locales/zh_CN/settings.json b/src/locales/zh_CN/settings.json index dd001213b9e..3c0d2ed9e12 100644 --- a/src/locales/zh_CN/settings.json +++ b/src/locales/zh_CN/settings.json @@ -11,6 +11,10 @@ "expGainsSpeed": "经验值获取动画速度", "expPartyDisplay": "显示队伍经验", "skipSeenDialogues": "跳过已读对话", + "eggSkip": "孵蛋跳过", + "never": "从不", + "always": "永久", + "ask": "询问", "battleStyle": "对战模式", "enableRetries": "允许重试", "hideIvs": "禁用个体值探测器信息", @@ -60,9 +64,10 @@ "playerGender": "玩家性别", "typeHints": "属性提示", "masterVolume": "主音量", - "bgmVolume": "音乐", + "bgmVolume": "音乐音量", "fieldVolume": "场景音量", - "seVolume": "音效", + "seVolume": "音效音量", + "uiVolume": "界面音量", "musicPreference": "音乐偏好", "mixed": "全曲混合", "gamepadPleasePlug": "请链接手柄或按任意键", From d660c217b34222c94d5bda8318cf70abea2e22d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ricardo?= Date: Mon, 30 Sep 2024 14:03:32 -0300 Subject: [PATCH 60/65] [Localization] Update pt_BR translations for menu, party, and settings (#4518) --- src/locales/pt_BR/menu-ui-handler.json | 3 ++- src/locales/pt_BR/party-ui-handler.json | 2 +- src/locales/pt_BR/settings.json | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/locales/pt_BR/menu-ui-handler.json b/src/locales/pt_BR/menu-ui-handler.json index df654976d68..5141a4ea612 100644 --- a/src/locales/pt_BR/menu-ui-handler.json +++ b/src/locales/pt_BR/menu-ui-handler.json @@ -25,5 +25,6 @@ "unlinkGoogle": "Desconectar Google", "cancel": "Cancelar", "losingProgressionWarning": "Você vai perder todo o progresso desde o início da batalha. Confirmar?", - "noEggs": "Você não está chocando nenhum ovo\nno momento!" + "noEggs": "Você não está chocando nenhum ovo\nno momento!", + "donate": "Contribuir" } diff --git a/src/locales/pt_BR/party-ui-handler.json b/src/locales/pt_BR/party-ui-handler.json index ef09e09fb2b..a8c492670dc 100644 --- a/src/locales/pt_BR/party-ui-handler.json +++ b/src/locales/pt_BR/party-ui-handler.json @@ -24,7 +24,7 @@ "tooManyItems": "{{pokemonName}} já tem\nmuitos desse item!", "anyEffect": "Isso não terá nenhum efeito.", "unpausedEvolutions": "Evoluções foram despausadas para {{pokemonName}}.", - "unspliceConfirmation": "Você realmente deseja desfazer a fusão de {{fusionName}}\ncom {{pokemonName}}? {{fusionName}} será perdido.", + "unspliceConfirmation": "Você realmente deseja desfazer a fusão de\n{{fusionName}} com {{pokemonName}}? {{fusionName}} será perdido.", "wasReverted": "{{fusionName}} foi revertido para {{pokemonName}}.", "releaseConfirmation": "Você realmente deseja soltar {{pokemonName}}?", "releaseInBattle": "Você não pode soltar um Pokémon que está em batalha!", diff --git a/src/locales/pt_BR/settings.json b/src/locales/pt_BR/settings.json index 6c4eae23a82..1d743f7b05a 100644 --- a/src/locales/pt_BR/settings.json +++ b/src/locales/pt_BR/settings.json @@ -11,6 +11,10 @@ "expGainsSpeed": "Velocidade do Ganho de EXP", "expPartyDisplay": "Exibição de EXP da Equipe", "skipSeenDialogues": "Pular Diálogos Vistos", + "eggSkip": "Pular Eclosões de Ovos", + "never": "Nunca", + "always": "Sempre", + "ask": "Perguntar", "battleStyle": "Estilo de Batalha", "enableRetries": "Habilitar Novas Tentativas", "hideIvs": "Esconder scanner de IV", From de9fdc5b9c2493dc63fc7d9795ebf20d9cb8d607 Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Mon, 30 Sep 2024 12:05:02 -0500 Subject: [PATCH 61/65] [Balance] Increase Minimum BST Filter for Elite 4 / Champion Teams (#4501) * Increase Champion BST * Slight E4 BST increase * Update trainer-config.ts * Move E4/Champion minimum BST values to consts * Update tsdocs for new consts --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/trainer-config.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 75a849574ea..296e4e9b1b5 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -18,6 +18,11 @@ import {Species} from "#enums/species"; import {TrainerType} from "#enums/trainer-type"; import {Gender} from "./gender"; +/** Minimum BST for Pokemon generated onto the Elite Four's teams */ +const ELITE_FOUR_MINIMUM_BST = 460; +/** Minimum BST for Pokemon generated onto the E4 Champion's team */ +const CHAMPION_MINIMUM_BST = 508; + export enum TrainerPoolTier { COMMON, UNCOMMON, @@ -860,10 +865,10 @@ export class TrainerConfig { // Set species filter and specialty types if provided, otherwise filter by base total. if (specialtyTypes.length) { - this.setSpeciesFilter(p => specialtyTypes.some(t => p.isOfType(t)) && p.baseTotal >= 450); + this.setSpeciesFilter(p => specialtyTypes.some(t => p.isOfType(t)) && p.baseTotal >= ELITE_FOUR_MINIMUM_BST); this.setSpecialtyTypes(...specialtyTypes); } else { - this.setSpeciesFilter(p => p.baseTotal >= 450); + this.setSpeciesFilter(p => p.baseTotal >= ELITE_FOUR_MINIMUM_BST); } // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. @@ -913,8 +918,7 @@ export class TrainerConfig { this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); }); - // Set species filter to only include species with a base total of 470 or higher. - this.setSpeciesFilter(p => p.baseTotal >= 470); + this.setSpeciesFilter(p => p.baseTotal >= CHAMPION_MINIMUM_BST); // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); From 5a20416fd47f7bde8bdc0ea4954f60270f030cf9 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:08:16 -0700 Subject: [PATCH 62/65] [Refactor] Remove redundant session data function in game-over-phase (#4515) --- src/phases/game-over-phase.ts | 63 ++++++++--------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index 8ecf1478b99..1db47e9e289 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -1,34 +1,28 @@ import { clientSessionId } from "#app/account"; -import BattleScene from "#app/battle-scene"; import { BattleType } from "#app/battle"; +import BattleScene from "#app/battle-scene"; import { getCharVariantFromDialogue } from "#app/data/dialogue"; import { pokemonEvolutions } from "#app/data/pokemon-evolutions"; import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species"; import { trainerConfigs } from "#app/data/trainer-config"; -import { PlayerGender } from "#app/enums/player-gender"; -import { TrainerType } from "#app/enums/trainer-type"; import Pokemon from "#app/field/pokemon"; import { modifierTypes } from "#app/modifier/modifier-type"; +import { BattlePhase } from "#app/phases/battle-phase"; +import { CheckSwitchPhase } from "#app/phases/check-switch-phase"; +import { EncounterPhase } from "#app/phases/encounter-phase"; +import { EndCardPhase } from "#app/phases/end-card-phase"; +import { GameOverModifierRewardPhase } from "#app/phases/game-over-modifier-reward-phase"; +import { PostGameOverPhase } from "#app/phases/post-game-over-phase"; +import { RibbonModifierRewardPhase } from "#app/phases/ribbon-modifier-reward-phase"; +import { SummonPhase } from "#app/phases/summon-phase"; +import { UnlockPhase } from "#app/phases/unlock-phase"; import { achvs, ChallengeAchv } from "#app/system/achv"; import { Unlockables } from "#app/system/unlockables"; import { Mode } from "#app/ui/ui"; -import i18next from "i18next"; import * as Utils from "#app/utils"; -import { BattlePhase } from "./battle-phase"; -import { CheckSwitchPhase } from "./check-switch-phase"; -import { EncounterPhase } from "./encounter-phase"; -import { GameOverModifierRewardPhase } from "./game-over-modifier-reward-phase"; -import { RibbonModifierRewardPhase } from "./ribbon-modifier-reward-phase"; -import { SummonPhase } from "./summon-phase"; -import { EndCardPhase } from "./end-card-phase"; -import { PostGameOverPhase } from "./post-game-over-phase"; -import { UnlockPhase } from "./unlock-phase"; -import { SessionSaveData } from "../system/game-data"; -import TrainerData from "../system/trainer-data"; -import PokemonData from "../system/pokemon-data"; -import PersistentModifierData from "../system/modifier-data"; -import ChallengeData from "../system/challenge-data"; -import ArenaData from "../system/arena-data"; +import { PlayerGender } from "#enums/player-gender"; +import { TrainerType } from "#enums/trainer-type"; +import i18next from "i18next"; export class GameOverPhase extends BattlePhase { private victory: boolean; @@ -114,7 +108,7 @@ export class GameOverPhase extends BattlePhase { this.scene.gameData.gameStats.dailyRunSessionsWon++; } } - this.scene.gameData.saveRunHistory(this.scene, this.getFinalSessionData(), this.victory); + this.scene.gameData.saveRunHistory(this.scene, this.scene.gameData.getSessionSaveData(this.scene), this.victory); const fadeDuration = this.victory ? 10000 : 5000; this.scene.fadeOutBgm(fadeDuration, true); const activeBattlers = this.scene.getField().filter(p => p?.isActive(true)); @@ -221,34 +215,5 @@ export class GameOverPhase extends BattlePhase { this.firstRibbons.push(getPokemonSpecies(pokemon.species.getRootSpeciesId(forStarter))); } } - - /** - * This function mirrors game-data.ts' getSessionSaveData() to update the session data to reflect any changes that occurred within the last wave - * This means that level ups, item usage, evolutions, etc. will all be accurately reflected. - * @returns {@linkCode SessionSaveData} an updated version of the wave's SessionSaveData that accurately reflects the events of the wave - */ - private getFinalSessionData(): SessionSaveData { - return { - seed: this.scene.seed, - playTime: this.scene.sessionPlayTime, - gameMode: this.scene.gameMode.modeId, - party: this.scene.getParty().map(p => new PokemonData(p)), - enemyParty: this.scene.getEnemyParty().map(p => new PokemonData(p)), - modifiers: this.scene.findModifiers(() => true).map(m => new PersistentModifierData(m, true)), - enemyModifiers: this.scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), - arena: new ArenaData(this.scene.arena), - pokeballCounts: this.scene.pokeballCounts, - money: Math.floor(this.scene.money), - score: this.scene.score, - waveIndex: this.scene.currentBattle.waveIndex, - battleType: this.scene.currentBattle.battleType, - trainer: this.scene.currentBattle.battleType === BattleType.TRAINER ? new TrainerData(this.scene.currentBattle.trainer) : null, - gameVersion: this.scene.game.config.gameVersion, - timestamp: new Date().getTime(), - challenges: this.scene.gameMode.challenges.map(c => new ChallengeData(c)), - mysteryEncounterType: this.scene.currentBattle.mysteryEncounter?.encounterType ?? -1, - mysteryEncounterSaveData: this.scene.mysteryEncounterSaveData - } as SessionSaveData; - } } From e9ee2c11799adfc33374133662cb153f4db03dec Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:10:00 -0700 Subject: [PATCH 63/65] [Refactor] Remove unused parameters in move flag functions (#4516) Also fix tsdocs for these functions --- src/data/move.ts | 140 +++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 79 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index e163e89a272..35b5ad56927 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -398,220 +398,202 @@ export default class Move implements Localizable { /** * Sets the {@linkcode MoveFlags.MAKES_CONTACT} flag for the calling Move - * @param makesContact The value (boolean) to set the flag to + * @param setFlag Default `true`, set to `false` if the move doesn't make contact + * @see {@linkcode Abilities.STATIC} * @returns The {@linkcode Move} that called this function */ - makesContact(makesContact: boolean = true): this { - this.setFlag(MoveFlags.MAKES_CONTACT, makesContact); + makesContact(setFlag: boolean = true): this { + this.setFlag(MoveFlags.MAKES_CONTACT, setFlag); return this; } /** * Sets the {@linkcode MoveFlags.IGNORE_PROTECT} flag for the calling Move - * @param ignoresProtect The value (boolean) to set the flag to - * example: @see {@linkcode Moves.CURSE} + * @see {@linkcode Moves.CURSE} * @returns The {@linkcode Move} that called this function */ - ignoresProtect(ignoresProtect: boolean = true): this { - this.setFlag(MoveFlags.IGNORE_PROTECT, ignoresProtect); + ignoresProtect(): this { + this.setFlag(MoveFlags.IGNORE_PROTECT, true); return this; } /** * Sets the {@linkcode MoveFlags.IGNORE_VIRTUAL} flag for the calling Move - * @param ignoresVirtual The value (boolean) to set the flag to - * example: @see {@linkcode Moves.NATURE_POWER} + * @see {@linkcode Moves.NATURE_POWER} * @returns The {@linkcode Move} that called this function */ - ignoresVirtual(ignoresVirtual: boolean = true): this { - this.setFlag(MoveFlags.IGNORE_VIRTUAL, ignoresVirtual); + ignoresVirtual(): this { + this.setFlag(MoveFlags.IGNORE_VIRTUAL, true); return this; } /** * Sets the {@linkcode MoveFlags.SOUND_BASED} flag for the calling Move - * @param soundBased The value (boolean) to set the flag to - * example: @see {@linkcode Moves.UPROAR} + * @see {@linkcode Moves.UPROAR} * @returns The {@linkcode Move} that called this function */ - soundBased(soundBased: boolean = true): this { - this.setFlag(MoveFlags.SOUND_BASED, soundBased); + soundBased(): this { + this.setFlag(MoveFlags.SOUND_BASED, true); return this; } /** * Sets the {@linkcode MoveFlags.HIDE_USER} flag for the calling Move - * @param hidesUser The value (boolean) to set the flag to - * example: @see {@linkcode Moves.TELEPORT} + * @see {@linkcode Moves.TELEPORT} * @returns The {@linkcode Move} that called this function */ - hidesUser(hidesUser: boolean = true): this { - this.setFlag(MoveFlags.HIDE_USER, hidesUser); + hidesUser(): this { + this.setFlag(MoveFlags.HIDE_USER, true); return this; } /** * Sets the {@linkcode MoveFlags.HIDE_TARGET} flag for the calling Move - * @param hidesTarget The value (boolean) to set the flag to - * example: @see {@linkcode Moves.WHIRLWIND} + * @see {@linkcode Moves.WHIRLWIND} * @returns The {@linkcode Move} that called this function */ - hidesTarget(hidesTarget: boolean = true): this { - this.setFlag(MoveFlags.HIDE_TARGET, hidesTarget); + hidesTarget(): this { + this.setFlag(MoveFlags.HIDE_TARGET, true); return this; } /** * Sets the {@linkcode MoveFlags.BITING_MOVE} flag for the calling Move - * @param bitingMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.BITE} + * @see {@linkcode Moves.BITE} * @returns The {@linkcode Move} that called this function */ - bitingMove(bitingMove: boolean = true): this { - this.setFlag(MoveFlags.BITING_MOVE, bitingMove); + bitingMove(): this { + this.setFlag(MoveFlags.BITING_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.PULSE_MOVE} flag for the calling Move - * @param pulseMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.WATER_PULSE} + * @see {@linkcode Moves.WATER_PULSE} * @returns The {@linkcode Move} that called this function */ - pulseMove(pulseMove: boolean = true): this { - this.setFlag(MoveFlags.PULSE_MOVE, pulseMove); + pulseMove(): this { + this.setFlag(MoveFlags.PULSE_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.PUNCHING_MOVE} flag for the calling Move - * @param punchingMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.DRAIN_PUNCH} + * @see {@linkcode Moves.DRAIN_PUNCH} * @returns The {@linkcode Move} that called this function */ - punchingMove(punchingMove: boolean = true): this { - this.setFlag(MoveFlags.PUNCHING_MOVE, punchingMove); + punchingMove(): this { + this.setFlag(MoveFlags.PUNCHING_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.SLICING_MOVE} flag for the calling Move - * @param slicingMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.X_SCISSOR} + * @see {@linkcode Moves.X_SCISSOR} * @returns The {@linkcode Move} that called this function */ - slicingMove(slicingMove: boolean = true): this { - this.setFlag(MoveFlags.SLICING_MOVE, slicingMove); + slicingMove(): this { + this.setFlag(MoveFlags.SLICING_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.RECKLESS_MOVE} flag for the calling Move * @see {@linkcode Abilities.RECKLESS} - * @param recklessMove The value to set the flag to * @returns The {@linkcode Move} that called this function */ - recklessMove(recklessMove: boolean = true): this { - this.setFlag(MoveFlags.RECKLESS_MOVE, recklessMove); + recklessMove(): this { + this.setFlag(MoveFlags.RECKLESS_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.BALLBOMB_MOVE} flag for the calling Move - * @param ballBombMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.ELECTRO_BALL} + * @see {@linkcode Moves.ELECTRO_BALL} * @returns The {@linkcode Move} that called this function */ - ballBombMove(ballBombMove: boolean = true): this { - this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove); + ballBombMove(): this { + this.setFlag(MoveFlags.BALLBOMB_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.POWDER_MOVE} flag for the calling Move - * @param powderMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.STUN_SPORE} + * @see {@linkcode Moves.STUN_SPORE} * @returns The {@linkcode Move} that called this function */ - powderMove(powderMove: boolean = true): this { - this.setFlag(MoveFlags.POWDER_MOVE, powderMove); + powderMove(): this { + this.setFlag(MoveFlags.POWDER_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.DANCE_MOVE} flag for the calling Move - * @param danceMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.PETAL_DANCE} + * @see {@linkcode Moves.PETAL_DANCE} * @returns The {@linkcode Move} that called this function */ - danceMove(danceMove: boolean = true): this { - this.setFlag(MoveFlags.DANCE_MOVE, danceMove); + danceMove(): this { + this.setFlag(MoveFlags.DANCE_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.WIND_MOVE} flag for the calling Move - * @param windMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.HURRICANE} + * @see {@linkcode Moves.HURRICANE} * @returns The {@linkcode Move} that called this function */ - windMove(windMove: boolean = true): this { - this.setFlag(MoveFlags.WIND_MOVE, windMove); + windMove(): this { + this.setFlag(MoveFlags.WIND_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.TRIAGE_MOVE} flag for the calling Move - * @param triageMove The value (boolean) to set the flag to - * example: @see {@linkcode Moves.ABSORB} + * @see {@linkcode Moves.ABSORB} * @returns The {@linkcode Move} that called this function */ - triageMove(triageMove: boolean = true): this { - this.setFlag(MoveFlags.TRIAGE_MOVE, triageMove); + triageMove(): this { + this.setFlag(MoveFlags.TRIAGE_MOVE, true); return this; } /** * Sets the {@linkcode MoveFlags.IGNORE_ABILITIES} flag for the calling Move - * @param ignoresAbilities sThe value (boolean) to set the flag to - * example: @see {@linkcode Moves.SUNSTEEL_STRIKE} + * @see {@linkcode Moves.SUNSTEEL_STRIKE} * @returns The {@linkcode Move} that called this function */ - ignoresAbilities(ignoresAbilities: boolean = true): this { - this.setFlag(MoveFlags.IGNORE_ABILITIES, ignoresAbilities); + ignoresAbilities(): this { + this.setFlag(MoveFlags.IGNORE_ABILITIES, true); return this; } /** * Sets the {@linkcode MoveFlags.CHECK_ALL_HITS} flag for the calling Move - * @param checkAllHits The value (boolean) to set the flag to - * example: @see {@linkcode Moves.TRIPLE_AXEL} + * @see {@linkcode Moves.TRIPLE_AXEL} * @returns The {@linkcode Move} that called this function */ - checkAllHits(checkAllHits: boolean = true): this { - this.setFlag(MoveFlags.CHECK_ALL_HITS, checkAllHits); + checkAllHits(): this { + this.setFlag(MoveFlags.CHECK_ALL_HITS, true); return this; } /** * Sets the {@linkcode MoveFlags.IGNORE_SUBSTITUTE} flag for the calling Move - * @param ignoresSubstitute The value (boolean) to set the flag to - * example: @see {@linkcode Moves.WHIRLWIND} + * @see {@linkcode Moves.WHIRLWIND} * @returns The {@linkcode Move} that called this function */ - ignoresSubstitute(ignoresSubstitute: boolean = true): this { - this.setFlag(MoveFlags.IGNORE_SUBSTITUTE, ignoresSubstitute); + ignoresSubstitute(): this { + this.setFlag(MoveFlags.IGNORE_SUBSTITUTE, true); return this; } /** * Sets the {@linkcode MoveFlags.REDIRECT_COUNTER} flag for the calling Move - * @param redirectCounter The value (boolean) to set the flag to - * example: @see {@linkcode Moves.METAL_BURST} + * @see {@linkcode Moves.METAL_BURST} * @returns The {@linkcode Move} that called this function */ - redirectCounter(redirectCounter: boolean = true): this { - this.setFlag(MoveFlags.REDIRECT_COUNTER, redirectCounter); + redirectCounter(): this { + this.setFlag(MoveFlags.REDIRECT_COUNTER, true); return this; } @@ -7268,7 +7250,7 @@ export function initMoves() { new StatusMove(Moves.CURSE, Type.GHOST, -1, 10, -1, 0, 2) .attr(CurseAttr) .ignoresSubstitute() - .ignoresProtect(true) + .ignoresProtect() .target(MoveTarget.CURSE), new AttackMove(Moves.FLAIL, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 2) .attr(LowHpPowerAttr), From 8a8adad7fee7614fa097531689e494d95dae716f Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:11:45 -0700 Subject: [PATCH 64/65] [Refactor] Clean up some `TODO`s from the `strict-null` refactor (#4267) --- src/data/ability.ts | 27 ++++++++++++--------------- src/data/pokemon-forms.ts | 10 +++++----- src/timed-event-manager.ts | 9 +++++---- src/utils.ts | 4 +++- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 041d90ac4c0..a698831a1eb 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -123,6 +123,7 @@ export class Ability implements Localizable { type AbAttrApplyFunc = (attr: TAttr, passive: boolean) => boolean | Promise; type AbAttrCondition = (pokemon: Pokemon) => boolean; +// TODO: Can this be improved? type PokemonAttackCondition = (user: Pokemon | null, target: Pokemon | null, move: Move) => boolean; type PokemonDefendCondition = (target: Pokemon, user: Pokemon, move: Move) => boolean; type PokemonStatStageChangeCondition = (target: Pokemon, statsChanged: BattleStat[], stages: number) => boolean; @@ -2432,7 +2433,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { pokemon.setStatStage(s, target.getStatStage(s)); } - pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m!.moveId, m!.ppUsed, m!.ppUp)); // TODO: are those bangs correct? + pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId ?? Moves.NONE, m?.ppUsed, m?.ppUp)); pokemon.summonData.types = target.getTypes(); @@ -3152,12 +3153,12 @@ export class ForewarnAbAttr extends PostSummonAbAttr { } else if (move?.getMove().power === -1) { movePower = 80; } else { - movePower = move!.getMove().power; // TODO: is this bang correct? + movePower = move?.getMove().power ?? 0; } if (movePower > maxPowerSeen) { maxPowerSeen = movePower; - maxMove = move!.getName(); // TODO: is this bang correct? + maxMove = move?.getName() ?? ""; } } } @@ -5175,8 +5176,7 @@ export function initAbilities() { .attr(IgnoreOpponentStatStagesAbAttr) .ignorable(), new Ability(Abilities.TINTED_LENS, 4) - //@ts-ignore - .attr(DamageBoostAbAttr, 2, (user, target, move) => target?.getMoveEffectiveness(user, move) <= 0.5), // TODO: fix TS issues + .attr(DamageBoostAbAttr, 2, (user, target, move) => (target?.getMoveEffectiveness(user!, move) ?? 1) <= 0.5), new Ability(Abilities.FILTER, 4) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75) .ignorable(), @@ -5294,8 +5294,9 @@ export function initAbilities() { .attr(WonderSkinAbAttr) .ignorable(), new Ability(Abilities.ANALYTIC, 5) - //@ts-ignore - .attr(MovePowerBoostAbAttr, (user, target, move) => !!target?.getLastXMoves(1).find(m => m.turn === target?.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command !== Command.FIGHT, 1.3), // TODO fix TS issues + .attr(MovePowerBoostAbAttr, (user, target, move) => + !!target?.getLastXMoves(1).find(m => m.turn === target?.scene.currentBattle.turn) + || user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command !== Command.FIGHT, 1.3), new Ability(Abilities.ILLUSION, 5) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) @@ -5460,8 +5461,7 @@ export function initAbilities() { .bypassFaint() .partial(), new Ability(Abilities.STAKEOUT, 7) - //@ts-ignore - .attr(MovePowerBoostAbAttr, (user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.POKEMON, 2), // TODO: fix TS issues + .attr(MovePowerBoostAbAttr, (user, target, move) => user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2), new Ability(Abilities.WATER_BUBBLE, 7) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5) .attr(MoveTypePowerBoostAbAttr, Type.WATER, 2) @@ -5599,8 +5599,7 @@ export function initAbilities() { new Ability(Abilities.PRISM_ARMOR, 7) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75), new Ability(Abilities.NEUROFORCE, 7) - //@ts-ignore - .attr(MovePowerBoostAbAttr, (user, target, move) => target?.getMoveEffectiveness(user, move) >= 2, 1.25), // TODO: fix TS issues + .attr(MovePowerBoostAbAttr, (user, target, move) => (target?.getMoveEffectiveness(user!, move) ?? 1) >= 2, 1.25), new Ability(Abilities.INTREPID_SWORD, 8) .attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)), @@ -5698,10 +5697,8 @@ export function initAbilities() { .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .ignorable(), new Ability(Abilities.HUNGER_SWITCH, 8) - //@ts-ignore - .attr(PostTurnFormChangeAbAttr, p => p.getFormKey ? 0 : 1) // TODO: fix ts-ignore - //@ts-ignore - .attr(PostTurnFormChangeAbAttr, p => p.getFormKey ? 1 : 0) // TODO: fix ts-ignore + .attr(PostTurnFormChangeAbAttr, p => p.getFormKey() ? 0 : 1) + .attr(PostTurnFormChangeAbAttr, p => p.getFormKey() ? 1 : 0) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index a904f497b0f..5c2dd06f7b3 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -4,7 +4,7 @@ import { SpeciesFormKey } from "./pokemon-species"; import { StatusEffect } from "./status-effect"; import { MoveCategory, allMoves } from "./move"; import { Type } from "./type"; -import { Constructor } from "#app/utils"; +import { Constructor, nil } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -185,7 +185,7 @@ export class SpeciesFormChange { return true; } - findTrigger(triggerType: Constructor): SpeciesFormChangeTrigger | null { + findTrigger(triggerType: Constructor): SpeciesFormChangeTrigger | nil { if (!this.trigger.hasTriggerType(triggerType)) { return null; } @@ -193,7 +193,7 @@ export class SpeciesFormChange { const trigger = this.trigger; if (trigger instanceof SpeciesFormChangeCompoundTrigger) { - return trigger.triggers.find(t => t.hasTriggerType(triggerType))!; // TODO: is this bang correct? + return trigger.triggers.find(t => t.hasTriggerType(triggerType)); } return trigger; @@ -202,11 +202,11 @@ export class SpeciesFormChange { export class SpeciesFormChangeCondition { public predicate: SpeciesFormChangeConditionPredicate; - public enforceFunc: SpeciesFormChangeConditionEnforceFunc | null; + public enforceFunc: SpeciesFormChangeConditionEnforceFunc | nil; constructor(predicate: SpeciesFormChangeConditionPredicate, enforceFunc?: SpeciesFormChangeConditionEnforceFunc) { this.predicate = predicate; - this.enforceFunc = enforceFunc!; // TODO: is this bang correct? + this.enforceFunc = enforceFunc; } } diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 9bfa3bdf54a..3caa84fd39b 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -1,5 +1,6 @@ import BattleScene from "#app/battle-scene"; import { TextStyle, addTextObject } from "#app/ui/text"; +import { nil } from "#app/utils"; import i18next from "i18next"; export enum EventType { @@ -64,19 +65,19 @@ export class TimedEventManager { let multiplier = 1; const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te)); shinyEvents.forEach((se) => { - multiplier *= se.shinyMultiplier!; // TODO: is this bang correct? + multiplier *= se.shinyMultiplier ?? 1; }); return multiplier; } getEventBannerFilename(): string { - return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey!; // TODO: is this bang correct? + return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey ?? ""; } } export class TimedEventDisplay extends Phaser.GameObjects.Container { - private event: TimedEvent | null; + private event: TimedEvent | nil; private eventTimerText: Phaser.GameObjects.Text; private banner: Phaser.GameObjects.Image; private bannerShadow: Phaser.GameObjects.Rectangle; @@ -84,7 +85,7 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { constructor(scene: BattleScene, x: number, y: number, event?: TimedEvent) { super(scene, x, y); - this.event = event!; // TODO: is this bang correct? + this.event = event; this.setVisible(false); } diff --git a/src/utils.ts b/src/utils.ts index b029067c8d6..68331211fc0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,8 @@ import { MoneyFormat } from "#enums/money-format"; import { Moves } from "#enums/moves"; import i18next from "i18next"; +export type nil = null | undefined; + export const MissingTextureKey = "__MISSING"; export function toReadableString(str: string): string { @@ -443,7 +445,7 @@ export function deltaRgb(rgb1: integer[], rgb2: integer[]): integer { } export function rgbHexToRgba(hex: string) { - const color = hex.match(/^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i)!; // TODO: is this bang correct? + const color = hex.match(/^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i) ?? ["000000", "00", "00", "00"]; return { r: parseInt(color[1], 16), g: parseInt(color[2], 16), From 145b80f4911834ced81acdec7f354ae333140944 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:14:38 -0700 Subject: [PATCH 65/65] [P2] Fix Substitute blocking field effects (#4504) Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/move.ts | 3 +- src/test/moves/substitute.test.ts | 79 ++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 35b5ad56927..d4b2b2f0e75 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -341,7 +341,8 @@ export default class Move implements Localizable { * @returns `true` if the move can bypass the target's Substitute; `false` otherwise. */ hitsSubstitute(user: Pokemon, target: Pokemon | null): boolean { - if (this.moveTarget === MoveTarget.USER || !target?.getTag(BattlerTagType.SUBSTITUTE)) { + if ([MoveTarget.USER, MoveTarget.USER_SIDE, MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES].includes(this.moveTarget) + || !target?.getTag(BattlerTagType.SUBSTITUTE)) { return false; } diff --git a/src/test/moves/substitute.test.ts b/src/test/moves/substitute.test.ts index d185c0ab471..3099446f081 100644 --- a/src/test/moves/substitute.test.ts +++ b/src/test/moves/substitute.test.ts @@ -1,13 +1,15 @@ import { BattlerIndex } from "#app/battle"; +import { ArenaTagSide } from "#app/data/arena-tag"; import { SubstituteTag, TrappedTag } from "#app/data/battler-tags"; import { allMoves, StealHeldItemChanceAttr } from "#app/data/move"; import { StatusEffect } from "#app/data/status-effect"; -import { Abilities } from "#app/enums/abilities"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import { BerryType } from "#app/enums/berry-type"; -import { Moves } from "#app/enums/moves"; -import { Species } from "#app/enums/species"; -import { Stat } from "#app/enums/stat"; +import { Abilities } from "#enums/abilities"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { BerryType } from "#enums/berry-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; import { MoveResult } from "#app/field/pokemon"; import { CommandPhase } from "#app/phases/command-phase"; import GameManager from "#app/test/utils/gameManager"; @@ -194,6 +196,71 @@ describe("Moves - Substitute", () => { } ); + it( + "shouldn't block moves that target the user's side of the field", + async () => { + game.override.moveset(Moves.LIGHT_SCREEN); + + await game.classicMode.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + vi.spyOn(leadPokemon, "getMoveEffectiveness"); + + leadPokemon.addTag(BattlerTagType.SUBSTITUTE, 0, Moves.NONE, leadPokemon.id); + + game.move.select(Moves.LIGHT_SCREEN); + + await game.toNextTurn(); + + expect(leadPokemon.getMoveEffectiveness).not.toHaveReturnedWith(0); + expect(game.scene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, ArenaTagSide.PLAYER)).toBeDefined(); + } + ); + + it( + "shouldn't block the opponent from setting hazards", + async () => { + game.override.enemyMoveset(Moves.STEALTH_ROCK); + + await game.classicMode.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + vi.spyOn(leadPokemon, "getMoveEffectiveness"); + + game.move.select(Moves.SUBSTITUTE); + + await game.toNextTurn(); + + expect(leadPokemon.getMoveEffectiveness).not.toHaveReturnedWith(0); + expect(game.scene.arena.getTagOnSide(ArenaTagType.STEALTH_ROCK, ArenaTagSide.PLAYER)).toBeDefined(); + } + ); + + it( + "shouldn't block moves that target both sides of the field", + async () => { + game.override + .moveset(Moves.TRICK_ROOM) + .enemyMoveset(Moves.GRAVITY); + + await game.classicMode.startBattle([Species.BLASTOISE]); + + const pokemon = game.scene.getField(true); + pokemon.forEach(p => { + vi.spyOn(p, "getMoveEffectiveness"); + p.addTag(BattlerTagType.SUBSTITUTE, 0, Moves.NONE, p.id); + }); + + game.move.select(Moves.TRICK_ROOM); + + await game.toNextTurn(); + + pokemon.forEach(p => expect(p.getMoveEffectiveness).not.toHaveReturnedWith(0)); + expect(game.scene.arena.getTag(ArenaTagType.TRICK_ROOM)).toBeDefined(); + expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); + } + ); + it( "should protect the user from flinching", async () => {