Compare commits

...

198 Commits

Author SHA1 Message Date
RedstonewolfX
8fdce2405c
Merge branch 'pagefaultgames:main' into daily-standardization 2024-09-12 10:46:23 -04:00
RedstonewolfX
64861447cb
Merge branch 'beta' into daily-standardization 2024-09-12 10:44:46 -04:00
Leo Kim
5724ed4a5c
[Enhancement] Add option for egg skip to settings (#4193)
* add option for egg skip

* change eggSkip variable name more descriptive to eggSkipPreference

* update requested changes from opaquer and tinylad and walker

* update requested change from tinylad

* update comment
2024-09-12 10:33:36 -04:00
Lugiad
c294e0846d
[Localization] Catalan translation batch (#4194)
* Update arena-flyout.json

* Update biome.json

* Update common.json

* Update menu.json

* Update nature.json

* Update pokemon-info.json

* Update pokemon-info.json
2024-09-12 10:22:30 -04:00
Chapybara-jp
d4d1788789
[Localisation] [JA] Translated modifier-type.json.json (#4195)
* Update ability-trigger.json

* Update ability.json

* Update arena-flyout.json

* Update arena-tag.json

* Update battle.json

* Update fight-ui-handler.json

* Update berry.json

* Update menu.json

* Update party-ui-handler.json

* Update starter-select-ui-handler.json

* Update tutorial.json

* Update move.json

* Update battle.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-tag.json

* Update party-ui-handler.json

* Update settings.json

* Update move-trigger.json

* Translate modifier-type.json

* Update modifier-type.json

* Translated modifier-type.json

* Update move-trigger.json

* Update move-trigger.json

* Update move-trigger.json

* Update modifier-type.json
2024-09-12 10:16:45 -04:00
Leo Kim
b422239a82
[Localization(ko)] Update Korean translation (#4196) 2024-09-12 10:16:10 -04:00
cam
2f0a53ba46
[Sprite] Added default head spots to spinda (#4188)
Spritesheets front & front shiny
2024-09-12 00:49:18 -04:00
AJ Fontaine
0af59bbb14
[Refactor] Fix linter issue (#4191) 2024-09-12 00:13:57 -04:00
Adrián T.
7ed7fec808
[BUG][UI/UX] Correction of errors when `` Save & Quit` and ` Log out`` (#3105)
* Fixes confirmation issues in SAVE_AND_QUIT and LOG_OUT

* Added LOADING mode to prevent spamming from SAVE_AND_QUIT and LOG_OUT buttons, and added option to set black background for LOADING mode

* Fixed conditional statement to ensure robustness in live environments to avoid potential issues in production

* Good overlay position
2024-09-11 23:12:20 -04:00
schmidtc1
28012b8d85
[Bug] Fixes Freezy Frost visual bug when attacking ally, and Freezy Frost not applying effects when fainting a target (#3753)
* Resolves bugs with freezy frost vs ally, and freezy frost fainting opp

* Adjusts unit tests, adds one more for doubles

* Refactor apply function to follow the async/await pattern

* Eslint fix attempt

* Update freezy_frost.test.ts

Remove js file extension
2024-09-11 22:20:24 -04:00
Madmadness65
6decd918e5
[Enhancement] Implement Tera-based form changes (Ogerpon and Terapagos) (#4147)
* Add Tera-based form changes

* Make teraType property private
2024-09-11 21:47:41 -04:00
Lylian BALL
8195373824
[Move] Add Retaliate double damage condition (#1831)
* Add retaliate double damage condition

* undo override changes

* add death history and bug fix where retaliate didn't work after 10 turns

* delete the unnecassary log

* optimization

* made some corrections

* add retaliate test as draft

* add retaliate test

* Update src/test/moves/retaliate.test.ts (delete log)

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* remove submodule

* Update src/test/moves/retaliate.test.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* update retaliate test

* Update src/test/moves/retaliate.test.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* update unit test

* remove wide lens for retaliate test

* Update src/test/moves/retaliate.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/battle.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/test/moves/retaliate.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/test/moves/retaliate.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* optimization

* Fix indentation

* Use default values

* Add parentheses for clarity

* Update src/battle.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* Update src/battle.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* Update src/data/move.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* Update src/phases/faint-phase.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* Update src/phases/faint-phase.ts

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* bug on import

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-11 21:31:57 -04:00
NightKev
91d266ea74
[Bug] Burning Bulwark, King's Shield, Obstruct and Silk Trap no longer protect against status moves. (#4106)
* Obstruct et al no longer protect against status moves

* Remove `.js` from import

Co-authored-by: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com>

* Add tsdocs for new/modified classes

* List relevant moves in tsdocs

---------

Co-authored-by: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com>
2024-09-11 21:31:38 -04:00
NightKev
951b568590
[Documentation] Add some tsdocs to move.ts, mark rollout and iceball (P) (#4099)
* Add some tsdocs to `move.ts`, some misc cleanup

* Mark Rollout and Ice Ball as partial
2024-09-11 21:05:43 -04:00
flx-sta
18dc1029b7
[Misc] Update issue/feature template (#4148)
* simplify bug-report form. Add `Triage` label to bug & feature form

* Add repro textfield to bug form

* Fix typo

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-11 21:01:16 -04:00
Mumble
f294f034aa
[Bug] Run History displays Pokemon that have their natures changed during the run (#4149)
* Nature mints... spaghetti...

* Update src/ui/run-info-ui-handler.ts

Co-authored-by: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com>

* No effect when no items

---------

Co-authored-by: frutescens <info@laptop>
Co-authored-by: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com>
2024-09-11 21:00:26 -04:00
NightKev
fec218b747
[Refactor] setTypeIcons explicitly handles null, mark it as such (#4155) 2024-09-11 20:59:57 -04:00
NightKev
d4cd74c8b7
[P2 Bug] Baddy Bad shouldn't activate Reflect if the target uses Protect, make gravity and water/mud sport ignore protect(#4180) 2024-09-11 20:58:21 -04:00
Amani H.
a6d5fc66f2
[Balance] Disable Eviolite for G-Max Pokémon (#4184)
* [Balance] Disable Eviolite for G-Max Pokémon

* Add Documentation
2024-09-11 20:56:58 -04:00
Frederico Santos
801b0a66f7 Readded vouchers to original weights 2024-09-12 01:13:22 +01:00
Frederico Santos
103c87ec3b Undo egg skip event 2024-09-12 01:09:44 +01:00
chaosgrimmon
50a7500561
[Sprite] Fix animated Cursola (#4186)
* [Sprite] Index Cursola exp

* [Sprite] Index shiny Cursola exp

* [Sprite] Update exp Cursola variant palette
2024-09-11 19:46:38 -04:00
Jannik Tappert
b33d86a1db
[BUG] Make Tate & Liza have seeded randomness #4175 2024-09-11 13:55:13 -07:00
NightKev
ce9a75f074
Replace vi.fn() with () => null whenenver possible (#4182) 2024-09-11 13:54:42 -07:00
Lugiad
89dac46dfc
[Localization] Localization batch - [Not meant to be merged until last minute] (#4127)
Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>
Co-authored-by: José Ricardo <josefleury@discente.ufg.br>
Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
Co-authored-by: Enoch <enoch.jwsong@gmail.com>
Co-authored-by: DanStevensonx <114961842+DanStevensonx@users.noreply.github.com>
Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com>
Co-authored-by: SangaraSorama <100420976+SangaraSorama@users.noreply.github.com>
2024-09-11 13:46:26 -07:00
Frederico Santos
abb133e253
Merge pull request #4167 from DayKev/beta
Synchronize beta with main
2024-09-11 15:38:23 +01:00
NightKev
9f82d796d3 Merge branch 'main' into beta 2024-09-11 07:29:18 -07:00
Leo Kim
e657322294
[Enhancement] Update instruction for gamepad in run history UI (#4053)
* update instruction for pad in run history UI

* move getGamepadType function to ui.ts

* Update src/ui/ui.ts

Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>

---------

Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>
2024-09-10 23:45:53 -04:00
Amani H.
4808c07cf9
[Hotfix] Fix System Data Conversion Failure 2 (#4159) 2024-09-10 23:05:48 +01:00
flx-sta
e17bf592c2
[Bug] Use silent mode during tests (unless debugging!) + test workflow optimization (#4154)
* add :silent to all tests

but disable it if the runner is in debug mode!

* fix: use `--silent` instead of `:silent`

Cause the previous was npm scrpt specific (whops)

* remove env and replace with logic in each call

* reduce redundancy by checking out once

* move pre-test into `needs` after `checkout`

* use cache approach in pre-test

* add node.js install step to `setup` job

* WIP: setup -> pre-test -> all other tests

with using cache

* use matrix approach for tests

* fix matrix approach for tests

* fix wrong use of env var in `run-test-template.yml`

* test: out-comment `run-tests` to see whats wrong

* test: see if this works

* let's try using matrix again...

* make `node-version` input a string

* remove `node-version` input for now

* test: without a matrix fornow

* change usage of reuseable workflow call

* fix call of matrix.project

* try using working-dir

* try setup for pre-tests

* remove `runs-on` from run-tests

* fix some identations for run-tests

* add pre-test as requirement for running tests

* use `1` instead of `'1'` to check `runner.debug`

* add `options` input. Possible fix for debug = not silent

* try again...

* not as an ENV but inside

* move 2nd ${{ !runner.debug && '--silent' }} check into test-template

* fix printing `false` instead of empty-string on runner-debug check

* try a yml array approach

* test running with file include path

* make `project` always `main` for now

* remove all extra vitest workspaces

* adopt `shards` workflow in vitest

* fix workflow reference in tests.yml

* add missing `$` in test-shard-template.yml`

* chore: fix vitest.config.ts after merge

man.. cant trust these machines

* make `project` a variable. try to use inputs on job names

* adjust `test-shard-template` job name
2024-09-10 22:13:42 +01:00
flx-sta
14ace40634
[Misc] eslint rule to prevent .js imports (#4160)
* add `eslint-plugin-import-x` module

* add import eslint rules

* remove .js extensions

* rename account.spec to account.test

* move fontFace.setup into `setupFiles`

instead of importing it in `vitest.setup.ts`
2024-09-10 22:34:50 +02:00
MokaStitcher
d1b058fe3e
[UI] fix candy upgrade icon not updating after purchasing eggs (#4153) 2024-09-10 14:00:50 -04:00
AJ Fontaine
150ab3d1b2
[UI/UX] Make "CH-CHING!" sound when unlocking passive (#4151)
* Make "CH-CHING!" sound when unlocking passive

* Remove unused parameters in line above sound
2024-09-10 11:54:23 -04:00
Amani H.
bd4729b4c5
[Hotfix] Fix Lapsing Modifiers Not Rolling (#4152) 2024-09-10 16:53:40 +01:00
PigeonBar
5bf21a4f75
[Bug] Fix rare egg move and species rates for Manaphy eggs (#4125) 2024-09-10 10:15:07 -04:00
Madmadness65
4b8083211a
[P3 Bug] Fix Transform SFX not playing on quiet form changes (#4144) 2024-09-10 10:13:16 -04:00
MokaStitcher
9c4c19b5fb
[UI Bug] Fix HA icon not always showing in egg summary screen (#4150) 2024-09-10 10:12:17 -04:00
James Diefenbach
7dd1832072
[Hotfix] fix UI transition causing unusual freezes after egg summary shown (#4126)
* console logs n stuff

* fix bad ui transition for egg summary freeze bug (logs included)

* cleanup egg lapse phase

* touchup

* add back removed whitespace

* remove console logs

---------

Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
2024-09-10 14:23:13 +01:00
Amani H.
ebb09dda34
[Hotfix] Fix Lures Refreshing on Reload (#4146) 2024-09-10 10:37:23 +01:00
Raidette
a919b9c0af
[Move] Implement After You (#1789)
* Complete after you implementation (no localization)

* reset override changes

* Remove hardcoded English text, add tests

* Fix test

* Make sure phases occur in the correct order

* fix after-you issues

- fix i18n interpolation ot state "target name" and not "pokemon name" as the target takes the offer, not the user
- fix some tsdocs
- add override to apply
- update scene.findPhase to be able to use generic types. Add tsdocs

* add move-trigger.afterYou for DE

* fix after_you.test.ts

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-09 14:35:04 -07:00
Adrian T.
e959595471
[Test] Fix throat chop and gorilla tactics tests (#4140) 2024-09-09 16:03:29 -04:00
Jannik Tappert
d9a8448c6e
[Enhancement] Added the ability to localize the tera type hover text (#4138) 2024-09-09 15:57:07 -04:00
Adrian T.
a82d64b5b5
[Ability] Implement Gorilla Tactics (#4051)
* fully implement gorilla tactics

* fix atk increase

* update oversight

* add showAbility param

* fix postmerge

* fix postmerge

* update tests
2024-09-09 15:41:53 -04:00
Brandon Bay
9317093044
[Enhancement] [UI/UX] Add ability and passive tooltips to starter select screen (#4023)
* Add ability and passive tooltips to starter select screen

* Remove explicit casts to BattleScene

* Increase tooltip size, reverse y when necessary, and always show passive tooltip

* Add ability name to tooltip title and persist tooltips between Pokemon

* Use vi function mocks
2024-09-09 15:07:00 -04:00
Adrian T.
9afab182e9
[Test] Remove obsolete splash_only (#4139) 2024-09-09 15:02:11 -04:00
Adrian T.
401568609b
[Dev] Add imports, Handle kebab-case fileName argument in test boilerplate script (#4072)
* add imports, handle kebab-case fileName argument

* fix spacing
2024-09-09 13:00:26 -04:00
Taylor Le Lievre
8df7422e8f
[Bug] Primal weather no longer persists if last mon dies to indirect damage (#3492)
* Fixed Delta Stream remaining active when last mon dies to indirect damage

* Rebasing changes

* Linting fix

* Combined if statements

* Changed params to optional

* Added unit test

* Apply suggestions from code review

* Fix test and remove `.js` from import

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-09 12:59:58 -04:00
NightKev
11d912bad8
[Dev] Make OPP_MOVESET_OVERRIDE fully override the enemy's moveset (#4062)
* Make `OPP_MOVESET_OVERRIDE` fully override the enemy's moveset

* Update tests with new override behavior

* Fix tests

* Fix another test

* Move overrides no longer required to be arrays

* Remove `SPLASH_ONLY` test utility variable

* Update moveset override helper functions

* Missed some tests
2024-09-09 12:55:11 -04:00
Adrian T.
c59f6edf36
[Move] Implement Power Shift (#4083)
* fully implement power shift

* cleanup
2024-09-09 12:54:31 -04:00
Leo Kim
80e347840d
[Bug] Fix line spacing in level up stats and move info in Japanese (#4095) 2024-09-09 12:54:17 -04:00
NightKev
89b33466a9
[Test] Fix Safeguard test that relied on a now-fixed bug (#4098) 2024-09-09 12:53:45 -04:00
Lugiad
3d01e905df
[Localization][UI/UX] Clean up of unused localized images (#4110)
* Delete public/images/ui/legacy/summary_moves_effect_de.png

* Delete public/images/ui/legacy/summary_moves_effect_es.png

* Delete public/images/ui/legacy/summary_moves_effect_fr.png

* Delete public/images/ui/legacy/summary_moves_effect_it.png

* Delete public/images/ui/legacy/summary_moves_effect_pt-BR.png

* Delete public/images/ui/legacy/summary_moves_effect_zh-CN.png
2024-09-09 12:53:22 -04:00
Adrian T.
3c05237b2e
[Move] Fully implement Throat Chop (#4115)
* fully implement throat chop

* add linkcode in docs

* address comments

* update test
2024-09-09 12:52:20 -04:00
José Ricardo
a88b989939
[Localization] [pt_BR] Updated some translations (#4131) 2024-09-09 12:50:47 -04:00
Chapybara-jp
e84fe8c24e
[Localisation] [JA] Translated/updated spacing in several files, fixed Ice Face bug (#4129)
* Update ability-trigger.json

* Update ability.json

* Update arena-flyout.json

* Update arena-tag.json

* Update battle.json

* Update fight-ui-handler.json

* Update berry.json

* Update menu.json

* Update party-ui-handler.json

* Update starter-select-ui-handler.json

* Update tutorial.json

* Update move.json

* Update battle.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-tag.json

* Update party-ui-handler.json

* Update settings.json
2024-09-09 12:50:30 -04:00
Mumble
26eb63cf67
[Refactor] Cleaning up Learn move phase (#3672)
* Learn Move Phase rewrite

* Typedocs

* messages with confirm do not need an extra button press no more

* Added Documentation

* This does not work

* so sad

* Some updates

* Eslint issues + clean up

* Additions to handle learning during evolution + test fixes

* some more checks

* Update src/overrides.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/test/phases/learn-move-phase.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Added new function and updated tests

* Fixed bracketing and added parameter types

* Added Sketch to the conditional

* Added some fixes. Weird stuff going on.

* Whoops

* async implementation done

* Update src/phases/learn-move-phase.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Made showText=> summary a promise

* adapt learn-move-phase to `async-await`

* await add

---------

Co-authored-by: frutescens <info@laptop>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-09 09:11:46 -07:00
AJ Fontaine
16fc3a87b7
Fix usedTMs crash (#4132) 2024-09-09 14:07:05 +01:00
Adrian T.
f5bf766ff7
[Move] Fully implement Tar Shot (#4043) 2024-09-09 00:42:53 -07:00
innerthunder
c710f85fd3
Fix Pokemon.isTrapped only checking enemy Pokemon for trapping abilities (#4124) 2024-09-09 14:19:59 +08:00
flx-sta
39b6a72517
[Bug] Fix #762: All Pokemon become invisible when capturing then switching with your only pokemon that was not fainted (#4025)
* fix #762 by using slotIndex to add to party

for now the new pokemon was ALWAYS just pushed to the party array. Now it's put into the slot that was also previously selected as the mon to release

* add docs for `Pokemon.addToParty()`

* add simple tests for addToParty

* update `isBetween` docs. Remove `.js` imports
2024-09-09 01:10:47 -04:00
Adrian T.
06f98f6737
[Bug] Fix console error from undefined stockpilingTag (#4118) 2024-09-08 20:50:47 -07:00
innerthunder
68b956cbe6
[Bug] Fix incorrect defensive properties on Terastallized Pokemon (#4070)
* Fix incorrect defensive properties on Terastallized Pokemon

* Add tests to `effectiveness.test.ts`

* Suppress errors from Tera achievement validation
2024-09-08 20:48:09 -07:00
Mumble
a30201f185
[Hotfix] Retrieving the correct form index for correct cry keys (#4121)
* [DOCS] adding JSDocs to `arena.ts` (#3590)

* adding some docs

* Update src/field/pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* seems like battleStats changed to statStages

* Apply suggestions from code review

editing doc text

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update tsdocs, convert comment to tsdoc in `pokemon.ts`

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* [Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)

* fix scrappy + etc. update inverse battle test code

* update test code following request from swain

* fix and optimize imports (#4061)

- remove any `.js` extension imports
- remove unncessary dynamic imports of `modifier.ts` file. The file was being imported statically & dynamically. Made it pure static
- increase vite chunk-size warning limit

Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>

* returned main

* Fixed cry key

* Revert "[DOCS] adding JSDocs to `arena.ts` (#3590)"

This reverts commit 675e6a0635.

* Revert "[Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)"

This reverts commit 45af0dd170.

* Revert "fix and optimize imports (#4061)"

This reverts commit e12548cdb0.

---------

Co-authored-by: DustinLin <39450497+DustinLin@users.noreply.github.com>
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: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>
Co-authored-by: frutescens <info@laptop>
2024-09-08 22:12:37 -04:00
Amani H.
38cb10ff97
[Hotfix] Fix System Data Conversion Failure (#4123) 2024-09-09 02:50:00 +01:00
Opaque02
93d6375894
Updated all fields (except passwords) to allow for 20 characters (#4119) 2024-09-09 00:57:44 +01:00
Mumble
021f31b589
[Hotfix] Retrieve the right cry when alternate-form Pokemon faint + retrieve the correct sprite key (#4117)
* [DOCS] adding JSDocs to `arena.ts` (#3590)

* adding some docs

* Update src/field/pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* seems like battleStats changed to statStages

* Apply suggestions from code review

editing doc text

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update tsdocs, convert comment to tsdoc in `pokemon.ts`

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* [Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)

* fix scrappy + etc. update inverse battle test code

* update test code following request from swain

* fix and optimize imports (#4061)

- remove any `.js` extension imports
- remove unncessary dynamic imports of `modifier.ts` file. The file was being imported statically & dynamically. Made it pure static
- increase vite chunk-size warning limit

Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>

* Fusion hotfix

* returned main

* Faint cry properly retrieved for non fused Pokemon with forms

* Revert "[DOCS] adding JSDocs to `arena.ts` (#3590)"

This reverts commit b73fd97760.

* Revert "[Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)"

This reverts commit 31fcbf49f4.

* Revert "fix and optimize imports (#4061)"

This reverts commit d1bd6974e4.

* Fixed sprite key generation

---------

Co-authored-by: DustinLin <39450497+DustinLin@users.noreply.github.com>
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: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>
Co-authored-by: frutescens <info@laptop>
2024-09-09 00:03:37 +01:00
Mumble
22c60ab532
[Hotfix][Bug] Retrieves the correct cry for Fused Pokemon (#4116)
* [DOCS] adding JSDocs to `arena.ts` (#3590)

* adding some docs

* Update src/field/pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* seems like battleStats changed to statStages

* Apply suggestions from code review

editing doc text

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update tsdocs, convert comment to tsdoc in `pokemon.ts`

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* [Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)

* fix scrappy + etc. update inverse battle test code

* update test code following request from swain

* fix and optimize imports (#4061)

- remove any `.js` extension imports
- remove unncessary dynamic imports of `modifier.ts` file. The file was being imported statically & dynamically. Made it pure static
- increase vite chunk-size warning limit

Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>

* Fusion hotfix

* Revert "fix and optimize imports (#4061)"

This reverts commit 287d671cfd.

* Revert "[Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)"

This reverts commit 9fd34c95d5.

* Revert "[DOCS] adding JSDocs to `arena.ts` (#3590)"

This reverts commit 0742efd196.

* typo

* Fixed fusionFaintCry to return correct cry

---------

Co-authored-by: DustinLin <39450497+DustinLin@users.noreply.github.com>
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: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>
Co-authored-by: frutescens <info@laptop>
2024-09-08 21:42:11 +01:00
Lugiad
df250c8b90
[Localization] New translations batch locales (Move-disabling effects, abilities triggers, error messages and some misc ajustements) (#4068)
* Update battle.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update battler-tags.json

* Update battle.json

* Update battler-tags.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update battler-tags.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update battler-tags.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update battle.json

* Update battler-tags.json

* Update battle.json

* Update battle.json

* Update src/locales/de/battle.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update src/locales/de/battler-tags.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update battler-tags.json

* Update src/locales/ko/battle.json

Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>

* Update src/locales/ko/battler-tags.json

Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>

* Update src/locales/it/battle.json

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

* Update src/locales/it/battler-tags.json

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

* Update menu.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update menu.json

* Update src/locales/de/ability-trigger.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update src/locales/de/ability-trigger.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update src/locales/de/menu.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update src/locales/ko/ability-trigger.json

Co-authored-by: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>

* Update src/locales/ko/menu.json

Co-authored-by: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>

* Update src/locales/ko/ability-trigger.json

Co-authored-by: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>

* Update src/locales/ko/menu.json

Co-authored-by: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>

* Update menu.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update ability-trigger.json

* Update menu.json

* Update ability-trigger.json

* Update battle.json

* Update battler-tags.json

* Update src/locales/zh_CN/battle.json

Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com>

* Update src/locales/zh_TW/battle.json

Co-authored-by: Yonmaru40 <47717431+40chyan@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 modifier-type.json

* Update modifier-type.json

* Update modifier-type.json

* Update modifier-type.json

* Update menu.json

* Update battler-tags.json

* Update battle.json

* Update ability-trigger.json

* Update battler-tags.json

* Update battler-tags.json

* Update battler-tags.json

* Update battler-tags.json

* Update modifier-type.json

* Update menu.json

* Update battle.json

* Update tutorial.json

* Update tutorial.json

* Update egg.json

* Update battle.json

* Update battle.json

* Update tutorial.json

* Update egg.json

* Update modifier-type.json

* Update modifier-type.json

* Update modifier-type.json

* Update modifier-type.json

* Update modifier-type.json

* Update challenges.json

* Update src/locales/ko/modifier-type.json

Co-authored-by: Enoch <enoch.jwsong@gmail.com>

* Update src/locales/ko/modifier-type.json

Co-authored-by: Enoch <enoch.jwsong@gmail.com>

* Update src/locales/ja/battle.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update src/locales/ja/menu.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update src/locales/ja/modifier-type.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update src/locales/ja/modifier-type.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update src/locales/ja/modifier-type.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* Update dialogue.json

* Update dialogue-misc.json

* Update dialogue-final-boss.json

* Update dialogue-double-battle.json

* Update ability-trigger.json

* Update achv.json

* Update arena-tag.json

* Update battle.json

* Update battler-tags.json

* Update command-ui-handler.json

* Update menu.json

* Update modifier-type.json

* Update modifier.json

* Update move-trigger.json

* Update pokemon-info-container.json

* Update pokemon-info.json

* Update splash-messages.json

* Update status-effect.json

* Update tutorial.json

* Update voucher.json

* Update weather.json

* Update ability-trigger.json

* Update src/locales/de/modifier-type.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update src/locales/de/modifier-type.json

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>

* Update modifier-type.json

* Update bgm-name.json

* Update bgm-name.json

* Update src/locales/it/menu.json

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

* types_ja.png update

* Apply suggestions from code review

Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com>

---------

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>
Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>
Co-authored-by: Leo Kim <47556641+KimJeongSun@users.noreply.github.com>
Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com>
Co-authored-by: Enoch <enoch.jwsong@gmail.com>
Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
2024-09-08 13:57:17 +02:00
Mumble
4a98c36427
[Hotfix] Properly whitelisting fused Pokemon that happen to have Pokemon with alt. forms (#4104) 2024-09-08 02:58:24 -04:00
NightKev
55b89e82c7
[Hotfix] Remove extra Roark victory line, fix baton pass i18n in achv.ts (#4103) 2024-09-08 02:46:56 -04:00
James Diefenbach
7ab0bbbd94
[Hotfix] Fix cases where hatched Pokemon don't get an egg move (#4102)
Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
2024-09-08 02:45:30 -04:00
innerthunder
8082e6dc58
[Hotfix] Fix harsh weather cancelling moves based on base type (#4097) 2024-09-08 02:29:49 -04:00
James Diefenbach
0bdb697077
[Hotfix] Show enemy item icons after egg summary (#4101)
Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
2024-09-08 02:18:51 -04:00
flx-sta
2bd07cb84e
fix and optimize imports (#4061)
- remove any `.js` extension imports
- remove unncessary dynamic imports of `modifier.ts` file. The file was being imported statically & dynamically. Made it pure static
- increase vite chunk-size warning limit

Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
2024-09-07 21:37:37 -07:00
Leo Kim
2fc3179bd9
[Bug] Fix scrappy (+ some immunity move and ability) in inverse battle (#4067)
* fix scrappy + etc. update inverse battle test code

* update test code following request from swain
2024-09-07 21:37:14 -07:00
DustinLin
f73a830f77
[DOCS] adding JSDocs to arena.ts (#3590)
* adding some docs

* Update src/field/pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* seems like battleStats changed to statStages

* Apply suggestions from code review

editing doc text

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update tsdocs, convert comment to tsdoc in `pokemon.ts`

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-07 21:36:47 -07:00
damocleas
a214110030
Voucher Event (#4094)
* Update modifier-type.ts

* Great tier vouch

* Update trainer-victory-phase.ts

* Update trainer-victory-phase.ts

* Update timed-event-manager.ts and loading-scene.ts (#1)

* Update timed-event-manager.ts and loading-scene.ts

* egg-update-zh-cn update

* Update language codes in loading-scene.ts and timed-event-manager.ts

* updated image

---------

Co-authored-by: Frederico Santos <frederico.f.santos@tecnico.ulisboa.pt>
2024-09-08 04:17:02 +01:00
Frederico Santos
9c74a86a10
Merge pull request #4087 from pagefaultgames/beta
Release #4
2024-09-08 04:15:00 +01:00
Amani H.
ffcedfd9a4
[Dev] Save Data Version Migration (#4080)
* Initial Draft

* Successfuly Migration with Vitamins and White Herb

* Apply Session Data Patches Earlier

* Remove Stray `console.log`
2024-09-08 02:40:45 +01:00
Opaque02
b36823af4a
Fixed small RNG misusage (#4092) 2024-09-08 02:33:33 +01:00
James Diefenbach
dfa3993864
Egg summary background touchup (#4091)
* darker egg-summary background

* reset old background for beta

* update egg summary bg

* reset overrides

---------

Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
2024-09-08 01:32:49 +02:00
Amani H.
7288350d45
[Item/Balance] Overhaul Lapsing Modifiers (#4032)
* Refactor Lapsing Modifiers, Lerp Hue of Count

* Fix Unit Tests

* Add Documentation to `hslToHex` Function

* Change Descriptions for New Behavior

* Add Documentation to Lapsing Modifiers

* Add Unit Tests for Lures

* Update Unit Tests for X Items and Lures

* Update Boilerplate Error Message

* Update Boilerplate Docs
2024-09-06 22:54:54 -04:00
James Diefenbach
ba212945de
[Enhancement] Darker egg summary background image (#4076)
* darker egg-summary background

* reset old background for beta

* darker egg summary bg

---------

Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
2024-09-06 20:34:13 -04:00
flx-sta
ae50db7710
[Optimization] parallel testing (#4075)
* add: vitest projects (multiple)

preparations for parallel testing

* update: tests workflow

better parallel testing
2024-09-06 16:24:38 -07:00
Adrian T.
e6a574c48f
[P2 Bug] Revert to normal form when Pokémon is fainted (#4049)
* revert to normal forms when fainted

* Remove `.js` from import

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-06 12:17:08 -07:00
Chapybara-jp
33cb999774
[Localization] [JA] Translated bgm-name.json (#4066)
* Translated bgm-name.json

Song titles from Bulbapedia and https://w.atwiki.jp/gamemusicbest100/
Kept mainline game abbrevs., changed PMD to ポケダン for clarity
Added translations for the original songs

* Update bgm-name.json

* Update bgm-name.json

* Update bgm-name.json
2024-09-06 14:51:32 -04:00
Adrian T.
acda34c2e4
[P2 Bug] Underwater and underground Pokemond do not take sand/hail damage (#4047)
* fix sandstorm/hail interaction with semi invulnerable state

* cant fly high enough to avoid sandstorm/hail damage
2024-09-06 14:15:15 -04:00
flx-sta
d8304421cf
fix endless end dialogue (#4069)
It was only displaying `ending_endless` because the `PGM` prefix was still present
2024-09-06 17:23:19 +00:00
Adrian T.
d58f035287
[Misc] Migrate REROLL_TARGET to SHOP_CURSOR_TARGET (#4016)
* migrate reroll target to shop cursor target

* delete key after migrating
2024-09-06 09:41:48 +00:00
innerthunder
7b97657756
[Bug] Fix Aura Break applying without Dark/Fairy Aura present (#4057)
* Fix Aura Break ignoring active Dark/Fairy Aura condition

* Add conditional post-summon message

---------

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-06 07:59:22 +00:00
chaosgrimmon
f1650d2515
[Sprite] Fix Tangrowth Variants (#4059)
* [Sprite] Front Tangrowth male variants

* [Sprite] Front Tangrowth female variants

* [Sprite] Back Tangrowth female variants

* [Sprite] Back Tangrowth male epic palette

* Delete public/images/pokemon/variant/465_2.png

* Delete public/images/pokemon/variant/back/465_3.png

* Delete public/images/pokemon/variant/465_3.png

* Delete public/images/pokemon/variant/465_2.json

* Delete public/images/pokemon/variant/465_3.json

* Delete public/images/pokemon/variant/back/465_3.json

* [Sprite] Update Tangrowth variants with females
2024-09-06 02:32:13 +00:00
flx-sta
f3bdaa12ca
[Bug][Refactor] fix username-finder issues + code & visual improvements (#4055)
* fix username-finder issues & refactor `login-form-ui-handler`

- reduce redundancy
- add hover effect for interactable game objects
- add error handler for "No save files found!"
- Make user finder errors support i18n

* add `disableInteractive` to mockContainer
2024-09-06 00:07:24 +00:00
Adrian T.
39f3572c1b
[Test] Add Dragon Cheer tests (#4013)
* add dragon cheer tests

* Update src/test/moves/dragon_cheer.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* update tests

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-05 23:51:47 +00:00
NightKev
57a3efd9e2
[Bug] Fix off-by-one errors in some random number calls (#3665)
* Fix off-by-one error in some random number calls

* Fix mock RNG function used by tests

Also remove unnecessary extra RNG mock from Glaive Rush test

* Just some github UI manipulation don't mind me

* Update Glaive Rush test

* Remove unnecessary `Math.floor()`

* Remove resolved comment

* Add tsdocs to various functions

* Remove `src/rng.md` file

* Update tsdoc
2024-09-05 23:51:05 +00:00
Adrian T.
deac3141a1
remove partial from tera blast (#4044) 2024-09-05 20:05:09 +00:00
innerthunder
6e26db27b8
Protection moves now fail when used last (#4045) 2024-09-05 19:07:04 +00:00
damocleas
6d312a2909
Update egg.ts Same-Species Egg Shiny Rate (#4052) 2024-09-05 18:50:28 +00:00
Chapybara-jp
e2e5b2c349
[Localisation] [JA] Translated remaining JA text files (#3999)
* [Localisation] [JA] Begun translation on arena-flyout.json

* Added english names to bgm-name.json

* Translated common.json

* Added English dialogue-double-battle.json

To make translation easier

* Added English dialogue-final-boss.json

* Added english dialogue-misc.json

* Added English dialogue.json

* Translated fight-ui-handler.json

* Update filter-bar.json

Changed 飴 to アメ for consistency with its spelling in Pokemon GO

* Update game-stats-ui-handler.json

changed 孵化 to ふか

* Update growth.json

Added kanji

* Update menu-ui-handler.json

changed 孵化 to ふか

* Update modifier-type.json

Changed name of IV Scanner to match with other files, the rest of the item descriptions need to be changed to Kanji as well.

* Update modifier.json

* Changed move-trigger.json

Added kanji and new moves.

* Update party-ui-handler.json

Added kanji

* Update pokemon-info-container.json

Changed to Kanji

* Translated pokemon-summary.json

The metFragment formatting is taken from BW

* Update run-history.json

Corrected some misinterpretations.
Added correct original line of "Welcome to Hall of Fame!"

* Added english splash-messages.json

* Update move-trigger.json

* Update move-trigger.json

* Update move-trigger.json

* Update arena-flyout.json

* Update move-trigger.json

* Translated arena-flyout.json

* Update weather.json

* Update save-slot-select-ui-handler.json

changed wave to ラウンド

* Update game-stats-ui-handler.json

* Update challenges.json

* Update achv.json

Corrected some mistakes, misspelling

* Added some translations dialogue.json

Youngster translation done
Female rival dialogue done, needs check

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json
2024-09-05 17:49:28 +00:00
Opaque02
01eb05469a
[QoL] Username finder (#4040)
* Added the ability to potentially get username from login screen

* Accidentally made dev login enforced :)

* Updated image
2024-09-05 14:00:19 +00:00
Lugiad
c902369eed
[Localization] Restoring "Safeguard" entries in arena-flyout.json of all locales where it existed (#4026)
* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json

* Update arena-flyout.json
2024-09-05 12:39:10 +00:00
Dmitriy K.
41bb12d0c0
skip pre-commit on merge and rebase, add pre-push (#1607) 2024-09-05 10:08:00 +00:00
Leo Kim
1968680104
[Enhancement] add font size option per language on registration UI (#3849)
* add language setting for register form ui

* remove button fontsize option

* fix tests

* remove deprecated comments

* update request changes

* update requested changes from es

* update requested changes from walker

* Update src/locales/es/menu.json

Co-authored-by: Asdar <asdargmng@gmail.com>

---------

Co-authored-by: Asdar <asdargmng@gmail.com>
2024-09-05 09:52:48 +00:00
Zach Day
13f38dce8d
[Move] Use BattlerTag for move-disabling effects (#2051)
* Use BattlerTag for move-disabling effects

* Fix RUN command causing freeze

* Improve documentation

* Clean up and document PokemonMove.isUsable

* Fix isMoveDisabled missing return

* Tags define the message shown when disabling interrupts a move

* Fix -1 duration on Disable effect

* Add tests for Disable

* En loc and fix message functions

* Fix Disable test

* Fix broken imports

* Fix test

* All disable tests passing

* Localize remaining strings

* Move cancellation logic out of lapse; use use TURN_END for lapse type

* Prevent disabling STRUGGLE

* Inline struggle check function

* Restore RechargingTag docs

* Move cancellation logic back to tag

Wanted to increase similarity to the existing code base to avoid that stupid hyper beam error but it's still happening here

* Fix hyper beam test

* Remove erroneous shit

* Fill movesets with SPLASH for disable test

* More robust condition for disable checking

* Remove DisabledTag lapse

* Simplify DisablingBattlerTag lapse

* Cancel disable-interrupted moves instead of failing them

* Avoid disabling virtual moves

* Consistent access modifiers across Disable tags

* Add abstract function for message when player tries to select the disabled move

* Fix syntax mistake

* Always disable last-used non-virtual move

* Overhaul tests + add tests

* Implement loadTag for DisabledTag

* Update translations

* Update translations

* Reimplement phase changes

* fix battlertag strings

* Fix disable test not running

* Update name of base class

* Rename "disabling" to "restriction"

* Fix sneaky string fuckup

* Fix test failure

* fix merge problems

* fix merge problems

* Update tests

* rerun RNG test

* Properly mock stats in test

* Document everything in battlertag

* More docs + typo fix

* Update tests

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-05 08:44:22 +00:00
innerthunder
1434a3edaf
Fix random failure in Parental Bond tests (#4036)
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-05 05:31:32 +00:00
Opaque02
61ab52c295
[Balance] Changed escape calculation (#3973)
* Changed escape calculation as per Mega

* Adding tests

* Updates some tests

* Updated all tests for bosses

* Removed console log lines

* Added some clarifying comments

* Fixed docs

* comment add

* comment add

* Convert comments into tsdoc comments

Convert `integer`/`IntegerHolder` to `number`/`NumberHolder`

Clean up tests a bit

---------

Co-authored-by: damocleas <damocleas25@gmail.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-05 05:29:39 +00:00
NightKev
237aad2184
[Misc] Clean up the Battle class a bit (#3995)
* Use default values in the `Battle` class

Turn a couple of comments into tsdoc comments

Replace a `!!` with `?? false`

* Replace `integer` with `number`
2024-09-05 05:29:02 +00:00
innerthunder
31d3bec55e
[Test] Fix Rage Powder test failing randomly (#4038)
* Fix random failure in Rage Powder test

* Remove redundant override
2024-09-05 04:54:51 +00:00
Tempoanon
834255447d
Fix mbh not using user's nickname (#4033) 2024-09-05 04:02:45 +00:00
innerthunder
f3ced7e814
[Bug] Fix inconsistencies with move type resolution for some ability triggers (#3988)
* Fix inconsistencies with ability triggers on variable-type moves

* Fix aura effects not accounting for the move user

* Fix Wonder Guard evaluating move type as if the defender used the move

* Some additional test coverage for move-type-changing effects
2024-09-05 00:49:01 +01:00
Mumble
cebd449335
I have a brain made of cheese!!! (#4028)
Co-authored-by: frutescens <info@laptop>
2024-09-04 23:16:47 +00:00
chaosgrimmon
8835ae0299
[Sprite] Index egg skip UI (#4027)
* [Sprite] Index egg skip UI

* [Sprite] Index egg skip legacy UI
2024-09-04 20:46:33 +00:00
NightKev
a537113c8f
Re-add lost i18n strings (#4024) 2024-09-04 20:45:56 +00:00
NightKev
fde32cea6c
[Misc][Bug] Add isBatonPassable property to BattlerTags (#3472)
* Add `isTransferrable` property to `BattlerTag`s

* Update Baton Pass to check `isTransferrable` for `BattlerTag`s

* Don't mark Salt Cure as transferrable

* Add Destiny Bond, remove `GroundedTag` and `ExposedTag`

* Fix daily mode test

* Add test

* Rename `isTransferrable` to `isBatonPassable`
2024-09-04 17:58:35 +00:00
innerthunder
207b3e1eb7
[Test] Add forceEnemyMove Game Manager util (#3678)
* Add `forceEnemyMove` test util

* fix ceaseless edge test

* Apply flx's suggestions

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Rewrite Follow Me test

* Reorganize new imports in game manager

* Rewrite Rage Powder + Spotlight tests

---------

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
2024-09-04 17:56:57 +00:00
MokaStitcher
11ac929a4d
fix getting the highest ivs for the iv scanner (#4022) 2024-09-04 17:00:31 +00:00
James Diefenbach
e822c91a16
[Enhancement] Skip egg hatching and show summary (#3726)
* cherry picked commits / manual copy

* better dex tracking for summary after regular egg hatching

* ui changes

* updated egg hatch bg, added candy tracker, icon anims for new shiny or new form unlock

* added i18 line, reset overrides

* touchup

* code cleanup, documentation and slight refactor

* sprite display fix

* load interrupts, simple sfx and no summary for small egg amounts

* Garbage Collection + Eslint/Docs approved.

* time logging and optimisation

* skip redundant load

* more time logs and fix pre-load issues

* more detailed loading logs

* changed loading to be on demand from cursor nav

* fix missing variant icon fallback

* removing redundant time logs and code touchup

* code cleanup

* Comments so developer doesn't get bugged about garbage collecton

* remove logs n stuff

* lang settings touchup and final touchup plus uploading blank egg summary bg

* fix nits, js imports, extra docs, magic numbers changed

* extra docs and spacing nits

* Update Github

---------

Co-authored-by: James Diefenbach <z5421232@ad.unsw.edu.au>
Co-authored-by: Frederico Santos <frederico.f.santos@tecnico.ulisboa.pt>
Co-authored-by: frutescens <info@laptop>
Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
2024-09-04 16:59:25 +00:00
Lugiad
3704680029
Update dialogue.json (#4021) 2024-09-04 16:28:10 +00:00
MokaStitcher
1055386949
starter select defaults to shiny with highest variant again (#4001) 2024-09-04 08:58:39 +00:00
Adrian T.
200deef0ed
[P1 Bug][UI/UX] Address shop cursor target feedbacks (#4009)
* address shop cursor target feedbacks

* make rewards left-most

* fix tests breaking

* Update src/test/items/dire_hit.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/test/items/temp_stat_stage_booster.test.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/locales/ja/settings.json

Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>

* update default value

* stylistic change

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
2024-09-04 01:07:56 +00:00
Frederico Santos
f63492d545 chore: Update merge_group configuration in GitHub workflows 2024-09-04 01:56:37 +01:00
gitlocalize-app[bot]
4e3a24c247
[Localization] [ES] 5 files reviewed and finish. [Ready] (#3921)
* Translate party-ui-handler.json via GitLocalize

* Translate party-ui-handler.json via GitLocalize

* Translate arena-tag.json via GitLocalize

* Translate arena-tag.json via GitLocalize

* Translate battler-tags.json via GitLocalize

* Translate battler-tags.json via GitLocalize

* Translate arena-flyout.json via GitLocalize

* Translate game-mode.json via GitLocalize

* Update src/locales/es/arena-tag.json

Co-authored-by: Asdar <asdargmng@gmail.com>

* Update src/locales/es/battler-tags.json

Co-authored-by: Asdar <asdargmng@gmail.com>

* Update src/locales/es/battler-tags.json

Co-authored-by: Asdar <asdargmng@gmail.com>

* Update src/locales/es/arena-tag.json

---------

Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: Rafa <rhijano@hotmail.com>
Co-authored-by: Lugiad <adrien.grivel@hotmail.fr>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
2024-09-03 15:19:05 -07:00
Mumble
3242a35341
[Misc][UI] Default Cursor Positioning for Command / Fight / Party (#4008)
* Cursor Pos. should match mainline

* Fixed command mode behavior

---------

Co-authored-by: frutescens <info@laptop>
2024-09-03 15:13:29 -07:00
PigeonBar
3a6146935c
[Bug] Fix reloads causing RNG inconsistencies, Moody and Acupressure use seeded RNG now (#3952)
* [Bug] Fix reloads causing RNG inconsistencies

* Minor revisions

* Allow reload helper to directly access getSessionSaveData()

* Changed Moody and Acupressure to use seeded RNG

* Fix broken unit test
2024-09-03 09:14:45 -04:00
Jannik Tappert
232cd2c91a
[Localization] [DE] Added missing keys in DE (#3998)
* Add missing keys in DE

* Challenge description fix
2024-09-03 09:12:57 -04:00
Lugiad
940992a940
[Localization] [FR] Added missing keys in French (#4000)
* Update battle.json

* Update menu-ui-handler.json
2024-09-03 14:48:13 +02:00
Frederico Santos
666cde94ae
Merge pull request #3997 from innerthunder/main-beta-merge
Main to Beta Merge (Wave 3)
2024-09-03 11:27:46 +01:00
innerthunder
38ae0a5d6d Merge remote-tracking branch 'upstream/main' into main-beta-merge 2024-09-03 03:21:54 -07:00
NightKev
d004d905bd
[Test] Remove nature RNG from Beast Boost tests (#3994) 2024-09-03 01:59:48 -04:00
chaosgrimmon
684d7b3009
[Misc] Repack Keyboard button sprites (#3993)
* [Misc] Repack keyboard input icons

* [Misc] Keyboard sprites repacking json

* [Bug] Capitalisation of "c"
2024-09-03 01:02:29 -04:00
NightKev
97a02e7c34
[Test] Set boss Pokémon test timeout to 20 seconds instead of 2.5 seconds (#3992) 2024-09-03 00:59:51 -04:00
PigeonBar
587360c8da
[Bug] Fix eggs having exploitable RNG (#3913)
* [Bug] Fix eggs having exploitable RNG

* Fix Wind Rider test having random chance to fail

* Revert egg's ID back to its own unseeded generation

* Remove change from wind rider test

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
2024-09-02 22:18:18 -04:00
Mumble
deb4e9dd24
[UI] Run history fixes and improvements (#3987)
* Challenge Rules Word Wrap

* Fixed Modifiers

* Fixed item count color.

* removed .js endings

---------

Co-authored-by: frutescens <info@laptop>
2024-09-02 22:14:09 -04:00
Amani H.
89e80f3deb
[Refactor/Bug/Move] Overhaul Stats and Battle Items, Implement Several Stat Moves (#2699)
* Create Getters, Setters, and Types

* Work on `pokemon.ts`

* Adjust Types, Refactor `White Herb` Modifier

* Migrate `TempBattleStat` Usage

* Refactor `PokemonBaseStatModifier` Slightly

* Remove `BattleStat`, Use "Stat Stages" & New Names

* Address Phase `integers`

* Finalize `BattleStat` Removal

* Address Minor Manual NITs

* Apply Own Review Suggestions

* Fix Syntax Error

* Add Docs

* Overhaul X Items

* Implement Guard and Power Split with Unit Tests

* Add Several Unit Tests and Fixes

* Implement Speed Swap with Unit Tests

* Fix Keys in Summary Menu

* Fix Starf Berry Raising EVA and ACC

* Fix Contrary & Simple, Verify with Unit Tests

* Implement Power & Guard Swap with Unit Tests

* Add Move Effect Message to Speed Swap

* Add Move Effect Message to Power & Guard Split

* Add Localization Entries

* Adjust Last X Item Unit Test

* Overhaul X Items Unit Tests

* Finish Missing Docs

* Revamp Crit-Based Unit Tests & Dire Hit

* Address Initial NITs

* Apply NIT Batch

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Fix Moody Test

* Address Multiple Messages for `ProtectStatAbAttr`

* Change `ignoreOverride` to `bypassSummonData`

* Adjust Italian Localization

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

* Fix Moody

---------

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>
2024-09-02 22:12:34 -04:00
NightKev
947400f2b9
[Test] Add tests for Freeze-Dry (#3990) 2024-09-02 22:11:35 -04:00
ckincaid17
234d617464
[Bug] Let Shedinja relearn egg moves when evolved from a starter (#3915)
* [Bug] Let Shedinja relearn egg moves when evolved from a starter

* Copy met level as well
2024-09-02 19:10:33 -07:00
cam
672bc77c58
Added Donate Link to Community Page (#3989)
* Added Donate Link to Community Page

Removed the cookies from the html and added a Donations link on the community page (with guidance from Walker)

* Added Translation Key
2024-09-03 01:37:53 +01:00
AJ Fontaine
b0360123e0
[Balance] [QoL] [Feature] Allow mons to track and relearn used TMs (#3656)
* Allow mons to track and relearn used TMs

* Fix issue getting level moves

* Apply suggested safety measures
2024-09-02 16:25:41 -07:00
Leo Kim
60becf54f8
[Enhancement][UI] Passive ability will be displayed even if it is locked or disabled (#3976)
* show passive name even if it is locked or disabled

* update passive label with updated new icons

* fix icon remains bug, when go start button and filterbar
2024-09-02 23:49:11 +01:00
Lugiad
df1c6efe2d
[Localization] [Fix] Restoring inverted rival dialogues in all dialogue-misc.json locales (#3986)
* Update dialogue-misc.json

* Update dialogue-misc.json

* Update dialogue-misc.json

* Update dialogue-misc.json

* Update dialogue-misc.json

* Update dialogue-misc.json

* Update dialogue-misc.json
2024-09-02 18:33:21 -04:00
MokaStitcher
89a1ff7b5b
[Bug] Fix Inconsistency with stat boost when breaking through boss shields + tests (#3785)
* fix boss shield stats up calculation and add tests

* update test to remove usage of deprecated startBattle
2024-09-03 00:29:15 +02:00
Lugiad
9c30e5b213
[Localization] [FR] [Fix] Dialogue fixs batch + ignored entries form previous PR (#3985)
* Update dialogue-misc.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue-misc.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json

* Update dialogue.json
2024-09-02 18:03:21 -04:00
njahja
03567ed56c
[Bugfix #3930] Moves That a Pokemon Knows and are not in their List of Learnable TMs Display as "Not Able" Rather than Learned (#3935)
* fix for [Bug] Moves That a Pokemon Knows and are not in their List of Learnable TMs Display as "Not Able" Rather than Learned #3930

* convert switch case block to if/elif/else
2024-09-02 17:59:26 -04:00
Chapybara-jp
4c4a2c1900
[Localisation] [JA] Translated trainer-classes.json, trainer-names.json, trainer-titles.json (#3978)
* [Localisation] [JA] trainer-classes.json

Names taken from Poke Corpus and Bulbapedia. 
Some double team names do not exist in the official games so I created some new fitting/localised/funny ones (e.g. (solo) サイキッカー -> (double) サイキッ家)
As we are using Scarlet/Violet Kanji usage conventions, I decided to write all class titles that were Hiragana only in BW/B2W2 with Kanji instead.

* Translate trainer-names.json

Should we localise the names of Finn and Ivy? 
Two possible ideas:
Finn -> チトセ (Finn may come from the "Whale Fin" snake plant; Latin Name Sansevieria Masoniana. The Sansevieria family is known as チトセラン属 in Japanese. チトセ(千歳 millenium;long time) can be a reference to endless loop of Classic Mode)
Ivy -> タイチ (Ivy -> IV. IV in Japanese is 固体値 (こたいち). タイチ also sounds like  対置 (opposition)

* Update trainer-classes.json

* Translate trainer-titles.json
2024-09-02 17:57:24 -04:00
Mumble
ce5a92325c
[UI][Misc] Rename Space to Action in voucher/achv menu (#3982)
* Changing only achvs-ui-handler for now

* Add ACTION sprite

---------

Co-authored-by: frutescens <info@laptop>
Co-authored-by: chaosgrimmon <31082757+chaosgrimmon@users.noreply.github.com>
2024-09-02 17:54:56 -04:00
Asdar
e9998fcc16
[Localisation] [ES] Bugfix pokemon-form-battle.json (#3981)
Removed an extra tab added by GitLocalize
2024-09-02 14:20:05 -07:00
timchi94
aae4d6933c
[QoL] Enable female gender for all default starters and all existing s… (#2194)
* fix: Enable female gender for all default starters and all existing saves

* Fixed Fresh Start so it doesn't restrict gender

---------

Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
Co-authored-by: frutescens <info@laptop>
2024-09-02 12:43:44 -07:00
Mumble
256dfbde6e
Fixed conditional (#3983)
Co-authored-by: frutescens <info@laptop>
2024-09-02 21:27:29 +02:00
Jannik Tappert
86316bd6f8
[Localization] [DE] DisguiseChange (#3979)
* [Localization] [DE] DisguiseChange

* Update src/locales/de/pokemon-form-battle.json
2024-09-02 10:55:57 -07:00
Jannik Tappert
ad778101e4
[DEV] Remove female achv file (#3977) 2024-09-02 10:32:49 -07:00
NightKev
c20f37bcf9
[P3 Bug] Add dialog lines for Rood (#3970) 2024-09-02 01:39:52 -04:00
AJ Fontaine
39cfe69cd9
[Bug] Fix affix used when enemy trainer switches Pokemon (#3899) 2024-09-02 01:25:45 -04:00
chaosgrimmon
634bfb7900
[Sprite] Pelipper variant cleanup (#3969)
* [Sprite] Sprite fix Pelipper front

* [Sprite] Map epic Pelipper front

* Delete public/images/pokemon/variant/279_1.png

* Delete public/images/pokemon/variant/279_2.png

* Delete public/images/pokemon/variant/279_3.png

* Delete public/images/pokemon/variant/279_1.json

* Delete public/images/pokemon/variant/279_2.json

* Delete public/images/pokemon/variant/279_3.json

* [Sprite] Use epic Pelipper palette

* [Sprite] Index base shiny Pelipper front
2024-09-02 01:16:47 -04:00
Madmadness65
434b823112
[Enhancement/Item] Separate form change items into non-rare and rare (#3957)
* Separate form change items into non-rare and rare

* Remove unnecessary !!
2024-09-02 01:15:52 -04:00
NightKev
744c8f8845
[Test] Update/modernize/fix some tests (#3968) 2024-09-02 01:06:20 -04:00
Mumble
0cbdaab28e
[UI][Misc] Force users to have an active challenge (#3953)
* I hope this is good enough

* renamed variable to better name

* Remove random newline

* When player is ready cool box

* Fixed cancel behavior

* standardized action/cancel behavior

* Added comments

---------

Co-authored-by: frutescens <info@laptop>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-02 00:32:22 -04:00
NightKev
84ef7f0683
[Balance] Double base shiny odds, adjusted Shiny Charm to match (#3964)
* Double shiny odds

"anyone wanna double the base shiny odds for me" - damo, 2024

* Adjust Shiny Charm to compensate for increased base odds

* Remove magic number

* Update tsdoc and remove unneeded `console.log()`

* Clarify tsdoc
2024-09-02 00:26:47 -04:00
Mumble
1e432fc74b
[Bug] Fixed pre-set volume oversight (#3963)
Co-authored-by: frutescens <info@laptop>
2024-09-02 00:26:35 -04:00
NightKev
f54846f735
[Move] Implement Safeguard (#3447)
* Implemented safeguard and tests

* Update tests

* Add i18n placeholders

* Implement Safeguard for non-volatile statuses

* Implement protection from confusion and Yawn

* Replace `target instanceof EnemyPokemon` with `target.isPlayer()`

* Minor capitalization change

* First batch of i18n

Adds fr, pt_BR, zh_CN, zh_TW

Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr>
Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br>
Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com>

* Add more translations

+ de, es, ko

Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>

* Fix broken character in es translation

* Update test with new function definition

* Add Italian translation

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

* Add move category check for message display

Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>

* Update phase imports in Safeguard test

* Fix test imports

* Update tests

---------

Co-authored-by: Joshua Keegan <keeganjosh@vuw.ac.nz>
Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr>
Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br>
Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com>
Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>
Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>
2024-09-02 00:26:20 -04:00
gitlocalize-app[bot]
2d5bd57c44
[Localization] [FR] pokemon-info.json and dialogue-misc.json completion (#3761)
* Translate pokemon-info.json via GitLocalize

* Update dialogue-misc.json

---------

Co-authored-by: Lugiad <adrien.grivel@hotmail.fr>
2024-09-02 00:25:07 -04:00
NightKev
f3c41edf5e
[Bug] Don't reset turn count or used moves array at the start of a new wave (fakeout and gigaton hammer) (#3606)
* Don't reset turn count or used moves array at the start of a new wave

* Add tests
2024-09-02 00:24:12 -04:00
NightKev
69a9916b4c
[Bug] Moves copied by Dancer should not consume PP (#3623)
* Moves copied by Dancer should not consume PP

* Add test for Dancer (unfinished)

* Delete src/test/abilities/dancer.test.ts

This test is not finished lol

* Add test
2024-09-02 00:21:56 -04:00
PrabbyDD
4553c1c34f
[Bug] Fix Octolock Ignores Clear Body, White Smoke, Big Pecks #3876
Pecks, Clear Body, and White Smoke

Adding tests for octolock
2024-09-02 00:20:16 -04:00
gitlocalize-app[bot]
22d31bc704
[Localisation] [ES] Review and finished pokemon-form and pokemon-form-battle (#3903)
* Translate pokemon-form.json via GitLocalize

* Translate pokemon-form.json via GitLocalize

* Translate pokemon-form-battle.json via GitLocalize

* Translate pokemon-form-battle.json via GitLocalize

* Update src/locales/es/pokemon-form.json

Co-authored-by: Asdar <asdargmng@gmail.com>

---------

Co-authored-by: Rafa <rhijano@hotmail.com>
Co-authored-by: LilyAlternis <tias.a2002@gmail.com>
Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
2024-09-02 00:19:02 -04:00
gitlocalize-app[bot]
a894438e24
[Localisation] [JA] Several files translated (#3916)
* Translate ability-trigger.json via GitLocalize

* Translate game-stats-ui-handler.json via GitLocalize

* Translate modifier-select-ui-handler.json via GitLocalize

* Translate pokemon-form-battle.json via GitLocalize

* Translate battle-info.json via GitLocalize

* Translate menu.json via GitLocalize

* Translate battler-tags.json via GitLocalize

* Translate pokemon-info.json via GitLocalize

* Translate achv.json via GitLocalize

* Translate berry.json via GitLocalize

* Translate achv-female.json via GitLocalize

* Translate challenges.json via GitLocalize

* Translate menu-ui-handler.json via GitLocalize

* Translate egg.json via GitLocalize

* Translate pokemon.json via GitLocalize

* Translate pokemon.json via GitLocalize

* Translate starter-select-ui-handler.json via GitLocalize

* Translate command-ui-handler.json via GitLocalize

* Translate settings.json via GitLocalize

* Update achv-female.json

* Update menu-ui-handler.json

* Update settings.json

* Update achv.json

* Update achv.json

* Update achv.json

* Delete src/locales/ja/achv-female.json

* Update achv.json

Compared in-game, with these changes it should all look good.

* Update challenges.json

* Update game-mode.json

* Update menu.json

* Update settings.json

* Translate game-stats-ui-handler.json via GitLocalize

* Update game-stats-ui-handler.json

* Update settings.json

---------

Co-authored-by: gitlocalize-app[bot] <55277160+gitlocalize-app[bot]@users.noreply.github.com>
Co-authored-by: Enoch <enoch.jwsong@gmail.com>
Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
2024-09-02 00:18:49 -04:00
gitlocalize-app[bot]
dd033f4ec1
[Localization] [pt_BR] Updated many translations (#3917)
* Translate tutorial.json via GitLocalize

* Translate challenges.json via GitLocalize

* Translate menu-ui-handler.json via GitLocalize

---------

Co-authored-by: José Ricardo <josefleury@discente.ufg.br>
2024-09-02 00:17:05 -04:00
gitlocalize-app[bot]
0671a244a8
[Localisation] [ES] Reviewed and finished ability.json and bgm-name.json (#3920)
* Translate ability.json via GitLocalize

* Translate ability.json via GitLocalize

* Translate bgm-name.json via GitLocalize

---------

Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: LilyAlternis <tias.a2002@gmail.com>
2024-09-02 00:16:54 -04:00
Mumble
c4c9cf939e
[Bug] Moved RNG call if the Pokemon's ability hasn't been determined (#3966)
Co-authored-by: frutescens <info@laptop>
2024-09-02 00:09:46 -04:00
Blitzy
51ab51cc64
[Balance Hotfix] GMax Butterfree tinted lens -> compound eyes (#3967) 2024-09-02 00:08:43 -04:00
gitlocalize-app[bot]
8edb9ca65b
[Localizaiton(pt_br)] Translate pokemon-summary.json via GitLocalize (#3868)
Co-authored-by: José Ricardo <josefleury@discente.ufg.br>
2024-09-01 23:57:48 -04:00
gitlocalize-app[bot]
08fe9e1e21
[Localization(fr)] Translate trainer-classes.json (#3882)
Co-authored-by: Lugiad <adrien.grivel@hotmail.fr>
2024-09-01 23:57:28 -04:00
gitlocalize-app[bot]
781bfd831f
[Localization] pokemon names, party-ui-handler, pokemon-info and pokemon-info-container localizations for italian (#3836)
* Translate pokemon-info-container.json via GitLocalize

* Translate pokemon-info.json via GitLocalize

* Translate party-ui-handler.json via GitLocalize

* Translate pokemon.json via GitLocalize

---------

Co-authored-by: Niccolò <niccolo.pulcini.07@gmail.com>
2024-09-01 23:55:07 -04:00
innerthunder
e29f1fe5fd
[Bug] Fix some trapping moves' interactions with Ghost-type Pokemon (#3936)
* Fix secondary effects to trapping moves not applying to Ghost types

* Docs for `isTrapped`

* more `isTrapped` cleanup

* Remove .js from imports
2024-09-01 23:39:26 -04:00
NightKev
1fd662111e
[Test] Tests now default to using "Set" battle style (#3728)
* Tests now default to using "Set" battle style

* Fix typo
2024-09-01 23:32:31 -04:00
Adrian T.
56b39032b9
[Dev] add script to create test boilerplate file (#3954)
* add script to create test boilerplate file

* add more docs

* add timeout to template
2024-09-01 23:30:27 -04:00
gitlocalize-app[bot]
80828359e2
[Localization(en)] Fix Roark Dialouge (#3873)
* Translate dialogue-male.json via GitLocalize

* Added female

* !

* Update src/locales/en/dialogue-male.json

* Remove empty files

* Added missing comma

---------

Co-authored-by: Jannik Tappert <tappertjannik@googlemail.com>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
2024-09-01 23:28:10 -04:00
NightKev
709066bd1a
[Move] Finish Alluring Voice, Burning Jealousy and Lash Out (#3508)
* Implement Alluring Voice and Burning Jealousy

* Fix Alluring Voice and add tests

* Replace `BattlerTag.STATS_BOOSTED` with `PokemonTurnData` field

* Work around bug with turn data

* Remove unused variable

* Replace nearby instances of `integer` with `number`

* Fix imports

* Implement Lash Out

* Rename `battleStats(In|De)crease` -> `battleStats(In|De)creased`

* Fix copy/paste error

Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>

* Update tests

---------

Co-authored-by: ElliottSimmonds <simmonds.elliott@yahoo.co.uk>
Co-authored-by: schmidtc1 <62030095+schmidtc1@users.noreply.github.com>
Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
2024-09-01 22:57:07 -04:00
MokaStitcher
dcb03f4ee9
[Test] Add test for final boss fight phase switch (#3847)
* implement test for final boss encounter phase switch

* Update Eternatus tests & helper function

* fix endless_boss test following GameManager update

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-01 22:47:22 -04:00
gitlocalize-app[bot]
14e0c66ed9
[Localisation] [ES] Finished and reviewed terrain, modifier, trainer-names, splash messages (#3848)
* Translate splash-messages.json via GitLocalize

* Translate splash-messages.json via GitLocalize

* Translate trainer-names.json via GitLocalize

* Translate modifier.json via GitLocalize

* Translate modifier.json via GitLocalize

* Translate modifier.json via GitLocalize

* Translate terrain.json via GitLocalize

* Update src/locales/es/trainer-names.json

Co-authored-by: Asdar <asdargmng@gmail.com>

---------

Co-authored-by: LilyAlternis <tias.a2002@gmail.com>
Co-authored-by: Asdar <asdargmng@gmail.com>
Co-authored-by: Rafa <rhijano@hotmail.com>
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-01 22:46:53 -04:00
gitlocalize-app[bot]
49c3158fd1
[Localization(ko)] Change ghost type challenge acv for achv-female (#3866)
Co-authored-by: sodam <sodamlee315@gmail.com>
Co-authored-by: Enoch <enoch.jwsong@gmail.com>
Co-authored-by: KimJeongSun <leo@atlaslabs.ai>
2024-09-01 22:45:42 -04:00
gitlocalize-app[bot]
c070f110e5
[Localization(fr)] Additional nature entries in pokemon-summary (#3869)
Co-authored-by: Lugiad <adrien.grivel@hotmail.fr>
2024-09-01 22:44:58 -04:00
flx-sta
0c28da75b4
[Bug] Fix Opponent pokemon sprite disappears after using Roar and Dragon Tail #481 (#3927) 2024-09-01 22:42:23 -04:00
Adrian T.
64368b62bc
[Ability] Add form change support for Flower Gift (#3941)
* add form change support for flower gift

* fix nits
2024-09-01 22:39:42 -04:00
Adrian T.
3bcee779e2
[Move] Fully implement dragon cheer (#3959) 2024-09-01 22:39:12 -04:00
chaosgrimmon
97e3250f62
[Sprite] Chien-Pao sprite cleanup (#3961)
* Delete public/images/pokemon/exp/shiny/1002b.png

* Delete public/images/pokemon/exp/shiny/1002s.png

* Delete public/images/pokemon/exp/shiny/1002sb.png
2024-09-01 22:31:25 -04:00
innerthunder
7755f798fd
[Ability] Implement Tera Shell (#3856)
* Implement Tera Shell

* Apply suggestions from code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update src/data/ability.ts

Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>

* Add comments and fixed damage condition to `applyPreDefend`

* Fix speed tie breaking things in tera shell test

* Change deprecated `startBattle` calls

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>
2024-09-02 02:21:11 +01:00
Frederico Santos
ac1c29faca fix: Fix missing comma in biomeLinks array 2024-09-02 00:03:51 +01:00
Frederico Santos
dc9a4852b4
Merge pull request #3960 from frutescens/bannerHotfix
[Bug][Hotfix] Missing Banners
2024-09-01 23:40:27 +01:00
frutescens
d7cc8a6e5c Fixed pt-BR and zh-CN 2024-09-01 15:33:10 -07:00
cadi
a41133a55a
blocking inputs while showing texts to prevent moveing cursor (#2371)
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-01 15:26:45 -07:00
AJ Fontaine
335d32e0d7
[UI] [QoL] [Enhancement] Exclude redundant species from certain filters in starter select (#3910)
* Exclude species without HA from HA filters in starter select

* Remove candyless starters from passive/cost reduction filters
2024-09-01 15:24:37 -07:00
Mumble
55e0d65ac8
[Refactor] Improvements on getOrder() (#3547)
* Moved getOrder() into TurnStartPhase

* Cleaned up bypass speed checks

* Revert "Cleaned up bypass speed checks"

This reverts commit 11150254f5.

* Added comments.

* Fixed up some inconsistencies

* changed isSameBracket check

* changed isSameBracket check p2

* changed isSameBracket check p3

* changed isSameBracket check p3

* Fixed up conditionals + stall/M.m

* Seems OK

* Update battle-spec.ts

* Updated tests to use new functions introduced. Less intuitive, but faster.

* Update src/phases.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Moved getOrder() into TurnStartPhase

* Cleaned up bypass speed checks

* Revert "Cleaned up bypass speed checks"

This reverts commit 11150254f5.

* Added comments.

* Fixed up some inconsistencies

* changed isSameBracket check

* changed isSameBracket check p2

* changed isSameBracket check p3

* changed isSameBracket check p3

* Fixed up conditionals + stall/M.m

* Seems OK

* Update battle-spec.ts

* Updated tests to use new functions introduced. Less intuitive, but faster.

* Removed import

* i hate git

* Moved getOrder() into TurnStartPhase

* Seems OK

* missing import

* Added Snooze's review

* Added test fixes and removed unwanted edit.

* fixed dynamax cannon test

* typedocs fixes

* Updating battle-order.test.ts

* merge fixes

* ughhh

* Update src/test/abilities/mycelium_might.test.ts

Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>

* tsdocs :)

* Fixed tests

* Update src/phases/turn-start-phase.ts

Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>

* Update src/phases/turn-start-phase.ts

Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>

* innerthunder's fixes

* commas

* Mocked stats instead of directly changing them

---------

Co-authored-by: Frutescens <info@laptop>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>
2024-09-01 15:23:25 -07:00
flx-sta
69a9e6a365
Localization: remove all "<key>_female": null entries in /en (#3918) 2024-09-02 00:21:48 +02:00
Frederico Santos
86fe4dd888
Merge pull request #3834 from pagefaultgames/beta
Beta Release #3
2024-09-01 23:15:28 +01:00
Frederico Santos
55acf0eeac
Merge branch 'main' into beta 2024-09-01 23:10:40 +01:00
Frederico Santos
e80b4fe122 feat: Update banner key assignment in TimedEventDisplay setup method 2024-09-01 21:16:20 +01:00
Mumble
95a02a96a7
Fixing banner error upon refresh (#3956) 2024-09-01 21:11:23 +01:00
Mumble
de66b450a5
[Beta][Misc] Banner (#3926)
* Initial work - does not work.

* Revert

* image replacement

* better scaling

* Removing most of the bangs

* no more bangs

* Update src/timed-event-manager.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Implemented Torranx's suggestion

* Ready for Translations

* Delete Picture

* Localized banners

* Biomes fix

* Corrections

* Update src/timed-event-manager.ts

Co-authored-by: Frederico Santos <frederico.f.santos@tecnico.ulisboa.pt>

---------

Co-authored-by: frutescens <info@laptop>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: Frederico Santos <frederico.f.santos@tecnico.ulisboa.pt>
2024-09-01 20:18:40 +01:00
NightKev
762aa9e49b
Update the GitHub pull request template (#3755) 2024-08-25 17:28:29 +01:00
687 changed files with 23892 additions and 35255 deletions

View File

@ -1,7 +1,7 @@
name: Bug Report
description: Create a report to help us improve
title: "[Bug] "
labels: ["Bug"]
labels: ["Bug", "Triage"]
body:
- type: markdown
attributes:
@ -19,21 +19,12 @@ body:
value: |
---
- type: textarea
id: session-file
id: repro
attributes:
label: Session export file
description: Open Menu → ManageData → Export Session → Select slot. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)).
placeholder: Focus me and then drop your file here (or use the upload button at the bottom)
label: Reproduction
description: Describe the steps to reproduce this bug. If applicable attach user/session data at the bottom
validations:
required: false
- type: textarea
id: data-file
attributes:
label: User data export file
description: Open Menu → ManageData → Export Data. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)).
placeholder: Focus me and then drop your file here (or use the upload button at the bottom)
validations:
required: false
required: true
- type: markdown
attributes:
value: |
@ -60,48 +51,20 @@ body:
attributes:
value: |
---
- type: dropdown
id: os
- type: textarea
id: session-file
attributes:
label: What OS did you observe the bug on?
multiple: true
options:
- PC/Windows
- Mac/OSX
- Linux
- iOS
- Android
- Other
validations:
required: true
- type: input
id: os-other
attributes:
label: If other please specify
label: Session export file
description: Open Menu → ManageData → Export Session → Select slot. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)).
placeholder: Focus me and then drop your file here (or use the upload button at the bottom)
validations:
required: false
- type: markdown
- type: textarea
id: data-file
attributes:
value: |
---
- type: dropdown
id: browser
attributes:
label: Which browser do you use?
multiple: true
options:
- Chrome
- Firefox
- Safari
- Edge
- Opera
- Other
validations:
required: true
- type: input
id: browser-other
attributes:
label: If other please specify
label: User data export file
description: Open Menu → ManageData → Export Data. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)).
placeholder: Focus me and then drop your file here (or use the upload button at the bottom)
validations:
required: false
- type: markdown

View File

@ -1,7 +1,7 @@
name: Feature Request
description: Suggest an idea for this project
title: "[Feature] "
labels: ["Enhancement"]
labels: ["Enhancement", "Triage"]
body:
- type: markdown
attributes:

View File

@ -30,7 +30,7 @@
- [ ] The PR is self-contained and cannot be split into smaller PRs?
- [ ] Have I provided a clear explanation of the changes?
- [ ] Have I considered writing automated tests for the issue?
- [ ] If I have text, did I add make it translatable and added a key in the English language?
- [ ] If I have text, did I make it translatable and add a key in the English locale file(s)?
- [ ] Have I tested the changes (manually)?
- [ ] Are all unit tests still passing? (`npm run test`)
- [ ] Are the changes visual?

View File

@ -11,6 +11,8 @@ on:
branches:
- main # Trigger on pull request events targeting the main branch
- beta # Trigger on pull request events targeting the beta branch
merge_group:
types: [checks_requested]
jobs:
run-linters: # Define a job named "run-linters"

View File

@ -8,6 +8,8 @@ on:
branches:
- main
- beta
merge_group:
types: [checks_requested]
jobs:
pages:

View File

@ -0,0 +1,30 @@
name: Test Template
on:
workflow_call:
inputs:
project:
required: true
type: string
shard:
required: true
type: number
totalShards:
required: true
type: number
jobs:
test:
name: Shard ${{ inputs.shard }} of ${{ inputs.totalShards }}
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: Run tests
run: npx vitest --project ${{ inputs.project }} --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }}

View File

@ -11,23 +11,37 @@ on:
branches:
- main # Trigger on pull request events targeting the main branch
- beta # Trigger on pull request events targeting the beta branch
merge_group:
types: [checks_requested]
jobs:
run-tests: # Define a job named "run-tests"
name: Run tests # Human-readable name for the job
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
pre-test:
name: Run Pre-test
runs-on: ubuntu-latest
steps:
- name: Check out Git repository # Step to check out the repository
uses: actions/checkout@v4 # Use the checkout action version 4
- name: Set up Node.js # Step to set up Node.js environment
uses: actions/setup-node@v4 # Use the setup-node action version 4
- name: Check out Git repository
uses: actions/checkout@v4
with:
node-version: 20 # Specify Node.js version 20
path: tests-action
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
working-directory: tests-action
run: npm ci
- name: Run Pre-test
working-directory: tests-action
run: npx vitest run --project pre ${{ !runner.debug && '--silent' || '' }}
- name: Install Node.js dependencies # Step to install Node.js dependencies
run: npm ci # Use 'npm ci' to install dependencies
- name: tests # Step to run tests
run: npm run test:silent
run-tests:
name: Run Tests
needs: [pre-test]
strategy:
matrix:
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
uses: ./.github/workflows/test-shard-template.yml
with:
project: main
shard: ${{ matrix.shard }}
totalShards: 10

110
create-test-boilerplate.js Normal file
View File

@ -0,0 +1,110 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
/**
* This script creates a test boilerplate file for a move or ability.
* @param {string} type - The type of test to create. Either "move", "ability",
* or "item".
* @param {string} fileName - The name of the file to create.
* @example npm run create-test move tackle
*/
// Get the directory name of the current module file
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Get the arguments from the command line
const args = process.argv.slice(2);
const type = args[0]; // "move" or "ability"
let fileName = args[1]; // The file name
if (!type || !fileName) {
console.error('Please provide a type ("move", "ability", or "item") and a file name.');
process.exit(1);
}
// Convert fileName from kebab-case or camelCase to snake_case
fileName = fileName
.replace(/-+/g, '_') // Convert kebab-case (dashes) to underscores
.replace(/([a-z])([A-Z])/g, '$1_$2') // Convert camelCase to snake_case
.toLowerCase(); // Ensure all lowercase
// Format the description for the test case
const formattedName = fileName
.replace(/_/g, ' ')
.replace(/\b\w/g, char => char.toUpperCase());
// Determine the directory based on the type
let dir;
let description;
if (type === 'move') {
dir = path.join(__dirname, 'src', 'test', 'moves');
description = `Moves - ${formattedName}`;
} else if (type === 'ability') {
dir = path.join(__dirname, 'src', 'test', 'abilities');
description = `Abilities - ${formattedName}`;
} else if (type === "item") {
dir = path.join(__dirname, 'src', 'test', 'items');
description = `Items - ${formattedName}`;
} else {
console.error('Invalid type. Please use "move", "ability", or "item".');
process.exit(1);
}
// Ensure the directory exists
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
// Create the file with the given name
const filePath = path.join(dir, `${fileName}.test.ts`);
if (fs.existsSync(filePath)) {
console.error(`File "${fileName}.test.ts" already exists.`);
process.exit(1);
}
// Define the content template
const content = `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 } from "vitest";
describe("${description}", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.SPLASH])
.battleType("single")
.enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
});
it("test case", async () => {
// await game.classicMode.startBattle([Species.MAGIKARP]);
// game.move.select(Moves.SPLASH);
}, TIMEOUT);
});
`;
// Write the template content to the file
fs.writeFileSync(filePath, content, 'utf8');
console.log(`File created at: ${filePath}`);

View File

@ -191,15 +191,15 @@ Now that the enemy Pokémon with the best matchup score is on the field (assumin
We then need to apply a 2x multiplier for the move's type effectiveness and a 1.5x multiplier since STAB applies. After applying these multipliers, the final score for this move is **75**.
- **Swords Dance**: As a non-attacking move, this move's benefit score is derived entirely from the sum of its attributes' benefit scores. Swords Dance's `StatChangeAttr` has a user benefit score of 0 and a target benefit score that, in this case, simplifies to
- **Swords Dance**: As a non-attacking move, this move's benefit score is derived entirely from the sum of its attributes' benefit scores. Swords Dance's `StatStageChangeAttr` has a user benefit score of 0 and a target benefit score that, in this case, simplifies to
$\text{TBS}=4\times \text{levels} + (-2\times \text{sign(levels)})$
where `levels` is the number of stat stages added by the attribute (in this case, +2). The final score for this move is **6** (Note: because this move is self-targeted, we don't flip the sign of TBS when computing the target score).
- **Crush Claw**: This move is a 75-power Normal-type physical attack with a 50 percent chance to lower the target's Defense by one stage. The additional effect is implemented by the same `StatChangeAttr` as Swords Dance, so we can use the same formulas from before to compute the total TBS and base target score.
- **Crush Claw**: This move is a 75-power Normal-type physical attack with a 50 percent chance to lower the target's Defense by one stage. The additional effect is implemented by the same `StatStageChangeAttr` as Swords Dance, so we can use the same formulas from before to compute the total TBS and base target score.
$\text{TBS}=\text{getTargetBenefitScore(StatChangeAttr)}-\text{attackScore}$
$\text{TBS}=\text{getTargetBenefitScore(StatStageChangeAttr)}-\text{attackScore}$
$\text{TBS}=(-4 + 2)-(-2\times 2 + \lfloor \frac{75}{5} \rfloor)=-2-11=-13$
@ -221,4 +221,4 @@ When implementing a new move attribute, it's important to override `MoveAttr`'s
- A move's **user benefit score (UBS)** incentivizes (or discourages) the move's usage in general. A positive UBS gives the move more incentive to be used, while a negative UBS gives the move less incentive.
- A move's **target benefit score (TBS)** incentivizes (or discourages) the move's usage on a specific target. A positive TBS indicates the move is better used on the user or its allies, while a negative TBS indicates the move is better used on enemies.
- **The total benefit score (UBS + TBS) of a move should never be 0.** The move selection algorithm assumes the move's benefit score is unimplemented if the total score is 0 and penalizes the move's usage as a result. With status moves especially, it's important to have some form of implementation among the move's attributes to avoid this scenario.
- **Score functions that use formulas should include comments.** If your attribute requires complex logic or formulas to calculate benefit scores, please add comments to explain how the logic works and its intended effect on the enemy's decision making.
- **Score functions that use formulas should include comments.** If your attribute requires complex logic or formulas to calculate benefit scores, please add comments to explain how the logic works and its intended effect on the enemy's decision making.

View File

@ -1,7 +1,7 @@
import tseslint from '@typescript-eslint/eslint-plugin';
import stylisticTs from '@stylistic/eslint-plugin-ts'
import parser from '@typescript-eslint/parser';
// import imports from 'eslint-plugin-import'; // Disabled due to not being compatible with eslint v9
import importX from 'eslint-plugin-import-x';
export default [
{
@ -11,7 +11,7 @@ export default [
parser: parser
},
plugins: {
// imports: imports.configs.recommended // Disabled due to not being compatible with eslint v9
"import-x": importX,
'@stylistic/ts': stylisticTs,
'@typescript-eslint': tseslint
},
@ -39,7 +39,8 @@ export default [
}],
"space-before-blocks": ["error", "always"], // Enforces a space before blocks
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
"comma-spacing": ["error", { "before": false, "after": true }] // Enforces spacing after comma
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
}
}
]

View File

@ -23,15 +23,6 @@ body {
}
}
#links {
width: 90%;
text-align: center;
position: fixed;
bottom: 0;
display: flex;
justify-content: space-around;
}
#app {
display: flex;
justify-content: center;
@ -93,7 +84,7 @@ input:-internal-autofill-selected {
@media (orientation: landscape) {
#touchControls {
--controls-size: 20vh;
--controls-size: 20vh;
--text-shadow-size: 1.3vh;
--small-button-offset: 4vh;
}

View File

@ -39,7 +39,6 @@
</style>
<link rel="stylesheet" type="text/css" href="./index.css" />
<link rel="manifest" href="./manifest.webmanifest">
<script type="text/javascript" src="https://app.termly.io/resource-blocker/c5dbfa2f-9723-4c0f-a84b-2895124e851f?autoBlock=on"></script>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
@ -144,13 +143,6 @@
</div>
</div>
<div id="tnc-links">
<a href="#" class="termly-display-preferences" style="display: none;" target="_blank" rel="noreferrer noopener">Consent Preferences</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=bc96778b-3f04-4d25-bafc-0deba53e8bec" target="_blank" rel="noreferrer noopener">Privacy Policy</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=8b523c05-7ec2-4646-9534-5bd61b386e2a" target="_blank" rel="noreferrer noopener">Cookie Disclaimer</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=b01e092a-9721-477f-8356-45576702ff9e" target="_blank" rel="noreferrer noopener">Terms & Conditions</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=3b5d1928-3f5b-4ee1-b8df-2d6c276b0bcc" target="_blank" rel="noreferrer noopener">Acceptable Use Policy</a>
</div>
<script type="module" src="./src/main.ts"></script>
<script src="./src/touch-controls.ts" type="module"></script>
<script src="./src/debug.js" type="module"></script>

View File

@ -2,6 +2,15 @@ pre-commit:
parallel: true
commands:
eslint:
glob: '*.{js,jsx,ts,tsx}'
glob: "*.{js,jsx,ts,tsx}"
run: npx eslint --fix {staged_files}
stage_fixed: true
stage_fixed: true
skip:
- merge
- rebase
pre-push:
commands:
eslint:
glob: "*.{js,ts,jsx,tsx}"
run: npx eslint --fix {push_files}

200
package-lock.json generated
View File

@ -28,6 +28,7 @@
"@vitest/coverage-istanbul": "^2.0.4",
"dependency-cruiser": "^16.3.10",
"eslint": "^9.7.0",
"eslint-plugin-import-x": "^4.2.1",
"jsdom": "^24.0.0",
"lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8",
@ -2505,6 +2506,19 @@
"node": ">=8"
}
},
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@ -2687,6 +2701,155 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
"integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^3.2.7",
"is-core-module": "^2.13.0",
"resolve": "^1.22.4"
}
},
"node_modules/eslint-import-resolver-node/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import-x": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.2.1.tgz",
"integrity": "sha512-WWi2GedccIJa0zXxx3WDnTgouGQTtdYK1nhXMwywbqqAgB0Ov+p1pYBsWh3VaB0bvBOwLse6OfVII7jZD9xo5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/utils": "^8.1.0",
"debug": "^4.3.4",
"doctrine": "^3.0.0",
"eslint-import-resolver-node": "^0.3.9",
"get-tsconfig": "^4.7.3",
"is-glob": "^4.0.3",
"minimatch": "^9.0.3",
"semver": "^7.6.3",
"stable-hash": "^0.0.4",
"tslib": "^2.6.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/scope-manager": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz",
"integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/types": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz",
"integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz",
"integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/utils": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz",
"integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.5.0",
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/typescript-estree": "8.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz",
"integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-scope": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
@ -3143,6 +3306,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-tsconfig": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz",
"integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==",
"dev": true,
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@ -4854,6 +5030,16 @@
"node": ">=4"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -5069,6 +5255,13 @@
"node": ">=0.10.0"
}
},
"node_modules/stable-hash": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz",
"integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==",
"dev": true,
"license": "MIT"
},
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@ -5460,6 +5653,13 @@
"node": ">=6"
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View File

@ -18,7 +18,8 @@
"eslint-ci": "eslint .",
"docs": "typedoc",
"depcruise": "depcruise src",
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg"
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
"create-test": "node ./create-test-boilerplate.js"
},
"devDependencies": {
"@eslint/js": "^9.3.0",
@ -31,6 +32,7 @@
"@vitest/coverage-istanbul": "^2.0.4",
"dependency-cruiser": "^16.3.10",
"eslint": "^9.7.0",
"eslint-plugin-import-x": "^4.2.1",
"jsdom": "^24.0.0",
"lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8",

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,38 +1,49 @@
{
"0": {
"bc4524": "af5457",
"31638c": "324a26",
"101010": "101010",
"5aa5ce": "40683c",
"a5e6ff": "b6d9ac",
"7bceef": "789c6e",
"ced6ef": "c09e99",
"737384": "774644",
"ce4252": "af2c4f",
"ffffff": "f1dcd8",
"8c4231": "420b0c",
"ffde4a": "c66f68",
"c57b31": "551917",
"ffffad": "f4bfb6",
"ffde4a": "c66f68",
"7bceef": "789c6e",
"a5e6ff": "b6d9ac",
"737384": "774644",
"f7b531": "af5457",
"ce4252": "af2c4f",
"bc4524": "af5457",
"00e5e7": "00e5e7"
"c57b31": "551917",
"ced6ef": "c09e99"
},
"1": {
"bc4524": "3d325e",
"31638c": "143a72",
"101010": "101010",
"5aa5ce": "4060bc",
"a5e6ff": "b4b3ff",
"7bceef": "657ddf",
"ced6ef": "a8b5dd",
"737384": "737384",
"ce4252": "b75558",
"ffffff": "e5ecff",
"8c4231": "17103f",
"ffde4a": "534e72",
"c57b31": "2a1f50",
"ffffad": "87879b",
"ffde4a": "534e72",
"7bceef": "657ddf",
"a5e6ff": "b4b3ff",
"f7b531": "3d325e",
"ce4252": "b75558",
"bc4524": "3d325e",
"00e5e7": "00e5e7"
"c57b31": "2a1f50",
"ced6ef": "a8b5dd"
},
"2": {
"ce4252": "215991",
"ffde4a": "f16f40",
"ffffad": "ffb274",
"737384": "884c43",
"c57b31": "761c03",
"7bceef": "be3d2f",
"8c4231": "5a0700",
"5aa5ce": "892722",
"8c4232": "761c03",
"ffffff": "f5e1d1",
"a5e6ff": "dd533a",
"f7b531": "bc4524",
"ced6ef": "d19e92",
"31638c": "610f0e"
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,22 @@
{
"1": {
"529cc5": "8153c7",
"d65a94": "5ad662",
"3a73ad": "6b3aad",
"bd216b": "21bd69",
"5a193a": "195a2a",
"193a63": "391963",
"295a84": "472984"
},
"2": {
"529cc5": "ffedb6",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"bd216b": "b35131",
"31313a": "3d1519",
"5a193a": "752e2e",
"193a63": "705040",
"295a84": "ad875a",
"4a4a52": "57211a"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1017,7 +1017,7 @@
"279": [
1,
1,
2
1
],
"280": [
0,
@ -1691,8 +1691,8 @@
],
"465": [
0,
2,
2
1,
1
],
"466": [
1,
@ -3980,6 +3980,11 @@
1,
1
],
"465": [
0,
1,
1
],
"592": [
1,
1,
@ -5690,7 +5695,7 @@
"465": [
0,
1,
2
1
],
"466": [
2,
@ -8008,6 +8013,11 @@
1,
1
],
"465": [
0,
1,
1
],
"592": [
1,
1,

View File

@ -8,5 +8,14 @@
"bd216b": "21bd69",
"31313a": "31313a",
"d65a94": "5ad662"
},
"2": {
"5a193a": "752e2e",
"31313a": "3d1519",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"295a84": "ad875a",
"bd216b": "b35131",
"193a63": "705040"
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,21 @@
{
"1": {
"193a63": "391963",
"295a84": "472984",
"3a73ad": "6b3aad",
"000000": "000000",
"5a193a": "195a2a",
"bd216b": "21bd69",
"31313a": "31313a",
"d65a94": "5ad662"
},
"2": {
"5a193a": "752e2e",
"31313a": "3d1519",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"295a84": "ad875a",
"bd216b": "b35131",
"193a63": "705040"
}
}

View File

@ -3,44 +3,36 @@
"bcb9be": "ae4c95",
"f9f2fc": "ffc0e5",
"7b787c": "793d6d",
"e1dfe2": "e88cc5",
"d0cfd0": "ce6bac",
"b8b4ba": "d7d2f6",
"dcd9dd": "e88cc5",
"c9c0ce": "ce6bac",
"cbc2d1": "d7d2f6",
"938f94": "b465b9",
"6c7275": "d3ffff",
"9362e6": "80a4ff",
"fcfcfc": "fcfcfc",
"4a494e": "a7e6e5",
"c6a4ff": "bed5ff",
"101010": "101010",
"3b3a3f": "4d8894",
"aeadae": "e88cc5",
"686568": "686568",
"6f6d71": "793d6d",
"b5b4b6": "ce6bac",
"706e6d": "7d7c75",
"fbf2ff": "d3ffff",
"e66294": "80a4ff",
"c6bbcb": "a7e6e5",
"ffa4c5": "bed5ff",
"7f806a": "4d8894",
"a8a0ac": "e88cc5",
"7c7a78": "793d6d",
"bbb4bc": "ce6bac",
"af9e9e": "42a2b1"
},
"2": {
"bcb9be": "055946",
"f9f2fc": "21be70",
"7b787c": "004140",
"e1dfe2": "12a169",
"d0cfd0": "0a7a57",
"b8b4ba": "567f83",
"dcd9dd": "12a169",
"c9c0ce": "0a7a57",
"cbc2d1": "567f83",
"938f94": "2b5458",
"6c7275": "874059",
"9362e6": "15c05f",
"fcfcfc": "fcfcfc",
"4a494e": "773050",
"c6a4ff": "8ff3a3",
"101010": "101010",
"3b3a3f": "4b1f28",
"aeadae": "12a169",
"686568": "686568",
"6f6d71": "004140",
"b5b4b6": "0a7a57",
"706e6d": "7d7c75",
"fbf2ff": "874059",
"e66294": "15c05f",
"c6bbcb": "773050",
"ffa4c5": "8ff3a3",
"7f806a": "4b1f28",
"a8a0ac": "12a169",
"7c7a78": "004140",
"bbb4bc": "0a7a57",
"af9e9e": "48c492"
}
}
}

View File

@ -0,0 +1,22 @@
{
"1": {
"529cc5": "8153c7",
"d65a94": "5ad662",
"3a73ad": "6b3aad",
"bd216b": "21bd69",
"5a193a": "195a2a",
"193a63": "391963",
"295a84": "472984"
},
"2": {
"529cc5": "ffedb6",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"bd216b": "b35131",
"31313a": "3d1519",
"5a193a": "752e2e",
"193a63": "705040",
"295a84": "ad875a",
"4a4a52": "57211a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

View File

@ -1,3 +1,3 @@
import BattleScene from "#app/battle-scene.js";
import BattleScene from "#app/battle-scene";
export type ConditionFn = (scene: BattleScene, args?: any[]) => boolean;

View File

@ -1,4 +1,4 @@
import { type enConfig } from "#app/locales/en/config.js";
import { type enConfig } from "#app/locales/en/config";
import { TOptions } from "i18next";
//TODO: this needs to be type properly in the future

View File

@ -63,7 +63,7 @@ import { Moves } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme";
import { TimedEventManager } from "#app/timed-event-manager.js";
import { TimedEventManager } from "#app/timed-event-manager";
import i18next from "i18next";
import { TrainerType } from "#enums/trainer-type";
import { battleSpecDialogue } from "./data/dialogue";
@ -130,7 +130,7 @@ export default class BattleScene extends SceneBase {
public gameSpeed: integer = 1;
public damageNumbersMode: integer = 0;
public reroll: boolean = false;
public shopCursorTarget: number = ShopCursorTarget.CHECK_TEAM;
public shopCursorTarget: number = ShopCursorTarget.REWARDS;
public showMovesetFlyout: boolean = true;
public showArenaFlyout: boolean = true;
public showTimeOfDayWidget: boolean = true;
@ -161,6 +161,13 @@ export default class BattleScene extends SceneBase {
public moveAnimations: boolean = true;
public expGainsSpeed: integer = 0;
public skipSeenDialogues: boolean = false;
/**
* Determines if the egg hatching animation should be skipped
* - 0 = Never (never skip animation)
* - 1 = Ask (ask to skip animation when hatching 2 or more eggs)
* - 2 = Always (automatically skip animation when hatching 2 or more eggs)
*/
public eggSkipPreference: number = 0;
/**
* Defines the experience gain display mode.
@ -841,12 +848,13 @@ export default class BattleScene extends SceneBase {
}
addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon {
if (Overrides.OPP_LEVEL_OVERRIDE > 0) {
level = Overrides.OPP_LEVEL_OVERRIDE;
}
if (Overrides.OPP_SPECIES_OVERRIDE) {
species = getPokemonSpecies(Overrides.OPP_SPECIES_OVERRIDE);
}
if (Overrides.OPP_LEVEL_OVERRIDE !== 0) {
level = Overrides.OPP_LEVEL_OVERRIDE;
// The fact that a Pokemon is a boss or not can change based on its Species and level
boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1;
}
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
@ -854,7 +862,7 @@ export default class BattleScene extends SceneBase {
overrideModifiers(this, false);
overrideHeldItems(this, pokemon, false);
if (boss && !dataSource) {
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296));
for (let s = 0; s < pokemon.ivs.length; s++) {
pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75));
@ -960,6 +968,16 @@ export default class BattleScene extends SceneBase {
this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym();
}
/**
* Generates a random number using the current battle's seed
*
* This calls {@linkcode Battle.randSeedInt}(`scene`, {@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`
*
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
*/
randBattleSeedInt(range: integer, min: integer = 0): integer {
return this.currentBattle?.randSeedInt(this, range, min);
}
@ -973,6 +991,7 @@ export default class BattleScene extends SceneBase {
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;
@ -1110,7 +1129,8 @@ export default class BattleScene extends SceneBase {
doubleTrainer = false;
}
}
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, doubleTrainer ? TrainerVariant.DOUBLE : Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT);
const variant = doubleTrainer ? TrainerVariant.DOUBLE : (Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT);
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant);
this.field.add(newTrainer);
}
}
@ -1327,6 +1347,13 @@ export default class BattleScene extends SceneBase {
}
getEncounterBossSegments(waveIndex: integer, level: integer, species?: PokemonSpecies, forceBoss: boolean = false): integer {
if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE > 1) {
return Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE;
} else if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE === 1) {
// The rest of the code expects to be returned 0 and not 1 if the enemy is not a boss
return 0;
}
if (this.gameMode.isDaily && this.gameMode.isWaveFinal(waveIndex)) {
return 5;
}
@ -1791,6 +1818,7 @@ export default class BattleScene extends SceneBase {
config = config ?? {};
try {
const keyDetails = key.split("/");
config["volume"] = config["volume"] ?? 1;
switch (keyDetails[0]) {
case "level_up_fanfare":
case "item_fanfare":
@ -1800,11 +1828,11 @@ export default class BattleScene extends SceneBase {
case "evolution_fanfare":
// These sounds are loaded in as BGM, but played as sound effects
// When these sounds are updated in updateVolume(), they are treated as BGM however because they are placed in the BGM Cache through being called by playSoundWithoutBGM()
config["volume"] = this.masterVolume * this.bgmVolume;
config["volume"] *= (this.masterVolume * this.bgmVolume);
break;
case "battle_anims":
case "cry":
config["volume"] = this.masterVolume * this.fieldVolume;
config["volume"] *= (this.masterVolume * this.fieldVolume);
//PRSFX sound files are unusually loud
if (keyDetails[1].startsWith("PRSFX- ")) {
config["volume"] *= 0.5;
@ -1812,10 +1840,10 @@ export default class BattleScene extends SceneBase {
break;
case "ui":
//As of, right now this applies to the "select", "menu_open", "error" sound effects
config["volume"] = this.masterVolume * this.uiVolume;
config["volume"] *= (this.masterVolume * this.uiVolume);
break;
case "se":
config["volume"] = this.masterVolume * this.seVolume;
config["volume"] *= (this.masterVolume * this.seVolume);
break;
}
this.sound.play(key, config);
@ -2172,8 +2200,14 @@ export default class BattleScene extends SceneBase {
return true;
}
findPhase(phaseFilter: (phase: Phase) => boolean): Phase | undefined {
return this.phaseQueue.find(phaseFilter);
/**
* Find a specific {@linkcode Phase} in the phase queue.
*
* @param phaseFilter filter function to use to find the wanted phase
* @returns the found phase or undefined if none found
*/
findPhase<P extends Phase = Phase>(phaseFilter: (phase: P) => boolean): P | undefined {
return this.phaseQueue.find(phaseFilter) as P;
}
tryReplacePhase(phaseFilter: (phase: Phase) => boolean, phase: Phase): boolean {
@ -2610,7 +2644,7 @@ export default class BattleScene extends SceneBase {
if (mods.length < 1) {
return mods;
}
const rand = Math.floor(Utils.randSeedInt(mods.length));
const rand = Utils.randSeedInt(mods.length);
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
};
modifiers = shuffleModifiers(modifiers);
@ -2732,6 +2766,35 @@ export default class BattleScene extends SceneBase {
(window as any).gameInfo = gameInfo;
}
/**
* This function retrieves the sprite and audio keys for active Pokemon.
* Active Pokemon include both enemy and player Pokemon of the current wave.
* Note: Questions on garbage collection go to @frutescens
* @returns a string array of active sprite and audio keys that should not be deleted
*/
getActiveKeys(): string[] {
const keys: string[] = [];
const playerParty = this.getParty();
playerParty.forEach(p => {
keys.push(p.getSpriteKey(true));
keys.push(p.getBattleSpriteKey(true, true));
keys.push("cry/" + p.species.getCryKey(p.formIndex));
if (p.fusionSpecies) {
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
}
});
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
const enemyParty = this.getEnemyParty();
enemyParty.forEach(p => {
keys.push(p.getSpriteKey(true));
keys.push("cry/" + p.species.getCryKey(p.formIndex));
if (p.fusionSpecies) {
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
}
});
return keys;
}
/**
* Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus)
* @param pokemon The (enemy) pokemon

View File

@ -1,12 +1,12 @@
import BattleScene from "./battle-scene";
import { EnemyPokemon, PlayerPokemon, QueuedMove } from "./field/pokemon";
import { Command } from "./ui/command-ui-handler";
import * as Utils from "./utils";
import Trainer, { TrainerVariant } from "./field/trainer";
import { GameMode } from "./game-mode";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { PokeballType } from "./data/pokeball";
import {trainerConfigs} from "#app/data/trainer-config";
import { trainerConfigs } from "#app/data/trainer-config";
import Pokemon, { EnemyPokemon, PlayerPokemon, QueuedMove } from "#app/field/pokemon";
import { ArenaTagType } from "#enums/arena-tag-type";
import { BattleSpec } from "#enums/battle-spec";
import { Moves } from "#enums/moves";
@ -31,46 +31,55 @@ export enum BattlerIndex {
export interface TurnCommand {
command: Command;
cursor?: integer;
cursor?: number;
move?: QueuedMove;
targets?: BattlerIndex[];
skip?: boolean;
args?: any[];
}
export interface FaintLogEntry {
pokemon: Pokemon,
turn: number
}
interface TurnCommands {
[key: integer]: TurnCommand | null
[key: number]: TurnCommand | null
}
export default class Battle {
protected gameMode: GameMode;
public waveIndex: integer;
public waveIndex: number;
public battleType: BattleType;
public battleSpec: BattleSpec;
public trainer: Trainer | null;
public enemyLevels: integer[] | undefined;
public enemyParty: EnemyPokemon[];
public seenEnemyPartyMemberIds: Set<integer>;
public enemyLevels: number[] | undefined;
public enemyParty: EnemyPokemon[] = [];
public seenEnemyPartyMemberIds: Set<number> = new Set<number>();
public double: boolean;
public started: boolean;
public enemySwitchCounter: integer;
public turn: integer;
public started: boolean = false;
public enemySwitchCounter: number = 0;
public turn: number = 0;
public turnCommands: TurnCommands;
public playerParticipantIds: Set<integer>;
public battleScore: integer;
public postBattleLoot: PokemonHeldItemModifier[];
public escapeAttempts: integer;
public playerParticipantIds: Set<number> = new Set<number>();
public battleScore: number = 0;
public postBattleLoot: PokemonHeldItemModifier[] = [];
public escapeAttempts: number = 0;
public lastMove: Moves;
public battleSeed: string;
private battleSeedState: string | null;
public moneyScattered: number;
public lastUsedPokeball: PokeballType | null;
public playerFaints: number; // The amount of times pokemon on the players side have fainted
public enemyFaints: number; // The amount of times pokemon on the enemies side have fainted
public battleSeed: string = Utils.randomString(16, true);
private battleSeedState: string | null = null;
public moneyScattered: number = 0;
public lastUsedPokeball: PokeballType | null = null;
/** The number of times a Pokemon on the player's side has fainted this battle */
public playerFaints: number = 0;
/** The number of times a Pokemon on the enemy's side has fainted this battle */
public enemyFaints: number = 0;
public playerFaintsHistory: FaintLogEntry[] = [];
public enemyFaintsHistory: FaintLogEntry[] = [];
private rngCounter: integer = 0;
private rngCounter: number = 0;
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer?: Trainer, double?: boolean) {
constructor(gameMode: GameMode, waveIndex: number, battleType: BattleType, trainer?: Trainer, double?: boolean) {
this.gameMode = gameMode;
this.waveIndex = waveIndex;
this.battleType = battleType;
@ -79,22 +88,7 @@ export default class Battle {
this.enemyLevels = battleType !== BattleType.TRAINER
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer?.getPartyLevels(this.waveIndex);
this.enemyParty = [];
this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = !!double;
this.enemySwitchCounter = 0;
this.turn = 0;
this.playerParticipantIds = new Set<integer>();
this.battleScore = 0;
this.postBattleLoot = [];
this.escapeAttempts = 0;
this.started = false;
this.battleSeed = Utils.randomString(16, true);
this.battleSeedState = null;
this.moneyScattered = 0;
this.lastUsedPokeball = null;
this.playerFaints = 0;
this.enemyFaints = 0;
this.double = double ?? false;
}
private initBattleSpec(): void {
@ -105,7 +99,7 @@ export default class Battle {
this.battleSpec = spec;
}
private getLevelForWave(): integer {
private getLevelForWave(): number {
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const bossMultiplier = 1.2;
@ -138,7 +132,7 @@ export default class Battle {
return rand / value;
}
getBattlerCount(): integer {
getBattlerCount(): number {
return this.double ? 2 : 1;
}
@ -367,7 +361,13 @@ export default class Battle {
return null;
}
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
/**
* Generates a random number using the current battle's seed. Calls {@linkcode Utils.randSeedInt}
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
*/
randSeedInt(scene: BattleScene, range: number, min: number = 0): number {
if (range <= 1) {
return min;
}
@ -392,7 +392,7 @@ export default class Battle {
}
export class FixedBattle extends Battle {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
constructor(scene: BattleScene, waveIndex: number, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : undefined, config.double);
if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty(scene);
@ -408,7 +408,7 @@ export class FixedBattleConfig {
public double: boolean;
public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: integer;
public seedOffsetWaveIndex: number;
setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType;
@ -430,7 +430,7 @@ export class FixedBattleConfig {
return this;
}
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
setSeedOffsetWave(seedOffsetWaveIndex: number): FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this;
}
@ -476,7 +476,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
}
export interface FixedBattleConfigs {
[key: integer]: FixedBattleConfig
[key: number]: FixedBattleConfig
}
/**
* Youngster/Lass on 5

View File

@ -1,4 +1,4 @@
import {SettingGamepad} from "#app/system/settings/settings-gamepad.js";
import {SettingGamepad} from "#app/system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
/**

1
src/constants.ts Normal file
View File

@ -0,0 +1 @@
export const PLAYER_PARTY_MAX_SIZE = 6;

773
src/data/ability.ts Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -7,17 +7,17 @@ import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
import { StatusEffect } from "./status-effect";
import { BattlerIndex } from "../battle";
import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
import { BattleStat } from "./battle-stat";
import { Stat } from "#enums/stat";
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
import i18next from "i18next";
import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { MoveEffectPhase } from "#app/phases/move-effect-phase.js";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase.js";
import { StatChangePhase } from "#app/phases/stat-change-phase.js";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
export enum ArenaTagSide {
BOTH,
@ -786,8 +786,8 @@ class StickyWebTag extends ArenaTrapTag {
applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled);
if (!cancelled.value) {
pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() }));
const statLevels = new Utils.NumberHolder(-1);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.SPD], statLevels.value));
const stages = new Utils.NumberHolder(-1);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value));
}
}
@ -875,7 +875,7 @@ class TailwindTag extends ArenaTag {
// Raise attack by one stage if party member has WIND_RIDER ability
if (pokemon.hasAbility(Abilities.WIND_RIDER)) {
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.getBattlerIndex()));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK], 1, true));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK ], 1, true));
}
}
}
@ -905,6 +905,21 @@ class HappyHourTag extends ArenaTag {
}
}
class SafeguardTag extends ArenaTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side);
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(i18next.t(`arenaTag:safeguardOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
onRemove(arena: Arena): void {
arena.scene.queueMessage(i18next.t(`arenaTag:safeguardOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
switch (tagType) {
case ArenaTagType.MIST:
@ -950,6 +965,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
return new TailwindTag(turnCount, sourceId, side);
case ArenaTagType.HAPPY_HOUR:
return new HappyHourTag(turnCount, sourceId, side);
case ArenaTagType.SAFEGUARD:
return new SafeguardTag(turnCount, sourceId, side);
default:
return null;
}

View File

@ -788,10 +788,10 @@ export abstract class BattleAnim {
targetSprite.pipelineData["tone"] = [ 0.0, 0.0, 0.0, 0.0 ];
targetSprite.setAngle(0);
if (!this.isHideUser() && userSprite) {
userSprite.setVisible(true);
this.user?.getSprite().setVisible(true); // using this.user to fix context loss due to isOppAnim swap (#481)
}
if (!this.isHideTarget() && (targetSprite !== userSprite || !this.isHideUser())) {
targetSprite.setVisible(true);
this.target?.getSprite().setVisible(true); // using this.target to fix context loss due to isOppAnim swap (#481)
}
for (const ms of Object.values(spriteCache).flat()) {
if (ms) {

View File

@ -1,71 +0,0 @@
import i18next, { ParseKeys } from "i18next";
export enum BattleStat {
ATK,
DEF,
SPATK,
SPDEF,
SPD,
ACC,
EVA,
RAND,
HP
}
export function getBattleStatName(stat: BattleStat) {
switch (stat) {
case BattleStat.ATK:
return i18next.t("pokemonInfo:Stat.ATK");
case BattleStat.DEF:
return i18next.t("pokemonInfo:Stat.DEF");
case BattleStat.SPATK:
return i18next.t("pokemonInfo:Stat.SPATK");
case BattleStat.SPDEF:
return i18next.t("pokemonInfo:Stat.SPDEF");
case BattleStat.SPD:
return i18next.t("pokemonInfo:Stat.SPD");
case BattleStat.ACC:
return i18next.t("pokemonInfo:Stat.ACC");
case BattleStat.EVA:
return i18next.t("pokemonInfo:Stat.EVA");
case BattleStat.HP:
return i18next.t("pokemonInfo:Stat.HPStat");
default:
return "???";
}
}
export function getBattleStatLevelChangeDescription(pokemonNameWithAffix: string, stats: string, levels: integer, up: boolean, count: number = 1) {
const stringKey = (() => {
if (up) {
switch (levels) {
case 1:
return "battle:statRose";
case 2:
return "battle:statSharplyRose";
case 3:
case 4:
case 5:
case 6:
return "battle:statRoseDrastically";
default:
return "battle:statWontGoAnyHigher";
}
} else {
switch (levels) {
case 1:
return "battle:statFell";
case 2:
return "battle:statHarshlyFell";
case 3:
case 4:
case 5:
case 6:
return "battle:statSeverelyFell";
default:
return "battle:statWontGoAnyLower";
}
}
})();
return i18next.t(stringKey as ParseKeys, { pokemonNameWithAffix, stats, count });
}

View File

@ -1,7 +1,6 @@
import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "./battle-anims";
import { getPokemonNameWithAffix } from "../messages";
import Pokemon, { MoveResult, HitResult } from "../field/pokemon";
import { Stat, getStatName } from "./pokemon-stat";
import { StatusEffect } from "./status-effect";
import * as Utils from "../utils";
import { ChargeAttr, MoveFlags, allMoves } from "./move";
@ -9,20 +8,20 @@ import { Type } from "./type";
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability";
import { TerrainType } from "./terrain";
import { WeatherType } from "./weather";
import { BattleStat } from "./battle-stat";
import { allAbilities } from "./ability";
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "#enums/abilities";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import i18next from "#app/plugins/i18n.js";
import { CommonAnimPhase } from "#app/phases/common-anim-phase.js";
import { MoveEffectPhase } from "#app/phases/move-effect-phase.js";
import { MovePhase } from "#app/phases/move-phase.js";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase.js";
import { StatChangePhase, StatChangeCallback } from "#app/phases/stat-change-phase.js";
import i18next from "#app/plugins/i18n";
import { Stat, type BattleStat, type EffectiveStat, EFFECTIVE_STATS, getStatKey } from "#app/enums/stat";
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MovePhase } from "#app/phases/move-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatStageChangePhase, StatStageChangeCallback } from "#app/phases/stat-stage-change-phase";
export enum BattlerTagLapseType {
FAINT,
@ -40,13 +39,15 @@ export class BattlerTag {
public turnCount: number;
public sourceMove: Moves;
public sourceId?: number;
public isBatonPassable: boolean;
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number) {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number, isBatonPassable: boolean = false) {
this.tagType = tagType;
this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ];
this.turnCount = turnCount;
this.sourceMove = sourceMove!; // TODO: is this bang correct?
this.sourceId = sourceId;
this.isBatonPassable = isBatonPassable;
}
canAdd(pokemon: Pokemon): boolean {
@ -97,6 +98,245 @@ export interface TerrainBattlerTag {
terrainTypes: TerrainType[];
}
/**
* Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move
* in-game. This is not to be confused with {@linkcode Moves.DISABLE}.
*
* Descendants can override {@linkcode isMoveRestricted} to restrict moves that
* match a condition. A restricted move gets cancelled before it is used. Players and enemies should not be allowed
* to select restricted moves.
*/
export abstract class MoveRestrictionBattlerTag extends BattlerTag {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: integer, sourceMove?: Moves, sourceId?: integer) {
super(tagType, lapseType, turnCount, sourceMove, sourceId);
}
/** @override */
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
// Cancel the affected pokemon's selected move
const phase = pokemon.scene.getCurrentPhase() as MovePhase;
const move = phase.move;
if (this.isMoveRestricted(move.moveId)) {
if (this.interruptedText(pokemon, move.moveId)) {
pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId));
}
phase.cancel();
}
return true;
}
return super.lapse(pokemon, lapseType);
}
/**
* Gets whether this tag is restricting a move.
*
* @param {Moves} move {@linkcode Moves} ID to check restriction for.
* @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`.
*/
abstract isMoveRestricted(move: Moves): boolean;
/**
* Gets the text to display when the player attempts to select a move that is restricted by this tag.
*
* @param {Pokemon} pokemon {@linkcode Pokemon} for which the player is attempting to select the restricted move
* @param {Moves} move {@linkcode Moves} ID of the move that is having its selection denied
* @returns {string} text to display when the player attempts to select the restricted move
*/
abstract selectionDeniedText(pokemon: Pokemon, move: Moves): string;
/**
* Gets the text to display when a move's execution is prevented as a result of the restriction.
* Because restriction effects also prevent selection of the move, this situation can only arise if a
* pokemon first selects a move, then gets outsped by a pokemon using a move that restricts the selected move.
*
* @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move
* @param {Moves} move {@linkcode Moves} ID of the move being interrupted
* @returns {string} text to display when the move is interrupted
*/
interruptedText(pokemon: Pokemon, move: Moves): string {
return "";
}
}
/**
* Tag representing the "Throat Chop" effect. Pokemon with this tag cannot use sound-based moves.
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Throat_Chop_(move) | Throat Chop}
* @extends MoveRestrictionBattlerTag
*/
export class ThroatChoppedTag extends MoveRestrictionBattlerTag {
constructor() {
super(BattlerTagType.THROAT_CHOPPED, [ BattlerTagLapseType.TURN_END, BattlerTagLapseType.PRE_MOVE ], 2, Moves.THROAT_CHOP);
}
/**
* Checks if a {@linkcode Moves | move} is restricted by Throat Chop.
* @override
* @param {Moves} move the {@linkcode Moves | move} to check for sound-based restriction
* @returns true if the move is sound-based
*/
override isMoveRestricted(move: Moves): boolean {
return allMoves[move].hasFlag(MoveFlags.SOUND_BASED);
}
/**
* Shows a message when the player attempts to select a move that is restricted by Throat Chop.
* @override
* @param {Pokemon} pokemon the {@linkcode Pokemon} that is attempting to select the restricted move
* @param {Moves} move the {@linkcode Moves | move} that is being restricted
* @returns the message to display when the player attempts to select the restricted move
*/
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
}
/**
* Shows a message when a move is interrupted by Throat Chop.
* @override
* @param {Pokemon} pokemon the interrupted {@linkcode Pokemon}
* @param {Moves} move the {@linkcode Moves | move} that was interrupted
* @returns the message to display when the move is interrupted
*/
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:throatChopInterruptedMove", { pokemonName: getPokemonNameWithAffix(pokemon) });
}
}
/**
* Tag representing the "disabling" effect performed by {@linkcode Moves.DISABLE} and {@linkcode Abilities.CURSED_BODY}.
* When the tag is added, the last-used move of the tag holder is set as the disabled move.
*/
export class DisabledTag extends MoveRestrictionBattlerTag {
/** The move being disabled. Gets set when {@linkcode onAdd} is called for this tag. */
private moveId: Moves = Moves.NONE;
constructor(sourceId: number) {
super(BattlerTagType.DISABLED, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], 4, Moves.DISABLE, sourceId);
}
/** @override */
override isMoveRestricted(move: Moves): boolean {
return move === this.moveId;
}
/**
* @override
*
* Ensures that move history exists on `pokemon` and has a valid move. If so, sets the {@linkcode moveId} and shows a message.
* Otherwise the move ID will not get assigned and this tag will get removed next turn.
*/
override onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
const move = pokemon.getLastXMoves()
.find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual);
if (move === undefined) {
return;
}
this.moveId = move.move;
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
override onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
}
/**
* @override
* @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move
* @param {Moves} move {@linkcode Moves} ID of the move being interrupted
* @returns {string} text to display when the move is interrupted
*/
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
/** @override */
override loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.moveId = source.moveId;
}
}
/**
* Tag used by Gorilla Tactics to restrict the user to using only one move.
* @extends MoveRestrictionBattlerTag
*/
export class GorillaTacticsTag extends MoveRestrictionBattlerTag {
private moveId = Moves.NONE;
constructor() {
super(BattlerTagType.GORILLA_TACTICS, BattlerTagLapseType.CUSTOM, 0);
}
/** @override */
override isMoveRestricted(move: Moves): boolean {
return move !== this.moveId;
}
/**
* @override
* @param {Pokemon} pokemon the {@linkcode Pokemon} to check if the tag can be added
* @returns `true` if the pokemon has a valid move and no existing {@linkcode GorillaTacticsTag}; `false` otherwise
*/
override canAdd(pokemon: Pokemon): boolean {
return (this.getLastValidMove(pokemon) !== undefined) && !pokemon.getTag(GorillaTacticsTag);
}
/**
* Ensures that move history exists on {@linkcode Pokemon} and has a valid move.
* If so, sets the {@linkcode moveId} and increases the user's Attack by 50%.
* @override
* @param {Pokemon} pokemon the {@linkcode Pokemon} to add the tag to
*/
override onAdd(pokemon: Pokemon): void {
const lastValidMove = this.getLastValidMove(pokemon);
if (!lastValidMove) {
return;
}
this.moveId = lastValidMove;
pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.ATK, false) * 1.5, false);
}
/**
*
* @override
* @param {Pokemon} pokemon n/a
* @param {Moves} move {@linkcode Moves} ID of the move being denied
* @returns {string} text to display when the move is denied
*/
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:canOnlyUseMove", { moveName: allMoves[this.moveId].name, pokemonName: getPokemonNameWithAffix(pokemon) });
}
/**
* Gets the last valid move from the pokemon's move history.
* @param {Pokemon} pokemon {@linkcode Pokemon} to get the last valid move from
* @returns {Moves | undefined} the last valid move from the pokemon's move history
*/
getLastValidMove(pokemon: Pokemon): Moves | undefined {
const move = pokemon.getLastXMoves()
.find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual);
return move?.move;
}
}
/**
* BattlerTag that represents the "recharge" effects of moves like Hyper Beam.
*/
@ -207,12 +447,12 @@ export class ShellTrapTag extends BattlerTag {
export class TrappedTag extends BattlerTag {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, lapseType, turnCount, sourceMove, sourceId);
super(tagType, lapseType, turnCount, sourceMove, sourceId, true);
}
canAdd(pokemon: Pokemon): boolean {
const isGhost = pokemon.isOfType(Type.GHOST);
const isTrapped = pokemon.getTag(BattlerTagType.TRAPPED);
const isTrapped = pokemon.getTag(TrappedTag);
return !isTrapped && !isGhost;
}
@ -245,6 +485,23 @@ export class TrappedTag extends BattlerTag {
}
}
/**
* BattlerTag implementing No Retreat's trapping effect.
* This is treated separately from other trapping effects to prevent
* Ghost-type Pokemon from being able to reuse the move.
* @extends TrappedTag
*/
class NoRetreatTag extends TrappedTag {
constructor(sourceId: number) {
super(BattlerTagType.NO_RETREAT, BattlerTagLapseType.CUSTOM, 0, Moves.NO_RETREAT, sourceId);
}
/** overrides {@linkcode TrappedTag.apply}, removing the Ghost-type condition */
canAdd(pokemon: Pokemon): boolean {
return !pokemon.getTag(TrappedTag);
}
}
/**
* BattlerTag that represents the {@link https://bulbapedia.bulbagarden.net/wiki/Flinch Flinch} status condition
*/
@ -310,7 +567,7 @@ export class InterruptedTag extends BattlerTag {
*/
export class ConfusedTag extends BattlerTag {
constructor(turnCount: number, sourceMove: Moves) {
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove);
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove, undefined, true);
}
canAdd(pokemon: Pokemon): boolean {
@ -345,9 +602,9 @@ export class ConfusedTag extends BattlerTag {
// 1/3 chance of hitting self with a 40 base power move
if (pokemon.randSeedInt(3) === 0) {
const atk = pokemon.getBattleStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF);
const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
const atk = pokemon.getEffectiveStat(Stat.ATK);
const def = pokemon.getEffectiveStat(Stat.DEF);
const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100) / 100));
pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++;
@ -370,7 +627,7 @@ export class ConfusedTag extends BattlerTag {
*/
export class DestinyBondTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: number) {
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId);
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId, true);
}
/**
@ -489,7 +746,7 @@ export class SeedTag extends BattlerTag {
private sourceIndex: number;
constructor(sourceId: number) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId, true);
}
/**
@ -750,7 +1007,7 @@ export class OctolockTag extends TrappedTag {
const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (shouldLapse) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.DEF, BattleStat.SPDEF], -1));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.DEF, Stat.SPDEF ], -1));
return true;
}
@ -760,7 +1017,7 @@ export class OctolockTag extends TrappedTag {
export class AquaRingTag extends BattlerTag {
constructor() {
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined);
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined, true);
}
onAdd(pokemon: Pokemon): void {
@ -792,7 +1049,7 @@ export class AquaRingTag extends BattlerTag {
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
export class MinimizeTag extends BattlerTag {
constructor() {
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE, undefined);
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE);
}
canAdd(pokemon: Pokemon): boolean {
@ -864,7 +1121,7 @@ export abstract class DamagingTrapTag extends TrappedTag {
}
canAdd(pokemon: Pokemon): boolean {
return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag);
return !pokemon.getTag(TrappedTag);
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1041,6 +1298,13 @@ export class ProtectedTag extends BattlerTag {
}
}
/** Base class for `BattlerTag`s that block damaging moves but not status moves */
export class DamageProtectedTag extends ProtectedTag {}
/**
* `BattlerTag` class for moves that block damaging moves damage the enemy if the enemy's move makes contact
* Used by {@linkcode Moves.SPIKY_SHIELD}
*/
export class ContactDamageProtectedTag extends ProtectedTag {
private damageRatio: number;
@ -1076,7 +1340,11 @@ export class ContactDamageProtectedTag extends ProtectedTag {
}
}
export class ContactStatChangeProtectedTag extends ProtectedTag {
/**
* `BattlerTag` class for moves that block damaging moves and lower enemy stats if the enemy's move makes contact
* Used by {@linkcode Moves.KINGS_SHIELD}, {@linkcode Moves.OBSTRUCT}, {@linkcode Moves.SILK_TRAP}
*/
export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
private stat: BattleStat;
private levels: number;
@ -1093,7 +1361,7 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.stat = source.stat as BattleStat;
this.stat = source.stat;
this.levels = source.levels;
}
@ -1104,7 +1372,7 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
const effectPhase = pokemon.scene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon();
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels));
}
}
@ -1132,7 +1400,11 @@ export class ContactPoisonProtectedTag extends ProtectedTag {
}
}
export class ContactBurnProtectedTag extends ProtectedTag {
/**
* `BattlerTag` class for moves that block damaging moves and burn the enemy if the enemy's move makes contact
* Used by {@linkcode Moves.BURNING_BULWARK}
*/
export class ContactBurnProtectedTag extends DamageProtectedTag {
constructor(sourceMove: Moves) {
super(sourceMove, BattlerTagType.BURNING_BULWARK);
}
@ -1190,7 +1462,7 @@ export class SturdyTag extends BattlerTag {
export class PerishSongTag extends BattlerTag {
constructor(turnCount: number) {
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG);
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG, undefined, true);
}
canAdd(pokemon: Pokemon): boolean {
@ -1246,7 +1518,7 @@ export class AbilityBattlerTag extends BattlerTag {
public ability: Abilities;
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
super(tagType, lapseType, turnCount, undefined);
super(tagType, lapseType, turnCount);
this.ability = ability;
}
@ -1331,11 +1603,10 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
const stats = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
let highestStat: Stat;
stats.map(s => pokemon.getBattleStat(s)).reduce((highestValue: number, value: number, i: number) => {
let highestStat: EffectiveStat;
EFFECTIVE_STATS.map(s => pokemon.getEffectiveStat(s)).reduce((highestValue: number, value: number, i: number) => {
if (value > highestValue) {
highestStat = stats[i];
highestStat = EFFECTIVE_STATS[i];
return value;
}
return highestValue;
@ -1353,7 +1624,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
break;
}
pokemon.scene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: getStatName(highestStat) }), null, false, null, true);
pokemon.scene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true);
}
onRemove(pokemon: Pokemon): void {
@ -1423,7 +1694,7 @@ export class TypeImmuneTag extends BattlerTag {
public immuneType: Type;
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) {
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove);
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove, undefined, true);
this.immuneType = immuneType;
}
@ -1487,7 +1758,7 @@ export class TypeBoostTag extends BattlerTag {
export class CritBoostTag extends BattlerTag {
constructor(tagType: BattlerTagType, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
}
onAdd(pokemon: Pokemon): void {
@ -1507,6 +1778,25 @@ export class CritBoostTag extends BattlerTag {
}
}
/**
* Tag for the effects of Dragon Cheer, which boosts the critical hit ratio of the user's allies.
* @extends {CritBoostTag}
*/
export class DragonCheerTag extends CritBoostTag {
/** The types of the user's ally when the tag is added */
public typesOnAdd: Type[];
constructor() {
super(BattlerTagType.CRIT_BOOST, Moves.DRAGON_CHEER);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
this.typesOnAdd = pokemon.getTypes(true);
}
}
export class SaltCuredTag extends BattlerTag {
private sourceIndex: number;
@ -1560,7 +1850,7 @@ export class CursedTag extends BattlerTag {
private sourceIndex: number;
constructor(sourceId: number) {
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId, true);
}
/**
@ -1678,25 +1968,25 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag {
*/
export class StockpilingTag extends BattlerTag {
public stockpiledCount: number = 0;
public statChangeCounts: { [BattleStat.DEF]: number; [BattleStat.SPDEF]: number } = {
[BattleStat.DEF]: 0,
[BattleStat.SPDEF]: 0
public statChangeCounts: { [Stat.DEF]: number; [Stat.SPDEF]: number } = {
[Stat.DEF]: 0,
[Stat.SPDEF]: 0
};
constructor(sourceMove: Moves = Moves.NONE) {
super(BattlerTagType.STOCKPILING, BattlerTagLapseType.CUSTOM, 1, sourceMove);
}
private onStatsChanged: StatChangeCallback = (_, statsChanged, statChanges) => {
const defChange = statChanges[statsChanged.indexOf(BattleStat.DEF)] ?? 0;
const spDefChange = statChanges[statsChanged.indexOf(BattleStat.SPDEF)] ?? 0;
private onStatStagesChanged: StatStageChangeCallback = (_, statsChanged, statChanges) => {
const defChange = statChanges[statsChanged.indexOf(Stat.DEF)] ?? 0;
const spDefChange = statChanges[statsChanged.indexOf(Stat.SPDEF)] ?? 0;
if (defChange) {
this.statChangeCounts[BattleStat.DEF]++;
this.statChangeCounts[Stat.DEF]++;
}
if (spDefChange) {
this.statChangeCounts[BattleStat.SPDEF]++;
this.statChangeCounts[Stat.SPDEF]++;
}
};
@ -1704,8 +1994,8 @@ export class StockpilingTag extends BattlerTag {
super.loadTag(source);
this.stockpiledCount = source.stockpiledCount || 0;
this.statChangeCounts = {
[ BattleStat.DEF ]: source.statChangeCounts?.[ BattleStat.DEF ] ?? 0,
[ BattleStat.SPDEF ]: source.statChangeCounts?.[ BattleStat.SPDEF ] ?? 0,
[ Stat.DEF ]: source.statChangeCounts?.[ Stat.DEF ] ?? 0,
[ Stat.SPDEF ]: source.statChangeCounts?.[ Stat.SPDEF ] ?? 0,
};
}
@ -1725,9 +2015,9 @@ export class StockpilingTag extends BattlerTag {
}));
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
pokemon.scene.unshiftPhase(new StatChangePhase(
pokemon.scene.unshiftPhase(new StatStageChangePhase(
pokemon.scene, pokemon.getBattlerIndex(), true,
[BattleStat.SPDEF, BattleStat.DEF], 1, true, false, true, this.onStatsChanged
[Stat.SPDEF, Stat.DEF], 1, true, false, true, this.onStatStagesChanged
));
}
}
@ -1741,15 +2031,15 @@ export class StockpilingTag extends BattlerTag {
* one stage for each stack which had successfully changed that particular stat during onAdd.
*/
onRemove(pokemon: Pokemon): void {
const defChange = this.statChangeCounts[BattleStat.DEF];
const spDefChange = this.statChangeCounts[BattleStat.SPDEF];
const defChange = this.statChangeCounts[Stat.DEF];
const spDefChange = this.statChangeCounts[Stat.SPDEF];
if (defChange) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.DEF], -defChange, true, false, true));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF ], -defChange, true, false, true));
}
if (spDefChange) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.SPDEF], -spDefChange, true, false, true));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPDEF ], -spDefChange, true, false, true));
}
}
}
@ -1827,7 +2117,38 @@ export class ExposedTag extends BattlerTag {
}
}
/**
* Tag that doubles the type effectiveness of Fire-type moves.
* @extends BattlerTag
*/
export class TarShotTag extends BattlerTag {
constructor() {
super(BattlerTagType.TAR_SHOT, BattlerTagLapseType.CUSTOM, 0);
}
/**
* If the Pokemon is terastallized, the tag cannot be added.
* @param {Pokemon} pokemon the {@linkcode Pokemon} to which the tag is added
* @returns whether the tag is applied
*/
override canAdd(pokemon: Pokemon): boolean {
return !pokemon.isTerastallized();
}
override onAdd(pokemon: Pokemon): void {
pokemon.scene.queueMessage(i18next.t("battlerTags:tarShotOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
/**
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
*
* @param {BattlerTagType} tagType the type of the {@linkcode BattlerTagType}.
* @param turnCount the turn count.
* @param {Moves} sourceMove the source {@linkcode Moves}.
* @param sourceId the source ID.
* @returns {BattlerTag} the corresponding {@linkcode BattlerTag} object.
*/
export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag {
switch (tagType) {
case BattlerTagType.RECHARGING:
@ -1864,6 +2185,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new DrowsyTag();
case BattlerTagType.TRAPPED:
return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
case BattlerTagType.NO_RETREAT:
return new NoRetreatTag(sourceId);
case BattlerTagType.BIND:
return new BindTag(turnCount, sourceId);
case BattlerTagType.WRAP:
@ -1889,11 +2212,11 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
case BattlerTagType.SPIKY_SHIELD:
return new ContactDamageProtectedTag(sourceMove, 8);
case BattlerTagType.KINGS_SHIELD:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.ATK, -1);
return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.ATK, -1);
case BattlerTagType.OBSTRUCT:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.DEF, -2);
return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.DEF, -2);
case BattlerTagType.SILK_TRAP:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.SPD, -1);
return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1);
case BattlerTagType.BANEFUL_BUNKER:
return new ContactPoisonProtectedTag(sourceMove);
case BattlerTagType.BURNING_BULWARK:
@ -1923,6 +2246,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new TypeBoostTag(tagType, sourceMove, Type.FIRE, 1.5, false);
case BattlerTagType.CRIT_BOOST:
return new CritBoostTag(tagType, sourceMove);
case BattlerTagType.DRAGON_CHEER:
return new DragonCheerTag();
case BattlerTagType.ALWAYS_CRIT:
case BattlerTagType.IGNORE_ACCURACY:
return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove);
@ -1955,6 +2280,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new StockpilingTag(sourceMove);
case BattlerTagType.OCTOLOCK:
return new OctolockTag(sourceId);
case BattlerTagType.DISABLED:
return new DisabledTag(sourceId);
case BattlerTagType.IGNORE_GHOST:
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
case BattlerTagType.IGNORE_DARK:
@ -1962,6 +2289,12 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
case BattlerTagType.GULP_MISSILE_ARROKUDA:
case BattlerTagType.GULP_MISSILE_PIKACHU:
return new GulpMissileTag(tagType, sourceMove);
case BattlerTagType.TAR_SHOT:
return new TarShotTag();
case BattlerTagType.THROAT_CHOPPED:
return new ThroatChoppedTag();
case BattlerTagType.GORILLA_TACTICS:
return new GorillaTacticsTag();
case BattlerTagType.NONE:
default:
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);

