Compare commits

...

63 Commits

Author SHA1 Message Date
Madmadness65
eaf25551c1
Merge branch 'main' into plates_memories 2024-05-26 00:49:32 -05:00
SnowCharm
a2996cdd66
add zh_CN biome.ts (#1389) 2024-05-26 00:33:14 -05:00
Nicholas Galauxy
9aa22d6150
Bugfix: In-Battle Formes are incorrectly selectable (#1388)
* Fix incorrectly unselectable starter formes

* Fix linter issue that got merged upstream

* Remove battle-bond key from form key overrides based on feedback

* Fixes being able to select forms that shouldn't be startable

* Add Minior Cores as cycleable

* Remove unused code from previous implementation
2024-05-25 22:31:42 -05:00
Matthew Olker
44f4f14956 Update Artist Sprite Fixes 2024-05-25 23:08:36 -04:00
Greenlamp2
b170478119
fix conflict without rebase (#1186) 2024-05-25 21:36:09 -04:00
Jannik Tappert
de1c2b2b5b
Added localization to the biomes. (#1378)
* Added localization to the biomes.

German Localization by me. (Native German).
French Localiztation by sangara42 from Discord

* Changed End back to ??? and Space is now Space again it all but German and French

* Changed english biome names according to https://wiki.pokerogue.net/biomes:biomes

* And we are back to grassy field since apparently the wiki is wrong...
2024-05-25 15:57:22 -05:00
nterrien
6f2d639a7b
Fix French translation of Genesect's Drive (#1379) 2024-05-25 15:54:31 -05:00
td76099
ae0cd86bc3
Adding clause so right Pokemon in double battle cannot target itself with a spread move when left one dies with no replacement (#1370) 2024-05-25 14:06:50 -05:00
Nicholas Galauxy
93c91bf73a
Fix incorrectly unselectable starter formes (#1332)
* Fix incorrectly unselectable starter formes

* Fix linter issue that got merged upstream

* Remove battle-bond key from form key overrides based on feedback
2024-05-25 12:53:46 -05:00
damocleas
1b8b0789c0
Made Lab 25% instead of 12.5% to encounter after Factory (#1351)
This biome is too rare, this is just a temporary change until biomes are redone.
2024-05-25 18:45:07 +01:00
ASCAlex
311f7b7420
Fixed German localization for Starf Berry description and localized zippyZap effect (#1373) 2024-05-25 11:47:31 -05:00
Frederico Santos
f95bd40353
Swapped Aron for Aggron on Iris pokemon pool (#1374) 2024-05-25 11:45:27 -05:00
Benjamin Odom
5c28e1fb11
Adds New BattleSceneEventTypes (#1372)
* Add BattleSceneEvents

* Update battle-scene-events.ts
2024-05-25 17:23:53 +01:00
Jannik Tappert
97d8275417
localized Honeygather again (#1369) 2024-05-25 09:31:30 -05:00
Frederico Santos
ef28e75b39
hotfix for alder bgm on double battle (#1368) 2024-05-25 09:20:27 -05:00
Jakub Hanko
caeb22c26b
Implement Honey Gather (#1360)
* Implement Honey Gather

* Updated Ability Description

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 08:01:08 -05:00
Jannik Tappert
aaa96ebe0e
Adding the option to have named trainers be able to have a double battle together (#1318)
* WIP: Adding the option to have named trainers be able to have a double battle together

* The team generation now works.
Also changed it so the special pools are now seperatly defined so we can access it for the team generation of the doubles.

They will happen at a 33% chance.

TODO: Option for seperate double dialogue (because for example the dialogue for tate and liza dont make sense since they reference their other sibling not beeing there...)

* Obviously didnt mean to push changes to battle.ts... (I made this change for a test)

* The doubles now have victory and encounter dialogue (the dialogue itself isnt THAT good since english isnt my first language)

* Changed signatureSpecies for the new galar elite 4

* Added Marnie & Piers as a double

* ESLint

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 07:47:18 -05:00
Tempoanon
49c365f154
Make iv scanner check against baby form IVs (#1214) 2024-05-25 06:47:26 -05:00
Jannik Tappert
b524be1db1
Issue #1118 Added Galar Elite 4 (#1246)
Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 06:38:59 -05:00
td76099
c4c4774528
Beat Up checks the user's party instead of always checking player's party (#1268) 2024-05-25 06:31:04 -05:00
innerthunder
4ffff8e1ee
Implement Quick Guard and other conditional team protection moves (#1275)
* Implement conditional protection arena tag

Affected moves:
- Quick Guard
- Wide Guard
- Mat Block
- Crafty Shield
- Feint (updated)

* Add support for moves that ignore Protect to conditional protection moves

* Comments for protect arena tags

* ESLint

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 06:22:10 -05:00
ReneGV
5c327e347a
Implement Purify (#1291)
* Implement purify

* Code review fixes

* Remove vitest import

* Update status-effect.ts

* Update status-effect.ts

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 06:01:23 -05:00
神龟
79f69ddfe0
Update move.ts (#1359) 2024-05-25 05:43:42 -05:00
LaukkaE
0da469d7a3
Fix Wind Rider (#607)
Fix Wind Rider
2024-05-25 05:32:32 -05:00
arColm
ae2928e1c9
Implement Poison Puppeteer (#320)
Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-25 04:51:36 -05:00
Franck TROUILLEZ
37ebbd28d5
Apply offset to baseY as well during Pokemon#setMini (#1357)
This fixes an issue where this.baseY and this.y were not sync anymore, leading to unexpected behavior while using both values, especially during the selectTargetPhase, where the UI was not working for the first player pokemon.
2024-05-25 04:45:47 -05:00
Tempoanon
d71451fc23
Players win if classic and past floor 200 (#1348)
* Players win if classic and past floor 200

* isClassic

* no need to handle game over twice
2024-05-25 04:36:30 -05:00
Jannik Tappert
34474fb10e
German Loc for the menu.ts change (#1354) 2024-05-25 04:36:14 -05:00
YounesM
4277439a2d
Implemented Dancer Ability (#590)
* implemented Dancer Ability

* corrected target selection for double battles, improved ability detection

* Added TSDoc

* Enhanced TSDoc

* Corrected dancing StatusMove triggering

* Linter corrections
2024-05-24 23:00:58 -05:00
SnowCharm
5f7c593365
Update zh_CN ability.ts and move.ts (#1350)
* fix translation error in zh_CN ability.ts

* add translation for Zippy Zap

* fix translation to keep up with the current impl
2024-05-24 23:46:16 -04:00
Matthew Olker
1e283afc84 fix anmation duplicate warnings 2024-05-24 22:57:47 -04:00
Benjamin Odom
32fadf8cb6
Update menu.ts (#1349) 2024-05-24 21:46:21 -04:00
Matthew Olker
840ac9f53f fix single pokemon run away in double battle 2024-05-24 21:16:27 -04:00
Matthew
623c05a3df
update running away in double battles for real this time (#1345) 2024-05-24 19:39:58 -05:00
zaccie
564add66d2
Changing Biome Text Colour (#1346)
On light coloured biomes this change should be similar readability
In darker biomes it's has much easier readability
+ now becomes more consistent colour with the rest of the game text which just looks better imo
2024-05-24 20:31:33 -04:00
Tempoanon
dc828c6801
Revert "Update running away in Double Battles (#1336)" (#1342)
This reverts commit 5e7a9b0872.
2024-05-25 09:54:46 +10:00
Matthew
5e7a9b0872
Update running away in Double Battles (#1336)
* Add check for active pokemon and double battle with 1 active

* remove unecessary case
2024-05-24 19:46:52 -04:00
Benjamin Odom
416d666b30
Update Biome Text Labels and Variable Name (#1340)
* Added ability to get hex colour from type, added biome text, added functionality for querying biomeType with object.

* Revert "Added ability to get hex colour from type, added biome text, added functionality for querying biomeType with object."

This reverts commit 0f87000aa4.

* Reverted changes, added biome text to line one and renamed wavecounttext to a more standard name.

* Update battle-scene.ts

* Update Formatting

* Update Enums

* Revert

* Update overrides.ts

* Update battle-scene.ts

---------

Co-authored-by: Jon Studders <jonstudders1@gmail.com>
2024-05-24 18:43:38 -05:00
Nicholas Galauxy
815b37d23c
Convert reconnect method to exponential backoff timeout (#1293)
* Convert reconnect method to exponential backoff timeout

* Reset to the starting duration after getting a response

* Fix broken scope enclosures
2024-05-24 17:57:49 -05:00
Jon Studders
c8b77cffc1
Added current biome text (#915)
* Added ability to get hex colour from type, added biome text, added functionality for querying biomeType with object.

* Revert "Added ability to get hex colour from type, added biome text, added functionality for querying biomeType with object."

This reverts commit 0f87000aa4.

* Reverted changes, added biome text to line one and renamed wavecounttext to a more standard name.

* Update battle-scene.ts

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-24 18:36:02 -04:00
Jon Studders
919760e2e1
Added if statement to deploy.yml stopping local builds failing. (#1335) 2024-05-24 18:26:23 -04:00
Greenlamp2
410b33a44f
Merge pull request #1338 from bennybroseph/MoveUsedEvent-Add
Add MoveUsedEvent to Listen For When a Move Gets Used
2024-05-25 00:20:12 +02:00
Benjamin Odom
3985c63dad Update battle-scene.ts 2024-05-24 17:03:49 -05:00
Benjamin Odom
74bf42b4b7 Let's try this again 2024-05-24 17:01:47 -05:00
Matthew Olker
751a3d1e49 add names to battle info ui objects and solve key already exists warning for starter select 2024-05-24 17:23:49 -04:00
Jon Studders
d01cd98d06
Fixed champion ribbon boss segments. (#1334) 2024-05-24 16:07:57 -05:00
Douglas Marchione de Souza
0d6145263f
Acrobatics does not treat vitamins as held items (#718)
* Changed the move Acrobatics so it doesn't include
non-held items on it's damage calculations

* Changed exception so it includes within_party
items, and updated the move description

* Small typo e_e'

* Change Description of Move

---------

Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
2024-05-24 15:49:23 -05:00
LaukkaE
0309fde7e8
Fix Aftermath not working (#1209) 2024-05-24 15:35:45 -05:00
Jakub Hanko
a48ba9864d
Implement Destiny Bond move (#1104)
* Use getBattleStat instead of getStat in BattleStatRatioPowerAttr

* Change unnecessary let into const

* Refactor BattleStatRatioPowerAttr into two distinct classes

* Add TSDoc for the new classes

* Implementation of Destiny Bond

* Add TSDocs

* Make the move fail in boss battles

* Fix boss immunity and ally fainting

* Update docs

* Add doc of return value of tag lapse

* Fix ESLint
2024-05-24 15:23:23 -05:00
Greenlamp2
136fcbfda8
init dialog call in the loading-scene (#1331) 2024-05-24 15:08:18 -05:00
Jon Studders
3670574342
Added a champion ribbon on enemy pokemon if they have a classic win. (#881)
* Added a champion ribbon on enemy pokemon if they have a classic win.

* Refactored to check for other non-root starterDex entities.

* Check for caughtIcon, if false then move ribbon to the left.

* Fixed Merge.

* Bit of refactoring, added check for classic mode.

* Removed random newline and removed unused import.

* Removed overlapping ribbon.
2024-05-24 15:57:02 -04:00
Madmadness65
41751ab8df Update encounter levels for some Pokémon
When the wild evolution delays were updated, the biomes file wasn't updated to match, so that has been fixed.
Additionally, the previous refactor removed the commented-out outputPools function. It is where it is because it allows for easily filling out the biomes file for an update.
2024-05-24 14:48:24 -05:00
Greenlamp2
c1a7df913a
refactor executed code while importing and initializing all of these in loading-scene (#1125) 2024-05-24 13:46:30 -04:00
神龟
a9af2bd6ff
Update pokemon.ts (#1297) 2024-05-24 11:15:11 -05:00
神龟
34e9236874
Make zh_CN translation easier to understand (#1292)
* Update modifier-type.ts

* Update menu.ts

* Update tutorial.ts
2024-05-24 11:13:51 -05:00
GhostFlys
6168b77761
Update Chinese battle.ts and egg-list-ui-handler.ts (#1314)
* Update battle.ts

update some lines of translation
make some translation more official

* Update egg-list-ui-handler.ts

make text position more accurate
2024-05-24 10:25:57 -05:00
Greenlamp2
622885767d
Enforce Consistent Spacing with ESLint's space-before-blocks and keyword-spacing Rules (#1308)
* added rule no-trailing-spaces

* added rule space-before-block

* added rule keyword spacing
2024-05-23 19:19:20 -05:00
Greenlamp2
e2be6ba002
added rule no-trailing-spaces (#1307) 2024-05-23 18:45:04 -05:00
Franck TROUILLEZ
68e94845ab
Add BattleInfo to TargetSelectUiHandler to move when target selected (#1255)
This change allows to move the box containing the battle info of the ennemy pokemons during double battle when the user has to choose a target. In addition to the pokemon opacity constantly changing, the battle info will also move up and down to indicate which Pokemon is targeted.

It exposes the BattleInfo object from the Pokemon object through an accessor method.
2024-05-23 18:28:53 -04:00
Benjamin Odom
c2bc94a5f3
Increases the Amount of Time Until a Reconnect up to a Maximum (#1295)
* Update unavailable-modal-ui-handler.ts

* Update unavailable-modal-ui-handler.ts

* Update unavailable-modal-ui-handler.ts
2024-05-23 16:19:36 -05:00
Greenlamp2
c86a51ba89
prevent opening the menu on confirm dialog + fix config error message on crash (#1278) 2024-05-23 13:26:12 -05:00
Lugiad
79af115278
Few new lines up to be localized from in battle.ts locales (#1144)
* Update phases.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update phases.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update battle.ts

* Update phases.ts
2024-05-23 13:22:09 -05:00
Matthew
f7a7b23dd1
Update README and package, re-add money formatter (#1286) 2024-05-23 12:29:18 -04:00
260 changed files with 23579 additions and 3440 deletions

View File

@ -22,7 +22,13 @@
"@typescript-eslint/no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax "@typescript-eslint/no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax
"brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors "brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors
"curly": ["error", "all"], // Enforces the use of curly braces for all control statements "curly": ["error", "all"], // Enforces the use of curly braces for all control statements
"@typescript-eslint/brace-style": ["error", "1tbs"] "@typescript-eslint/brace-style": ["error", "1tbs"],
"no-trailing-spaces": ["error", { // Disallows trailing whitespace at the end of lines
"skipBlankLines": false, // Enforces the rule even on blank lines
"ignoreComments": false // Enforces the rule on lines containing comments
}],
"space-before-blocks": ["error", "always"], // Enforces a space before blocks
"keyword-spacing": ["error", { "before": true, "after": true }] // Enforces spacing before and after keywords
} }
} }
] ]

View File

@ -6,6 +6,7 @@ on:
jobs: jobs:
deploy: deploy:
if: github.repository == 'pagefaultgames/pokerogue'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

3
.gitignore vendored
View File

@ -24,9 +24,6 @@ dist-ssr
*.sln *.sln
*.sw? *.sw?
# Docummentation
docs/*
public/images/trainer/convert/* public/images/trainer/convert/*
public/images/battle_anims/input/*.png public/images/battle_anims/input/*.png
public/images/pokemon/input/*.png public/images/pokemon/input/*.png

View File

@ -8,7 +8,7 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
### 💻 Environment Setup ### 💻 Environment Setup
#### Prerequisites #### Prerequisites
- node: 18.3.0 - node: 20.13.1
- npm: [how to install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - npm: [how to install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
#### Running Locally #### Running Locally
@ -16,6 +16,9 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
- *if you run into any errors, reach out in the **#dev-corner** channel in discord* - *if you run into any errors, reach out in the **#dev-corner** channel in discord*
2. Run `npm run start:dev` to locally run the project in `localhost:8000` 2. Run `npm run start:dev` to locally run the project in `localhost:8000`
#### Linting
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script.
### ❔ FAQ ### ❔ FAQ
**How do I test a new _______?** **How do I test a new _______?**

40
docs/linting.md Normal file
View File

@ -0,0 +1,40 @@
# ESLint
## Key Features
1. **Automation**:
- A pre-commit hook has been added to automatically run ESLint on the added or modified files, ensuring code quality before commits.
2. **Manual Usage**:
- If you prefer not to use the pre-commit hook, you can manually run ESLint to automatically fix issues using the command:
```sh
npx eslint --fix . or npm run eslint
```
- Running this command will lint all files in the repository.
3. **GitHub Action**:
- A GitHub Action has been added to automatically run ESLint on every push and pull request, ensuring code quality in the CI/CD pipeline.
## Summary of ESLint Rules
1. **General Rules**:
- **Equality**: Use `===` and `!==` instead of `==` and `!=` (`eqeqeq`).
- **Indentation**: Enforce 2-space indentation (`indent`).
- **Quotes**: Use doublequotes for strings (`quotes`).
- **Variable Declarations**:
- Disallow `var`; use `let` or `const` (`no-var`).
- Prefer `const` for variables that are never reassigned (`prefer-const`).
- **Unused Variables**: Allow unused function parameters but enforce error for other unused variables (`@typescript-eslint/no-unused-vars`).
- **End of Line**: Ensure at least one newline at the end of files (`eol-last`).
- **Curly Braces**: Enforce the use of curly braces for all control statements (`curly`).
- **Brace Style**: Use one true brace style (`1tbs`) for TypeScript-specific syntax (`@typescript-eslint/brace-style`).
2. **TypeScript-Specific Rules**:
- **Semicolons**:
- Enforce semicolons for TypeScript-specific syntax (`@typescript-eslint/semi`).
- Disallow unnecessary semicolons (`@typescript-eslint/no-extra-semi`).
## Benefits
- **Consistency**: Ensures consistent coding style across the project.
- **Code Quality**: Helps catch potential errors and improve overall code quality.
- **Readability**: Makes the codebase easier to read and maintain.

6111
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@
"phaser3-rex-plugins": "^1.1.84" "phaser3-rex-plugins": "^1.1.84"
}, },
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=20.0.0"
}, },
"imports": { "imports": {
"#app": "./src/main.js", "#app": "./src/main.js",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
{
"1": {
"1b2627": "1b2627",
"474749": "156a66",
"010101": "010101",
"303034": "094448",
"f5f5f6": "f5ffea",
"b2b3b2": "90c093",
"949496": "1c8155",
"282730": "002729",
"242428": "001b1a",
"6f7071": "01473a",
"df84ad": "ff69fa",
"9b4f69": "d414dd",
"fcfcfc": "fcfcfc"
},
"2": {
"1b2627": "060724",
"474749": "8655e1",
"010101": "010101",
"303034": "5a3eb9",
"f5f5f6": "342d4c",
"b2b3b2": "18133d",
"949496": "302e89",
"282730": "180c46",
"242428": "161058",
"6f7071": "2e1d7b",
"df84ad": "54f1ff",
"9b4f69": "0099ce",
"fcfcfc": "fcfcfc"
}
}

View File

@ -1220,7 +1220,7 @@
1 1
], ],
"623": [ "623": [
1, 2,
1, 1,
1 1
], ],
@ -1754,6 +1754,11 @@
1, 1,
1 1
], ],
"862": [
0,
1,
1
],
"863": [ "863": [
0, 0,
1, 1,
@ -1796,8 +1801,8 @@
], ],
"890-eternamax": [ "890-eternamax": [
0, 0,
2, 1,
2 1
], ],
"890": [ "890": [
0, 0,
@ -2499,7 +2504,7 @@
], ],
"212-mega": [ "212-mega": [
1, 1,
1, 2,
1 1
], ],
"212": [ "212": [
@ -2920,7 +2925,7 @@
"426": [ "426": [
0, 0,
1, 1,
1 2
], ],
"427": [ "427": [
0, 0,
@ -3323,7 +3328,7 @@
1 1
], ],
"623": [ "623": [
1, 2,
1, 1,
1 1
], ],
@ -3857,6 +3862,11 @@
1, 1,
1 1
], ],
"862": [
0,
1,
1
],
"863": [ "863": [
0, 0,
1, 1,
@ -4175,7 +4185,7 @@
], ],
"399": [ "399": [
0, 0,
1, 2,
1 1
], ],
"400": [ "400": [
@ -4249,7 +4259,7 @@
"212-mega": [ "212-mega": [
1, 1,
1, 1,
1 2
], ],
"282-mega": [ "282-mega": [
0, 0,
@ -4473,7 +4483,7 @@
], ],
"696": [ "696": [
0, 0,
1, 2,
2 2
], ],
"697": [ "697": [
@ -4553,8 +4563,8 @@
], ],
"729": [ "729": [
0, 0,
1, 2,
1 2
], ],
"730": [ "730": [
0, 0,
@ -4564,7 +4574,7 @@
"747": [ "747": [
0, 0,
2, 2,
1 2
], ],
"748": [ "748": [
0, 0,
@ -4578,8 +4588,8 @@
], ],
"754": [ "754": [
0, 0,
1, 2,
1 2
], ],
"755": [ "755": [
0, 0,
@ -4746,6 +4756,11 @@
1, 1,
1 1
], ],
"862": [
0,
1,
1
],
"863": [ "863": [
0, 0,
1, 1,
@ -4789,7 +4804,12 @@
"890": [ "890": [
0, 0,
2, 2,
2 1
],
"890-eternamax": [
0,
1,
1
], ],
"900": [ "900": [
0, 0,
@ -5070,8 +5090,8 @@
], ],
"212-mega": [ "212-mega": [
1, 1,
1, 2,
1 2
], ],
"282-mega": [ "282-mega": [
0, 0,
@ -5400,7 +5420,7 @@
], ],
"754": [ "754": [
0, 0,
1, 2,
2 2
], ],
"755": [ "755": [
@ -5563,6 +5583,11 @@
1, 1,
1 1
], ],
"862": [
0,
1,
1
],
"863": [ "863": [
0, 0,
1, 1,
@ -5725,8 +5750,8 @@
], ],
"970": [ "970": [
0, 0,
2, 1,
2 1
], ],
"973": [ "973": [
1, 1,

View File

@ -0,0 +1,41 @@
{
"textures": [
{
"image": "212-mega_2.png",
"format": "RGBA8888",
"size": {
"w": 86,
"h": 86
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 72,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
},
"frame": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:3fba14a8cd6c5a8717bb5ccf414ed76d:5ebfc3bcaa77a0ff9d55a9b15383f0ef:d0a607721d6bb74ae9b6d486116d85e3$"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
{
"1": {
"1b2627": "1b2627",
"010101": "010101",
"474749": "156a66",
"303034": "094448",
"6f7071": "01473a",
"b2b3b2": "90c093",
"463f39": "001b1a",
"949496": "1c8155",
"f5f5f6": "f5ffea",
"9b4f69": "d414dd",
"df84ad": "ff69fa",
"2b2d2e": "052332",
"fcfcfc": "fcfcfc"
},
"2": {
"1b2627": "180c46",
"010101": "010101",
"474749": "8655e1",
"303034": "5a3eb9",
"6f7071": "2e1d7b",
"b2b3b2": "1f1a43",
"463f39": "161058",
"949496": "302e89",
"f5f5f6": "342d4c",
"9b4f69": "0099ce",
"df84ad": "54f1ff",
"2b2d2e": "060429",
"fcfcfc": "fcfcfc"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,692 @@
{
"textures": [
{
"image": "696_2.png",
"format": "RGBA8888",
"size": {
"w": 135,
"h": 135
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0031.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0032.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 53,
"y": 0,
"w": 53,
"h": 46
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 46,
"w": 53,
"h": 46
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 53,
"h": 46
},
"frame": {
"x": 0,
"y": 46,
"w": 53,
"h": 46
}
},
{
"filename": "0025.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 53,
"h": 43
},
"frame": {
"x": 0,
"y": 92,
"w": 53,
"h": 43
}
},
{
"filename": "0026.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 53,
"h": 43
},
"frame": {
"x": 0,
"y": 92,
"w": 53,
"h": 43
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0021.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0022.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0029.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0030.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 53,
"h": 45
},
"frame": {
"x": 53,
"y": 46,
"w": 53,
"h": 45
}
},
{
"filename": "0023.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 2,
"w": 53,
"h": 44
},
"frame": {
"x": 53,
"y": 91,
"w": 53,
"h": 44
}
},
{
"filename": "0024.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 2,
"w": 53,
"h": 44
},
"frame": {
"x": 53,
"y": 91,
"w": 53,
"h": 44
}
},
{
"filename": "0027.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 2,
"w": 53,
"h": 44
},
"frame": {
"x": 53,
"y": 91,
"w": 53,
"h": 44
}
},
{
"filename": "0028.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 53,
"h": 46
},
"spriteSourceSize": {
"x": 0,
"y": 2,
"w": 53,
"h": 44
},
"frame": {
"x": 53,
"y": 91,
"w": 53,
"h": 44
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:f6c90e8287d3ce2aa68c9fef98f6e12f:24cf84ba4764bd88b4e751ca1911a8d5:58b7763fb9abdd043e9bfa400cfafdef$"
}
}

View File

@ -0,0 +1,272 @@
{
"textures": [
{
"image": "729_2.png",
"format": "RGBA8888",
"size": {
"w": 141,
"h": 141
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 51,
"w": 49,
"h": 51
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 51,
"w": 49,
"h": 51
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 48,
"h": 50
},
"frame": {
"x": 49,
"y": 0,
"w": 48,
"h": 50
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 48,
"h": 50
},
"frame": {
"x": 49,
"y": 0,
"w": 48,
"h": 50
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 42,
"h": 47
},
"frame": {
"x": 97,
"y": 0,
"w": 42,
"h": 47
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 42,
"h": 47
},
"frame": {
"x": 97,
"y": 0,
"w": 42,
"h": 47
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 40,
"h": 47
},
"frame": {
"x": 97,
"y": 47,
"w": 40,
"h": 47
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 46,
"h": 48
},
"frame": {
"x": 49,
"y": 50,
"w": 46,
"h": 48
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 46,
"h": 48
},
"frame": {
"x": 49,
"y": 50,
"w": 46,
"h": 48
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 45,
"h": 47
},
"frame": {
"x": 95,
"y": 94,
"w": 45,
"h": 47
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 45,
"h": 47
},
"frame": {
"x": 95,
"y": 94,
"w": 45,
"h": 47
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:4df3ec883b357e664a50e3015060795f:29a8d34f9df9fa51691fda1da5961207:b2d5dd692ec79c7357afdffa7b3670a9$"
}
}

View File

@ -0,0 +1,272 @@
{
"textures": [
{
"image": "729_3.png",
"format": "RGBA8888",
"size": {
"w": 141,
"h": 141
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 51,
"w": 49,
"h": 51
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 49,
"h": 51
},
"frame": {
"x": 0,
"y": 51,
"w": 49,
"h": 51
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 48,
"h": 50
},
"frame": {
"x": 49,
"y": 0,
"w": 48,
"h": 50
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 48,
"h": 50
},
"frame": {
"x": 49,
"y": 0,
"w": 48,
"h": 50
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 42,
"h": 47
},
"frame": {
"x": 97,
"y": 0,
"w": 42,
"h": 47
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 42,
"h": 47
},
"frame": {
"x": 97,
"y": 0,
"w": 42,
"h": 47
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 40,
"h": 47
},
"frame": {
"x": 97,
"y": 47,
"w": 40,
"h": 47
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 46,
"h": 48
},
"frame": {
"x": 49,
"y": 50,
"w": 46,
"h": 48
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 46,
"h": 48
},
"frame": {
"x": 49,
"y": 50,
"w": 46,
"h": 48
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 45,
"h": 47
},
"frame": {
"x": 95,
"y": 94,
"w": 45,
"h": 47
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 50,
"h": 51
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 45,
"h": 47
},
"frame": {
"x": 95,
"y": 94,
"w": 45,
"h": 47
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:4df3ec883b357e664a50e3015060795f:29a8d34f9df9fa51691fda1da5961207:b2d5dd692ec79c7357afdffa7b3670a9$"
}
}

View File

@ -0,0 +1,188 @@
{
"textures": [
{
"image": "747_3.png",
"format": "RGBA8888",
"size": {
"w": 110,
"h": 110
},
"scale": 1,
"frames": [
{
"filename": "0003.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
},
"frame": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
},
"frame": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
},
"frame": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
},
"frame": {
"x": 0,
"y": 0,
"w": 55,
"h": 47
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 46
},
"frame": {
"x": 55,
"y": 0,
"w": 55,
"h": 46
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 55,
"h": 46
},
"frame": {
"x": 55,
"y": 0,
"w": 55,
"h": 46
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 55,
"h": 46
},
"frame": {
"x": 55,
"y": 46,
"w": 55,
"h": 46
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 55,
"h": 47
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 55,
"h": 46
},
"frame": {
"x": 55,
"y": 46,
"w": 55,
"h": 46
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:e4c4f790c4f0286f608dcdb15a609059:464f7ae7db1c0d034c2a1a65612b0da8:b26f7254994561969f00f765318acf1c$"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
{
"1": {
"1b2627": "1b2627",
"474749": "156a66",
"010101": "010101",
"f5f5f6": "f5ffea",
"b2b3b2": "90c093",
"303034": "094448",
"949496": "1c8155",
"463f39": "156a66",
"6f7071": "01473a",
"df84ad": "ff69fa",
"9b4f69": "d414dd",
"fcfcfc": "fcfcfc",
"494d56": "156a66"
},
"2": {
"1b2627": "060724",
"474749": "8655e1",
"010101": "010101",
"f5f5f6": "342d4c",
"b2b3b2": "18133d",
"303034": "5a3eb9",
"949496": "302e89",
"463f39": "8655e1",
"6f7071": "2e1d7b",
"df84ad": "54f1ff",
"9b4f69": "0099ce",
"fcfcfc": "fcfcfc",
"494d56": "8655e1"
}
}

View File

@ -0,0 +1,28 @@
{
"1": {
"25134c": "162a52",
"010101": "010101",
"3622a7": "406d89",
"6461ba": "4989a6",
"31245f": "264864",
"ab2a4c": "0d6fae",
"ffb6b6": "a6fbff",
"ff5657": "45c5e5",
"ffdfdf": "f1faff",
"e23434": "1c98c7",
"ff8c8c": "6ee7f8"
},
"2": {
"25134c": "354e95",
"010101": "010101",
"3622a7": "bfd1fa",
"6461ba": "e1ecff",
"31245f": "87a3dd",
"ab2a4c": "ac4709",
"ffb6b6": "ffd456",
"ff5657": "d47823",
"ffdfdf": "ffee85",
"e23434": "c86016",
"ff8c8c": "ed972e"
}
}

View File

@ -0,0 +1,19 @@
{
"2": {
"26124d": "4963af",
"3a15bc": "bfd1fa",
"010101": "010101",
"b21833": "7b2f0e",
"eb1533": "cb7622",
"9a2433": "732208",
"3d2871": "87a3dd",
"f46d70": "f1bd4b",
"fb2553": "934516",
"675cc5": "675cc5",
"ffbcbc": "de9335",
"12042d": "12042d",
"e22dbc": "298fb9",
"f18cd5": "73e5dc",
"fefefe": "fefefe"
}
}

View File

@ -0,0 +1,440 @@
{
"textures": [
{
"image": "212-mega_2.png",
"format": "RGBA8888",
"size": {
"w": 344,
"h": 344
},
"scale": 1,
"frames": [
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 0,
"w": 76,
"h": 86
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 0,
"w": 76,
"h": 86
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 86,
"w": 76,
"h": 86
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 172,
"w": 76,
"h": 86
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 258,
"w": 76,
"h": 86
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 172,
"w": 74,
"h": 86
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 258,
"w": 74,
"h": 86
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 258,
"w": 74,
"h": 86
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 172,
"w": 74,
"h": 86
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
},
"frame": {
"x": 150,
"y": 258,
"w": 72,
"h": 86
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
},
"frame": {
"x": 222,
"y": 258,
"w": 72,
"h": 86
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 71,
"h": 86
},
"frame": {
"x": 224,
"y": 172,
"w": 71,
"h": 86
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:1b7ede0d536069418738b9c0f67f14fd:7b469c796eb673d31bdab8ad7b99b881:d0a607721d6bb74ae9b6d486116d85e3$"
}
}

View File

@ -0,0 +1,440 @@
{
"textures": [
{
"image": "212-mega_3.png",
"format": "RGBA8888",
"size": {
"w": 344,
"h": 344
},
"scale": 1,
"frames": [
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 0,
"w": 76,
"h": 86
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 0,
"w": 76,
"h": 86
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 86,
"w": 76,
"h": 86
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 172,
"w": 76,
"h": 86
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 3,
"y": 0,
"w": 76,
"h": 86
},
"frame": {
"x": 0,
"y": 258,
"w": 76,
"h": 86
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 0,
"w": 74,
"h": 86
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 2,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 172,
"w": 74,
"h": 86
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 258,
"w": 74,
"h": 86
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 76,
"y": 258,
"w": 74,
"h": 86
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 224,
"y": 86,
"w": 74,
"h": 86
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 1,
"y": 0,
"w": 74,
"h": 86
},
"frame": {
"x": 150,
"y": 172,
"w": 74,
"h": 86
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
},
"frame": {
"x": 150,
"y": 258,
"w": 72,
"h": 86
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 72,
"h": 86
},
"frame": {
"x": 222,
"y": 258,
"w": 72,
"h": 86
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 79,
"h": 86
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 71,
"h": 86
},
"frame": {
"x": 224,
"y": 172,
"w": 71,
"h": 86
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:1b7ede0d536069418738b9c0f67f14fd:7b469c796eb673d31bdab8ad7b99b881:d0a607721d6bb74ae9b6d486116d85e3$"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
{
"1": {
"010101": "010101",
"1b2627": "1b2627",
"474749": "156a66",
"303034": "094448",
"6f7071": "01473a",
"b2b3b2": "90c093",
"463f39": "001b1a",
"f5f5f6": "f5ffea",
"949496": "1c8155",
"9b4f69": "d414dd",
"df84ad": "ff69fa",
"fcfcfc": "fcfcfc"
},
"2": {
"010101": "010101",
"1b2627": "180c46",
"474749": "8655e1",
"303034": "5a3eb9",
"6f7071": "2e1d7b",
"b2b3b2": "1f1a43",
"463f39": "161058",
"f5f5f6": "342d4c",
"949496": "302e89",
"9b4f69": "0099ce",
"df84ad": "54f1ff",
"fcfcfc": "fcfcfc"
}
}

View File

@ -0,0 +1,26 @@
{
"1": {
"242737": "242737",
"366956": "521d0c",
"41968b": "c57833",
"5de0aa": "fbce5d",
"262b6b": "323b51",
"3253d6": "577b81",
"2c369a": "435469",
"a02c75": "3f4a6f",
"fd84ba": "bbe3ee",
"e0548f": "758eb4"
},
"2": {
"242737": "2e1d1a",
"366956": "6d171f",
"41968b": "b21a1a",
"5de0aa": "d95e3e",
"262b6b": "b07963",
"3253d6": "ffe6ca",
"2c369a": "d9aa8a",
"a02c75": "153532",
"fd84ba": "429d72",
"e0548f": "28625e"
}
}

View File

@ -5979,6 +5979,6 @@
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "3.0", "version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:8e8bd4d6d941cb88610eb6155fd86133:38ee262ea69421a5e49109e3abfe85dd:2e7c5873ead8fd8fce82a0b3fcc86b42$" "smartupdate": "$TexturePacker:SmartUpdate:a4de8d1c4f7d4f58c929b8b5479e03f1:3c8ac308e19a7f9420a4df8a78188490:2e7c5873ead8fd8fce82a0b3fcc86b42$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -7365,6 +7365,6 @@
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "3.0", "version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:c7db0232f46f4f968b13cb4a8cdb7bce:bcba724c9d58839d9045773dbcc992bc:8190d2ecf16422e962cfb1a751b5e1fc$" "smartupdate": "$TexturePacker:SmartUpdate:4716314f809733c6bcb221809776ba11:4fb09375a87d8a348dc0e609db8a95fd:8190d2ecf16422e962cfb1a751b5e1fc$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,76 @@
import Move from "./data/move";
/** Alias for all {@linkcode BattleScene} events */
export enum BattleSceneEventType {
/**
* Triggers when a move is successfully used
* @see {@linkcode MoveUsedEvent}
*/
MOVE_USED = "onMoveUsed",
/**
* Triggers on the first turn of a new battle
* @see {@linkcode TurnInitEvent}
*/
TURN_INIT = "onTurnInit",
/**
* Triggers after a turn ends in battle
* @see {@linkcode TurnEndEvent}
*/
TURN_END = "onTurnEnd",
/**
* Triggers when a new {@linkcode Arena} is created during initialization
* @see {@linkcode NewArenaEvent}
*/
NEW_ARENA = "onNewArena",
}
/**
* Container class for {@linkcode BattleSceneEventType.MOVE_USED} events
* @extends Event
*/
export class MoveUsedEvent extends Event {
/** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */
public userId: number;
/** The {@linkcode Move} used */
public move: Move;
/** The amount of PP used on the {@linkcode Move} this turn */
public ppUsed: number;
constructor(userId: number, move: Move, ppUsed: number) {
super(BattleSceneEventType.MOVE_USED);
this.userId = userId;
this.move = move;
this.ppUsed = ppUsed;
}
}
/**
* Container class for {@linkcode BattleSceneEventType.TURN_INIT} events
* @extends Event
*/
export class TurnInitEvent extends Event {
constructor() {
super(BattleSceneEventType.TURN_INIT);
}
}
/**
* Container class for {@linkcode BattleSceneEventType.TURN_END} events
* @extends Event
*/
export class TurnEndEvent extends Event {
/** The amount of turns in the current battle */
public turnCount: number;
constructor(turnCount: number) {
super(BattleSceneEventType.TURN_END);
this.turnCount = turnCount;
}
}
/**
* Container class for {@linkcode BattleSceneEventType.NEW_ARENA} events
* @extends Event
*/
export class NewArenaEvent extends Event {
constructor() {
super(BattleSceneEventType.NEW_ARENA);
}
}

View File

@ -2,7 +2,7 @@ import Phaser from "phaser";
import UI from "./ui/ui"; import UI from "./ui/ui";
import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from "./phases"; import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from "./phases";
import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon"; import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon";
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies } from "./data/pokemon-species"; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species";
import * as Utils from "./utils"; import * as Utils from "./utils";
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier"; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier";
import { PokeballType } from "./data/pokeball"; import { PokeballType } from "./data/pokeball";
@ -15,10 +15,9 @@ import { GameData, PlayerGender } from "./system/game-data";
import { TextStyle, addTextObject } from "./ui/text"; import { TextStyle, addTextObject } from "./ui/text";
import { Moves } from "./data/enums/moves"; import { Moves } from "./data/enums/moves";
import { allMoves } from "./data/move"; import { allMoves } from "./data/move";
import { initMoves } from "./data/move";
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from "./modifier/modifier-type"; import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from "./modifier/modifier-type";
import AbilityBar from "./ui/ability-bar"; import AbilityBar from "./ui/ability-bar";
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, applyAbAttrs, initAbilities } from "./data/ability"; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, applyAbAttrs } from "./data/ability";
import { allAbilities } from "./data/ability"; import { allAbilities } from "./data/ability";
import Battle, { BattleType, FixedBattleConfig, fixedBattles } from "./battle"; import Battle, { BattleType, FixedBattleConfig, fixedBattles } from "./battle";
import { GameMode, GameModes, gameModes } from "./game-mode"; import { GameMode, GameModes, gameModes } from "./game-mode";
@ -57,6 +56,7 @@ import { Localizable } from "./plugins/i18n";
import * as Overrides from "./overrides"; import * as Overrides from "./overrides";
import {InputsController} from "./inputs-controller"; import {InputsController} from "./inputs-controller";
import {UiInputs} from "./ui-inputs"; import {UiInputs} from "./ui-inputs";
import { NewArenaEvent } from "./battle-scene-events";
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
@ -152,7 +152,8 @@ export default class BattleScene extends SceneBase {
public money: integer; public money: integer;
public pokemonInfoContainer: PokemonInfoContainer; public pokemonInfoContainer: PokemonInfoContainer;
private party: PlayerPokemon[]; private party: PlayerPokemon[];
private waveCountText: Phaser.GameObjects.Text; /** Combined Biome and Wave count text */
private biomeWaveText: Phaser.GameObjects.Text;
private moneyText: Phaser.GameObjects.Text; private moneyText: Phaser.GameObjects.Text;
private scoreText: Phaser.GameObjects.Text; private scoreText: Phaser.GameObjects.Text;
private luckLabelText: Phaser.GameObjects.Text; private luckLabelText: Phaser.GameObjects.Text;
@ -185,13 +186,16 @@ export default class BattleScene extends SceneBase {
public rngSeedOverride: string = ""; public rngSeedOverride: string = "";
public rngOffset: integer = 0; public rngOffset: integer = 0;
/**
* Allows subscribers to listen for events
*
* Current Events:
* - {@linkcode BattleSceneEventType.MOVE_USED} {@linkcode MoveUsedEvent}
*/
public readonly eventTarget: EventTarget = new EventTarget();
constructor() { constructor() {
super("battle"); super("battle");
initSpecies();
initMoves();
initAbilities();
this.phaseQueue = []; this.phaseQueue = [];
this.phaseQueuePrepend = []; this.phaseQueuePrepend = [];
this.phaseQueuePrependSpliceIndex = -1; this.phaseQueuePrependSpliceIndex = -1;
@ -348,9 +352,9 @@ export default class BattleScene extends SceneBase {
this.candyBar.setup(); this.candyBar.setup();
this.fieldUI.add(this.candyBar); this.fieldUI.add(this.candyBar);
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO); this.biomeWaveText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO);
this.waveCountText.setOrigin(1, 0); this.biomeWaveText.setOrigin(1, 0);
this.fieldUI.add(this.waveCountText); this.fieldUI.add(this.biomeWaveText);
this.moneyText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "", TextStyle.MONEY); this.moneyText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, "", TextStyle.MONEY);
this.moneyText.setOrigin(1, 0); this.moneyText.setOrigin(1, 0);
@ -478,7 +482,7 @@ export default class BattleScene extends SceneBase {
} }
}); });
this.updateWaveCountText(); this.updateBiomeWaveText();
this.updateMoneyText(); this.updateMoneyText();
this.updateScoreText(); this.updateScoreText();
} }
@ -553,17 +557,17 @@ export default class BattleScene extends SceneBase {
const species = getPokemonSpecies(parseInt(s)); const species = getPokemonSpecies(parseInt(s));
loadPokemonAssets.push(species.loadAssets(this, false, 0, false)); loadPokemonAssets.push(species.loadAssets(this, false, 0, false));
} }
Promise.all(loadPokemonAssets).then(() => { Promise.all(loadPokemonAssets).then(() => {
const starterCandyColors = {}; const starterCandyColors = {};
const rgbaToHexFunc = (r, g, b) => [r, g, b].map(x => x.toString(16).padStart(2, '0')).join(''); const rgbaToHexFunc = (r, g, b) => [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
for (let s of Object.keys(speciesStarters)) { for (let s of Object.keys(speciesStarters)) {
const species = getPokemonSpecies(parseInt(s)); const species = getPokemonSpecies(parseInt(s));
starterCandyColors[species.speciesId] = species.generateCandyColors(this).map(c => rgbaToHexFunc(c[0], c[1], c[2])); starterCandyColors[species.speciesId] = species.generateCandyColors(this).map(c => rgbaToHexFunc(c[0], c[1], c[2]));
} }
console.log(JSON.stringify(starterCandyColors)); console.log(JSON.stringify(starterCandyColors));
resolve(); resolve();
@ -669,7 +673,7 @@ export default class BattleScene extends SceneBase {
addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container {
const container = this.add.container(x, y); const container = this.add.container(x, y);
const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride));
icon.setFrame(pokemon.getIconId(true)); icon.setFrame(pokemon.getIconId(true));
// Temporary fix to show pokemon's default icon if variant icon doesn't exist // Temporary fix to show pokemon's default icon if variant icon doesn't exist
@ -695,7 +699,7 @@ export default class BattleScene extends SceneBase {
const originalFrame = icon.frame; const originalFrame = icon.frame;
const iconHeight = (icon.frame.cutHeight <= fusionIcon.frame.cutHeight ? Math.ceil : Math.floor)((icon.frame.cutHeight + fusionIcon.frame.cutHeight) / 4); const iconHeight = (icon.frame.cutHeight <= fusionIcon.frame.cutHeight ? Math.ceil : Math.floor)((icon.frame.cutHeight + fusionIcon.frame.cutHeight) / 4);
// Inefficient, but for some reason didn't work with only the unique properties as part of the name // Inefficient, but for some reason didn't work with only the unique properties as part of the name
const iconFrameId = `${icon.frame.name}f${fusionIcon.frame.name}`; const iconFrameId = `${icon.frame.name}f${fusionIcon.frame.name}`;
@ -760,7 +764,7 @@ export default class BattleScene extends SceneBase {
} }
this.gameMode = gameModes[GameModes.CLASSIC]; this.gameMode = gameModes[GameModes.CLASSIC];
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24)); this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
console.log("Seed:", this.seed); console.log("Seed:", this.seed);
@ -789,11 +793,11 @@ export default class BattleScene extends SceneBase {
for (const p of this.getEnemyParty()) { for (const p of this.getEnemyParty()) {
p.destroy(); p.destroy();
} }
this.currentBattle = null; this.currentBattle = null;
this.waveCountText.setText(startingWave.toString()); this.biomeWaveText.setText(startingWave.toString());
this.waveCountText.setVisible(false); this.biomeWaveText.setVisible(false);
this.updateMoneyText(); this.updateMoneyText();
this.moneyText.setVisible(false); this.moneyText.setVisible(false);
@ -818,7 +822,7 @@ export default class BattleScene extends SceneBase {
this.trainer.setTexture(`trainer_${this.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`); this.trainer.setTexture(`trainer_${this.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
this.trainer.setPosition(406, 186); this.trainer.setPosition(406, 186);
this.trainer.setVisible(true); this.trainer.setVisible(true);
this.updateGameInfo(); this.updateGameInfo();
if (reloadI18n) { if (reloadI18n) {
@ -865,7 +869,7 @@ export default class BattleScene extends SceneBase {
this.resetSeed(newWaveIndex); this.resetSeed(newWaveIndex);
const playerField = this.getPlayerField(); const playerField = this.getPlayerField();
if (this.gameMode.hasFixedBattles && fixedBattles.hasOwnProperty(newWaveIndex) && trainerData === undefined) { if (this.gameMode.hasFixedBattles && fixedBattles.hasOwnProperty(newWaveIndex) && trainerData === undefined) {
battleConfig = fixedBattles[newWaveIndex]; battleConfig = fixedBattles[newWaveIndex];
newDouble = battleConfig.double; newDouble = battleConfig.double;
@ -986,12 +990,13 @@ export default class BattleScene extends SceneBase {
} }
} }
} }
return this.currentBattle; return this.currentBattle;
} }
newArena(biome: Biome): Arena { newArena(biome: Biome): Arena {
this.arena = new Arena(this, biome, Biome[biome].toLowerCase()); this.arena = new Arena(this, biome, Biome[biome].toLowerCase());
this.eventTarget.dispatchEvent(new NewArenaEvent());
this.arenaBg.pipelineData = { terrainColorRatio: this.arena.getBgTerrainColorRatioForBiome() }; this.arenaBg.pipelineData = { terrainColorRatio: this.arena.getBgTerrainColorRatioForBiome() };
@ -1157,7 +1162,7 @@ export default class BattleScene extends SceneBase {
if (!pokemon.pokerus || infectedIndexes.indexOf(p) > -1) { if (!pokemon.pokerus || infectedIndexes.indexOf(p) > -1) {
return; return;
} }
this.executeWithSeedOffset(() => { this.executeWithSeedOffset(() => {
if (p) { if (p) {
spread(p, -1); spread(p, -1);
@ -1242,16 +1247,17 @@ export default class BattleScene extends SceneBase {
}); });
} }
updateWaveCountText(): void { updateBiomeWaveText(): void {
const isBoss = !(this.currentBattle.waveIndex % 10); const isBoss = !(this.currentBattle.waveIndex % 10);
this.waveCountText.setText(this.currentBattle.waveIndex.toString()); const biomeString: string = getBiomeName(this.arena.biomeType);
this.waveCountText.setColor(!isBoss ? "#404040" : "#f89890"); this.biomeWaveText.setText( biomeString + " - " + this.currentBattle.waveIndex.toString());
this.waveCountText.setShadowColor(!isBoss ? "#ded6b5" : "#984038"); this.biomeWaveText.setColor(!isBoss ? "#ffffff" : "#f89890");
this.waveCountText.setVisible(true); this.biomeWaveText.setShadowColor(!isBoss ? "#636363" : "#984038");
this.biomeWaveText.setVisible(true);
} }
updateMoneyText(): void { updateMoneyText(): void {
this.moneyText.setText(`${this.money.toLocaleString("en-US")}`); this.moneyText.setText(`${Utils.formatLargeNumber(this.money, 1000)}`);
this.moneyText.setVisible(true); this.moneyText.setVisible(true);
} }
@ -1295,8 +1301,8 @@ export default class BattleScene extends SceneBase {
updateUIPositions(): void { updateUIPositions(): void {
const enemyModifierCount = this.enemyModifiers.filter(m => m.isIconVisible(this)).length; const enemyModifierCount = this.enemyModifiers.filter(m => m.isIconVisible(this)).length;
this.waveCountText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0)); this.biomeWaveText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0));
this.moneyText.setY(this.waveCountText.y + 10); this.moneyText.setY(this.biomeWaveText.y + 10);
this.scoreText.setY(this.moneyText.y + 10); this.scoreText.setY(this.moneyText.y + 10);
[ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); [ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10));
const offsetY = (this.scoreText.visible ? this.scoreText : this.moneyText).y + 15; const offsetY = (this.scoreText.visible ? this.scoreText : this.moneyText).y + 15;
@ -1622,7 +1628,7 @@ export default class BattleScene extends SceneBase {
this.currentPhase = this.phaseQueue.shift(); this.currentPhase = this.phaseQueue.shift();
this.currentPhase.start(); this.currentPhase.start();
} }
overridePhase(phase: Phase): boolean { overridePhase(phase: Phase): boolean {
if (this.standbyPhase) { if (this.standbyPhase) {
return false; return false;
@ -1721,7 +1727,7 @@ export default class BattleScene extends SceneBase {
this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true); this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true);
return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(success => resolve(success)); return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(success => resolve(success));
} }
for (const rm of modifiersToRemove) { for (const rm of modifiersToRemove) {
this.removeModifier(rm); this.removeModifier(rm);
} }
@ -1750,7 +1756,7 @@ export default class BattleScene extends SceneBase {
} else if (modifier instanceof FusePokemonModifier) { } else if (modifier instanceof FusePokemonModifier) {
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon); args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
} }
if (modifier.shouldApply(args)) { if (modifier.shouldApply(args)) {
const result = modifier.apply(args); const result = modifier.apply(args);
if (result instanceof Promise) { if (result instanceof Promise) {
@ -1760,7 +1766,7 @@ export default class BattleScene extends SceneBase {
} }
} }
} }
return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success)); return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success));
} else { } else {
const args = [ this ]; const args = [ this ];
@ -2109,7 +2115,7 @@ export default class BattleScene extends SceneBase {
return false; return false;
} }
updateGameInfo(): void { updateGameInfo(): void {
const gameInfo = { const gameInfo = {
playTime: this.sessionPlayTime ? this.sessionPlayTime : 0, playTime: this.sessionPlayTime ? this.sessionPlayTime : 0,

View File

@ -11,6 +11,7 @@ import { BattleSpec } from "./enums/battle-spec";
import { PlayerGender } from "./system/game-data"; import { PlayerGender } from "./system/game-data";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { PokeballType } from "./data/pokeball"; import { PokeballType } from "./data/pokeball";
import {trainerConfigs} from "#app/data/trainer-config";
export enum BattleType { export enum BattleType {
WILD, WILD,
@ -89,7 +90,7 @@ export default class Battle {
this.moneyScattered = 0; this.moneyScattered = 0;
this.lastUsedPokeball = null; this.lastUsedPokeball = null;
} }
private initBattleSpec(): void { private initBattleSpec(): void {
let spec = BattleSpec.DEFAULT; let spec = BattleSpec.DEFAULT;
if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) { if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) {
@ -116,14 +117,14 @@ export default class Battle {
} }
let levelOffset = 0; let levelOffset = 0;
const deviation = 10 / levelWaveIndex; const deviation = 10 / levelWaveIndex;
levelOffset = Math.abs(this.randSeedGaussForLevel(deviation)); levelOffset = Math.abs(this.randSeedGaussForLevel(deviation));
return Math.max(Math.round(baseLevel + levelOffset), 1); return Math.max(Math.round(baseLevel + levelOffset), 1);
} }
randSeedGaussForLevel(value: number): number { randSeedGaussForLevel(value: number): number {
let rand = 0; let rand = 0;
for (let i = value; i > 0; i--) { for (let i = value; i > 0; i--) {
rand += Phaser.Math.RND.realInRange(0, 1); rand += Phaser.Math.RND.realInRange(0, 1);
@ -162,7 +163,7 @@ export default class Battle {
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
scene.addMoney(moneyAmount.value); scene.addMoney(moneyAmount.value);
scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString("en-US")}!`, null, true); scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString("en-US")}!`, null, true);
scene.currentBattle.moneyScattered = 0; scene.currentBattle.moneyScattered = 0;
@ -309,6 +310,10 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get
: trainerPoolEntry; : trainerPoolEntry;
trainerTypes.push(trainerType); trainerTypes.push(trainerType);
} }
// If the trainer type has a double variant, there's a 33% chance of it being a double battle
if (trainerConfigs[trainerTypes[rand]].trainerTypeDouble) {
return new Trainer(scene, trainerTypes[rand], Utils.randSeedInt(3) ? TrainerVariant.DOUBLE : TrainerVariant.DEFAULT);
}
return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT); return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT);
}; };
} }
@ -331,15 +336,15 @@ export const fixedBattles: FixedBattleConfigs = {
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.RIKA, TrainerType.CRISPIN ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ],TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.POPPY, TrainerType.AMARYS ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY, TrainerType.AMARYS ])),
[186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, TrainerType.LARRY_ELITE, TrainerType.LACEY ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, [TrainerType.BEA_ELITE,TrainerType.ALLISTER_ELITE], TrainerType.LARRY_ELITE, TrainerType.LACEY ])),
[188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.HASSEL, TrainerType.DRAYTON ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI,TrainerType.RAIHAN_ELITE, TrainerType.HASSEL, TrainerType.DRAYTON ])),
[190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN, TrainerType.LEON ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU,TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
}; };

View File

@ -2,14 +2,14 @@ import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
import { Type } from "./type"; import { Type } from "./type";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { BattleStat, getBattleStatName } from "./battle-stat"; import { BattleStat, getBattleStatName } from "./battle-stat";
import { PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases"; import { MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases";
import { getPokemonMessage, getPokemonPrefix } from "../messages"; import { getPokemonMessage, getPokemonPrefix } from "../messages";
import { Weather, WeatherType } from "./weather"; import { Weather, WeatherType } from "./weather";
import { BattlerTag } from "./battler-tags"; import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
@ -20,8 +20,10 @@ import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import i18next, { Localizable } from "#app/plugins/i18n.js"; import i18next, { Localizable } from "#app/plugins/i18n.js";
import { Command } from "../ui/command-ui-handler"; import { Command } from "../ui/command-ui-handler";
import { getPokeballName } from "./pokeball";
import { BerryModifierType } from "#app/modifier/modifier-type"; import { BerryModifierType } from "#app/modifier/modifier-type";
import { getPokeballName } from "./pokeball";
import { Species } from "./enums/species";
import {BattlerIndex} from "#app/battle";
export class Ability implements Localizable { export class Ability implements Localizable {
public id: Abilities; public id: Abilities;
@ -68,10 +70,10 @@ export class Ability implements Localizable {
const attr = new AttrType(...args); const attr = new AttrType(...args);
attr.addCondition(condition); attr.addCondition(condition);
this.attrs.push(attr); this.attrs.push(attr);
return this; return this;
} }
hasAttr(attrType: { new(...args: any[]): AbAttr }): boolean { hasAttr(attrType: { new(...args: any[]): AbAttr }): boolean {
return !!this.getAttrs(attrType).length; return !!this.getAttrs(attrType).length;
} }
@ -117,7 +119,7 @@ export abstract class AbAttr {
constructor(showAbility: boolean = true) { constructor(showAbility: boolean = true) {
this.showAbility = showAbility; this.showAbility = showAbility;
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false; return false;
} }
@ -218,7 +220,7 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
pokemon.scene.unshiftPhase(statChangePhase); pokemon.scene.unshiftPhase(statChangePhase);
} }
} }
return true; return true;
} }
} }
@ -254,10 +256,10 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (pokemon.hp === pokemon.getMaxHp() && if (pokemon.hp === pokemon.getMaxHp() &&
pokemon.getMaxHp() > 1 && //Checks if pokemon has wonder_guard (which forces 1hp) pokemon.getMaxHp() > 1 && //Checks if pokemon has wonder_guard (which forces 1hp)
(args[0] as Utils.NumberHolder).value >= pokemon.hp){ //Damage >= hp (args[0] as Utils.NumberHolder).value >= pokemon.hp) { //Damage >= hp
return pokemon.addTag(BattlerTagType.STURDY, 1); return pokemon.addTag(BattlerTagType.STURDY, 1);
} }
return false; return false;
} }
} }
@ -265,7 +267,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
export class BlockItemTheftAbAttr extends AbAttr { export class BlockItemTheftAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
cancelled.value = true; cancelled.value = true;
return true; return true;
} }
@ -280,7 +282,7 @@ export class StabBoostAbAttr extends AbAttr {
(args[0] as Utils.NumberHolder).value += 0.5; (args[0] as Utils.NumberHolder).value += 0.5;
return true; return true;
} }
return false; return false;
} }
} }
@ -371,7 +373,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
} }
return true; return true;
} }
return false; return false;
} }
} }
@ -397,7 +399,7 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
} }
return ret; return ret;
} }
} }
@ -423,7 +425,7 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id); pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
} }
} }
return ret; return ret;
} }
} }
@ -458,7 +460,7 @@ export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon.formIndex === 0 && pokemon.battleData.hitCount !== 0 && (move.getMove().category === MoveCategory.SPECIAL || move.getMove().category === MoveCategory.PHYSICAL)) { if (pokemon.formIndex === 0 && pokemon.battleData.hitCount !== 0 && (move.getMove().category === MoveCategory.SPECIAL || move.getMove().category === MoveCategory.PHYSICAL)) {
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt); const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
if (!recoilDamage) { if (!recoilDamage) {
return false; return false;
@ -498,16 +500,16 @@ export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
const attackPriority = new Utils.IntegerHolder(move.getMove().priority); const attackPriority = new Utils.IntegerHolder(move.getMove().priority);
applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority); applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority);
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority); applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
if(move.getMove().moveTarget===MoveTarget.USER) { if (move.getMove().moveTarget===MoveTarget.USER) {
return false; return false;
} }
if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) { if (attackPriority.value > 0 && !move.getMove().isMultiTarget()) {
cancelled.value = true; cancelled.value = true;
return true; return true;
} }
return false; return false;
} }
} }
@ -554,7 +556,10 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args); const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args);
if (ret) { if (ret) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); const simulated = args.length > 1 && args[1];
if (!simulated) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
}
} }
return ret; return ret;
@ -782,7 +787,7 @@ export class PostDefendCritStatChangeAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
return true; return true;
} }
@ -799,14 +804,14 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
this.damageRatio = damageRatio; this.damageRatio = damageRatio;
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
attacker.turnData.damageTaken += Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)); attacker.turnData.damageTaken += Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio));
return true; return true;
} }
return false; return false;
} }
@ -837,7 +842,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
constructor() { constructor() {
super(); super();
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) {
const tempAbilityId = attacker.getAbility().id; const tempAbilityId = attacker.getAbility().id;
@ -845,7 +850,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
pokemon.summonData.ability = tempAbilityId; pokemon.summonData.ability = tempAbilityId;
return true; return true;
} }
return false; return false;
} }
@ -861,14 +866,14 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
super(); super();
this.ability = ability; this.ability = ability;
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) {
attacker.summonData.ability = this.ability; attacker.summonData.ability = this.ability;
return true; return true;
} }
return false; return false;
} }
@ -887,7 +892,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
this.chance = chance; this.chance = chance;
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!attacker.summonData.disabledMove) { if (!attacker.summonData.disabledMove) {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) {
@ -946,7 +951,7 @@ export class VariableMovePowerAbAttr extends PreAttackAbAttr {
export class VariableMoveTypeAbAttr extends AbAttr { export class VariableMoveTypeAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
//const power = args[0] as Utils.IntegerHolder; //const power = args[0] as Utils.IntegerHolder;
return false; return false;
} }
} }
@ -955,7 +960,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
private newType: Type; private newType: Type;
private powerMultiplier: number; private powerMultiplier: number;
constructor(matchType: Type, newType: Type, powerMultiplier: number){ constructor(matchType: Type, newType: Type, powerMultiplier: number) {
super(true); super(true);
this.matchType = matchType; this.matchType = matchType;
this.newType = newType; this.newType = newType;
@ -969,7 +974,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier; (args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
return true; return true;
} }
return false; return false;
} }
} }
@ -986,7 +991,7 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr {
private powerMultiplier: number; private powerMultiplier: number;
private condition: PokemonAttackCondition; private condition: PokemonAttackCondition;
constructor(newType: Type, powerMultiplier: number, condition: PokemonAttackCondition){ constructor(newType: Type, powerMultiplier: number, condition: PokemonAttackCondition) {
super(true); super(true);
this.newType = newType; this.newType = newType;
this.powerMultiplier = powerMultiplier; this.powerMultiplier = powerMultiplier;
@ -1008,21 +1013,21 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr {
/** /**
* Class for abilities that boost the damage of moves * Class for abilities that boost the damage of moves
* For abilities that boost the base power of moves, see VariableMovePowerAbAttr * For abilities that boost the base power of moves, see VariableMovePowerAbAttr
* @param damageMultiplier the amount to multiply the damage by * @param damageMultiplier the amount to multiply the damage by
* @param condition the condition for this ability to be applied * @param condition the condition for this ability to be applied
*/ */
export class DamageBoostAbAttr extends PreAttackAbAttr { export class DamageBoostAbAttr extends PreAttackAbAttr {
private damageMultiplier: number; private damageMultiplier: number;
private condition: PokemonAttackCondition; private condition: PokemonAttackCondition;
constructor(damageMultiplier: number, condition: PokemonAttackCondition){ constructor(damageMultiplier: number, condition: PokemonAttackCondition) {
super(true); super(true);
this.damageMultiplier = damageMultiplier; this.damageMultiplier = damageMultiplier;
this.condition = condition; this.condition = condition;
} }
/** /**
* *
* @param pokemon the attacker pokemon * @param pokemon the attacker pokemon
* @param passive N/A * @param passive N/A
* @param defender the target pokemon * @param defender the target pokemon
@ -1081,7 +1086,7 @@ export class LowHpMoveTypePowerBoostAbAttr extends MoveTypePowerBoostAbAttr {
export class FieldVariableMovePowerAbAttr extends AbAttr { export class FieldVariableMovePowerAbAttr extends AbAttr {
applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
//const power = args[0] as Utils.NumberHolder; //const power = args[0] as Utils.NumberHolder;
return false; return false;
} }
} }
@ -1210,7 +1215,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
private chance: (user: Pokemon, target: Pokemon, move: PokemonMove) => integer; private chance: (user: Pokemon, target: Pokemon, move: PokemonMove) => integer;
private effects: BattlerTagType[]; private effects: BattlerTagType[];
constructor(contactRequired: boolean, chance: (user: Pokemon, target: Pokemon, move: PokemonMove) => integer, ...effects: BattlerTagType[]) { constructor(contactRequired: boolean, chance: (user: Pokemon, target: Pokemon, move: PokemonMove) => integer, ...effects: BattlerTagType[]) {
super(); super();
@ -1287,7 +1292,7 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
return true; return true;
} }
} }
@ -1334,7 +1339,7 @@ export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
return true; return true;
} }
} }
@ -1350,7 +1355,7 @@ export class CopyFaintedAllyAbilityAbAttr extends PostKnockOutAbAttr {
pokemon.scene.queueMessage(getPokemonMessage(knockedOut, `'s ${allAbilities[knockedOut.getAbility().id].name} was taken over!`)); pokemon.scene.queueMessage(getPokemonMessage(knockedOut, `'s ${allAbilities[knockedOut.getAbility().id].name} was taken over!`));
return true; return true;
} }
return false; return false;
} }
} }
@ -1366,7 +1371,7 @@ export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
return true; return true;
} }
} }
/** /**
* Ignores opponent's evasion stat changes when determining if a move hits or not * Ignores opponent's evasion stat changes when determining if a move hits or not
* @extends AbAttr * @extends AbAttr
* @see {@linkcode apply} * @see {@linkcode apply}
@ -1382,14 +1387,14 @@ export class IgnoreOpponentEvasionAbAttr extends AbAttr {
* @param cancelled N/A * @param cancelled N/A
* @param args [0] {@linkcode Utils.IntegerHolder} of BattleStat.EVA * @param args [0] {@linkcode Utils.IntegerHolder} of BattleStat.EVA
* @returns if evasion level was successfully considered as 0 * @returns if evasion level was successfully considered as 0
*/ */
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]) { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]) {
(args[0] as Utils.IntegerHolder).value = 0; (args[0] as Utils.IntegerHolder).value = 0;
return true; return true;
} }
} }
export class IntimidateImmunityAbAttr extends AbAttr { export class IntimidateImmunityAbAttr extends AbAttr {
constructor() { constructor() {
super(false); super(false);
} }
@ -1404,7 +1409,7 @@ export class IntimidateImmunityAbAttr extends AbAttr {
} }
} }
export class PostIntimidateStatChangeAbAttr extends AbAttr { export class PostIntimidateStatChangeAbAttr extends AbAttr {
private stats: BattleStat[]; private stats: BattleStat[];
private levels: integer; private levels: integer;
private overwrites: boolean; private overwrites: boolean;
@ -1445,7 +1450,7 @@ export class PostSummonMessageAbAttr extends PostSummonAbAttr {
} }
} }
export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr { export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr {
//Attr doesn't force pokemon name on the message //Attr doesn't force pokemon name on the message
private message: string; private message: string;
@ -1455,7 +1460,7 @@ export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr {
this.message = message; this.message = message;
} }
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
pokemon.scene.queueMessage(this.message); pokemon.scene.queueMessage(this.message);
return true; return true;
@ -1534,7 +1539,7 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
Math.max(Math.floor(pokemon.getMaxHp() / this.healRatio), 1), getPokemonMessage(target, ` drank down all the\nmatcha that ${pokemon.name} made!`), true, !this.showAnim)); Math.max(Math.floor(pokemon.getMaxHp() / this.healRatio), 1), getPokemonMessage(target, ` drank down all the\nmatcha that ${pokemon.name} made!`), true, !this.showAnim));
return true; return true;
} }
return false; return false;
} }
} }
@ -1563,7 +1568,7 @@ export class PostSummonClearAllyStatsAbAttr extends PostSummonAbAttr {
return true; return true;
} }
return false; return false;
} }
} }
@ -1576,12 +1581,12 @@ export class DownloadAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
this.enemyDef = 0; this.enemyDef = 0;
this.enemySpDef = 0; this.enemySpDef = 0;
for (const opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
this.enemyDef += opponent.stats[BattleStat.DEF]; this.enemyDef += opponent.stats[BattleStat.DEF];
this.enemySpDef += opponent.stats[BattleStat.SPDEF]; this.enemySpDef += opponent.stats[BattleStat.SPDEF];
} }
if (this.enemyDef < this.enemySpDef) { if (this.enemyDef < this.enemySpDef) {
this.stats = [BattleStat.ATK]; this.stats = [BattleStat.ATK];
} else { } else {
@ -1592,7 +1597,7 @@ export class DownloadAbAttr extends PostSummonAbAttr {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1));
return true; return true;
} }
return false; return false;
} }
} }
@ -1654,7 +1659,7 @@ export class TraceAbAttr extends PostSummonAbAttr {
if (!targets.length) { if (!targets.length) {
return false; return false;
} }
let target: Pokemon; let target: Pokemon;
if (targets.length > 1) { if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
@ -1702,7 +1707,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
pokemon.summonData.battleStats = target.summonData.battleStats.slice(0); pokemon.summonData.battleStats = target.summonData.battleStats.slice(0);
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp)); pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp));
pokemon.summonData.types = target.getTypes(); pokemon.summonData.types = target.getTypes();
pokemon.scene.playSound("PRSFX- Transform"); pokemon.scene.playSound("PRSFX- Transform");
pokemon.loadAssets(false).then(() => pokemon.playAnim()); pokemon.loadAssets(false).then(() => pokemon.playAnim());
@ -1768,7 +1773,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
cancelled.value = true; cancelled.value = true;
return true; return true;
} }
return false; return false;
} }
@ -1777,6 +1782,39 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
} }
} }
/**
* This attribute applies confusion to the target whenever the user
* directly poisons them with a move, e.g. Poison Puppeteer.
* Called in {@linkcode StatusEffectAttr}.
* @extends PostAttackAbAttr
* @see {@linkcode applyPostAttack}
*/
export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr {
/** List of effects to apply confusion after */
private effects: StatusEffect[];
constructor(...effects: StatusEffect[]) {
super();
this.effects = effects;
}
/**
* Applies confusion to the target pokemon.
* @param pokemon {@link Pokemon} attacking
* @param passive N/A
* @param defender {@link Pokemon} defending
* @param move {@link Move} used to apply status effect and confusion
* @param hitResult N/A
* @param args [0] {@linkcode StatusEffect} applied by move
* @returns true if defender is confused
*/
applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (this.effects.indexOf(args[0]) > -1 && !defender.isFainted()) {
return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3,2), move.moveId, defender.id);
}
return false;
}
}
export class PreSetStatusAbAttr extends AbAttr { export class PreSetStatusAbAttr extends AbAttr {
applyPreSetStatus(pokemon: Pokemon, passive: boolean, effect: StatusEffect, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> { applyPreSetStatus(pokemon: Pokemon, passive: boolean, effect: StatusEffect, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false; return false;
@ -1860,7 +1898,7 @@ export class MultCritAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const critMult = args[0] as Utils.NumberHolder; const critMult = args[0] as Utils.NumberHolder;
if (critMult.value > 1){ if (critMult.value > 1) {
critMult.value *= this.multAmount; critMult.value *= this.multAmount;
return true; return true;
} }
@ -1885,14 +1923,14 @@ export class ConditionalCritAbAttr extends AbAttr {
/** /**
* @param pokemon {@linkcode Pokemon} user. * @param pokemon {@linkcode Pokemon} user.
* @param args [0] {@linkcode Utils.BooleanHolder} If true critical hit is guaranteed. * @param args [0] {@linkcode Utils.BooleanHolder} If true critical hit is guaranteed.
* [1] {@linkcode Pokemon} Target. * [1] {@linkcode Pokemon} Target.
* [2] {@linkcode Move} used by ability user. * [2] {@linkcode Move} used by ability user.
*/ */
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const target = (args[1] as Pokemon); const target = (args[1] as Pokemon);
const move = (args[2] as Move); const move = (args[2] as Move);
if(!this.condition(pokemon,target,move)) { if (!this.condition(pokemon,target,move)) {
return false; return false;
} }
@ -1930,7 +1968,7 @@ export class IncrementMovePriorityAbAttr extends AbAttr {
if (!this.moveIncrementFunc(pokemon, args[0] as Move)) { if (!this.moveIncrementFunc(pokemon, args[0] as Move)) {
return false; return false;
} }
(args[1] as Utils.IntegerHolder).value += this.increaseAmount; (args[1] as Utils.IntegerHolder).value += this.increaseAmount;
return true; return true;
} }
@ -2013,7 +2051,7 @@ function getAnticipationCondition(): AbAttrCondition {
+(opponent.ivs[Stat.SPD] & 1) * 8 +(opponent.ivs[Stat.SPD] & 1) * 8
+(opponent.ivs[Stat.SPATK] & 1) * 16 +(opponent.ivs[Stat.SPATK] & 1) * 16
+(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63); +(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
const type = [ const type = [
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
@ -2065,10 +2103,10 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
} else { } else {
movePower = move.getMove().power; movePower = move.getMove().power;
} }
if (movePower > maxPowerSeen) { if (movePower > maxPowerSeen) {
maxPowerSeen = movePower; maxPowerSeen = movePower;
maxMove = move.getName(); maxMove = move.getName();
} }
} }
} }
@ -2142,7 +2180,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
constructor(healFactor: integer, ...weatherTypes: WeatherType[]) { constructor(healFactor: integer, ...weatherTypes: WeatherType[]) {
super(...weatherTypes); super(...weatherTypes);
this.healFactor = healFactor; this.healFactor = healFactor;
} }
@ -2164,7 +2202,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
constructor(damageFactor: integer, ...weatherTypes: WeatherType[]) { constructor(damageFactor: integer, ...weatherTypes: WeatherType[]) {
super(...weatherTypes); super(...weatherTypes);
this.damageFactor = damageFactor; this.damageFactor = damageFactor;
} }
@ -2242,13 +2280,13 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
this.target = pokemon; this.target = pokemon;
} }
if (this.target?.status) { if (this.target?.status) {
this.target.scene.queueMessage(getPokemonMessage(this.target, getStatusEffectHealText(this.target.status?.effect))); this.target.scene.queueMessage(getPokemonMessage(this.target, getStatusEffectHealText(this.target.status?.effect)));
this.target.resetStatus(false); this.target.resetStatus(false);
this.target.updateInfo(); this.target.updateInfo();
return true; return true;
} }
return false; return false;
} }
} }
@ -2403,44 +2441,44 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
/** /**
* Deals damage to all sleeping opponents equal to 1/8 of their max hp (min 1) * Deals damage to all sleeping opponents equal to 1/8 of their max hp (min 1)
* @param {Pokemon} pokemon Pokemon that has this ability * @param {Pokemon} pokemon Pokemon that has this ability
* @param {boolean} passive N/A * @param {boolean} passive N/A
* @param {any[]} args N/A * @param {any[]} args N/A
* @returns {boolean} true if any opponents are sleeping * @returns {boolean} true if any opponents are sleeping
*/ */
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
let hadEffect: boolean = false; let hadEffect: boolean = false;
for(const opp of pokemon.getOpponents()) { for (const opp of pokemon.getOpponents()) {
if(opp.status !== undefined && opp.status.effect === StatusEffect.SLEEP) { if (opp.status !== undefined && opp.status.effect === StatusEffect.SLEEP) {
opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER); opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER);
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`})); pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`}));
hadEffect = true; hadEffect = true;
} }
} }
return hadEffect; return hadEffect;
} }
} }
/** /**
* Grabs the last failed Pokeball used * Grabs the last failed Pokeball used
* @extends PostTurnAbAttr * @extends PostTurnAbAttr
* @see {@linkcode applyPostTurn} */ * @see {@linkcode applyPostTurn} */
export class FetchBallAbAttr extends PostTurnAbAttr { export class FetchBallAbAttr extends PostTurnAbAttr {
constructor() { constructor() {
super(); super();
} }
/** /**
* Adds the last used Pokeball back into the player's inventory * Adds the last used Pokeball back into the player's inventory
* @param pokemon {@linkcode Pokemon} with this ability * @param pokemon {@linkcode Pokemon} with this ability
* @param passive N/A * @param passive N/A
* @param args N/A * @param args N/A
* @returns true if player has used a pokeball and this pokemon is owned by the player * @returns true if player has used a pokeball and this pokemon is owned by the player
*/ */
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const lastUsed = pokemon.scene.currentBattle.lastUsedPokeball; const lastUsed = pokemon.scene.currentBattle.lastUsedPokeball;
if(lastUsed !== null && pokemon.isPlayer) { if (lastUsed !== null && pokemon.isPlayer) {
pokemon.scene.pokeballCounts[lastUsed]++; pokemon.scene.pokeballCounts[lastUsed]++;
pokemon.scene.currentBattle.lastUsedPokeball = null; pokemon.scene.currentBattle.lastUsedPokeball = null;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`));
@ -2484,6 +2522,62 @@ export class PostBiomeChangeTerrainChangeAbAttr extends PostBiomeChangeAbAttr {
} }
} }
/**
* Triggers just after a move is used either by the opponent or the player
* @extends AbAttr
*/
export class PostMoveUsedAbAttr extends AbAttr {
applyPostMoveUsed(pokemon: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], args: any[]): boolean | Promise<boolean> {
return false;
}
}
/**
* Triggers after a dance move is used either by the opponent or the player
* @extends PostMoveUsedAbAttr
*/
export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
/**
* Resolves the Dancer ability by replicating the move used by the source of the dance
* either on the source itself or on the target of the dance
* @param dancer {@linkcode Pokemon} with Dancer ability
* @param move {@linkcode PokemonMove} Dancing move used by the source
* @param source {@linkcode Pokemon} that used the dancing move
* @param targets {@linkcode BattlerIndex}Targets of the dancing move
* @param args N/A
*
* @return true if the Dancer ability was resolved
*/
applyPostMoveUsed(dancer: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], args: any[]): boolean | Promise<boolean> {
// The move to replicate cannot come from the Dancer
if (source.getBattlerIndex() !== dancer.getBattlerIndex()) {
// If the move is an AttackMove or a StatusMove the Dancer must replicate the move on the source of the Dance
if (move.getMove() instanceof AttackMove || move.getMove() instanceof StatusMove) {
const target = this.getTarget(dancer, source, targets);
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, target, move, true));
} else if (move.getMove() instanceof SelfStatusMove) {
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [dancer.getBattlerIndex()], move, true));
}
}
return true;
}
/**
* Get the correct targets of Dancer ability
*
* @param dancer {@linkcode Pokemon} Pokemon with Dancer ability
* @param source {@linkcode Pokemon} Source of the dancing move
* @param targets {@linkcode BattlerIndex} Targets of the dancing move
*/
getTarget(dancer: Pokemon, source: Pokemon, targets: BattlerIndex[]) : BattlerIndex[] {
if (dancer.isPlayer()) {
return source.isPlayer() ? targets : [source.getBattlerIndex()];
}
return source.isPlayer() ? [source.getBattlerIndex()] : targets;
}
}
export class StatChangeMultiplierAbAttr extends AbAttr { export class StatChangeMultiplierAbAttr extends AbAttr {
private multiplier: integer; private multiplier: integer;
@ -2575,7 +2669,7 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr {
* @returns if enemy Pokemon is trapped or not * @returns if enemy Pokemon is trapped or not
*/ */
applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean { applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean {
if (otherPokemon.getTypes().includes(Type.GHOST)){ if (otherPokemon.getTypes().includes(Type.GHOST)) {
trapped.value = false; trapped.value = false;
return false; return false;
} }
@ -2630,7 +2724,7 @@ export class PostFaintAbAttr extends AbAttr {
export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
private damageRatio: integer; private damageRatio: integer;
constructor(damageRatio: integer) { constructor(damageRatio: integer) {
super(); super();
@ -2641,7 +2735,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)); pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled));
if (cancelled) { if (cancelled.value) {
return false; return false;
} }
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
@ -2657,7 +2751,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
} }
} }
/** /**
* Attribute used for abilities (Innards Out) that damage the opponent based on how much HP the last attack used to knock out the owner of the ability. * Attribute used for abilities (Innards Out) that damage the opponent based on how much HP the last attack used to knock out the owner of the ability.
*/ */
export class PostFaintHPDamageAbAttr extends PostFaintAbAttr { export class PostFaintHPDamageAbAttr extends PostFaintAbAttr {
@ -2670,7 +2764,7 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr {
attacker.damageAndUpdate((damage), HitResult.OTHER); attacker.damageAndUpdate((damage), HitResult.OTHER);
attacker.turnData.damageTaken += damage; attacker.turnData.damageTaken += damage;
return true; return true;
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${abilityName} hurt\nits attacker!`); return getPokemonMessage(pokemon, `'s ${abilityName} hurt\nits attacker!`);
@ -2690,7 +2784,7 @@ export class RedirectMoveAbAttr extends AbAttr {
return false; return false;
} }
canRedirect(moveId: Moves): boolean { canRedirect(moveId: Moves): boolean {
const move = allMoves[moveId]; const move = allMoves[moveId];
return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t); return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t);
@ -2918,6 +3012,29 @@ export class IgnoreTypeStatusEffectImmunityAbAttr extends AbAttr {
} }
} }
/**
* Gives money to the user after the battle.
*
* @extends PostBattleAbAttr
* @see {@linkcode applyPostBattle}
*/
export class MoneyAbAttr extends PostBattleAbAttr {
constructor() {
super();
}
/**
* @param pokemon {@linkcode Pokemon} that is the user of this ability.
* @param passive N/A
* @param args N/A
* @returns true
*/
applyPostBattle(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
pokemon.scene.currentBattle.moneyScattered += pokemon.scene.getWaveMoneyAmount(0.2);
return true;
}
}
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr }, function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> { pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
@ -3013,6 +3130,11 @@ export function applyPostDefendAbAttrs(attrType: { new(...args: any[]): PostDefe
return applyAbAttrsInternal<PostDefendAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostDefend(pokemon, passive, attacker, move, hitResult, args), args); return applyAbAttrsInternal<PostDefendAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostDefend(pokemon, passive, attacker, move, hitResult, args), args);
} }
export function applyPostMoveUsedAbAttrs(attrType: { new(...args: any[]): PostMoveUsedAbAttr },
pokemon: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PostMoveUsedAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostMoveUsed(pokemon, move, source, targets, args), args);
}
export function applyBattleStatMultiplierAbAttrs(attrType: { new(...args: any[]): BattleStatMultiplierAbAttr }, export function applyBattleStatMultiplierAbAttrs(attrType: { new(...args: any[]): BattleStatMultiplierAbAttr },
pokemon: Pokemon, battleStat: BattleStat, statValue: Utils.NumberHolder, ...args: any[]): Promise<void> { pokemon: Pokemon, battleStat: BattleStat, statValue: Utils.NumberHolder, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<BattleStatMultiplierAbAttr>(attrType, pokemon, (attr, passive) => attr.applyBattleStat(pokemon, passive, battleStat, statValue, args), args); return applyAbAttrsInternal<BattleStatMultiplierAbAttr>(attrType, pokemon, (attr, passive) => attr.applyBattleStat(pokemon, passive, battleStat, statValue, args), args);
@ -3031,7 +3153,7 @@ export function applyPostAttackAbAttrs(attrType: { new(...args: any[]): PostAtta
export function applyPostKnockOutAbAttrs(attrType: { new(...args: any[]): PostKnockOutAbAttr }, export function applyPostKnockOutAbAttrs(attrType: { new(...args: any[]): PostKnockOutAbAttr },
pokemon: Pokemon, knockedOut: Pokemon, ...args: any[]): Promise<void> { pokemon: Pokemon, knockedOut: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PostKnockOutAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostKnockOut(pokemon, passive, knockedOut, args), args); return applyAbAttrsInternal<PostKnockOutAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostKnockOut(pokemon, passive, knockedOut, args), args);
} }
export function applyPostVictoryAbAttrs(attrType: { new(...args: any[]): PostVictoryAbAttr }, export function applyPostVictoryAbAttrs(attrType: { new(...args: any[]): PostVictoryAbAttr },
pokemon: Pokemon, ...args: any[]): Promise<void> { pokemon: Pokemon, ...args: any[]): Promise<void> {
@ -3133,7 +3255,7 @@ export function initAbilities() {
new Ability(Abilities.BATTLE_ARMOR, 3) new Ability(Abilities.BATTLE_ARMOR, 3)
.attr(BlockCritAbAttr) .attr(BlockCritAbAttr)
.ignorable(), .ignorable(),
new Ability(Abilities.STURDY, 3) new Ability(Abilities.STURDY, 3)
.attr(PreDefendFullHpEndureAbAttr) .attr(PreDefendFullHpEndureAbAttr)
.attr(BlockOneHitKOAbAttr) .attr(BlockOneHitKOAbAttr)
.ignorable(), .ignorable(),
@ -3185,7 +3307,7 @@ export function initAbilities() {
.attr(IntimidateImmunityAbAttr) .attr(IntimidateImmunityAbAttr)
.ignorable(), .ignorable(),
new Ability(Abilities.SUCTION_CUPS, 3) new Ability(Abilities.SUCTION_CUPS, 3)
.attr(ForceSwitchOutImmunityAbAttr) .attr(ForceSwitchOutImmunityAbAttr)
.ignorable(), .ignorable(),
new Ability(Abilities.INTIMIDATE, 3) new Ability(Abilities.INTIMIDATE, 3)
.attr(PostSummonStatChangeAbAttr, BattleStat.ATK, -1, false, true), .attr(PostSummonStatChangeAbAttr, BattleStat.ATK, -1, false, true),
@ -3395,7 +3517,7 @@ export function initAbilities() {
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2) .conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5), .conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
new Ability(Abilities.NORMALIZE, 4) new Ability(Abilities.NORMALIZE, 4)
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL && .attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL &&
move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST), move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST),
new Ability(Abilities.SNIPER, 4) new Ability(Abilities.SNIPER, 4)
.attr(MultCritAbAttr, 1.5), .attr(MultCritAbAttr, 1.5),
@ -3458,7 +3580,7 @@ export function initAbilities() {
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW) .attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SNOW), .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SNOW),
new Ability(Abilities.HONEY_GATHER, 4) new Ability(Abilities.HONEY_GATHER, 4)
.unimplemented(), .attr(MoneyAbAttr),
new Ability(Abilities.FRISK, 4) new Ability(Abilities.FRISK, 4)
.attr(FriskAbAttr), .attr(FriskAbAttr),
new Ability(Abilities.RECKLESS, 4) new Ability(Abilities.RECKLESS, 4)
@ -3518,8 +3640,8 @@ export function initAbilities() {
.attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user.status?.effect === StatusEffect.BURN, 1.5), .attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user.status?.effect === StatusEffect.BURN, 1.5),
new Ability(Abilities.HARVEST, 5) new Ability(Abilities.HARVEST, 5)
.attr( .attr(
PostTurnLootAbAttr, PostTurnLootAbAttr,
"EATEN_BERRIES", "EATEN_BERRIES",
/** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */ /** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */
(pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1) (pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1)
) )
@ -3769,7 +3891,7 @@ export function initAbilities() {
.attr(PostFaintHPDamageAbAttr) .attr(PostFaintHPDamageAbAttr)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.DANCER, 7) new Ability(Abilities.DANCER, 7)
.unimplemented(), .attr(PostDancingMoveAbAttr),
new Ability(Abilities.BATTERY, 7) new Ability(Abilities.BATTERY, 7)
.unimplemented(), .unimplemented(),
new Ability(Abilities.FLUFFY, 7) new Ability(Abilities.FLUFFY, 7)
@ -4032,7 +4154,7 @@ export function initAbilities() {
.attr(PostDefendApplyArenaTrapTagAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, ArenaTagType.TOXIC_SPIKES) .attr(PostDefendApplyArenaTrapTagAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, ArenaTagType.TOXIC_SPIKES)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.ARMOR_TAIL, 9) new Ability(Abilities.ARMOR_TAIL, 9)
.attr(FieldPriorityMoveImmunityAbAttr) .attr(FieldPriorityMoveImmunityAbAttr)
.ignorable(), .ignorable(),
new Ability(Abilities.EARTH_EATER, 9) new Ability(Abilities.EARTH_EATER, 9)
.attr(TypeImmunityHealAbAttr, Type.GROUND) .attr(TypeImmunityHealAbAttr, Type.GROUND)
@ -4091,6 +4213,6 @@ export function initAbilities() {
new Ability(Abilities.POISON_PUPPETEER, 9) new Ability(Abilities.POISON_PUPPETEER, 9)
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.unimplemented(), .conditionalAttr(pokemon => pokemon.species.speciesId===Species.PECHARUNT,ConfusionOnStatusEffectAbAttr,StatusEffect.POISON,StatusEffect.TOXIC)
); );
} }

View File

@ -103,7 +103,7 @@ export async function printPokemon() {
const offset = 0; const offset = 0;
const pokemonResponse = await api.pokemon.listPokemons(offset, 2000); const pokemonResponse = await api.pokemon.listPokemons(offset, 2000);
pokemonArr = pokemonResponse.results; pokemonArr = pokemonResponse.results;
const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase()); const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase());
@ -121,7 +121,7 @@ export async function printPokemon() {
if (!dexIdMatch) { if (!dexIdMatch) {
continue; continue;
} }
const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1]; const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1];
if (!matchingSpecies) { if (!matchingSpecies) {
@ -236,7 +236,7 @@ export async function printPokemon() {
let generationIndex = 0; let generationIndex = 0;
if (!region) { if (!region) {
while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]){} while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]) {}
} else { } else {
generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6; generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6;
} }
@ -448,7 +448,7 @@ export async function printAbilities() {
const replaceText = true; const replaceText = true;
let abilityContent: string = await fs.readFile("./src/data/ability.ts"); let abilityContent: string = await fs.readFile("./src/data/ability.ts");
const api = new MainClient(); const api = new MainClient();
let enumStr = "export enum Abilities {\n NONE,"; let enumStr = "export enum Abilities {\n NONE,";
@ -516,7 +516,7 @@ export async function printMoves() {
const replaceText = true; const replaceText = true;
let moveContent: string = await fs.readFile("./src/data/move.ts"); let moveContent: string = await fs.readFile("./src/data/move.ts");
const api = new MainClient(); const api = new MainClient();
let enumStr = "export enum Moves {\n NONE,"; let enumStr = "export enum Moves {\n NONE,";
@ -528,7 +528,7 @@ export async function printMoves() {
const offset = 0; const offset = 0;
const movesResponse = await api.move.listMoves(offset, 2000); const movesResponse = await api.move.listMoves(offset, 2000);
moves = movesResponse.results; moves = movesResponse.results;
console.log(moves); console.log(moves);
for (const m of moves) { for (const m of moves) {
@ -594,7 +594,7 @@ export async function printTmSpecies() {
const api = new MainClient(); const api = new MainClient();
const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves); const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves);
for (const moveId of moveIds) { for (const moveId of moveIds) {
const move = await api.move.getMoveById(moveId); const move = await api.move.getMoveById(moveId);
@ -643,9 +643,9 @@ export async function printTmSpecies() {
console.log("NO MATCH", species.name); console.log("NO MATCH", species.name);
continue; continue;
} }
const speciesKey = Species[matchingSpecies.speciesId]; const speciesKey = Species[matchingSpecies.speciesId];
const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey); const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey);
if (matchingIndex === -1) { if (matchingIndex === -1) {

View File

@ -1,7 +1,7 @@
import { Arena } from "../field/arena"; import { Arena } from "../field/arena";
import { Type } from "./type"; import { Type } from "./type";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { MoveCategory, allMoves } from "./move"; import { MoveCategory, allMoves, MoveTarget } from "./move";
import { getPokemonMessage } from "../messages"; import { getPokemonMessage } from "../messages";
import Pokemon, { HitResult, PokemonMove } from "../field/pokemon"; import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
import { MoveEffectPhase, PokemonHealPhase, StatChangePhase} from "../phases"; import { MoveEffectPhase, PokemonHealPhase, StatChangePhase} from "../phases";
@ -11,6 +11,7 @@ import { Moves } from "./enums/moves";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability"; import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
import { BattleStat } from "./battle-stat"; import { BattleStat } from "./battle-stat";
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
export enum ArenaTagSide { export enum ArenaTagSide {
BOTH, BOTH,
@ -72,7 +73,7 @@ export class MistTag extends ArenaTag {
(args[0] as Utils.BooleanHolder).value = true; (args[0] as Utils.BooleanHolder).value = true;
arena.scene.queueMessage("The mist prevented\nthe lowering of stats!"); arena.scene.queueMessage("The mist prevented\nthe lowering of stats!");
return true; return true;
} }
} }
@ -146,6 +147,128 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
} }
} }
type ProtectConditionFunc = (...args: any[]) => boolean;
/**
* Abstract class to implement conditional team protection
* applies protection based on the attributes of incoming moves
* @param protectConditionFunc: The function determining if an incoming move is negated
*/
abstract class ConditionalProtectTag extends ArenaTag {
protected protectConditionFunc: ProtectConditionFunc;
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, condition: ProtectConditionFunc) {
super(tagType, 1, sourceMove, sourceId, side);
this.protectConditionFunc = condition;
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`${super.getMoveName()} protected${this.side === ArenaTagSide.PLAYER ? " your" : this.side === ArenaTagSide.ENEMY ? " the\nopposing" : ""} team!`);
}
// Removes default message for effect removal
onRemove(arena: Arena): void { }
/**
* apply(): Checks incoming moves against the condition function
* and protects the target if conditions are met
* @param arena The arena containing this tag
* @param args[0] (Utils.BooleanHolder) Signals if the move is cancelled
* @param args[1] (Pokemon) The intended target of the move
* @param args[2...] (any[]) The parameters to the condition function
* @returns
*/
apply(arena: Arena, args: any[]): boolean {
if ((args[0] as Utils.BooleanHolder).value) {
return false;
}
const target = args[1] as Pokemon;
if ((this.side === ArenaTagSide.PLAYER) === target.isPlayer()
&& this.protectConditionFunc(...args.slice(2))) {
(args[0] as Utils.BooleanHolder).value = true;
new CommonBattleAnim(CommonAnim.PROTECT, target).play(arena.scene);
arena.scene.queueMessage(`${super.getMoveName()} protected ${getPokemonMessage(target, "!")}`);
return true;
}
return false;
}
}
/**
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Quick_Guard_(move) Quick Guard}
* Condition: The incoming move has increased priority.
*/
class QuickGuardTag extends ConditionalProtectTag {
constructor(sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side,
(priority: integer) : boolean => {
return priority > 0;
}
);
}
}
/**
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Wide_Guard_(move) Wide Guard}
* Condition: The incoming move can target multiple Pokemon. The move's source
* can be an ally or enemy.
*/
class WideGuardTag extends ConditionalProtectTag {
constructor(sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side,
(moveTarget: MoveTarget) : boolean => {
switch (moveTarget) {
case MoveTarget.ALL_ENEMIES:
case MoveTarget.ALL_NEAR_ENEMIES:
case MoveTarget.ALL_OTHERS:
case MoveTarget.ALL_NEAR_OTHERS:
return true;
}
return false;
}
);
}
}
/**
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Mat_Block_(move) Mat Block}
* Condition: The incoming move is a Physical or Special attack move.
*/
class MatBlockTag extends ConditionalProtectTag {
constructor(sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side,
(moveCategory: MoveCategory) : boolean => {
return moveCategory !== MoveCategory.STATUS;
}
);
}
onAdd(arena: Arena) {
const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(getPokemonMessage(source, " intends to flip up a mat\nand block incoming attacks!"));
}
}
/**
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Crafty_Shield_(move) Crafty Shield}
* Condition: The incoming move is a Status move, is not a hazard, and does
* not target all Pokemon or sides of the field.
*/
class CraftyShieldTag extends ConditionalProtectTag {
constructor(sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side,
(moveCategory: MoveCategory, moveTarget: MoveTarget) : boolean => {
return moveCategory === MoveCategory.STATUS
&& moveTarget !== MoveTarget.ENEMY_SIDE
&& moveTarget !== MoveTarget.BOTH_SIDES
&& moveTarget !== MoveTarget.ALL;
}
);
}
}
class WishTag extends ArenaTag { class WishTag extends ArenaTag {
private battlerIndex: BattlerIndex; private battlerIndex: BattlerIndex;
private triggerMessage: string; private triggerMessage: string;
@ -161,7 +284,7 @@ class WishTag extends ArenaTag {
this.triggerMessage = getPokemonMessage(user, "'s wish\ncame true!"); this.triggerMessage = getPokemonMessage(user, "'s wish\ncame true!");
this.healHp = Math.max(Math.floor(user.getMaxHp() / 2), 1); this.healHp = Math.max(Math.floor(user.getMaxHp() / 2), 1);
} }
onRemove(arena: Arena): void { onRemove(arena: Arena): void {
const target = arena.scene.getField()[this.battlerIndex]; const target = arena.scene.getField()[this.battlerIndex];
if (target?.isActive(true)) { if (target?.isActive(true)) {
@ -299,7 +422,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
onAdd(arena: Arena): void { onAdd(arena: Arena): void {
super.onAdd(arena); super.onAdd(arena);
const source = arena.scene.getPokemonById(this.sourceId); const source = arena.scene.getPokemonById(this.sourceId);
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`); arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
} }
@ -322,7 +445,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
const toxic = this.layers > 1; const toxic = this.layers > 1;
if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, `the ${this.getMoveName()}`)) { if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, `the ${this.getMoveName()}`)) {
return true; return true;
} }
} }
} }
@ -410,7 +533,7 @@ class StealthRockTag extends ArenaTrapTag {
if (cancelled.value) { if (cancelled.value) {
return false; return false;
} }
const damageHpRatio = this.getDamageHpRatio(pokemon); const damageHpRatio = this.getDamageHpRatio(pokemon);
if (damageHpRatio) { if (damageHpRatio) {
@ -513,6 +636,14 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
switch (tagType) { switch (tagType) {
case ArenaTagType.MIST: case ArenaTagType.MIST:
return new MistTag(turnCount, sourceId, side); return new MistTag(turnCount, sourceId, side);
case ArenaTagType.QUICK_GUARD:
return new QuickGuardTag(sourceId, side);
case ArenaTagType.WIDE_GUARD:
return new WideGuardTag(sourceId, side);
case ArenaTagType.MAT_BLOCK:
return new MatBlockTag(sourceId, side);
case ArenaTagType.CRAFTY_SHIELD:
return new CraftyShieldTag(sourceId, side);
case ArenaTagType.MUD_SPORT: case ArenaTagType.MUD_SPORT:
return new MudSportTag(turnCount, sourceId); return new MudSportTag(turnCount, sourceId);
case ArenaTagType.WATER_SPORT: case ArenaTagType.WATER_SPORT:

View File

@ -296,7 +296,7 @@ class ImportedAnimFrame extends AnimFrame {
abstract class AnimTimedEvent { abstract class AnimTimedEvent {
public frameIndex: integer; public frameIndex: integer;
public resourceName: string; public resourceName: string;
constructor(frameIndex: integer, resourceName: string) { constructor(frameIndex: integer, resourceName: string) {
this.frameIndex = frameIndex; this.frameIndex = frameIndex;
this.resourceName = resourceName; this.resourceName = resourceName;
@ -310,7 +310,7 @@ abstract class AnimTimedEvent {
class AnimTimedSoundEvent extends AnimTimedEvent { class AnimTimedSoundEvent extends AnimTimedEvent {
public volume: number = 100; public volume: number = 100;
public pitch: number = 100; public pitch: number = 100;
constructor(frameIndex: integer, resourceName: string, source?: any) { constructor(frameIndex: integer, resourceName: string, source?: any) {
super(frameIndex, resourceName); super(frameIndex, resourceName);
@ -813,7 +813,7 @@ export abstract class BattleAnim {
this.srcLine = [ userFocusX, userFocusY, targetFocusX, targetFocusY ]; this.srcLine = [ userFocusX, userFocusY, targetFocusX, targetFocusY ];
this.dstLine = [ userInitialX, userInitialY, targetInitialX, targetInitialY ]; this.dstLine = [ userInitialX, userInitialY, targetInitialX, targetInitialY ];
let r = anim.frames.length; let r = anim.frames.length;
let f = 0; let f = 0;
@ -855,7 +855,7 @@ export abstract class BattleAnim {
const pokemonSprite = sprites[spriteIndex]; const pokemonSprite = sprites[spriteIndex];
const graphicFrameData = frameData.get(frame.target).get(spriteIndex); const graphicFrameData = frameData.get(frame.target).get(spriteIndex);
pokemonSprite.setPosition(graphicFrameData.x, graphicFrameData.y - ((spriteSource.height / 2) * (spriteSource.parentContainer.scale - 1))); pokemonSprite.setPosition(graphicFrameData.x, graphicFrameData.y - ((spriteSource.height / 2) * (spriteSource.parentContainer.scale - 1)));
pokemonSprite.setAngle(graphicFrameData.angle); pokemonSprite.setAngle(graphicFrameData.angle);
pokemonSprite.setScale(graphicFrameData.scaleX * spriteSource.parentContainer.scale, graphicFrameData.scaleY * spriteSource.parentContainer.scale); pokemonSprite.setScale(graphicFrameData.scaleX * spriteSource.parentContainer.scale, graphicFrameData.scaleY * spriteSource.parentContainer.scale);
@ -873,7 +873,7 @@ export abstract class BattleAnim {
scene.field.add(newSprite); scene.field.add(newSprite);
spritePriorities.push(1); spritePriorities.push(1);
} }
const graphicIndex = g++; const graphicIndex = g++;
const moveSprite = sprites[graphicIndex]; const moveSprite = sprites[graphicIndex];
if (spritePriorities[graphicIndex] !== frame.priority) { if (spritePriorities[graphicIndex] !== frame.priority) {
@ -924,7 +924,7 @@ export abstract class BattleAnim {
} }
moveSprite.setFrame(frame.graphicFrame); moveSprite.setFrame(frame.graphicFrame);
//console.log(AnimFocus[frame.focus]); //console.log(AnimFocus[frame.focus]);
const graphicFrameData = frameData.get(frame.target).get(graphicIndex); const graphicFrameData = frameData.get(frame.target).get(graphicIndex);
moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y); moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
moveSprite.setAngle(graphicFrameData.angle); moveSprite.setAngle(graphicFrameData.angle);
@ -999,7 +999,7 @@ export class CommonBattleAnim extends BattleAnim {
export class MoveAnim extends BattleAnim { export class MoveAnim extends BattleAnim {
public move: Moves; public move: Moves;
constructor(move: Moves, user: Pokemon, target: BattlerIndex) { constructor(move: Moves, user: Pokemon, target: BattlerIndex) {
super(user, user.scene.getField()[target]); super(user, user.scene.getField()[target]);
@ -1027,7 +1027,7 @@ export class MoveAnim extends BattleAnim {
export class MoveChargeAnim extends MoveAnim { export class MoveChargeAnim extends MoveAnim {
private chargeAnim: ChargeAnim; private chargeAnim: ChargeAnim;
constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) { constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) {
super(move, user, 0); super(move, user, 0);
@ -1060,13 +1060,13 @@ export async function populateAnims() {
} }
const seNames = [];//(await fs.readdir('./public/audio/se/battle_anims/')).map(se => se.toString()); const seNames = [];//(await fs.readdir('./public/audio/se/battle_anims/')).map(se => se.toString());
const animsData = [];//battleAnimRawData.split('!ruby/array:PBAnimation').slice(1); const animsData = [];//battleAnimRawData.split('!ruby/array:PBAnimation').slice(1);
for (let a = 0; a < animsData.length; a++) { for (let a = 0; a < animsData.length; a++) {
const fields = animsData[a].split("@").slice(1); const fields = animsData[a].split("@").slice(1);
const nameField = fields.find(f => f.startsWith("name: ")); const nameField = fields.find(f => f.startsWith("name: "));
let isOppMove: boolean; let isOppMove: boolean;
let commonAnimId: CommonAnim; let commonAnimId: CommonAnim;
let chargeAnimId: ChargeAnim; let chargeAnimId: ChargeAnim;

View File

@ -41,7 +41,7 @@ export function getBattleStatLevelChangeDescription(levels: integer, up: boolean
case 4: case 4:
case 5: case 5:
case 6: case 6:
return "rose drastically"; return "rose drastically";
default: default:
return "won't go any higher"; return "won't go any higher";
} }

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