View File

@ -1,14 +1,14 @@
import { getPokemonNameWithAffix } from "../messages";
import Pokemon, { HitResult } from "../field/pokemon";
import { BattleStat } from "./battle-stat";
import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from "i18next";
import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js";
import { StatChangePhase } from "#app/phases/stat-change-phase.js";
import { Stat, type BattleStat } from "#app/enums/stat";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`);
@ -35,9 +35,10 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
case BerryType.SALAC:
return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25);
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
// Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const stat: BattleStat = berryType - BerryType.ENIGMA;
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6;
return pokemon.getHpRatio() < threshold.value && pokemon.getStatStage(stat) < 6;
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
@ -95,10 +96,11 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
const statLevels = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value));
// Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const stat: BattleStat = berryType - BerryType.ENIGMA;
const statStages = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value));
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
@ -112,9 +114,10 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType);
}
const statLevels = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK);
const stages = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value));
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {

View File

@ -1,6 +1,6 @@
import { Type } from "./type";
import * as Utils from "../utils";
import {pokemonEvolutions, SpeciesFormEvolution} from "./pokemon-evolutions";
import { pokemonEvolutions, SpeciesFormEvolution } from "./pokemon-evolutions";
import i18next from "i18next";
import { Biome } from "#enums/biome";
import { Species } from "#enums/species";
@ -46,7 +46,7 @@ export const biomeLinks: BiomeLinks = {
[Biome.SEABED]: [ Biome.CAVE, [ Biome.VOLCANO, 3 ] ],
[Biome.MOUNTAIN]: [ Biome.VOLCANO, [ Biome.WASTELAND, 2 ], [ Biome.SPACE, 3 ] ],
[Biome.BADLANDS]: [ Biome.DESERT, Biome.MOUNTAIN ],
[Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE [ Biome.LABORATORY, 2 ] ],
[Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE, [ Biome.LABORATORY, 2 ] ],
[Biome.DESERT]: [ Biome.RUINS, [ Biome.CONSTRUCTION_SITE, 2 ] ],
[Biome.ICE_CAVE]: Biome.SNOWY_FOREST,
[Biome.MEADOW]: [ Biome.PLAINS, Biome.FAIRY_CAVE ],
@ -7666,7 +7666,7 @@ export function initBiomes() {
if (biome === Biome.END) {
const biomeList = Object.keys(Biome).filter(key => !isNaN(Number(key)));
biomeList.pop(); // Removes Biome.END from the list
const randIndex = Utils.randInt(biomeList.length, 2); // Will never be Biome.TOWN or Biome.PLAINS
const randIndex = Utils.randInt(biomeList.length, 1); // Will never be Biome.TOWN
biome = Biome[biomeList[randIndex]];
}
const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome])

View File

@ -1,19 +1,18 @@
import * as Utils from "../utils";
import i18next from "i18next";
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data.js";
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data";
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
import Pokemon, { PokemonMove } from "#app/field/pokemon.js";
import { BattleType, FixedBattleConfig } from "#app/battle.js";
import Trainer, { TrainerVariant } from "#app/field/trainer.js";
import { GameMode } from "#app/game-mode.js";
import Pokemon, { PokemonMove } from "#app/field/pokemon";
import { BattleType, FixedBattleConfig } from "#app/battle";
import Trainer, { TrainerVariant } from "#app/field/trainer";
import { GameMode } from "#app/game-mode";
import { Type } from "./type";
import { Challenges } from "#enums/challenges";
import { Species } from "#enums/species";
import { TrainerType } from "#enums/trainer-type";
import { Nature } from "./nature";
import { Moves } from "#app/enums/moves.js";
import { TypeColor, TypeShadow } from "#app/enums/color.js";
import { Gender } from "./gender";
import { Moves } from "#app/enums/moves";
import { TypeColor, TypeShadow } from "#app/enums/color";
import { pokemonEvolutions } from "./pokemon-evolutions";
import { pokemonFormChanges } from "./pokemon-forms";
@ -659,7 +658,6 @@ export class FreshStartChallenge extends Challenge {
pokemon.luck = 0; // No luck
pokemon.shiny = false; // Not shiny
pokemon.variant = 0; // Not shiny
pokemon.gender = Gender.MALE; // Starters default to male
pokemon.formIndex = 0; // Froakie should be base form
pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats
return true;

View File

@ -1,6 +1,6 @@
import { BattleSpec } from "#enums/battle-spec";
import { TrainerType } from "#enums/trainer-type";
import {trainerConfigs} from "./trainer-config";
import { trainerConfigs } from "./trainer-config";
export interface TrainerTypeMessages {
encounter?: string | string[],
@ -707,6 +707,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
]
}
],
[TrainerType.ROOD]: [
{
encounter: [
"dialogue:rood.encounter.1",
"dialogue:rood.encounter.2",
"dialogue:rood.encounter.3",
],
victory: [
"dialogue:rood.victory.1",
"dialogue:rood.victory.2",
"dialogue:rood.victory.3",
]
}
],
[TrainerType.FLARE_GRUNT]: [
{
encounter: [
@ -1555,8 +1569,7 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
"dialogue:roark.victory.1",
"dialogue:roark.victory.2",
"dialogue:roark.victory.3",
"dialogue:roark.victory.4",
"dialogue:roark.victory.5"
"dialogue:roark.victory.4"
],
defeat: [
"dialogue:roark.defeat.1",

View File

@ -0,0 +1,98 @@
import BattleScene from "#app/battle-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import { DexEntry, StarterDataEntry } from "#app/system/game-data";
/**
* Stores data associated with a specific egg and the hatched pokemon
* Allows hatch info to be stored at hatch then retrieved for display during egg summary
*/
export class EggHatchData {
/** the pokemon that hatched from the file (including shiny, IVs, ability) */
public pokemon: PlayerPokemon;
/** index of the egg move from the hatched pokemon (not stored in PlayerPokemon) */
public eggMoveIndex: number;
/** boolean indicating if the egg move for the hatch is new */
public eggMoveUnlocked: boolean;
/** stored copy of the hatched pokemon's dex entry before it was updated due to hatch */
public dexEntryBeforeUpdate: DexEntry;
/** stored copy of the hatched pokemon's starter entry before it was updated due to hatch */
public starterDataEntryBeforeUpdate: StarterDataEntry;
/** reference to the battle scene to get gamedata and update dex */
private scene: BattleScene;
constructor(scene: BattleScene, pokemon: PlayerPokemon, eggMoveIndex: number) {
this.scene = scene;
this.pokemon = pokemon;
this.eggMoveIndex = eggMoveIndex;
}
/**
* Sets the boolean for if the egg move for the hatch is a new unlock
* @param unlocked True if the EM is new
*/
setEggMoveUnlocked(unlocked: boolean) {
this.eggMoveUnlocked = unlocked;
}
/**
* Stores a copy of the current DexEntry of the pokemon and StarterDataEntry of its starter
* Used before updating the dex, so comparing the pokemon to these entries will show the new attributes
*/
setDex() {
const currDexEntry = this.scene.gameData.dexData[this.pokemon.species.speciesId];
const currStarterDataEntry = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()];
this.dexEntryBeforeUpdate = {
seenAttr: currDexEntry.seenAttr,
caughtAttr: currDexEntry.caughtAttr,
natureAttr: currDexEntry.natureAttr,
seenCount: currDexEntry.seenCount,
caughtCount: currDexEntry.caughtCount,
hatchedCount: currDexEntry.hatchedCount,
ivs: [...currDexEntry.ivs]
};
this.starterDataEntryBeforeUpdate = {
moveset: currStarterDataEntry.moveset,
eggMoves: currStarterDataEntry.eggMoves,
candyCount: currStarterDataEntry.candyCount,
friendship: currStarterDataEntry.friendship,
abilityAttr: currStarterDataEntry.abilityAttr,
passiveAttr: currStarterDataEntry.passiveAttr,
valueReduction: currStarterDataEntry.valueReduction,
classicWinCount: currStarterDataEntry.classicWinCount
};
}
/**
* Gets the dex entry before update
* @returns Dex Entry corresponding to this pokemon before the pokemon was added / updated to dex
*/
getDex(): DexEntry {
return this.dexEntryBeforeUpdate;
}
/**
* Gets the starter dex entry before update
* @returns Starter Dex Entry corresponding to this pokemon before the pokemon was added / updated to dex
*/
getStarterEntry(): StarterDataEntry {
return this.starterDataEntryBeforeUpdate;
}
/**
* Update the pokedex data corresponding with the new hatch's pokemon data
* Also sets whether the egg move is a new unlock or not
* @param showMessage boolean to show messages for the new catches and egg moves (false by default)
* @returns
*/
updatePokemon(showMessage : boolean = false) {
return new Promise<void>(resolve => {
this.scene.gameData.setPokemonCaught(this.pokemon, true, true, showMessage).then(() => {
this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
this.scene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex, showMessage).then((value) => {
this.setEggMoveUnlocked(value);
resolve();
});
});
});
}
}

Some files were not shown because too many files have changed in this diff Show More