Merge branch 'pagefaultgames:main' into main

This commit is contained in:
takeyourt1me 2024-05-03 00:48:01 -07:00 committed by GitHub
commit a542f742fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
87 changed files with 2677 additions and 415 deletions

View File

@ -41,4 +41,6 @@ jobs:
files: |
https://pokerogue.net/
https://pokerogue.net/index.html
https://pokerogue.net/manifest.json
https://pokerogue.net/manifest.json
https://pokerogue.net/manifest.webmanifest
https://pokerogue.net/service-worker.js

View File

@ -150,6 +150,10 @@ body {
display: none;
}
#touchControls:not([data-ui-mode='COMMAND']):not([data-ui-mode='FIGHT']):not([data-ui-mode='BALL']):not([data-ui-mode='TARGET_SELECT']) #apad #apadStats {
display: none;
}
#apad .apadRectBtnContainer + .apadSqBtnContainer {
top: calc(var(--controls-size) * -1.9);
left: calc(var(--controls-size) * -0.9);

View File

@ -74,6 +74,9 @@
<div id="apadCycleVariant" class="apadSqBtn apadBtn" data-key="CYCLE_VARIANT">
<text class="apadLabel apadLabelSmall">V</text>
</div>
<div id="apadStats" class="apadRectBtn apadBtn" data-key="STATS">
<text class="apadLabel apadLabelSmall">C</text>
</div>
<div id="apadMenu" class="apadRectBtn apadBtn" data-key="MENU">
<text class="apadLabel apadLabelSmall">Menu</text>
</div>

View File

@ -0,0 +1,293 @@
{
"textures": [
{
"image": "pbinfo_stat_numbers.png",
"format": "RGBA8888",
"size": {
"w": 117,
"h": 8
},
"scale": 1,
"frames": [
{
"filename": "+1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 9,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 18,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 27,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 36,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 45,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 54,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 63,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 72,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 81,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 90,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 99,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "0",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 108,
"y": 0,
"w": 9,
"h": 8
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:794aa4af3291db5abd8a2667626c1998:1a6706ad557b92f9bf099c23e02af4a6:6537c634087637bb27e8a1edb1ee2e35$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

View File

@ -0,0 +1,188 @@
{
"textures": [
{
"image": "pbinfo_stat.png",
"format": "RGBA8888",
"size": {
"w": 112,
"h": 6
},
"scale": 1,
"frames": [
{
"filename": "SPATK",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 19,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 18,
"h": 6
},
"frame": {
"x": 0,
"y": 0,
"w": 18,
"h": 6
}
},
{
"filename": "SPDEF",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 19,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 18,
"h": 6
},
"frame": {
"x": 18,
"y": 0,
"w": 18,
"h": 6
}
},
{
"filename": "CRIT",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 17,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 16,
"h": 6
},
"frame": {
"x": 36,
"y": 0,
"w": 16,
"h": 6
}
},
{
"filename": "ACC",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 12,
"h": 6
},
"frame": {
"x": 52,
"y": 0,
"w": 12,
"h": 6
}
},
{
"filename": "ATK",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 12,
"h": 6
},
"frame": {
"x": 64,
"y": 0,
"w": 12,
"h": 6
}
},
{
"filename": "DEF",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 12,
"h": 6
},
"frame": {
"x": 76,
"y": 0,
"w": 12,
"h": 6
}
},
{
"filename": "EVA",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 12,
"h": 6
},
"frame": {
"x": 88,
"y": 0,
"w": 12,
"h": 6
}
},
{
"filename": "SPD",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 1,
"y": 2,
"w": 12,
"h": 6
},
"frame": {
"x": 100,
"y": 0,
"w": 12,
"h": 6
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:40d30205ce8efd40dfa86cd11b0491d6:7076db6ed74199dcfb38fc8cd4d4a0e8:05882267d3999884e0491134e98b1b53$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

View File

@ -0,0 +1,293 @@
{
"textures": [
{
"image": "pbinfo_stat_numbers.png",
"format": "RGBA8888",
"size": {
"w": 117,
"h": 8
},
"scale": 1,
"frames": [
{
"filename": "+1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 9,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 18,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 27,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 36,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "+6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 45,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 54,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 63,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 72,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 81,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 90,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 99,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "0",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 108,
"y": 0,
"w": 9,
"h": 8
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:1f22b7cb085faf9e9764273fa5e70c28:afc5587ebacca78d178ac7e0c434591b:6537c634087637bb27e8a1edb1ee2e35$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,188 @@
{
"textures": [
{
"image": "pbinfo_stat.png",
"format": "RGBA8888",
"size": {
"w": 120,
"h": 7
},
"scale": 1,
"frames": [
{
"filename": "SPATK",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 19,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 19,
"h": 7
},
"frame": {
"x": 0,
"y": 0,
"w": 19,
"h": 7
}
},
{
"filename": "SPDEF",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 19,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 19,
"h": 7
},
"frame": {
"x": 19,
"y": 0,
"w": 19,
"h": 7
}
},
{
"filename": "CRIT",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 17,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 17,
"h": 7
},
"frame": {
"x": 38,
"y": 0,
"w": 17,
"h": 7
}
},
{
"filename": "ACC",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 13,
"h": 7
},
"frame": {
"x": 55,
"y": 0,
"w": 13,
"h": 7
}
},
{
"filename": "ATK",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 13,
"h": 7
},
"frame": {
"x": 68,
"y": 0,
"w": 13,
"h": 7
}
},
{
"filename": "DEF",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 13,
"h": 7
},
"frame": {
"x": 81,
"y": 0,
"w": 13,
"h": 7
}
},
{
"filename": "EVA",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 13,
"h": 7
},
"frame": {
"x": 94,
"y": 0,
"w": 13,
"h": 7
}
},
{
"filename": "SPD",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 13,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 1,
"w": 13,
"h": 7
},
"frame": {
"x": 107,
"y": 0,
"w": 13,
"h": 7
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:86fbd1b45d46271597a7d9de482aaa74:df702dd9d88db50369f1a096f82fd915:05882267d3999884e0491134e98b1b53$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

View File

@ -0,0 +1,293 @@
{
"textures": [
{
"image": "pbinfo_stat_numbers.png",
"format": "RGBA8888",
"size": {
"w": 117,
"h": 8
},
"scale": 1,
"frames": [
{
"filename": "1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 9,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 18,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 27,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 36,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 45,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-1",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 54,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-2",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 63,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-3",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 72,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-4",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 81,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-5",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 90,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "-6",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 99,
"y": 0,
"w": 9,
"h": 8
}
},
{
"filename": "0",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 9,
"h": 8
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 9,
"h": 8
},
"frame": {
"x": 108,
"y": 0,
"w": 9,
"h": 8
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:b0719fae0d9b670a727148cdc7202249:afc5587ebacca78d178ac7e0c434591b:4825a9f02f72f1fe28a724c6c5dffb37$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

View File

@ -3,8 +3,8 @@
"short_name": "PokéRogue",
"description": "A Pokémon fangame heavily inspired by the roguelite genre. Battle endlessly while gathering stacking items, exploring many different biomes, and reaching Pokémon stats you never thought possible.",
"scope": "/",
"start_url": "/",
"display": "standalone",
"start_url": "https://pokerogue.net",
"display": "fullscreen",
"background_color": "#8c8c8c",
"theme_color": "#8c8c8c",
"icons": [

View File

@ -85,6 +85,7 @@ export enum Button {
ACTION,
CANCEL,
MENU,
STATS,
CYCLE_SHINY,
CYCLE_FORM,
CYCLE_GENDER,
@ -196,25 +197,26 @@ export default class BattleScene extends SceneBase {
private movementButtonLock: Button;
// using a dualshock controller as a map
private gamepadKeyConfig = {
[Button.UP]: 12, // up
[Button.DOWN]: 13, // down
[Button.LEFT]: 14, // left
[Button.RIGHT]: 15, // right
[Button.SUBMIT]: 17, // touchpad
[Button.ACTION]: 0, // X
[Button.CANCEL]: 1, // O
[Button.MENU]: 9, // options
[Button.CYCLE_SHINY]: 5, // RB
[Button.CYCLE_FORM]: 4, // LB
[Button.CYCLE_GENDER]: 6, // LT
[Button.CYCLE_ABILITY]: 7, // RT
[Button.CYCLE_NATURE]: 2, // square
[Button.CYCLE_VARIANT]: 3, // triangle
[Button.SPEED_UP]: 10, // L3
[Button.SLOW_DOWN]: 11 // R3
};
public gamepadButtonStates: boolean[] = new Array(17).fill(false);
private gamepadKeyConfig = {
[Button.UP]: 12, // up
[Button.DOWN]: 13, // down
[Button.LEFT]: 14, // left
[Button.RIGHT]: 15, // right
[Button.SUBMIT]: 17, // touchpad
[Button.ACTION]: 0, // X
[Button.CANCEL]: 1, // O
[Button.MENU]: 9, // options
[Button.STATS]: 8, // share
[Button.CYCLE_SHINY]: 5, // RB
[Button.CYCLE_FORM]: 4, // LB
[Button.CYCLE_GENDER]: 6, // LT
[Button.CYCLE_ABILITY]: 7, // RT
[Button.CYCLE_NATURE]: 2, // square
[Button.CYCLE_VARIANT]: 3, // triangle
[Button.SPEED_UP]: 10, // L3
[Button.SLOW_DOWN]: 11 // R3
};
public gamepadButtonStates: boolean[] = new Array(17).fill(false);
public rngCounter: integer = 0;
public rngSeedOverride: string = '';
@ -615,6 +617,7 @@ export default class BattleScene extends SceneBase {
[Button.ACTION]: [keyCodes.SPACE, keyCodes.ENTER, keyCodes.Z],
[Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X],
[Button.MENU]: [keyCodes.ESC, keyCodes.M],
[Button.STATS]: [keyCodes.SHIFT, keyCodes.C],
[Button.CYCLE_SHINY]: [keyCodes.R],
[Button.CYCLE_FORM]: [keyCodes.F],
[Button.CYCLE_GENDER]: [keyCodes.G],
@ -1432,8 +1435,16 @@ export default class BattleScene extends SceneBase {
if (this.ui?.getMode() === Mode.SETTINGS)
(this.ui.getHandler() as SettingsUiHandler).show([]);
}
} else
return;
} else {
let pressed = false;
if (this.ui && (this.buttonJustReleased(Button.STATS) || (pressed = this.buttonJustPressed(Button.STATS)))) {
for (let p of this.getField().filter(p => p?.isActive(true)))
p.toggleStats(pressed);
if (pressed)
this.setLastProcessedMovementTime(Button.STATS);
} else
return;
}
if (inputSuccess && this.enableVibration && typeof navigator.vibrate !== 'undefined')
navigator.vibrate(vibrationLength || 10);
}
@ -1443,7 +1454,7 @@ export default class BattleScene extends SceneBase {
* or not. It will only return true once, until the key is released and pressed down
* again.
*/
gamepadButtonJustDown(button: Phaser.Input.Gamepad.Button) : boolean {
gamepadButtonJustDown(button: Phaser.Input.Gamepad.Button): boolean {
if (!button || !this.gamepadSupport)
return false;
@ -1463,6 +1474,23 @@ export default class BattleScene extends SceneBase {
return this.buttonKeys[button].some(k => Phaser.Input.Keyboard.JustDown(k)) || this.gamepadButtonJustDown(gamepad?.buttons[this.gamepadKeyConfig[button]]);
}
/**
* gamepadButtonJustUp returns true if @param button has just been released
* or not. It will only return true once, until the key is released and pressed down
* again.
*/
gamepadButtonJustUp(button: Phaser.Input.Gamepad.Button): boolean {
if (!button || !this.gamepadSupport)
return false;
return !this.gamepadButtonStates[button.index];
}
buttonJustReleased(button: Button): boolean {
const gamepad = this.input.gamepad?.gamepads[0];
return this.buttonKeys[button].some(k => Phaser.Input.Keyboard.JustUp(k)) || this.gamepadButtonJustUp(gamepad?.buttons[this.gamepadKeyConfig[button]]);
}
/**
* repeatInputDurationJustPassed returns true if @param button has been held down long
* enough to fire a repeated input. A button must claim the movementButtonLock before

View File

@ -679,6 +679,19 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
}
}
export class EffectSporeAbAttr extends PostDefendContactApplyStatusEffectAbAttr {
constructor() {
super(10, StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP);
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (attacker.hasAbility(Abilities.OVERCOAT) || attacker.isOfType(Type.GRASS)) {
return false;
}
return super.applyPostDefend(pokemon, passive, attacker, move, hitResult, args);
}
}
export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
private chance: integer;
private tagType: BattlerTagType;
@ -928,8 +941,8 @@ export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
private condition: PokemonAttackCondition;
private powerMultiplier: number;
constructor(condition: PokemonAttackCondition, powerMultiplier: number) {
super(true);
constructor(condition: PokemonAttackCondition, powerMultiplier: number, showAbility: boolean = true) {
super(showAbility);
this.condition = condition;
this.powerMultiplier = powerMultiplier;
}
@ -2594,7 +2607,7 @@ export function initAbilities() {
.attr(TypeImmunityAbAttr, Type.GROUND, (pokemon: Pokemon) => !pokemon.getTag(BattlerTagType.IGNORE_FLYING) && !pokemon.scene.arena.getTag(ArenaTagType.GRAVITY) && !pokemon.getTag(BattlerTagType.GROUNDED))
.ignorable(),
new Ability(Abilities.EFFECT_SPORE, 3)
.attr(PostDefendContactApplyStatusEffectAbAttr, 10, StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP),
.attr(EffectSporeAbAttr),
new Ability(Abilities.SYNCHRONIZE, 3)
.attr(SyncEncounterNatureAbAttr)
.unimplemented(),
@ -2734,7 +2747,7 @@ export function initAbilities() {
.attr(TypeImmunityStatChangeAbAttr, Type.ELECTRIC, BattleStat.SPD, 1)
.ignorable(),
new Ability(Abilities.RIVALRY, 4)
.attr(MovePowerBoostAbAttr, (user, target, move) => user.gender !== Gender.GENDERLESS && target.gender !== Gender.GENDERLESS && user.gender === target.gender, 1.25)
.attr(MovePowerBoostAbAttr, (user, target, move) => user.gender !== Gender.GENDERLESS && target.gender !== Gender.GENDERLESS && user.gender === target.gender, 1.25, true)
.attr(MovePowerBoostAbAttr, (user, target, move) => user.gender !== Gender.GENDERLESS && target.gender !== Gender.GENDERLESS && user.gender !== target.gender, 0.75),
new Ability(Abilities.STEADFAST, 4)
.attr(FlinchStatChangeAbAttr, BattleStat.SPD, 1),

View File

@ -482,6 +482,20 @@ export class GravityTag extends ArenaTag {
}
}
class TailwindTag extends ArenaTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side);
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? '\nyour' : this.side === ArenaTagSide.ENEMY ? '\nthe opposing' : ''} team!`);
}
onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? 'Your' : this.side === ArenaTagSide.ENEMY ? 'The opposing' : ''} team's Tailwind petered out!`);
}
}
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag {
switch (tagType) {
case ArenaTagType.MIST:
@ -513,5 +527,7 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
return new LightScreenTag(turnCount, sourceId, side);
case ArenaTagType.AURORA_VEIL:
return new AuroraVeilTag(turnCount, sourceId, side);
case ArenaTagType.TAILWIND:
return new TailwindTag(turnCount, sourceId, side);
}
}

View File

@ -163,6 +163,29 @@ export class FlinchedTag extends BattlerTag {
}
}
export class InterruptedTag extends BattlerTag {
constructor(sourceMove: Moves){
super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove)
}
canAdd(pokemon: Pokemon): boolean {
return !!pokemon.getTag(BattlerTagType.FLYING)
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.getMoveQueue().shift()
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER})
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
return true
}
}
export class ConfusedTag extends BattlerTag {
constructor(turnCount: integer, sourceMove: Moves) {
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove);
@ -1081,6 +1104,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new RechargingTag(sourceMove);
case BattlerTagType.FLINCHED:
return new FlinchedTag(sourceMove);
case BattlerTagType.INTERRUPTED:
return new InterruptedTag(sourceMove);
case BattlerTagType.CONFUSED:
return new ConfusedTag(turnCount, sourceMove);
case BattlerTagType.INFATUATED:

View File

@ -99,6 +99,8 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
case BerryType.SITRUS:
case BerryType.ENIGMA:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
@ -106,6 +108,8 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
};
case BerryType.LUM:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
if (pokemon.status) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
pokemon.resetStatus();
@ -119,6 +123,8 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
case BerryType.APICOT:
case BerryType.SALAC:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
const statLevels = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
@ -126,16 +132,22 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
pokemon.addTag(BattlerTagType.CRIT_BOOST);
};
case BerryType.STARF:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
const statLevels = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
if (pokemon.battleData)
pokemon.battleData.berriesEaten.push(berryType);
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio());
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`));

View File

@ -615,7 +615,7 @@ export const biomePokemonPools: BiomePokemonPools = {
[TimeOfDay.DAY]: [],
[TimeOfDay.DUSK]: [],
[TimeOfDay.NIGHT]: [],
[TimeOfDay.ALL]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, { 1: [ Species.MANTYKE ], 20: [ Species.MANTINE ] }, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ] }, Species.DHELMISE ]
[TimeOfDay.ALL]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, { 1: [ Species.MANTYKE ], 52: [ Species.MANTINE ] }, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ] }, Species.DHELMISE ]
},
[BiomePoolTier.SUPER_RARE]: {
[TimeOfDay.DAWN]: [],
@ -1128,8 +1128,8 @@ export const biomePokemonPools: BiomePokemonPools = {
]
},
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ] }, Species.KLEFKI ] },
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ] }, { 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ] } ] },
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ] } ] },
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ] } ] },
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENESECT, Species.MAGEARNA ] },
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KLINKLANG, Species.KLEFKI ] },
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
@ -1319,7 +1319,7 @@ export const biomePokemonPools: BiomePokemonPools = {
[TimeOfDay.DAY]: [ Species.VESPIQUEN, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ] }, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ] } ],
[TimeOfDay.DUSK]: [ Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ] }, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ],
[TimeOfDay.NIGHT]: [ { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] }, Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ] }, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ],
[TimeOfDay.ALL]: [ Species.AIPOM, { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ] }, { 1: [ Species.PIKIPEK ], 14: [ Species.TRUMBEAK ], 36: [ Species.TOUCANNON ] } ]
[TimeOfDay.ALL]: [ Species.AIPOM, { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ] }, { 1: [ Species.PIKIPEK ], 14: [ Species.TRUMBEAK ], 28: [ Species.TOUCANNON ] } ]
},
[BiomePoolTier.UNCOMMON]: {
[TimeOfDay.DAWN]: [ Species.EXEGGCUTE, Species.TROPIUS, Species.COMBEE, Species.KOMALA ],
@ -2708,7 +2708,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
]
],
[ Species.PORYGON, Type.NORMAL, -1, [
[ Biome.FACTORY, BiomePoolTier.SUPER_RARE ],
[ Biome.FACTORY, BiomePoolTier.RARE ],
[ Biome.SPACE, BiomePoolTier.SUPER_RARE ],
[ Biome.LABORATORY, BiomePoolTier.RARE ]
]
@ -3165,7 +3165,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
]
],
[ Species.PORYGON2, Type.NORMAL, -1, [
[ Biome.FACTORY, BiomePoolTier.SUPER_RARE ],
[ Biome.FACTORY, BiomePoolTier.RARE ],
[ Biome.SPACE, BiomePoolTier.SUPER_RARE ],
[ Biome.LABORATORY, BiomePoolTier.RARE ]
]

View File

@ -458,9 +458,9 @@ export const speciesEggMoves = {
[Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.PARTING_SHOT, Moves.SWORDS_DANCE ],
[Species.CUFANT]: [ Moves.LIQUIDATION, Moves.HEAVY_SLAM, Moves.CLOSE_COMBAT, Moves.GIGATON_HAMMER ],
[Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ],
[Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.EARTHQUAKE, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ],
[Species.ARCTOVISH]: [ Moves.TRIPLE_AXEL, Moves.EARTHQUAKE, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.ARCTOVISH]: [ Moves.TRIPLE_AXEL, Moves.SUPERCELL_SLAM, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.DURALUDON]: [ Moves.CALM_MIND, Moves.BODY_PRESS, Moves.EARTH_POWER, Moves.RECOVER ],
[Species.DREEPY]: [ Moves.DRAGON_ENERGY, Moves.SHED_TAIL, Moves.BLAZING_TORQUE, Moves.SPECTRAL_THIEF ],
[Species.ZACIAN]: [ Moves.MAGICAL_TORQUE, Moves.BITTER_BLADE, Moves.LEAF_BLADE, Moves.VICTORY_DANCE ],

View File

@ -15,5 +15,6 @@ export enum ArenaTagType {
GRAVITY = "GRAVITY",
REFLECT = "REFLECT",
LIGHT_SCREEN = "LIGHT_SCREEN",
AURORA_VEIL = "AURORA_VEIL"
AURORA_VEIL = "AURORA_VEIL",
TAILWIND = "TAILWIND"
}

View File

@ -3,6 +3,7 @@ export enum BattlerTagType {
NONE = "NONE",
RECHARGING = "RECHARGING",
FLINCHED = "FLINCHED",
INTERRUPTED = "INTERRUPTED",
CONFUSED = "CONFUSED",
INFATUATED = "INFATUATED",
SEEDED = "SEEDED",

View File

@ -557,7 +557,7 @@ export class TargetHalfHpDamageAttr extends FixedDamageAttr {
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.IntegerHolder).value = Math.floor(target.hp / 2);
(args[0] as Utils.IntegerHolder).value = Math.max(Math.floor(target.hp / 2), 1);
return true;
}
@ -1009,6 +1009,25 @@ export class StatusEffectAttr extends MoveEffectAttr {
}
}
export class MultiStatusEffectAttr extends StatusEffectAttr {
public effects: StatusEffect[];
constructor(effects: StatusEffect[], selfTarget?: boolean, cureTurn?: integer, overrideStatus?: boolean) {
super(effects[0], selfTarget, cureTurn, overrideStatus);
this.effects = effects;
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
this.effect = Utils.randSeedItem(this.effects);
const result = super.apply(user, target, move, args);
return result;
}
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(this.effect, true) ? Math.floor(move.chance * -0.1) : 0;
}
}
export class PsychoShiftEffectAttr extends MoveEffectAttr {
constructor() {
super(false, MoveEffectTrigger.HIT);
@ -1552,6 +1571,8 @@ export class CopyStatsAttr extends MoveEffectAttr {
else
user.removeTag(BattlerTagType.CRIT_BOOST);
user.updateInfo();
target.scene.queueMessage(getPokemonMessage(user, 'copied\n') + getPokemonMessage(target, `'s stat changes!`));
return true;
@ -1566,6 +1587,8 @@ export class InvertStatsAttr extends MoveEffectAttr {
for (let s = 0; s < target.summonData.battleStats.length; s++)
target.summonData.battleStats[s] *= -1;
user.updateInfo();
target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere all reversed!`));
return true;
@ -1580,6 +1603,8 @@ export class ResetStatsAttr extends MoveEffectAttr {
for (let s = 0; s < target.summonData.battleStats.length; s++)
target.summonData.battleStats[s] = 0;
user.updateInfo();
target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere eliminated!`));
return true;
@ -2590,7 +2615,7 @@ export class CurseAttr extends MoveEffectAttr {
}
let curseRecoilDamage = Math.floor(user.getMaxHp() / 2);
user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true, true);
user.scene.queueMessage(getPokemonMessage(user, ' cut its own HP!'));
user.scene.queueMessage(getPokemonMessage(user, ` cut its own HP\nand laid a curse on the ${target.name}!`));
target.addTag(BattlerTagType.CURSED, 0, move.id, user.id);
return true;
} else {
@ -3569,6 +3594,23 @@ export class SwitchAbilitiesAttr extends MoveEffectAttr {
}
}
export class SuppressAbilitiesAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args))
return false;
target.summonData.abilitySuppressed = true;
target.scene.queueMessage(getPokemonMessage(target, ` ability\nwas suppressed!`));
return true;
}
getCondition(): MoveConditionFunc {
return (user, target, move) => !target.getAbility().hasAttr(UnsuppressableAbilityAbAttr);
}
}
export class TransformAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => {
@ -3620,6 +3662,20 @@ export class MoneyAttr extends MoveEffectAttr {
}
}
export class LastResortAttr extends MoveAttr {
getCondition(): MoveConditionFunc {
return (user: Pokemon, target: Pokemon, move: Move) => {
const uniqueUsedMoveIds = new Set<Moves>();
const movesetMoveIds = user.getMoveset().map(m => m.moveId);
user.getMoveHistory().map(m => {
if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move))
uniqueUsedMoveIds.add(m.move);
});
return uniqueUsedMoveIds.size >= movesetMoveIds.length - 1;
};
}
}
const failOnGravityCondition: MoveConditionFunc = (user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY);
const failOnBossCondition: MoveConditionFunc = (user, target, move) => !target.isBossImmune();
@ -3681,6 +3737,19 @@ export class FirstMoveCondition extends MoveCondition {
}
}
export class hitsSameTypeAttr extends VariableMoveTypeMultiplierAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const multiplier = args[0] as Utils.NumberHolder;
if (!user.getTypes().some(type => target.getTypes().includes(type))){
multiplier.value = 0;
return true;
}
return false;
}
}
const unknownTypeCondition: MoveConditionFunc = (user, target, move) => !user.getTypes().includes(Type.UNKNOWN);
export type MoveTargetSet = {
targets: BattlerIndex[];
multiple: boolean;
@ -4164,9 +4233,7 @@ export function initMoves() {
new SelfStatusMove(Moves.CONVERSION, Type.NORMAL, -1, 30, -1, 0, 1)
.attr(FirstMoveTypeAttr),
new AttackMove(Moves.TRI_ATTACK, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, 20, 0, 1)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.attr(StatusEffectAttr, StatusEffect.BURN)
.attr(StatusEffectAttr, StatusEffect.FREEZE),
.attr(MultiStatusEffectAttr, [StatusEffect.BURN, StatusEffect.FREEZE, StatusEffect.PARALYSIS]),
new AttackMove(Moves.SUPER_FANG, Type.NORMAL, MoveCategory.PHYSICAL, -1, 90, 10, -1, 0, 1)
.attr(TargetHalfHpDamageAttr),
new AttackMove(Moves.SLASH, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 1)
@ -4738,8 +4805,8 @@ export function initMoves() {
.partial(),
new StatusMove(Moves.TAILWIND, Type.FLYING, -1, 15, -1, 0, 4)
.windMove()
.target(MoveTarget.USER_SIDE)
.unimplemented(),
.attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true)
.target(MoveTarget.USER_SIDE),
new StatusMove(Moves.ACUPRESSURE, Type.NORMAL, -1, 30, -1, 0, 4)
.attr(StatChangeAttr, BattleStat.RAND, 2)
.target(MoveTarget.USER_OR_NEAR_ALLY),
@ -4781,7 +4848,7 @@ export function initMoves() {
new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4)
.unimplemented(),
new StatusMove(Moves.GASTRO_ACID, Type.POISON, 100, 10, -1, 0, 4)
.unimplemented(),
.attr(SuppressAbilitiesAttr),
new StatusMove(Moves.LUCKY_CHANT, Type.NORMAL, -1, 30, -1, 0, 4)
.attr(AddBattlerTagAttr, BattlerTagType.NO_CRIT, false, false, 5)
.target(MoveTarget.USER_SIDE)
@ -4800,15 +4867,7 @@ export function initMoves() {
new AttackMove(Moves.PUNISHMENT, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4)
.unimplemented(),
new AttackMove(Moves.LAST_RESORT, Type.NORMAL, MoveCategory.PHYSICAL, 140, 100, 5, -1, 0, 4)
.condition((user, target, move) => {
const uniqueUsedMoveIds = new Set<Moves>();
const movesetMoveIds = user.getMoveset().map(m => m.moveId);
user.getMoveHistory().map(m => {
if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move))
uniqueUsedMoveIds.add(m.move);
});
return uniqueUsedMoveIds.size >= movesetMoveIds.length - 1;
}),
.attr(LastResortAttr),
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
.attr(AbilityChangeAttr, Abilities.INSOMNIA),
new AttackMove(Moves.SUCKER_PUNCH, Type.DARK, MoveCategory.PHYSICAL, 70, 100, 5, -1, 1, 4)
@ -5047,6 +5106,8 @@ export function initMoves() {
.unimplemented(),
new AttackMove(Moves.SMACK_DOWN, Type.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5)
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 5)
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
.attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING])
.attr(HitsTagAttr, BattlerTagType.FLYING, false)
.makesContact(false),
new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
@ -5064,7 +5125,8 @@ export function initMoves() {
.condition(failOnMaxCondition),
new AttackMove(Moves.SYNCHRONOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 5)
.target(MoveTarget.ALL_NEAR_OTHERS)
.partial(),
.condition(unknownTypeCondition)
.attr(hitsSameTypeAttr),
new AttackMove(Moves.ELECTRO_BALL, Type.ELECTRIC, MoveCategory.SPECIAL, -1, 100, 10, -1, 0, 5)
.attr(BattleStatRatioPowerAttr, Stat.SPD)
.ballBombMove(),
@ -5134,7 +5196,7 @@ export function initMoves() {
new StatusMove(Moves.QUASH, Type.DARK, 100, 15, -1, 0, 5)
.unimplemented(),
new AttackMove(Moves.ACROBATICS, Type.FLYING, MoveCategory.PHYSICAL, 55, 100, 15, -1, 0, 5)
.partial(),
.attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.getHeldItems().reduce((v, m) => v + m.stackCount, 0))),
new StatusMove(Moves.REFLECT_TYPE, Type.NORMAL, -1, 15, -1, 0, 5)
.attr(CopyTypeAttr),
new AttackMove(Moves.RETALIATE, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 5, -1, 0, 5)
@ -5264,7 +5326,7 @@ export function initMoves() {
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
.unimplemented(),
new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6)
.partial(),
.condition((user, target, move) => user.battleData.berriesEaten.length > 0),
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, 100, 0, 6)
.target(MoveTarget.ALL)
.unimplemented(),
@ -5409,6 +5471,8 @@ export function initMoves() {
new AttackMove(Moves.THOUSAND_ARROWS, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, 100, 0, 6)
.attr(NeutralDamageAgainstFlyingTypeMultiplierAttr)
.attr(HitsTagAttr, BattlerTagType.FLYING, false)
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
.attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING])
.makesContact(false)
.target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
@ -5980,9 +6044,7 @@ export function initMoves() {
.soundBased()
.partial(),
new AttackMove(Moves.DIRE_CLAW, Type.POISON, MoveCategory.PHYSICAL, 80, 100, 15, 50, 0, 8)
.attr(StatusEffectAttr, StatusEffect.POISON)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.attr(StatusEffectAttr, StatusEffect.SLEEP),
.attr(MultiStatusEffectAttr, [StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP]),
new AttackMove(Moves.PSYSHIELD_BASH, Type.PSYCHIC, MoveCategory.PHYSICAL, 70, 90, 10, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.DEF, 1, true),
new SelfStatusMove(Moves.POWER_SHIFT, Type.NORMAL, -1, 10, 100, 0, 8)
@ -6297,8 +6359,7 @@ export function initMoves() {
}), // TODO Add Instruct/Encore interaction
new AttackMove(Moves.COMEUPPANCE, Type.DARK, MoveCategory.PHYSICAL, 1, 100, 10, -1, 0, 9)
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
.target(MoveTarget.ATTACKER)
.partial(),
.target(MoveTarget.ATTACKER),
new AttackMove(Moves.AQUA_CUTTER, Type.WATER, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 9)
.attr(HighCritAttr)
.slicingMove()

View File

@ -4278,6 +4278,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 30, Moves.ANCIENT_POWER ],
[ 40, Moves.LIFE_DEW ],
[ 50, Moves.LEECH_SEED ],
[ 55, Moves.HEAL_BLOCK ],
[ 60, Moves.RECOVER ],
[ 70, Moves.FUTURE_SIGHT ],
[ 80, Moves.HEALING_WISH ],
@ -4976,6 +4977,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 23, Moves.ABSORB ],
[ 29, Moves.SHADOW_SNEAK ],
[ 36, Moves.FURY_SWIPES ],
[ 41, Moves.HEAL_BLOCK ],
[ 43, Moves.MIND_READER ],
[ 50, Moves.SHADOW_BALL ],
[ 57, Moves.SPITE ],
@ -5796,6 +5798,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.PSYSHOCK ],
[ 25, Moves.COSMIC_POWER ],
[ 30, Moves.PSYCHIC ],
[ 33, Moves.HEAL_BLOCK ],
[ 35, Moves.STONE_EDGE ],
[ 40, Moves.FUTURE_SIGHT ],
[ 45, Moves.MAGIC_ROOM ],
@ -5814,6 +5817,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.ZEN_HEADBUTT ],
[ 25, Moves.COSMIC_POWER ],
[ 30, Moves.PSYCHIC ],
[ 33, Moves.HEAL_BLOCK ],
[ 35, Moves.STONE_EDGE ],
[ 40, Moves.SOLAR_BEAM ],
[ 45, Moves.WONDER_ROOM ],
@ -5890,6 +5894,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 3, Moves.RAPID_SPIN ],
[ 6, Moves.CONFUSION ],
[ 9, Moves.ROCK_TOMB ],
[ 10, Moves.HEAL_BLOCK ],
[ 12, Moves.POWER_TRICK ],
[ 15, Moves.PSYBEAM ],
[ 18, Moves.ANCIENT_POWER ],
@ -5911,6 +5916,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.MUD_SLAP ],
[ 1, Moves.RAPID_SPIN ],
[ 9, Moves.ROCK_TOMB ],
[ 10, Moves.HEAL_BLOCK ],
[ 12, Moves.POWER_TRICK ],
[ 15, Moves.PSYBEAM ],
[ 18, Moves.ANCIENT_POWER ],
@ -6506,6 +6512,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.LATIOS]: [
[ 1, Moves.DRAGON_DANCE ],
[ 1, Moves.STORED_POWER ],
[ 1, Moves.HEAL_BLOCK ],
[ 5, Moves.HELPING_HAND ],
[ 10, Moves.RECOVER ],
[ 15, Moves.CONFUSION ],
@ -7364,6 +7371,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 36, Moves.IRON_DEFENSE ],
[ 40, Moves.METAL_SOUND ],
[ 44, Moves.FUTURE_SIGHT ],
[ 45, Moves.HEAL_BLOCK ],
],
[Species.BRONZONG]: [
[ 0, Moves.BLOCK ],
@ -7382,6 +7390,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 38, Moves.IRON_DEFENSE ],
[ 44, Moves.METAL_SOUND ],
[ 50, Moves.FUTURE_SIGHT ],
[ 52, Moves.HEAL_BLOCK ],
[ 56, Moves.RAIN_DANCE ],
],
[Species.BONSLY]: [
@ -9491,6 +9500,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.YAMASK]: [
[ 1, Moves.PROTECT ],
[ 1, Moves.ASTONISH ],
[ 1, Moves.HEAL_BLOCK ],
[ 4, Moves.HAZE ],
[ 8, Moves.NIGHT_SHADE ],
[ 12, Moves.DISABLE ],
@ -9513,6 +9523,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.PROTECT ],
[ 1, Moves.SCARY_FACE ],
[ 1, Moves.ASTONISH ],
[ 1, Moves.HEAL_BLOCK ],
[ 12, Moves.DISABLE ],
[ 16, Moves.WILL_O_WISP ],
[ 20, Moves.CRAFTY_SHIELD ],
@ -9720,6 +9731,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 24, Moves.HYPNOSIS ],
[ 28, Moves.FAKE_TEARS ],
[ 33, Moves.PSYCH_UP ],
[ 34, Moves.HEAL_BLOCK ],
[ 36, Moves.PSYCHIC ],
[ 40, Moves.FLATTER ],
[ 44, Moves.FUTURE_SIGHT ],
@ -9735,6 +9747,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.PSYSHOCK ],
[ 24, Moves.HYPNOSIS ],
[ 28, Moves.FAKE_TEARS ],
[ 34, Moves.HEAL_BLOCK ],
[ 35, Moves.PSYCH_UP ],
[ 46, Moves.FLATTER ],
[ 52, Moves.FUTURE_SIGHT ],
@ -9750,6 +9763,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.PSYSHOCK ],
[ 24, Moves.HYPNOSIS ],
[ 28, Moves.FAKE_TEARS ],
[ 34, Moves.HEAL_BLOCK ],
[ 35, Moves.PSYCH_UP ],
[ 40, Moves.PSYCHIC ],
[ 48, Moves.FLATTER ],
@ -9771,6 +9785,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 36, Moves.PSYCHIC ],
[ 40, Moves.SKILL_SWAP ],
[ 44, Moves.FUTURE_SIGHT ],
[ 46, Moves.HEAL_BLOCK ],
[ 48, Moves.WONDER_ROOM ],
],
[Species.DUOSION]: [
@ -9787,6 +9802,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 35, Moves.PAIN_SPLIT ],
[ 40, Moves.PSYCHIC ],
[ 46, Moves.SKILL_SWAP ],
[ 50, Moves.HEAL_BLOCK ],
[ 52, Moves.FUTURE_SIGHT ],
[ 58, Moves.WONDER_ROOM ],
],
@ -9805,6 +9821,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 35, Moves.PAIN_SPLIT ],
[ 40, Moves.PSYCHIC ],
[ 48, Moves.SKILL_SWAP ],
[ 54, Moves.HEAL_BLOCK ],
[ 56, Moves.FUTURE_SIGHT ],
[ 64, Moves.WONDER_ROOM ],
],
@ -10209,6 +10226,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.GROWL ],
[ 1, Moves.CONFUSION ],
[ 6, Moves.IMPRISON ],
[ 8, Moves.HEAL_BLOCK ],
[ 12, Moves.TELEPORT ],
[ 18, Moves.PSYBEAM ],
[ 24, Moves.GUARD_SPLIT ],
@ -10226,6 +10244,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.TELEPORT ],
[ 1, Moves.IMPRISON ],
[ 1, Moves.PSYCHIC_TERRAIN ],
[ 8, Moves.HEAL_BLOCK ],
[ 18, Moves.PSYBEAM ],
[ 24, Moves.GUARD_SPLIT ],
[ 24, Moves.POWER_SPLIT ],
@ -10884,6 +10903,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.SHOCK_WAVE ],
[ 25, Moves.AGILITY ],
[ 30, Moves.CHARGE ],
[ 31, Moves.HEAL_BLOCK ],
[ 35, Moves.VOLT_SWITCH ],
[ 40, Moves.CRUNCH ],
[ 45, Moves.DISCHARGE ],
@ -11972,6 +11992,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 40, Moves.PLAY_ROUGH ],
[ 44, Moves.MAGIC_ROOM ],
[ 48, Moves.FOUL_PLAY ],
[ 50, Moves.HEAL_BLOCK ],
[ 52, Moves.LAST_RESORT ],
],
[Species.PHANTUMP]: [
@ -13045,6 +13066,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 45, Moves.IRON_HEAD ],
[ 50, Moves.TAKE_DOWN ],
[ 55, Moves.DOUBLE_EDGE ],
[ 60, Moves.HEAL_BLOCK ],
],
[Species.SILVALLY]: [
[ 0, Moves.MULTI_ATTACK ],
@ -13059,6 +13081,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.ICE_FANG ],
[ 1, Moves.FIRE_FANG ],
[ 1, Moves.IRON_HEAD ],
[ 1, Moves.HEAL_BLOCK ],
[ 15, Moves.DOUBLE_HIT ],
[ 20, Moves.METAL_SOUND ],
[ 25, Moves.CRUSH_CLAW ],

View File

@ -138,9 +138,9 @@ export abstract class PokemonSpeciesForm {
this.genderDiffs = genderDiffs;
}
getRootSpeciesId(): Species {
getRootSpeciesId(forStarter: boolean = false): Species {
let ret = this.speciesId;
while (pokemonPrevolutions.hasOwnProperty(ret))
while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret)))
ret = pokemonPrevolutions[ret];
return ret;
}
@ -367,8 +367,8 @@ export abstract class PokemonSpeciesForm {
loadAssets(scene: BattleScene, female: boolean, formIndex?: integer, shiny?: boolean, variant?: Variant, startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
const spriteKey = this.getSpriteKey(female, formIndex, shiny, variant);
scene.load.audio(this.getCryKey(formIndex), `audio/cry/${this.getCryKey(formIndex)}.m4a`);
scene.loadPokemonAtlas(spriteKey, this.getSpriteAtlasPath(female, formIndex, shiny, variant));
scene.load.audio(this.getCryKey(formIndex), `audio/cry/${this.getCryKey(formIndex)}.m4a`);
scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot
@ -3156,6 +3156,30 @@ export const noStarterFormKeys: string[] = [
SpeciesFormKey.ETERNAMAX
].map(k => k.toString());
export function getStarterValueFriendshipCap(value: integer): integer {
switch (value) {
case 1:
return 20;
case 2:
return 40;
case 3:
return 60;
case 4:
return 100;
case 5:
return 140;
case 6:
return 200;
case 7:
return 280;
case 8:
case 9:
return 450;
default:
return 600;
}
}
export const starterPassiveAbilities = {
[Species.BULBASAUR]: Abilities.SOLAR_POWER,
[Species.CHARMANDER]: Abilities.INTIMIDATE,

View File

@ -33,6 +33,5 @@ splashMessages.push(...[
'Also Try Emerald Rogue!',
'Also Try Radical Red!',
'Eevee Expo!',
'YNOproject!',
'Shh, don\'t tell Sam!'
'YNOproject!'
]);

View File

@ -29550,7 +29550,6 @@ export const tmSpecies: TmSpecies = {
Species.MURKROW,
Species.SLOWKING,
Species.MISDREAVUS,
Species.UNOWN,
Species.GIRAFARIG,
Species.PINECO,
Species.FORRETRESS,
@ -62012,21 +62011,49 @@ export const tmSpecies: TmSpecies = {
Species.ALOLA_MAROWAK,
],
[Moves.TERA_BLAST]: [
Species.BULBASAUR,
Species.IVYSAUR,
Species.VENUSAUR,
Species.CHARMANDER,
Species.CHARMELEON,
Species.CHARIZARD,
Species.SQUIRTLE,
Species.WARTORTLE,
Species.BLASTOISE,
Species.BUTTERFREE,
Species.BEEDRILL,
Species.PIDGEY,
Species.PIDGEOTTO,
Species.PIDGEOT,
Species.RATTATA,
Species.RATICATE,
Species.SPEAROW,
Species.FEAROW,
Species.EKANS,
Species.ARBOK,
Species.PIKACHU,
Species.RAICHU,
Species.SANDSHREW,
Species.SANDSLASH,
Species.NIDORAN_F,
Species.NIDORINA,
Species.NIDOQUEEN,
Species.NIDORAN_M,
Species.NIDORINO,
Species.NIDOKING,
Species.CLEFAIRY,
Species.CLEFABLE,
Species.VULPIX,
Species.NINETALES,
Species.JIGGLYPUFF,
Species.WIGGLYTUFF,
Species.ZUBAT,
Species.GOLBAT,
Species.ODDISH,
Species.GLOOM,
Species.VILEPLUME,
Species.PARAS,
Species.PARASECT,
Species.VENONAT,
Species.VENOMOTH,
Species.DIGLETT,
@ -62042,16 +62069,31 @@ export const tmSpecies: TmSpecies = {
Species.POLIWAG,
Species.POLIWHIRL,
Species.POLIWRATH,
Species.ABRA,
Species.KADABRA,
Species.ALAKAZAM,
Species.MACHOP,
Species.MACHOKE,
Species.MACHAMP,
Species.BELLSPROUT,
Species.WEEPINBELL,
Species.VICTREEBEL,
Species.TENTACOOL,
Species.TENTACRUEL,
Species.GEODUDE,
Species.GRAVELER,
Species.GOLEM,
Species.PONYTA,
Species.RAPIDASH,
Species.SLOWPOKE,
Species.SLOWBRO,
Species.MAGNEMITE,
Species.MAGNETON,
Species.FARFETCHD,
Species.DODUO,
Species.DODRIO,
Species.SEEL,
Species.DEWGONG,
Species.GRIMER,
Species.MUK,
Species.SHELLDER,
@ -62059,20 +62101,52 @@ export const tmSpecies: TmSpecies = {
Species.GASTLY,
Species.HAUNTER,
Species.GENGAR,
Species.ONIX,
Species.DROWZEE,
Species.HYPNO,
Species.KRABBY,
Species.KINGLER,
Species.VOLTORB,
Species.ELECTRODE,
Species.EXEGGCUTE,
Species.EXEGGUTOR,
Species.CUBONE,
Species.MAROWAK,
Species.HITMONLEE,
Species.HITMONCHAN,
Species.LICKITUNG,
Species.KOFFING,
Species.WEEZING,
Species.RHYHORN,
Species.RHYDON,
Species.CHANSEY,
Species.TANGELA,
Species.KANGASKHAN,
Species.HORSEA,
Species.SEADRA,
Species.GOLDEEN,
Species.SEAKING,
Species.STARYU,
Species.STARMIE,
Species.MR_MIME,
Species.SCYTHER,
Species.JYNX,
Species.ELECTABUZZ,
Species.MAGMAR,
Species.PINSIR,
Species.TAUROS,
Species.GYARADOS,
Species.LAPRAS,
Species.EEVEE,
Species.VAPOREON,
Species.JOLTEON,
Species.FLAREON,
Species.PORYGON,
Species.OMANYTE,
Species.OMASTAR,
Species.KABUTO,
Species.KABUTOPS,
Species.AERODACTYL,
Species.SNORLAX,
Species.ARTICUNO,
Species.ZAPDOS,
@ -62082,21 +62156,37 @@ export const tmSpecies: TmSpecies = {
Species.DRAGONITE,
Species.MEWTWO,
Species.MEW,
Species.CHIKORITA,
Species.BAYLEEF,
Species.MEGANIUM,
Species.CYNDAQUIL,
Species.QUILAVA,
Species.TYPHLOSION,
Species.TOTODILE,
Species.CROCONAW,
Species.FERALIGATR,
Species.SENTRET,
Species.FURRET,
Species.HOOTHOOT,
Species.NOCTOWL,
Species.LEDYBA,
Species.LEDIAN,
Species.SPINARAK,
Species.ARIADOS,
Species.CROBAT,
Species.CHINCHOU,
Species.LANTURN,
Species.PICHU,
Species.CLEFFA,
Species.IGGLYBUFF,
Species.TOGEPI,
Species.TOGETIC,
Species.NATU,
Species.XATU,
Species.MAREEP,
Species.FLAAFFY,
Species.AMPHAROS,
Species.BELLOSSOM,
Species.MARILL,
Species.AZUMARILL,
Species.SUDOWOODO,
@ -62120,8 +62210,12 @@ export const tmSpecies: TmSpecies = {
Species.FORRETRESS,
Species.DUNSPARCE,
Species.GLIGAR,
Species.STEELIX,
Species.SNUBBULL,
Species.GRANBULL,
Species.QWILFISH,
Species.SCIZOR,
Species.SHUCKLE,
Species.HERACROSS,
Species.SNEASEL,
Species.TEDDIURSA,
@ -62130,24 +62224,58 @@ export const tmSpecies: TmSpecies = {
Species.MAGCARGO,
Species.SWINUB,
Species.PILOSWINE,
Species.CORSOLA,
Species.REMORAID,
Species.OCTILLERY,
Species.DELIBIRD,
Species.MANTINE,
Species.SKARMORY,
Species.HOUNDOUR,
Species.HOUNDOOM,
Species.KINGDRA,
Species.PHANPY,
Species.DONPHAN,
Species.PORYGON2,
Species.STANTLER,
Species.TYROGUE,
Species.HITMONTOP,
Species.SMOOCHUM,
Species.ELEKID,
Species.MAGBY,
Species.MILTANK,
Species.BLISSEY,
Species.RAIKOU,
Species.ENTEI,
Species.SUICUNE,
Species.LARVITAR,
Species.PUPITAR,
Species.TYRANITAR,
Species.LUGIA,
Species.HO_OH,
Species.CELEBI,
Species.TREECKO,
Species.GROVYLE,
Species.SCEPTILE,
Species.TORCHIC,
Species.COMBUSKEN,
Species.BLAZIKEN,
Species.MUDKIP,
Species.MARSHTOMP,
Species.SWAMPERT,
Species.POOCHYENA,
Species.MIGHTYENA,
Species.ZIGZAGOON,
Species.LINOONE,
Species.BEAUTIFLY,
Species.DUSTOX,
Species.LOTAD,
Species.LOMBRE,
Species.LUDICOLO,
Species.SEEDOT,
Species.NUZLEAF,
Species.SHIFTRY,
Species.TAILLOW,
Species.SWELLOW,
Species.WINGULL,
Species.PELIPPER,
Species.RALTS,
@ -62160,49 +62288,101 @@ export const tmSpecies: TmSpecies = {
Species.SLAKOTH,
Species.VIGOROTH,
Species.SLAKING,
Species.NINCADA,
Species.NINJASK,
Species.SHEDINJA,
Species.WHISMUR,
Species.LOUDRED,
Species.EXPLOUD,
Species.MAKUHITA,
Species.HARIYAMA,
Species.AZURILL,
Species.NOSEPASS,
Species.SKITTY,
Species.DELCATTY,
Species.SABLEYE,
Species.MAWILE,
Species.ARON,
Species.LAIRON,
Species.AGGRON,
Species.MEDITITE,
Species.MEDICHAM,
Species.ELECTRIKE,
Species.MANECTRIC,
Species.PLUSLE,
Species.MINUN,
Species.VOLBEAT,
Species.ILLUMISE,
Species.ROSELIA,
Species.GULPIN,
Species.SWALOT,
Species.CARVANHA,
Species.SHARPEDO,
Species.WAILMER,
Species.WAILORD,
Species.NUMEL,
Species.CAMERUPT,
Species.TORKOAL,
Species.SPOINK,
Species.GRUMPIG,
Species.SPINDA,
Species.TRAPINCH,
Species.VIBRAVA,
Species.FLYGON,
Species.CACNEA,
Species.CACTURNE,
Species.SWABLU,
Species.ALTARIA,
Species.ZANGOOSE,
Species.SEVIPER,
Species.LUNATONE,
Species.SOLROCK,
Species.BARBOACH,
Species.WHISCASH,
Species.CORPHISH,
Species.CRAWDAUNT,
Species.BALTOY,
Species.CLAYDOL,
Species.LILEEP,
Species.CRADILY,
Species.ANORITH,
Species.ARMALDO,
Species.FEEBAS,
Species.MILOTIC,
Species.CASTFORM,
Species.KECLEON,
Species.SHUPPET,
Species.BANETTE,
Species.DUSKULL,
Species.DUSCLOPS,
Species.TROPIUS,
Species.CHIMECHO,
Species.ABSOL,
Species.SNORUNT,
Species.GLALIE,
Species.SPHEAL,
Species.SEALEO,
Species.WALREIN,
Species.CLAMPERL,
Species.HUNTAIL,
Species.GOREBYSS,
Species.RELICANTH,
Species.LUVDISC,
Species.BAGON,
Species.SHELGON,
Species.SALAMENCE,
Species.METANG,
Species.METAGROSS,
Species.REGIROCK,
Species.REGICE,
Species.REGISTEEL,
Species.LATIAS,
Species.LATIOS,
Species.KYOGRE,
Species.GROUDON,
Species.RAYQUAZA,
Species.JIRACHI,
Species.DEOXYS,
Species.TURTWIG,
Species.GROTLE,
Species.TORTERRA,
@ -62215,30 +62395,49 @@ export const tmSpecies: TmSpecies = {
Species.STARLY,
Species.STARAVIA,
Species.STARAPTOR,
Species.BIDOOF,
Species.BIBAREL,
Species.KRICKETOT,
Species.KRICKETUNE,
Species.SHINX,
Species.LUXIO,
Species.LUXRAY,
Species.BUDEW,
Species.ROSERADE,
Species.CRANIDOS,
Species.RAMPARDOS,
Species.SHIELDON,
Species.BASTIODON,
Species.BURMY,
Species.WORMADAM,
Species.MOTHIM,
Species.COMBEE,
Species.VESPIQUEN,
Species.PACHIRISU,
Species.BUIZEL,
Species.FLOATZEL,
Species.CHERUBI,
Species.CHERRIM,
Species.SHELLOS,
Species.GASTRODON,
Species.AMBIPOM,
Species.DRIFLOON,
Species.DRIFBLIM,
Species.BUNEARY,
Species.LOPUNNY,
Species.MISMAGIUS,
Species.HONCHKROW,
Species.GLAMEOW,
Species.PURUGLY,
Species.CHINGLING,
Species.STUNKY,
Species.SKUNTANK,
Species.BRONZOR,
Species.BRONZONG,
Species.BONSLY,
Species.MIME_JR,
Species.HAPPINY,
Species.CHATOT,
Species.SPIRITOMB,
Species.GIBLE,
Species.GABITE,
@ -62248,19 +62447,30 @@ export const tmSpecies: TmSpecies = {
Species.LUCARIO,
Species.HIPPOPOTAS,
Species.HIPPOWDON,
Species.SKORUPI,
Species.DRAPION,
Species.CROAGUNK,
Species.TOXICROAK,
Species.CARNIVINE,
Species.FINNEON,
Species.LUMINEON,
Species.MANTYKE,
Species.SNOVER,
Species.ABOMASNOW,
Species.WEAVILE,
Species.MAGNEZONE,
Species.LICKILICKY,
Species.RHYPERIOR,
Species.TANGROWTH,
Species.ELECTIVIRE,
Species.MAGMORTAR,
Species.TOGEKISS,
Species.YANMEGA,
Species.LEAFEON,
Species.GLACEON,
Species.GLISCOR,
Species.MAMOSWINE,
Species.PORYGON_Z,
Species.GALLADE,
Species.PROBOPASS,
Species.DUSKNOIR,
@ -62272,39 +62482,127 @@ export const tmSpecies: TmSpecies = {
Species.DIALGA,
Species.PALKIA,
Species.HEATRAN,
Species.REGIGIGAS,
Species.GIRATINA,
Species.CRESSELIA,
Species.PHIONE,
Species.MANAPHY,
Species.DARKRAI,
Species.SHAYMIN,
Species.ARCEUS,
Species.VICTINI,
Species.SNIVY,
Species.SERVINE,
Species.SERPERIOR,
Species.TEPIG,
Species.PIGNITE,
Species.EMBOAR,
Species.OSHAWOTT,
Species.DEWOTT,
Species.SAMUROTT,
Species.PATRAT,
Species.WATCHOG,
Species.LILLIPUP,
Species.HERDIER,
Species.STOUTLAND,
Species.PURRLOIN,
Species.LIEPARD,
Species.PANSAGE,
Species.SIMISAGE,
Species.PANSEAR,
Species.SIMISEAR,
Species.PANPOUR,
Species.SIMIPOUR,
Species.MUNNA,
Species.MUSHARNA,
Species.PIDOVE,
Species.TRANQUILL,
Species.UNFEZANT,
Species.BLITZLE,
Species.ZEBSTRIKA,
Species.ROGGENROLA,
Species.BOLDORE,
Species.GIGALITH,
Species.WOOBAT,
Species.SWOOBAT,
Species.DRILBUR,
Species.EXCADRILL,
Species.AUDINO,
Species.TIMBURR,
Species.GURDURR,
Species.CONKELDURR,
Species.TYMPOLE,
Species.PALPITOAD,
Species.SEISMITOAD,
Species.THROH,
Species.SAWK,
Species.SEWADDLE,
Species.SWADLOON,
Species.LEAVANNY,
Species.VENIPEDE,
Species.WHIRLIPEDE,
Species.SCOLIPEDE,
Species.COTTONEE,
Species.WHIMSICOTT,
Species.PETILIL,
Species.LILLIGANT,
Species.BASCULIN,
Species.SANDILE,
Species.KROKOROK,
Species.KROOKODILE,
Species.DARUMAKA,
Species.DARMANITAN,
Species.MARACTUS,
Species.DWEBBLE,
Species.CRUSTLE,
Species.SCRAGGY,
Species.SCRAFTY,
Species.SIGILYPH,
Species.YAMASK,
Species.COFAGRIGUS,
Species.TIRTOUGA,
Species.CARRACOSTA,
Species.ARCHEN,
Species.ARCHEOPS,
Species.TRUBBISH,
Species.GARBODOR,
Species.ZORUA,
Species.ZOROARK,
Species.MINCCINO,
Species.CINCCINO,
Species.GOTHITA,
Species.GOTHORITA,
Species.GOTHITELLE,
Species.SOLOSIS,
Species.DUOSION,
Species.REUNICLUS,
Species.DUCKLETT,
Species.SWANNA,
Species.VANILLITE,
Species.VANILLISH,
Species.VANILLUXE,
Species.DEERLING,
Species.SAWSBUCK,
Species.EMOLGA,
Species.KARRABLAST,
Species.ESCAVALIER,
Species.FOONGUS,
Species.AMOONGUSS,
Species.FRILLISH,
Species.JELLICENT,
Species.ALOMOMOLA,
Species.JOLTIK,
Species.GALVANTULA,
Species.FERROSEED,
Species.FERROTHORN,
Species.KLINK,
Species.KLANG,
Species.KLINKLANG,
Species.TYNAMO,
Species.EELEKTRIK,
Species.EELEKTROSS,
Species.ELGYEM,
Species.BEHEEYEM,
Species.LITWICK,
Species.LAMPENT,
Species.CHANDELURE,
@ -62314,23 +62612,40 @@ export const tmSpecies: TmSpecies = {
Species.CUBCHOO,
Species.BEARTIC,
Species.CRYOGONAL,
Species.SHELMET,
Species.ACCELGOR,
Species.STUNFISK,
Species.MIENFOO,
Species.MIENSHAO,
Species.DRUDDIGON,
Species.GOLETT,
Species.GOLURK,
Species.PAWNIARD,
Species.BISHARP,
Species.BOUFFALANT,
Species.RUFFLET,
Species.BRAVIARY,
Species.VULLABY,
Species.MANDIBUZZ,
Species.HEATMOR,
Species.DURANT,
Species.DEINO,
Species.ZWEILOUS,
Species.HYDREIGON,
Species.LARVESTA,
Species.VOLCARONA,
Species.COBALION,
Species.TERRAKION,
Species.VIRIZION,
Species.TORNADUS,
Species.THUNDURUS,
Species.RESHIRAM,
Species.ZEKROM,
Species.LANDORUS,
Species.KYUREM,
Species.KELDEO,
Species.MELOETTA,
Species.GENESECT,
Species.CHESPIN,
Species.QUILLADIN,
Species.CHESNAUGHT,
@ -62345,6 +62660,8 @@ export const tmSpecies: TmSpecies = {
'battle-bond',
'ash',
],
Species.BUNNELBY,
Species.DIGGERSBY,
Species.FLETCHLING,
Species.FLETCHINDER,
Species.TALONFLAME,
@ -62354,14 +62671,43 @@ export const tmSpecies: TmSpecies = {
Species.LITLEO,
Species.PYROAR,
Species.FLABEBE,
Species.FLOETTE,
[
Species.FLOETTE,
'red',
'yellow',
'orange',
'blue',
'white',
],
Species.FLORGES,
Species.SKIDDO,
Species.GOGOAT,
Species.PANCHAM,
Species.PANGORO,
Species.FURFROU,
Species.ESPURR,
Species.MEOWSTIC,
Species.HONEDGE,
Species.DOUBLADE,
Species.AEGISLASH,
Species.SPRITZEE,
Species.AROMATISSE,
Species.SWIRLIX,
Species.SLURPUFF,
Species.INKAY,
Species.MALAMAR,
Species.BINACLE,
Species.BARBARACLE,
Species.SKRELP,
Species.DRAGALGE,
Species.CLAUNCHER,
Species.CLAWITZER,
Species.HELIOPTILE,
Species.HELIOLISK,
Species.TYRUNT,
Species.TYRANTRUM,
Species.AMAURA,
Species.AURORUS,
Species.SYLVEON,
Species.HAWLUCHA,
Species.DEDENNE,
@ -62372,16 +62718,30 @@ export const tmSpecies: TmSpecies = {
Species.KLEFKI,
Species.PHANTUMP,
Species.TREVENANT,
Species.PUMPKABOO,
Species.GOURGEIST,
Species.BERGMITE,
Species.AVALUGG,
Species.NOIBAT,
Species.NOIVERN,
Species.XERNEAS,
Species.YVELTAL,
Species.ZYGARDE,
Species.DIANCIE,
Species.HOOPA,
Species.VOLCANION,
Species.ROWLET,
Species.DARTRIX,
Species.DECIDUEYE,
Species.LITTEN,
Species.TORRACAT,
Species.INCINEROAR,
Species.POPPLIO,
Species.BRIONNE,
Species.PRIMARINA,
Species.PIKIPEK,
Species.TRUMBEAK,
Species.TOUCANNON,
Species.YUNGOOS,
Species.GUMSHOOS,
Species.GRUBBIN,
@ -62394,28 +62754,84 @@ export const tmSpecies: TmSpecies = {
Species.RIBOMBEE,
Species.ROCKRUFF,
Species.LYCANROC,
Species.WISHIWASHI,
Species.MAREANIE,
Species.TOXAPEX,
Species.MUDBRAY,
Species.MUDSDALE,
Species.DEWPIDER,
Species.ARAQUANID,
Species.FOMANTIS,
Species.LURANTIS,
Species.MORELULL,
Species.SHIINOTIC,
Species.SALANDIT,
Species.SALAZZLE,
Species.STUFFUL,
Species.BEWEAR,
Species.BOUNSWEET,
Species.STEENEE,
Species.TSAREENA,
Species.COMFEY,
Species.ORANGURU,
Species.PASSIMIAN,
Species.WIMPOD,
Species.GOLISOPOD,
Species.SANDYGAST,
Species.PALOSSAND,
Species.TYPE_NULL,
Species.SILVALLY,
Species.MINIOR,
Species.KOMALA,
Species.TURTONATOR,
Species.TOGEDEMARU,
Species.MIMIKYU,
Species.BRUXISH,
Species.DRAMPA,
Species.DHELMISE,
Species.JANGMO_O,
Species.HAKAMO_O,
Species.KOMMO_O,
Species.TAPU_KOKO,
Species.TAPU_LELE,
Species.TAPU_BULU,
Species.TAPU_FINI,
Species.SOLGALEO,
Species.LUNALA,
Species.NIHILEGO,
Species.BUZZWOLE,
Species.PHEROMOSA,
Species.XURKITREE,
Species.CELESTEELA,
Species.KARTANA,
Species.GUZZLORD,
Species.NECROZMA,
Species.MAGEARNA,
Species.MARSHADOW,
Species.POIPOLE,
Species.NAGANADEL,
Species.STAKATAKA,
Species.BLACEPHALON,
Species.ZERAORA,
Species.ALOLA_RATTATA,
Species.ALOLA_RATICATE,
Species.ALOLA_RAICHU,
Species.ALOLA_SANDSHREW,
Species.ALOLA_SANDSLASH,
Species.ALOLA_VULPIX,
Species.ALOLA_NINETALES,
Species.ALOLA_DIGLETT,
Species.ALOLA_DUGTRIO,
Species.ALOLA_MEOWTH,
Species.ALOLA_PERSIAN,
Species.ALOLA_GEODUDE,
Species.ALOLA_GRAVELER,
Species.ALOLA_GOLEM,
Species.ALOLA_GRIMER,
Species.ALOLA_MUK,
Species.ALOLA_EXEGGUTOR,
Species.ALOLA_MAROWAK,
Species.ETERNAL_FLOETTE,
Species.GROOKEY,
Species.THWACKEY,
Species.RILLABOOM,
@ -62596,21 +63012,6 @@ export const tmSpecies: TmSpecies = {
Species.MUNKIDORI,
Species.FEZANDIPITI,
Species.OGERPON,
Species.ALOLA_RAICHU,
Species.ALOLA_SANDSHREW,
Species.ALOLA_SANDSLASH,
Species.ALOLA_VULPIX,
Species.ALOLA_NINETALES,
Species.ALOLA_DIGLETT,
Species.ALOLA_DUGTRIO,
Species.ALOLA_MEOWTH,
Species.ALOLA_PERSIAN,
Species.ALOLA_GEODUDE,
Species.ALOLA_GRAVELER,
Species.ALOLA_GOLEM,
Species.ALOLA_GRIMER,
Species.ALOLA_MUK,
Species.ETERNAL_FLOETTE,
Species.GALAR_MEOWTH,
Species.GALAR_SLOWPOKE,
Species.GALAR_SLOWBRO,

View File

@ -5,12 +5,12 @@ import { variantData } from '#app/data/variant';
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
import { Moves } from "../data/enums/moves";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, starterPassiveAbilities } from '../data/pokemon-species';
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species';
import * as Utils from '../utils';
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
import { getLevelTotalExp } from '../data/exp';
import { Stat } from '../data/pokemon-stat';
import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, TerastallizeModifier } from '../modifier/modifier';
import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, TerastallizeModifier } from '../modifier/modifier';
import { PokeballType } from '../data/pokeball';
import { Gender } from '../data/gender';
import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
@ -37,13 +37,15 @@ import PartyUiHandler, { PartyOption, PartyUiMode } from '../ui/party-ui-handler
import SoundFade from 'phaser3-rex-plugins/plugins/soundfade';
import { LevelMoves } from '../data/pokemon-level-moves';
import { DamageAchv, achvs } from '../system/achv';
import { DexAttr, StarterMoveset } from '../system/game-data';
import { DexAttr, StarterDataEntry, StarterMoveset } from '../system/game-data';
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from '@material/material-color-utilities';
import { Nature, getNatureStatMultiplier } from '../data/nature';
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms';
import { TerrainType } from '../data/terrain';
import { TrainerSlot } from '../data/trainer-config';
import { BerryType } from '../data/berry';
import { ABILITY_OVERRIDE, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE, OPP_SHINY_OVERRIDE, OPP_VARIANT_OVERRIDE } from '../overrides';
import i18next from '../plugins/i18n';
export enum FieldPosition {
CENTER,
@ -455,6 +457,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return 1;
}
getHeldItems(): PokemonHeldItemModifier[] {
if (!this.scene)
return [];
return this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === this.id, this.isPlayer()) as PokemonHeldItemModifier[];
}
updateScale(): void {
this.setScale(this.getSpriteScale());
}
@ -581,6 +589,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
ret *= 1.5;
break;
case Stat.SPD:
// Check both the player and enemy to see if Tailwind should be multiplying the speed of the Pokemon
if ((this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.PLAYER))
|| (!this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.ENEMY)))
ret *= 2;
if (this.getTag(BattlerTagType.SLOW_START))
ret >>= 1;
if (this.status && this.status.effect === StatusEffect.PARALYSIS)
@ -1179,6 +1192,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.battleInfo.updateInfo(this, instant);
}
toggleStats(visible: boolean): void {
this.battleInfo.toggleStats(visible);
}
addExp(exp: integer) {
const maxExpLevel = this.scene.getMaxExpLevel();
const initialExp = this.exp;
@ -1407,7 +1424,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
damage.value = this.damageAndUpdate(damage.value, result as DamageResult, isCritical, oneHitKo, oneHitKo);
this.turnData.damageTaken += damage.value;
if (isCritical)
this.scene.queueMessage('A critical hit!');
this.scene.queueMessage(i18next.t('battle:hitResultCriticalHit'));
this.scene.setPhaseQueueSplice();
if (source.isPlayer()) {
this.scene.validateAchvs(DamageAchv, damage);
@ -1425,16 +1442,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (source.turnData.hitsLeft === 1) {
switch (result) {
case HitResult.SUPER_EFFECTIVE:
this.scene.queueMessage('It\'s super effective!');
this.scene.queueMessage(i18next.t('battle:hitResultSuperEffective'));
break;
case HitResult.NOT_VERY_EFFECTIVE:
this.scene.queueMessage('It\'s not very effective…');
this.scene.queueMessage(i18next.t('battle:hitResultNotVeryEffective'));
break;
case HitResult.NO_EFFECT:
this.scene.queueMessage(`It doesn\'t affect ${this.name}!`);
this.scene.queueMessage(i18next.t('battle:hitResultNoEffect', { pokemonName: this.name }));
break;
case HitResult.ONE_HIT_KO:
this.scene.queueMessage('It\'s a one-hit KO!');
this.scene.queueMessage(i18next.t('battle:hitResultOneHitKO'));
break;
}
}
@ -1451,7 +1468,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, battlerMove, cancelled, typeMultiplier));
}
if (!typeMultiplier.value)
this.scene.queueMessage(`It doesn\'t affect ${this.name}!`);
this.scene.queueMessage(i18next.t('battle:hitResultNoEffect', { pokemonName: this.name }));
result = cancelled.value || !typeMultiplier.value ? HitResult.NO_EFFECT : HitResult.STATUS;
break;
}
@ -1621,6 +1638,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.summonData.tags.push(tag);
if (this instanceof PlayerPokemon && source.summonData.battleStats.find(bs => bs === 6))
this.scene.validateAchv(achvs.TRANSFER_MAX_BATTLE_STAT);
this.updateInfo();
}
getMoveHistory(): TurnMove[] {
@ -1921,6 +1939,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
this.summonDataPrimer = null;
}
this.updateInfo();
}
resetBattleData(): void {
@ -2349,6 +2368,37 @@ export class PlayerPokemon extends Pokemon {
}, PartyUiHandler.FilterNonFainted);
});
}
addFriendship(friendship: integer): void {
const starterSpeciesId = this.species.getRootSpeciesId();
const fusionStarterSpeciesId = this.isFusion() ? this.fusionSpecies.getRootSpeciesId() : 0;
const starterData = [
this.scene.gameData.starterData[starterSpeciesId],
fusionStarterSpeciesId ? this.scene.gameData.starterData[fusionStarterSpeciesId] : null
].filter(d => d);
const amount = new Utils.IntegerHolder(friendship);
const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic ? 2 : 1) / (fusionStarterSpeciesId ? 2 : 1)));
if (amount.value > 0) {
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, starterAmount);
this.friendship = Math.min(this.friendship + amount.value, 255);
if (this.friendship === 255)
this.scene.validateAchv(achvs.MAX_FRIENDSHIP);
starterData.forEach((sd: StarterDataEntry, i: integer) => {
const speciesId = !i ? starterSpeciesId : fusionStarterSpeciesId as Species;
sd.friendship = (sd.friendship || 0) + starterAmount.value;
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarters[speciesId])) {
this.scene.gameData.addStarterCandy(getPokemonSpecies(speciesId), 1);
sd.friendship = 0;
}
});
} else {
this.friendship = Math.max(this.friendship + amount.value, 0);
for (let sd of starterData)
sd.friendship = Math.max((sd.friendship || 0) + starterAmount.value, 0);
}
}
getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> {
return new Promise(resolve => {
@ -2416,12 +2466,17 @@ export class PlayerPokemon extends Pokemon {
private handleSpecialEvolutions(evolution: SpeciesFormEvolution) {
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
if ((!isFusion ? this.species : this.fusionSpecies).speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const newEvolution = pokemonEvolutions[this.species.speciesId][1];
const evoSpecies = (!isFusion ? this.species : this.fusionSpecies)
if (evoSpecies.speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const newEvolution = pokemonEvolutions[evoSpecies.speciesId][1];
if (newEvolution.condition.predicate(this)) {
const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, undefined, this.shiny, this.variant, this.ivs, this.nature);
newPokemon.natureOverride = this.natureOverride;
newPokemon.moveset = this.moveset.slice();
newPokemon.luck = this.luck;
newPokemon.fusionSpecies = this.fusionSpecies;
newPokemon.fusionFormIndex = this.fusionFormIndex;
newPokemon.fusionAbilityIndex = this.fusionAbilityIndex;
@ -2429,8 +2484,9 @@ export class PlayerPokemon extends Pokemon {
newPokemon.fusionVariant = this.fusionVariant;
newPokemon.fusionGender = this.fusionGender;
newPokemon.fusionLuck = this.fusionLuck;
this.scene.getParty().push(newPokemon);
newPokemon.evolve(newEvolution);
newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution));
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === this.id, true) as PokemonHeldItemModifier[];
modifiers.forEach(m => {
@ -2668,7 +2724,7 @@ export class EnemyPokemon extends Pokemon {
for (let mt of moveTargets[move.id]) {
const target = this.scene.getField()[mt];
let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1);
if (move.name.endsWith(' (N)'))
if (move.name.endsWith(' (N)') || !move.applyConditions(this, target, move))
targetScore = -20;
else if (move instanceof AttackMove) {
const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove);
@ -2988,6 +3044,7 @@ export class PokemonSummonData {
export class PokemonBattleData {
public hitCount: integer = 0;
public endured: boolean = false;
public berriesEaten: BerryType[] = [];
}
export class PokemonBattleSummonData {

View File

@ -39,15 +39,21 @@ export class LoadingScene extends SceneBase {
}
this.loadAtlas('namebox', 'ui');
this.loadImage('pbinfo_player', 'ui');
this.loadImage('pbinfo_player_stats', 'ui');
this.loadImage('pbinfo_player_mini', 'ui');
this.loadImage('pbinfo_player_mini_stats', 'ui');
this.loadAtlas('pbinfo_player_type', 'ui');
this.loadAtlas('pbinfo_player_type1', 'ui');
this.loadAtlas('pbinfo_player_type2', 'ui');
this.loadImage('pbinfo_enemy_mini', 'ui');
this.loadImage('pbinfo_enemy_mini_stats', 'ui');
this.loadImage('pbinfo_enemy_boss', 'ui');
this.loadImage('pbinfo_enemy_boss_stats', 'ui');
this.loadAtlas('pbinfo_enemy_type', 'ui');
this.loadAtlas('pbinfo_enemy_type1', 'ui');
this.loadAtlas('pbinfo_enemy_type2', 'ui');
this.loadAtlas('pbinfo_stat', 'ui');
this.loadAtlas('pbinfo_stat_numbers', 'ui');
this.loadImage('overlay_lv', 'ui');
this.loadAtlas('numbers', 'ui');
this.loadAtlas('numbers_red', 'ui');
@ -61,6 +67,7 @@ export class LoadingScene extends SceneBase {
this.loadImage('achv_bar_2', 'ui');
this.loadImage('achv_bar_3', 'ui');
this.loadImage('achv_bar_4', 'ui');
this.loadImage('achv_bar_5', 'ui');
this.loadImage('shiny_star', 'ui', 'shiny.png');
this.loadImage('shiny_star_1', 'ui', 'shiny_1.png');
this.loadImage('shiny_star_2', 'ui', 'shiny_2.png');

52
src/locales/de/battle.ts Normal file
View File

@ -0,0 +1,52 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "{{bossName}} erscheint.",
"trainerAppeared": "{{trainerName}}\nmöchte kämpfen!",
"singleWildAppeared": "Ein wildes {{pokemonName}} erscheint!",
"multiWildAppeared": "Ein wildes {{pokemonName1}}\nund {{pokemonName2}} erscheinen!",
"playerComeBack": "Komm zurück, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} ruft {{pokemonName}} zurück!",
"playerGo": "Los! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sendet {{pokemonName}} raus!",
"switchQuestion": "Willst du\n{{pokemonName}} auswechseln?",
"trainerDefeated": `You defeated\n{{trainerName}}!`,
"pokemonCaught": "{{pokemonName}} was caught!",
"pokemon": "Pokémon",
"sendOutPokemon": "Los! {{pokemonName}}!",
"hitResultCriticalHit": "A critical hit!",
"hitResultSuperEffective": "It's super effective!",
"hitResultNotVeryEffective": "It's not very effective…",
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "But it failed!",
"attackHitsCount": `Hit {{count}} time(s)!`,
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",
"levelUp": "{{pokemonName}} grew to\nLv. {{level}}!",
"learnMove": "{{pokemonName}} learned\n{{moveName}}!",
"learnMovePrompt": "{{pokemonName}} wants to learn the\nmove {{moveName}}.",
"learnMoveLimitReached": "However, {{pokemonName}} already\nknows four moves.",
"learnMoveReplaceQuestion": "Should a move be forgotten and\nreplaced with {{moveName}}?",
"learnMoveStopTeaching": "Stop trying to teach\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} did not learn the\nmove {{moveName}}.",
"learnMoveForgetQuestion": "Which move should be forgotten?",
"learnMoveForgetSuccess": "{{pokemonName}} forgot how to\nuse {{moveName}}.",
"levelCapUp": "Das Levellimit\nhat sich zu {{levelCap}} erhöht!",
"moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.",
"moveDisabled": "{{moveName}} ist deaktiviert!",
"noPokeballForce": "Eine unsichtbare Kraft\nverhindert die Nutzung von Pokébällen.",
"noPokeballTrainer": "Du kannst das Pokémon\neines anderen Trainers nicht fangen!",
"noPokeballMulti": "Du kannst erst einen Pokéball werden,\nwenn nur noch ein Pokémon übrig ist!",
"noPokeballStrong": "Das Ziel-Pokémon ist zu stark, um gefangen zu werden!\nDu musst es zuerst schwächen!",
"noEscapeForce": "Eine unsichtbare Kraft\nverhindert die Flucht.",
"noEscapeTrainer": "Du kannst nicht\naus einem Trainerkampf fliehen!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nverhindert {{escapeVerb}}!",
"runAwaySuccess": "You got away safely!",
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "auswechseln",
"escapeVerbFlee": "flucht",
"notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
} as const;

View File

@ -0,0 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP",
"power": "POWER",
} as const;

View File

@ -35,32 +35,8 @@ export const menu: SimpleTranslationEntries = {
"boyOrGirl": "Bist du ein Junge oder ein Mädchen?",
"boy": "Junge",
"girl": "Mädchen",
"bossAppeared": "{{bossName}} erscheint.",
"trainerAppeared": "{{trainerName}}\nmöchte kämpfen!",
"singleWildAppeared": "Ein wildes {{pokemonName}} erscheint!",
"multiWildAppeared": "Ein wildes {{pokemonName1}}\nund {{pokemonName2}} erscheinen!",
"playerComeBack": "Komm zurück, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} ruft {{pokemonName}} zurück!",
"playerGo": "Los! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sendet {{pokemonName}} raus!",
"switchQuestion": "Willst du\n{{pokemonName}} auswechseln?",
"pokemon": "Pokémon",
"sendOutPokemon": "Los! {{pokemonName}}!",
"levelCapUp": "Das Levellimit\nhat sich zu {{levelCap}} erhöht!",
"moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.",
"moveDisabled": "{{moveName}} ist deaktiviert!",
"noPokeballForce": "Eine unsichtbare Kraft\nverhindert die Nutzung von Pokébällen.",
"noPokeballTrainer": "Du kannst das Pokémon\neines anderen Trainers nicht fangen!",
"noPokeballMulti": "Du kannst erst einen Pokéball werden,\nwenn nur noch ein Pokémon übrig ist!",
"noPokeballStrong": "Das Ziel-Pokémon ist zu stark, um gefangen zu werden!\nDu musst es zuerst schwächen!",
"noEscapeForce": "Eine unsichtbare Kraft\nverhindert die Flucht.",
"noEscapeTrainer": "Du kannst nicht\naus einem Trainerkampf fliehen!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nverhindert {{escapeVerb}}!",
"escapeVerbSwitch": "auswechseln",
"escapeVerbFlee": "flucht",
"notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!",
"rankings": "Rankings",
"dailyRankings": "Daily Rankings",
"weeklyRankings": "Weekly Rankings",
"noRankings": "No Rankings",
"loading": "Loading…",
"playersOnline": "Players Online"

View File

@ -20,6 +20,10 @@ export const tutorial: SimpleTranslationEntries = {
"pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled.
$Your Pokémon are recalled before a trainer battle and before entering a new biome.
$You can also view the stat changes for the Pokémon on the field by holding C or Shift.`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways.

52
src/locales/en/battle.ts Normal file
View File

@ -0,0 +1,52 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "{{bossName}} appeared.",
"trainerAppeared": "{{trainerName}}\nwould like to battle!",
"singleWildAppeared": "A wild {{pokemonName}} appeared!",
"multiWildAppeared": "A wild {{pokemonName1}}\nand {{pokemonName2}} appeared!",
"playerComeBack": "Come back, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} withdrew {{pokemonName}}!",
"playerGo": "Go! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sent out {{pokemonName}}!",
"switchQuestion": "Will you switch\n{{pokemonName}}?",
"trainerDefeated": `You defeated\n{{trainerName}}!`,
"pokemonCaught": "{{pokemonName}} was caught!",
"pokemon": "Pokémon",
"sendOutPokemon": "Go! {{pokemonName}}!",
"hitResultCriticalHit": "A critical hit!",
"hitResultSuperEffective": "It's super effective!",
"hitResultNotVeryEffective": "It's not very effective…",
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "But it failed!",
"attackHitsCount": `Hit {{count}} time(s)!`,
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",
"levelUp": "{{pokemonName}} grew to\nLv. {{level}}!",
"learnMove": "{{pokemonName}} learned\n{{moveName}}!",
"learnMovePrompt": "{{pokemonName}} wants to learn the\nmove {{moveName}}.",
"learnMoveLimitReached": "However, {{pokemonName}} already\nknows four moves.",
"learnMoveReplaceQuestion": "Should a move be forgotten and\nreplaced with {{moveName}}?",
"learnMoveStopTeaching": "Stop trying to teach\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} did not learn the\nmove {{moveName}}.",
"learnMoveForgetQuestion": "Which move should be forgotten?",
"learnMoveForgetSuccess": "{{pokemonName}} forgot how to\nuse {{moveName}}.",
"levelCapUp": "The level cap\nhas increased to {{levelCap}}!",
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
"moveDisabled": "{{moveName}} is disabled!",
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
"noPokeballStrong": "The target Pokémon is too strong to be caught!\nYou need to weaken it first!",
"noEscapeForce": "An unseen force\nprevents escape.",
"noEscapeTrainer": "You can't run\nfrom a trainer battle!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nprevents {{escapeVerb}}!",
"runAwaySuccess": "You got away safely!",
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "switching",
"escapeVerbFlee": "fleeing",
"notDisabled": "{{moveName}} is disabled\nno more!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
} as const;

View File

@ -35,51 +35,8 @@ export const menu: SimpleTranslationEntries = {
"boyOrGirl": "Are you a boy or a girl?",
"boy": "Boy",
"girl": "Girl",
"bossAppeared": "{{bossName}} appeared.",
"trainerAppeared": "{{trainerName}}\nwould like to battle!",
"singleWildAppeared": "A wild {{pokemonName}} appeared!",
"multiWildAppeared": "A wild {{pokemonName1}}\nand {{pokemonName2}} appeared!",
"playerComeBack": "Come back, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} withdrew {{pokemonName}}!",
"playerGo": "Go! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sent out {{pokemonName}}!",
"switchQuestion": "Will you switch\n{{pokemonName}}?",
"trainerDefeated": `You defeated\n{{trainerName}}!`,
"pokemonCaught": "{{pokemonName}} was caught!",
"pokemon": "Pokémon",
"sendOutPokemon": "Go! {{pokemonName}}!",
"attackFailed": "But it failed!",
"attackHitsCount": `Hit {{count}} time(s)!`,
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",
"levelUp": "{{pokemonName}} grew to\nLv. {{level}}!",
"learnMove": "{{pokemonName}} learned\n{{moveName}}!",
"learnMovePrompt": "{{pokemonName}} wants to learn the\nmove {{moveName}}.",
"learnMoveLimitReached": "However, {{pokemonName}} already\nknows four moves.",
"learnMoveReplaceQuestion": "Should a move be forgotten and\nreplaced with {{moveName}}?",
"learnMoveStopTeaching": "Stop trying to teach\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} did not learn the\nmove {{moveName}}.",
"learnMoveForgetQuestion": "Which move should be forgotten?",
"learnMoveForgetSuccess": "{{pokemonName}} forgot how to\nuse {{moveName}}.",
"levelCapUp": "The level cap\nhas increased to {{levelCap}}!",
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
"moveDisabled": "{{moveName}} is disabled!",
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
"noPokeballStrong": "The target Pokémon is too strong to be caught!\nYou need to weaken it first!",
"noEscapeForce": "An unseen force\nprevents escape.",
"noEscapeTrainer": "You can't run\nfrom a trainer battle!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nprevents {{escapeVerb}}!",
"runAwaySuccess": "You got away safely!",
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "switching",
"escapeVerbFlee": "fleeing",
"notDisabled": "{{moveName}} is disabled\nno more!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
"rankings": "Rankings",
"dailyRankings": "Daily Rankings",
"weeklyRankings": "Weekly Rankings",
"noRankings": "No Rankings",
"loading": "Loading…",
"playersOnline": "Players Online"

View File

@ -20,6 +20,10 @@ export const tutorial: SimpleTranslationEntries = {
"pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled.
$Your Pokémon are recalled before a trainer battle and before entering a new biome.
$You can also view the stat changes for the Pokémon on the field by holding C or Shift.`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways.

52
src/locales/es/battle.ts Normal file
View File

@ -0,0 +1,52 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "¡{{bossName}} te corta el paso!",
"trainerAppeared": "¡{{trainerName}}\nte desafía!",
"singleWildAppeared": "¡Un {{pokemonName}} salvaje te corta el paso!",
"multiWildAppeared": "¡Un {{pokemonName1}} y un {{pokemonName2}} salvajes\nte cortan el paso!",
"playerComeBack": "¡{{pokemonName}}, ven aquí!",
"trainerComeBack": "¡{{trainerName}} retira a {{pokemonName}} del combate!",
"playerGo": "¡Adelante, {{pokemonName}}!",
"trainerGo": "¡{{trainerName}} saca a {{pokemonName}}!",
"switchQuestion": "¿Quieres cambiar a\n{{pokemonName}}?",
"trainerDefeated": "¡Has derrotado a\n{{trainerName}}!",
"pokemonCaught": "¡{{pokemonName}} atrapado!",
"pokemon": "Pokémon",
"sendOutPokemon": "¡Adelante, {{pokemonName}}!",
"hitResultCriticalHit": "A critical hit!",
"hitResultSuperEffective": "It's super effective!",
"hitResultNotVeryEffective": "It's not very effective…",
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "¡Pero ha fallado!",
"attackHitsCount": `N.º de golpes: {{count}}.`,
"expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.",
"levelUp": "¡{{pokemonName}} ha subido al \nNv. {{level}}!",
"learnMove": "¡{{pokemonName}} ha aprendido {{moveName}}!",
"learnMovePrompt": "{{pokemonName}} quiere aprender {{moveName}}.",
"learnMoveLimitReached": "Pero, {{pokemonName}} ya conoce\ncuatro movimientos.",
"learnMoveReplaceQuestion": "¿Quieres sustituir uno de sus movimientos por {{moveName}}?",
"learnMoveStopTeaching": "¿Prefieres que no aprenda\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} no ha aprendido {{moveName}}.",
"learnMoveForgetQuestion": "¿Qué movimiento quieres que olvide?",
"learnMoveForgetSuccess": "{{pokemonName}} ha olvidado cómo utilizar {{moveName}}.",
"levelCapUp": "¡Se ha incrementado el\nnivel máximo a {{levelCap}}!",
"moveNotImplemented": "{{moveName}} aún no está implementado y no se puede seleccionar.",
"moveDisabled": "!No puede usar {{moveName}} porque ha sido anulado!",
"noPokeballForce": "Una fuerza misteriosa\nte impide usar Poké Balls.",
"noPokeballTrainer": "¡No puedes atrapar a los\nPokémon de los demás!",
"noPokeballMulti": "¡No se pueden lanzar Poké Balls\ncuando hay más de un Pokémon!",
"noPokeballStrong": "¡Este Pokémon es demasiado fuerte para ser capturado!\nNecesitas bajarle los PS primero!",
"noEscapeForce": "Una fuerza misteriosa\nte impide huir.",
"noEscapeTrainer": "¡No puedes huir de los\ncombates contra Entrenadores!",
"noEscapePokemon": "¡El movimiento {{moveName}} de {{pokemonName}} impide la huida!",
"runAwaySuccess": "¡Escapas sin problemas!",
"runAwayCannotEscape": "¡No has podido escapar!",
"escapeVerbSwitch": "cambiar",
"escapeVerbFlee": "huir",
"notDisabled": "¡El movimiento {{moveName}}\nya no está anulado!",
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
"eggHatching": "¿Y esto?",
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?"
} as const;

View File

@ -0,0 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP",
"power": "POTENCIA",
} as const;

View File

@ -19,51 +19,8 @@ export const menu: SimpleTranslationEntries = {
"boyOrGirl": "¿Eres un chico o una chica?",
"boy": "Chico",
"girl": "Chica",
"bossAppeared": "¡{{bossName}} te corta el paso!",
"trainerAppeared": "¡{{trainerName}}\nte desafía!",
"singleWildAppeared": "¡Un {{pokemonName}} salvaje te corta el paso!",
"multiWildAppeared": "¡Un {{pokemonName1}} y un {{pokemonName2}} salvajes\nte cortan el paso!",
"playerComeBack": "¡{{pokemonName}}, ven aquí!",
"trainerComeBack": "¡{{trainerName}} retira a {{pokemonName}} del combate!",
"playerGo": "¡Adelante, {{pokemonName}}!",
"trainerGo": "¡{{trainerName}} saca a {{pokemonName}}!",
"switchQuestion": "¿Quieres cambiar a\n{{pokemonName}}?",
"trainerDefeated": "¡Has derrotado a\n{{trainerName}}!",
"pokemonCaught": "¡{{pokemonName}} atrapado!",
"pokemon": "Pokémon",
"sendOutPokemon": "¡Adelante, {{pokemonName}}!",
"attackFailed": "¡Pero ha fallado!",
"attackHitsCount": `N.º de golpes: {{count}}.`,
"expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.",
"levelUp": "¡{{pokemonName}} ha subido al \nNv. {{level}}!",
"learnMove": "¡{{pokemonName}} ha aprendido {{moveName}}!",
"learnMovePrompt": "{{pokemonName}} quiere aprender {{moveName}}.",
"learnMoveLimitReached": "Pero, {{pokemonName}} ya conoce\ncuatro movimientos.",
"learnMoveReplaceQuestion": "¿Quieres sustituir uno de sus movimientos por {{moveName}}?",
"learnMoveStopTeaching": "¿Prefieres que no aprenda\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} no ha aprendido {{moveName}}.",
"learnMoveForgetQuestion": "¿Qué movimiento quieres que olvide?",
"learnMoveForgetSuccess": "{{pokemonName}} ha olvidado cómo utilizar {{moveName}}.",
"levelCapUp": "¡Se ha incrementado el\nnivel máximo a {{levelCap}}!",
"moveNotImplemented": "{{moveName}} aún no está implementado y no se puede seleccionar.",
"moveDisabled": "!No puede usar {{moveName}} porque ha sido anulado!",
"noPokeballForce": "Una fuerza misteriosa\nte impide usar Poké Balls.",
"noPokeballTrainer": "¡No puedes atrapar a los\nPokémon de los demás!",
"noPokeballMulti": "¡No se pueden lanzar Poké Balls\ncuando hay más de un Pokémon!",
"noPokeballStrong": "¡Este Pokémon es demasiado fuerte para ser capturado!\nNecesitas bajarle los PS primero!",
"noEscapeForce": "Una fuerza misteriosa\nte impide huir.",
"noEscapeTrainer": "¡No puedes huir de los\ncombates contra Entrenadores!",
"noEscapePokemon": "¡El movimiento {{moveName}} de {{pokemonName}} impide la huida!",
"runAwaySuccess": "¡Escapas sin problemas!",
"runAwayCannotEscape": "¡No has podido escapar!",
"escapeVerbSwitch": "cambiar",
"escapeVerbFlee": "huir",
"notDisabled": "¡El movimiento {{moveName}}\nya no está anulado!",
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
"eggHatching": "¿Y esto?",
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?",
"rankings": "Rankings",
"dailyRankings": "Daily Rankings",
"weeklyRankings": "Weekly Rankings",
"noRankings": "No Rankings",
"loading": "Loading…",
"playersOnline": "Players Online"

View File

@ -20,6 +20,10 @@ export const tutorial: SimpleTranslationEntries = {
"pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled.
$Your Pokémon are recalled before a trainer battle and before entering a new biome.
$You can also view the stat changes for the Pokémon on the field by holding C or Shift.`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways.

52
src/locales/fr/battle.ts Normal file
View File

@ -0,0 +1,52 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "Un {{bossName}} apparaît.",
"trainerAppeared": "Un combat est lancé\npar {{trainerName}} !",
"singleWildAppeared": "Un {{pokemonName}} sauvage apparaît !",
"multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !",
"playerComeBack": "{{pokemonName}}, on change !\nReviens !",
"trainerComeBack": "{{trainerName}} retire {{pokemonName}} !",
"playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?",
"trainerDefeated": `Vous avez battu\n{{trainerName}} !`,
"pokemonCaught": "Vous avez attrapé {{pokemonName}} !",
"pokemon": "Pokémon",
"sendOutPokemon": "{{pokemonName}} ! Go !",
"hitResultCriticalHit": "Coup critique!",
"hitResultSuperEffective": "Cest super efficace!",
"hitResultNotVeryEffective": "Ce nest pas très efficace…",
"hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…",
"hitResultOneHitKO": "K.O. en un coup!",
"attackFailed": "Mais cela échoue !",
"attackHitsCount": `Touché {{count}} fois !`,
"expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !",
"levelUp": "{{pokemonName}} monte au\nN. {{level}} !",
"learnMove": "{{pokemonName}} apprend \n{{moveName}} !",
"learnMovePrompt": "{{pokemonName}} veut apprendre\n{{moveName}}.",
"learnMoveLimitReached": "Cependant, {{pokemonName}} connait\ndéjà quatre capacités.",
"learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?",
"learnMoveStopTeaching": "Arrêter dapprendre\n{{moveName}} ?",
"learnMoveNotLearned": "{{pokemonName}} na pas appris\n{{moveName}}.",
"learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?",
"learnMoveForgetSuccess": "{{pokemonName}} oublie comment\nutiliser {{moveName}}.",
"levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !",
"moveNotImplemented": "{{moveName}} nest pas encore implémenté et ne peut pas être sélectionné.",
"moveDisabled": "{{moveName}} est sous entrave !",
"noPokeballForce": "Une force mystérieuse\nempêche lutilisation des Poké Balls.",
"noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, cest mal !",
"noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon!",
"noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez dabord laffaiblir !",
"noEscapeForce": "Une force mystérieuse\nempêche la fuite.",
"noEscapeTrainer": "On ne senfuit pas dun\ncombat de Dresseurs !",
"noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !",
"runAwaySuccess": "Vous prenez la fuite !",
"runAwayCannotEscape": "Fuite impossible !",
"escapeVerbSwitch": "le changement",
"escapeVerbFlee": "la fuite",
"notDisabled": "{{moveName}} nest plus sous entrave !",
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"eggHatching": "Oh ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV sur {{pokemonName}} ?"
} as const;

View File

@ -30,51 +30,8 @@ export const menu: SimpleTranslationEntries = {
"boyOrGirl": "Es-tu un garçon ou une fille ?",
"boy": "Garçon",
"girl": "Fille",
"bossAppeared": "Un {{bossName}} apparaît.",
"trainerAppeared": "Un combat est lancé\npar {{trainerName}} !",
"singleWildAppeared": "Un {{pokemonName}} sauvage apparaît !",
"multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !",
"playerComeBack": "{{pokemonName}}, on change !\nReviens !",
"trainerComeBack": "{{trainerName}} retire {{pokemonName}} !",
"playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?",
"trainerDefeated": `Vous avez battu\n{{trainerName}} !`,
"pokemonCaught": "Vous avez attrapé {{pokemonName}} !",
"pokemon": "Pokémon",
"sendOutPokemon": "{{pokemonName}} ! Go !",
"attackFailed": "Mais cela échoue !",
"attackHitsCount": `Touché {{count}} fois !`,
"expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !",
"levelUp": "{{pokemonName}} monte au\nN. {{level}} !",
"learnMove": "{{pokemonName}} apprend \n{{moveName}} !",
"learnMovePrompt": "{{pokemonName}} veut apprendre\n{{moveName}}.",
"learnMoveLimitReached": "Cependant, {{pokemonName}} connait\ndéjà quatre capacités.",
"learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?",
"learnMoveStopTeaching": "Arrêter dapprendre\n{{moveName}} ?",
"learnMoveNotLearned": "{{pokemonName}} na pas appris\n{{moveName}}.",
"learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?",
"learnMoveForgetSuccess": "{{pokemonName}} oublie comment\nutiliser {{moveName}}.",
"levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !",
"moveNotImplemented": "{{moveName}} nest pas encore implémenté et ne peut pas être sélectionné.",
"moveDisabled": "{{moveName}} est sous entrave !",
"noPokeballForce": "Une force mystérieuse\nempêche lutilisation des Poké Balls.",
"noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, cest mal !",
"noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon!",
"noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez dabord laffaiblir !",
"noEscapeForce": "Une force mystérieuse\nempêche la fuite.",
"noEscapeTrainer": "On ne senfuit pas dun\ncombat de Dresseurs !",
"noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !",
"runAwaySuccess": "Vous prenez la fuite !",
"runAwayCannotEscape": "Fuite impossible !",
"escapeVerbSwitch": "le changement",
"escapeVerbFlee": "la fuite",
"notDisabled": "{{moveName}} nest plus sous entrave !",
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"eggHatching": "Oh ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV sur {{pokemonName}} ?",
"rankings": "Classement",
"dailyRankings": "Classement du Jour",
"weeklyRankings": "Classement de la Semaine",
"noRankings": "Pas de Classement",
"loading": "Chargement…",
"playersOnline": "Joueurs Connectés"

View File

@ -8,7 +8,7 @@ export const tutorial: SimpleTranslationEntries = {
$Tout signalement de bugs passe par le serveur Discord.
$Si le jeu est lent, vérifiez que lAccélération Matérielle est activée dans les paramètres du navigateur.`,
"accessMenu": `Accédez au menu avec M ou Échap lors de l'attente dune\naction.
"accessMenu": `Accédez au menu avec M ou Échap lors de lattente dune\naction.
$Il contient les paramètres et diverses fonctionnalités`,
"menu": `Vous pouvez accéder aux paramètres depuis ce menu.
@ -17,13 +17,20 @@ export const tutorial: SimpleTranslationEntries = {
$jetez-y un œil !`,
"starterSelect": `Choisissez vos starters depuis cet écran.\nIls formeront votre équipe de départ.
$Chacun possède une valeur. Votre équipe peut avoir jusquà\n6 membres, tant que vous ne dépassez pas un coût de 10.
$Chacun possède une valeur. Votre équipe peut avoir jusquà\n6 membres, tant que vous ne dépassez pas un cout de 10.
$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.
$Les IVs dun starter sont les meilleurs de tous ceux de son\nespèce déjà obtenus. Essayez donc den obtenir plusieurs !`,
"pokerus": `Chaque jour, 3 starters tirés aléatoirement ont un contour
$violet. Si un starter que vous possédez la, essayez de
$ lajouter à votre équipe. Vérifiez bien son résumé !`,
$lajouter à votre équipe. Vérifiez bien son résumé !`,
"statChange": `Les changements de stats restent à travers les combats tant que le Pokémon
$nest pas rappelé.
$Vos Pokémon sont rappelés avant un combat de Dresseur et avant dentrer
$dans un nouveau biome.
$Vous pouvez également voir en combat les changements de stats dun Pokémon
$en maintenant C ou Maj.`,
"selectItem": `Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre quun.
$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.
@ -40,4 +47,4 @@ export const tutorial: SimpleTranslationEntries = {
$Les Pokémon issus dŒufs ont généralement de\nmeilleurs IVs que les Pokémon sauvages.
$Certains Pokémon ne peuvent être obtenus\nque dans des Œufs.
$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !`,
} as const;
} as const;

52
src/locales/it/battle.ts Normal file
View File

@ -0,0 +1,52 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "{{bossName}} appeared.",
"trainerAppeared": "{{trainerName}}\nwould like to battle!",
"singleWildAppeared": "A wild {{pokemonName}} appeared!",
"multiWildAppeared": "A wild {{pokemonName1}}\nand {{pokemonName2}} appeared!",
"playerComeBack": "Come back, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} withdrew {{pokemonName}}!",
"playerGo": "Go! {{pokemonName}}!",
"trainerGo": "{{trainerName}} sent out {{pokemonName}}!",
"switchQuestion": "Will you switch\n{{pokemonName}}?",
"trainerDefeated": `You defeated\n{{trainerName}}!`,
"pokemonCaught": "{{pokemonName}} was caught!",
"pokemon": "Pokémon",
"sendOutPokemon": "Go! {{pokemonName}}!",
"hitResultCriticalHit": "A critical hit!",
"hitResultSuperEffective": "It's super effective!",
"hitResultNotVeryEffective": "It's not very effective…",
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "But it failed!",
"attackHitsCount": `Hit {{count}} time(s)!`,
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",
"levelUp": "{{pokemonName}} grew to\nLv. {{level}}!",
"learnMove": "{{pokemonName}} learned\n{{moveName}}!",
"learnMovePrompt": "{{pokemonName}} wants to learn the\nmove {{moveName}}.",
"learnMoveLimitReached": "However, {{pokemonName}} already\nknows four moves.",
"learnMoveReplaceQuestion": "Should a move be forgotten and\nreplaced with {{moveName}}?",
"learnMoveStopTeaching": "Stop trying to teach\n{{moveName}}?",
"learnMoveNotLearned": "{{pokemonName}} did not learn the\nmove {{moveName}}.",
"learnMoveForgetQuestion": "Which move should be forgotten?",
"learnMoveForgetSuccess": "{{pokemonName}} forgot how to\nuse {{moveName}}.",
"levelCapUp": "The level cap\nhas increased to {{levelCap}}!",
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
"moveDisabled": "{{moveName}} is disabled!",
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
"noPokeballStrong": "The target Pokémon is too strong to be caught!\nYou need to weaken it first!",
"noEscapeForce": "An unseen force\nprevents escape.",
"noEscapeTrainer": "You can't run\nfrom a trainer battle!",
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nprevents {{escapeVerb}}!",
"runAwaySuccess": "You got away safely!",
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "switching",
"escapeVerbFlee": "fleeing",
"notDisabled": "{{moveName}} is disabled\nno more!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
} as const;

View File

@ -0,0 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP",
"power": "POWER",
} as const;

View File

@ -1,5 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
/**
* The menu namespace holds most miscellaneous text that isn't directly part of the game's
* contents or directly related to Pokemon data. This includes menu navigation, settings,
* account interactions, descriptive text, etc.
*/
export const menu: SimpleTranslationEntries = {
"cancel": "Annulla",
"continue": "Continua",
@ -7,8 +12,31 @@ export const menu: SimpleTranslationEntries = {
"loadGame": "Carica Partita",
"dailyRun": "Corsa Giornaliera (Beta)",
"selectGameMode": "Seleziona una modalità di gioco.",
"rankings": "Rankings",
"logInOrCreateAccount": "Log in or create an account to start. No email required!",
"username": "Username",
"password": "Password",
"login": "Login",
"register": "Register",
"emptyUsername": "Username must not be empty",
"invalidLoginUsername": "The provided username is invalid",
"invalidRegisterUsername": "Username must only contain letters, numbers, or underscores",
"invalidLoginPassword": "The provided password is invalid",
"invalidRegisterPassword": "Password must be 6 characters or longer",
"usernameAlreadyUsed": "The provided username is already in use",
"accountNonExistent": "The provided user does not exist",
"unmatchingPassword": "The provided password does not match",
"passwordNotMatchingConfirmPassword": "Password must match confirm password",
"confirmPassword": "Confirm Password",
"registrationAgeWarning": "By registering, you confirm you are of 13 years of age or older.",
"backToLogin": "Back to Login",
"failedToLoadSaveData": "Failed to load save data. Please reload the page.\nIf this continues, please contact the administrator.",
"sessionSuccess": "Session loaded successfully.",
"failedToLoadSession": "Your session data could not be loaded.\nIt may be corrupted.",
"boyOrGirl": "Are you a boy or a girl?",
"boy": "Boy",
"girl": "Girl",
"dailyRankings": "Daily Rankings",
"weeklyRankings": "Weekly Rankings",
"noRankings": "No Rankings",
"loading": "Loading…",
"playersOnline": "Players Online"

View File

@ -1,16 +1,16 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const pokemonStat: SimpleTranslationEntries = {
"HP": "Max. HP",
"HPshortened": "MaxHP",
"ATK": "Attack",
"ATKshortened": "Atk",
"DEF": "Defense",
"DEFshortened": "Def",
"SPATK": "Sp. Atk",
"SPATKshortened": "SpAtk",
"SPDEF": "Sp. Def",
"SPDEFshortened": "SpDef",
"SPD": "Speed",
"SPDshortened": "Spd"
} as const;
"HP": "PS Max",
"HPshortened": "PS",
"ATK": "Attacco",
"ATKshortened": "Att",
"DEF": "Difesa",
"DEFshortened": "Dif",
"SPATK": "Att. Sp.",
"SPATKshortened": "AttSp",
"SPDEF": "Dif. Sp.",
"SPDEFshortened": "DifSp",
"SPD": "Velocità",
"SPDshortened": "Vel"
} as const;

View File

@ -1,38 +1,42 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = {
"intro": `Welcome to PokéRogue! This is a battle-focused Pokémon fangame with roguelite elements.
$This game is not monetized and we claim no ownership of Pokémon nor of the copyrighted assets used.
$The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community.
$If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`,
"intro": `Benvenuto in PokéRogue! Questo gioco si concentra sulle battaglie, con elementi roguelite.
$Questo gioco non è monetizzato e non siamo proprietari di Pokemon e Assets presenti nel gioco.
$Il gioco è work-in-progress ma giocabile al 100%.\nPer reportare eventuali bugs è possibile discuterne sul nostro Discord.
$Se il game risulta 'lento', assicurati di aver abilitato l'Accelerazione Hardware nelle impostazioni del tuo Browser`,
"accessMenu": `To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.`,
"accessMenu": `Per accedere al menù, press M o Esc.\nDal menù puoi cambiare impostazioni, controllare la wiki e accedere a varie features.`,
"menu": `From this menu you can access the settings.
$From the settings you can change game speed, window style, and other options.
$There are also various other features here, so be sure to check them all!`,
"menu": `Da questo menù puoi accedere alle impostazioni.
$Dalle impostazioni puoi cambiare velocità di gioco, stile di finestra e altre opzioni.
$Ci sono varie funzionalità, controlla bene e non perderti nulla!`,
"starterSelect": `From this screen, you can select your starters.\nThese are your initial party members.
$Each starter has a value. Your party can have up to\n6 members as long as the total does not exceed 10.
$You can also select gender, ability, and form depending on\nthe variants you've caught or hatched.
$The IVs for a species are also the best of every one you've\ncaught or hatched, so try to get lots of the same species!`,
"starterSelect": `Da questa schermata puoi selezionare il tuo starter.\nQuesti sono i membri iniziali del tuo parti.
$Ogni starter ha un valore. Puoi avere fino a \n6 Pokèmon, avendo a disposizione un massimo di 10 punti.
$Puoi anche selezionare Sesso, Abilità, e Forma a seconda delle\nvarianti che hai catturato o schiuso.
$Le IVs di una specie sono le migliori rispetto a tutte quelle che hai\ncatturato o schiuso, quindi prova a catturarne il piu possibile!`,
"pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"pokerus": `Giornalmente 3 Starter casuali disponibili avranno il bordo viola.
$Se possiedi uno di questi starter,\nprova ad aggiungerlo al party. Ricorda di controllare le info!`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways.
$Some items will only show up if they can be used, such as evolution items.
$You can also transfer held items between Pokémon using the transfer option.
$The transfer option will appear in the bottom right once you have obtained a held item.
$You may purchase consumable items with money, and a larger variety will be available the further you get.
$Be sure to buy these before you pick your random item, as it will progress to the next battle once you do.`,
"statChange": `I cambiamenti alle statistiche persistono fintanto che i tuoi pokèmon resteranno in campo.
$I tuoi pokemon verranno richiamati quando incontrerai un allenatore o al cambiamento di bioma.
$Puoi anche vedere i cambiamenti alle statistiche in corso tenendo premuto C o Shift`,
"eggGacha": `From this screen, you can redeem your vouchers for\nPokémon eggs.
$Eggs have to be hatched and get closer to hatching after\nevery battle. Rarer eggs take longer to hatch.
$Hatched Pokémon also won't be added to your party, they will\nbe added to your starters.
$Pokémon hatched from eggs generally have better IVs than\nwild Pokémon.
$Some Pokémon can only even be obtained from eggs.
$There are 3 different machines to pull from with different\nbonuses, so pick the one that suits you best!`,
"selectItem": `Dopo ogni battaglia avrai disponibili tre item.\nPotrai prenderne solo uno.
$Questi spaziano tra consumabili, item tenuti da Pokèmon o con un effetto passivo permanente.
$La maggior parte degli Item non Consumabili possono stackare in diversi modi.
$Alcuni Item risulteranno disponibili solo se possono essere usati, come Item Evolutivi.
$Puoi anche passare un Item tenuto da un Pokèmon ad un altro attraverso l'opzione 'trasferisci strumento'.
$L'opzione 'trasferisci strumento' sarà disponibile solo dopo aver assegnato uno strumento ad un Pokèmon.
$Puoi acquistare consumabili con le monete, progredendo saranno poi disponibili ulteriori oggetti.
$Assicurati di fare un acquisto prima di selezionare un item casuale, poichè passerai subito alla lotta successiva.`,
"eggGacha": `Da questa schermata, puoi riscattare i tuoi vouchers in cambio di\nuova Pokèmon.
$Le uova vanno schiuse e saranno sempre più vicine alla schiusura dopo\nogni battaglia. Le uova più rare impiegheranno più battaglie per la schiusura.
$I Pokémon schiusi non verranno aggiunti alla tua squadra, saranno\naggiunti ai tuoi starters.
$I Pokémon schiusi generalmente hanno IVs migliori rispetto ai\n Pokémon selvatici.
$Alcuni Pokémon possono essere ottenuti solo tramite uova.
$Ci sono 3 diversi macchinari con differenti\nbonus, scegli quello che preferisci!`,
} as const;

View File

@ -9,6 +9,23 @@ import BBCodeText from 'phaser3-rex-plugins/plugins/bbcodetext';
import TransitionImagePackPlugin from 'phaser3-rex-plugins/templates/transitionimagepack/transitionimagepack-plugin.js';
import { LoadingScene } from './loading-scene';
// Catch global errors and display them in an alert so users can report the issue.
window.onerror = function (message, source, lineno, colno, error) {
console.error(error);
let errorString = `Received unhandled error. Open browser console and click OK to see details.\nError: ${message}\nSource: ${source}\nLine: ${lineno}\nColumn: ${colno}\nStack: ${error.stack}`;
//alert(errorString);
// Avoids logging the error a second time.
return true;
};
// Catch global promise rejections and display them in an alert so users can report the issue.
window.addEventListener('unhandledrejection', (event) => {
let errorString = `Received unhandled promise rejection. Open browser console and click OK to see details.\nReason: ${event.reason}`;
console.error(event.reason);
//alert(errorString);
});
const config: Phaser.Types.Core.GameConfig = {
type: Phaser.WEBGL,
parent: 'app',

View File

@ -1058,7 +1058,6 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.TM_ULTRA, 8),
new WeightedModifierType(modifierTypes.RARER_CANDY, 4),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party.find(p => (pokemonEvolutions.hasOwnProperty(p.species.speciesId) && pokemonEvolutions[p.species.speciesId].find(e => e.condition && e.condition instanceof SpeciesFriendshipEvolutionCondition)) || p.moveset.find(m => m.moveId === Moves.RETURN)) ? 16 : 0, 16),
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, 2),
new WeightedModifierType(modifierTypes.IV_SCANNER, 4),
new WeightedModifierType(modifierTypes.EXP_CHARM, 8),
@ -1078,6 +1077,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BATON, 2),
new WeightedModifierType(modifierTypes.SOUL_DEW, 8),
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4),
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 6),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),

View File

@ -1111,9 +1111,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
pokemon.levelExp = 0;
}
const friendshipIncrease = new Utils.IntegerHolder(5);
pokemon.scene.applyModifier(PokemonFriendshipBoosterModifier, true, pokemon, friendshipIncrease);
pokemon.friendship = Math.min(pokemon.friendship + friendshipIncrease.value, 255);
pokemon.addFriendship(5);
pokemon.scene.unshiftPhase(new LevelUpPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.level - levelCount.value, pokemon.level));
@ -1392,13 +1390,14 @@ export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier {
}
apply(args: any[]): boolean {
(args[1] as Utils.IntegerHolder).value *= 1 + 0.5 * this.getStackCount();
const friendship = args[1] as Utils.IntegerHolder;
friendship.value = Math.floor(friendship.value * (1 + 0.5 * this.getStackCount()));
return true;
}
getMaxHeldItemCount(pokemon: Pokemon): integer {
return 5;
return 3;
}
}

View File

@ -6,7 +6,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, PokemonFriendshipBoosterModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier } from "./modifier/modifier";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier } from "./modifier/modifier";
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
@ -19,7 +19,7 @@ import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } fr
import { biomeLinks, getBiomeName } from "./data/biomes";
import { Biome } from "./data/enums/biome";
import { ModifierTier } from "./modifier/modifier-tier";
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags";
import { BattlerTagType } from "./data/enums/battler-tag-type";
@ -331,6 +331,8 @@ export class TitlePhase extends Phase {
this.scene.sessionPlayTime = 0;
this.end();
});
}).catch(err => {
console.error("Failed to load daily run:\n", err);
});
});
}
@ -815,14 +817,14 @@ export class EncounterPhase extends BattlePhase {
const enemyField = this.scene.getEnemyField();
if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS)
return i18next.t('menu:bossAppeared', {bossName: enemyField[0].name});
return i18next.t('battle:bossAppeared', {bossName: enemyField[0].name});
if (this.scene.currentBattle.battleType === BattleType.TRAINER)
return i18next.t('menu:trainerAppeared', {trainerName: this.scene.currentBattle.trainer.getName(TrainerSlot.NONE, true)});
return i18next.t('battle:trainerAppeared', {trainerName: this.scene.currentBattle.trainer.getName(TrainerSlot.NONE, true)});
return enemyField.length === 1
? i18next.t('menu:singleWildAppeared', {pokemonName: enemyField[0].name})
: i18next.t('menu:multiWildAppeared', {pokemonName1: enemyField[0].name, pokemonName2: enemyField[1].name})
? i18next.t('battle:singleWildAppeared', {pokemonName: enemyField[0].name})
: i18next.t('battle:multiWildAppeared', {pokemonName1: enemyField[0].name, pokemonName2: enemyField[1].name})
}
doEncounterCommon(showEncounterMessage: boolean = true) {
@ -1187,7 +1189,7 @@ export class SummonPhase extends PartyMemberPokemonPhase {
}
if (this.player) {
this.scene.ui.showText(i18next.t('menu:playerGo', { pokemonName: this.getPokemon().name }));
this.scene.ui.showText(i18next.t('battle:playerGo', { pokemonName: this.getPokemon().name }));
if (this.player)
this.scene.pbTray.hide();
this.scene.trainer.setTexture(`trainer_${this.scene.gameData.gender === PlayerGender.FEMALE ? 'f' : 'm'}_back_pb`);
@ -1355,8 +1357,8 @@ export class SwitchSummonPhase extends SummonPhase {
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, pokemon);
this.scene.ui.showText(this.player ?
i18next.t('menu:playerComeBack', { pokemonName: pokemon.name }) :
i18next.t('menu:trainerComeBack', {
i18next.t('battle:playerComeBack', { pokemonName: pokemon.name }) :
i18next.t('battle:trainerComeBack', {
trainerName: this.scene.currentBattle.trainer.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER),
pokemonName: pokemon.name
})
@ -1396,8 +1398,8 @@ export class SwitchSummonPhase extends SummonPhase {
party[this.fieldIndex] = switchedPokemon;
const showTextAndSummon = () => {
this.scene.ui.showText(this.player ?
i18next.t('menu:playerGo', { pokemonName: switchedPokemon.name }) :
i18next.t('menu:trainerGo', {
i18next.t('battle:playerGo', { pokemonName: switchedPokemon.name }) :
i18next.t('battle:trainerGo', {
trainerName: this.scene.currentBattle.trainer.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER),
pokemonName: this.getPokemon().name
})
@ -1544,7 +1546,7 @@ export class CheckSwitchPhase extends BattlePhase {
return;
}
this.scene.ui.showText(i18next.t('menu:switchQuestion', { pokemonName: this.useName ? pokemon.name : i18next.t('menu:pokemon') }), null, () => {
this.scene.ui.showText(i18next.t('battle:switchQuestion', { pokemonName: this.useName ? pokemon.name : i18next.t('battle:pokemon') }), null, () => {
this.scene.ui.setMode(Mode.CONFIRM, () => {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex);
@ -1564,7 +1566,7 @@ export class SummonMissingPhase extends SummonPhase {
}
preSummon(): void {
this.scene.ui.showText(i18next.t('menu:sendOutPokemon', { pokemonName: this.getPokemon().name}));
this.scene.ui.showText(i18next.t('battle:sendOutPokemon', { pokemonName: this.getPokemon().name}));
this.scene.time.delayedCall(250, () => this.summon());
}
}
@ -1579,7 +1581,7 @@ export class LevelCapPhase extends FieldPhase {
this.scene.ui.setMode(Mode.MESSAGE).then(() => {
this.scene.playSound('level_up_fanfare');
this.scene.ui.showText(i18next.t('menu:levelCapUp', { levelCap: this.scene.getMaxExpLevel() }), null, () => this.end(), null, true);
this.scene.ui.showText(i18next.t('battle:levelCapUp', { levelCap: this.scene.getMaxExpLevel() }), null, () => this.end(), null, true);
this.executeForAll(pokemon => pokemon.updateInfo(true));
});
}
@ -1673,7 +1675,7 @@ export class CommandPhase extends FieldPhase {
const move = playerPokemon.getMoveset()[cursor];
if (move.getName().endsWith(' (N)')) {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:moveNotImplemented', { moveName: move.getName().slice(0, -4) }), null, () => {
this.scene.ui.showText(i18next.t('battle:moveNotImplemented', { moveName: move.getName().slice(0, -4) }), null, () => {
this.scene.ui.clearText();
this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex);
}, null, true);
@ -1692,7 +1694,7 @@ export class CommandPhase extends FieldPhase {
const move = playerPokemon.getMoveset()[cursor];
if (playerPokemon.summonData.disabledMove === move.moveId) {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:moveDisabled', { moveName: move.getName() }), null, () => {
this.scene.ui.showText(i18next.t('battle:moveDisabled', { moveName: move.getName() }), null, () => {
this.scene.ui.clearText();
this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex);
}, null, true);
@ -1703,14 +1705,14 @@ export class CommandPhase extends FieldPhase {
if (this.scene.arena.biomeType === Biome.END && (!this.scene.gameMode.isClassic || (this.scene.getEnemyField().filter(p => p.isActive(true)).some(p => !p.scene.gameData.dexData[p.species.speciesId].caughtAttr) && this.scene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarters).length - 1))) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noPokeballForce'), null, () => {
this.scene.ui.showText(i18next.t('battle:noPokeballForce'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noPokeballTrainer'), null, () => {
this.scene.ui.showText(i18next.t('battle:noPokeballTrainer'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
@ -1719,7 +1721,7 @@ export class CommandPhase extends FieldPhase {
if (targets.length > 1) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noPokeballMulti'), null, () => {
this.scene.ui.showText(i18next.t('battle:noPokeballMulti'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
@ -1728,7 +1730,7 @@ export class CommandPhase extends FieldPhase {
if (targetPokemon.isBoss() && targetPokemon.bossSegmentIndex >= 1 && cursor < PokeballType.MASTER_BALL) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noPokeballStrong'), null, () => {
this.scene.ui.showText(i18next.t('battle:noPokeballStrong'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
@ -1748,14 +1750,14 @@ export class CommandPhase extends FieldPhase {
if (!isSwitch && this.scene.arena.biomeType === Biome.END) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noEscapeForce'), null, () => {
this.scene.ui.showText(i18next.t('battle:noEscapeForce'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (!isSwitch && this.scene.currentBattle.battleType === BattleType.TRAINER) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.showText(i18next.t('menu:noEscapeTrainer'), null, () => {
this.scene.ui.showText(i18next.t('battle:noEscapeTrainer'), null, () => {
this.scene.ui.showText(null, 0);
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
@ -1778,10 +1780,10 @@ export class CommandPhase extends FieldPhase {
this.scene.ui.setMode(Mode.MESSAGE);
}
this.scene.ui.showText(
i18next.t('menu:noEscapePokemon', {
i18next.t('battle:noEscapePokemon', {
pokemonName: this.scene.getPokemonById(trapTag.sourceId).name,
moveName: trapTag.getMoveName(),
escapeVerb: isSwitch ? i18next.t('menu:escapeVerbSwitch') : i18next.t('menu:escapeVerbFlee')
escapeVerb: isSwitch ? i18next.t('battle:escapeVerbSwitch') : i18next.t('battle:escapeVerbFlee')
}),
null,
() => {
@ -2031,7 +2033,7 @@ export class TurnEndPhase extends FieldPhase {
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('menu:notDisabled', { moveName: allMoves[pokemon.summonData.disabledMove].name })));
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { moveName: allMoves[pokemon.summonData.disabledMove].name })));
pokemon.summonData.disabledMove = Moves.NONE;
}
@ -2331,7 +2333,7 @@ export class MovePhase extends BattlePhase {
return;
}
if (this.pokemon.getTag(BattlerTagType.RECHARGING))
if (this.pokemon.getTag(BattlerTagType.RECHARGING|| BattlerTagType.INTERRUPTED))
return;
this.scene.queueMessage(getPokemonMessage(this.pokemon, ` used\n${this.move.getName()}!`), 500);
@ -2339,7 +2341,7 @@ export class MovePhase extends BattlePhase {
}
showFailedText(failedText: string = null): void {
this.scene.queueMessage(failedText || i18next.t('menu:attackFailed'));
this.scene.queueMessage(failedText || i18next.t('battle:attackFailed'));
}
end() {
@ -2402,7 +2404,7 @@ export class MoveEffectPhase extends PokemonPhase {
moveHistoryEntry.result = MoveResult.MISS;
applyMoveAttrs(MissEffectAttr, user, null, this.move.getMove());
} else {
this.scene.queueMessage(i18next.t('menu:attackFailed'));
this.scene.queueMessage(i18next.t('battle:attackFailed'));
moveHistoryEntry.result = MoveResult.FAIL;
}
return this.end();
@ -2486,7 +2488,7 @@ export class MoveEffectPhase extends PokemonPhase {
else {
const hitsTotal = user.turnData.hitCount - Math.max(user.turnData.hitsLeft, 0);
if (hitsTotal > 1)
this.scene.queueMessage(i18next.t('menu:attackHitsCount', { count: hitsTotal }));
this.scene.queueMessage(i18next.t('battle:attackHitsCount', { count: hitsTotal }));
this.scene.applyModifiers(HitHealModifier, this.player, user);
}
}
@ -2671,7 +2673,6 @@ export class StatChangePhase extends PokemonPhase {
let random = false;
const allStats = Utils.getEnumValues(BattleStat);
if (this.stats.length === 1 && this.stats[0] === BattleStat.RAND) {
this.stats[0] = this.getRandomStat();
random = true;
@ -2712,8 +2713,11 @@ export class StatChangePhase extends PokemonPhase {
for (let stat of filteredStats)
pokemon.summonData.battleStats[stat] = Math.max(Math.min(pokemon.summonData.battleStats[stat] + levels.value, 6), -6);
applyPostStatChangeAbAttrs(PostStatChangeAbAttr, pokemon, filteredStats, this.levels, this.selfTarget)
this.end();
applyPostStatChangeAbAttrs(PostStatChangeAbAttr, pokemon, filteredStats, this.levels, this.selfTarget);
pokemon.updateInfo();
handleTutorial(this.scene, Tutorial.Stat_Change).then(() => super.end());
};
if (relLevels.filter(l => l).length && this.scene.moveAnimations) {
@ -3150,8 +3154,8 @@ export class FaintPhase extends PokemonPhase {
this.scene.getField(true).filter(p => p !== pokemon).forEach(p => p.removeTagsBySourceId(pokemon.id));
pokemon.faintCry(() => {
const friendshipDecrease = new Utils.IntegerHolder(10);
pokemon.friendship = Math.max(pokemon.friendship - friendshipDecrease.value, 0);
if (pokemon instanceof PlayerPokemon)
pokemon.addFriendship(-10);
pokemon.hideInfo();
this.scene.playSound('faint');
this.scene.tweens.add({
@ -3222,13 +3226,8 @@ export class VictoryPhase extends PokemonPhase {
for (let partyMember of expPartyMembers) {
const pId = partyMember.id;
const participated = participantIds.has(pId);
if (participated) {
const friendshipIncrease = new Utils.IntegerHolder(2);
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, partyMember, friendshipIncrease);
partyMember.friendship = Math.min(partyMember.friendship + friendshipIncrease.value, 255);
if (partyMember.friendship === 255)
this.scene.validateAchv(achvs.MAX_FRIENDSHIP);
}
if (participated)
partyMember.addFriendship(2);
else if (!expShareModifier) {
partyMemberExp.push(0);
continue;
@ -3337,10 +3336,10 @@ export class TrainerVictoryPhase extends BattlePhase {
const trainerType = this.scene.currentBattle.trainer.config.trainerType;
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
if (!this.scene.validateVoucher(vouchers[TrainerType[trainerType]]) && this.scene.currentBattle.trainer.config.isBoss)
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.VOUCHER));
this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, [ modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType]));
}
this.scene.ui.showText(i18next.t('menu:trainerDefeated', { trainerName: this.scene.currentBattle.trainer.getName(TrainerSlot.NONE, true) }), null, () => {
this.scene.ui.showText(i18next.t('battle:trainerDefeated', { trainerName: this.scene.currentBattle.trainer.getName(TrainerSlot.NONE, true) }), null, () => {
const victoryMessages = this.scene.currentBattle.trainer.getVictoryMessages();
const showMessage = () => {
let message: string;
@ -3607,7 +3606,7 @@ export class ExpPhase extends PlayerPartyMemberPokemonPhase {
let exp = new Utils.NumberHolder(this.expValue);
this.scene.applyModifiers(ExpBoosterModifier, true, exp);
exp.value = Math.floor(exp.value);
this.scene.ui.showText(i18next.t('menu:expGain', { pokemonName: pokemon.name, exp: exp.value }), null, () => {
this.scene.ui.showText(i18next.t('battle:expGain', { pokemonName: pokemon.name, exp: exp.value }), null, () => {
const lastLevel = pokemon.level;
let newLevel: integer;
pokemon.addExp(exp.value);
@ -3695,7 +3694,7 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
pokemon.calculateStats();
pokemon.updateInfo();
this.scene.playSound('level_up_fanfare');
this.scene.ui.showText(i18next.t('menu:levelUp', { pokemonName: this.getPokemon().name, level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
this.scene.ui.showText(i18next.t('battle:levelUp', { pokemonName: this.getPokemon().name, level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
if (this.level <= 100) {
const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1);
for (let lm of levelMoves)
@ -3744,7 +3743,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
.then(() => {
this.scene.ui.setMode(messageMode).then(() => {
this.scene.playSound('level_up_fanfare');
this.scene.ui.showText(i18next.t('menu:learnMove', { pokemonName: pokemon.name, moveName: move.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMove', { pokemonName: pokemon.name, moveName: move.name }), null, () => {
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
this.end();
}, messageMode === Mode.EVOLUTION_SCENE ? 1000 : null, true);
@ -3753,15 +3752,15 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
});
} else {
this.scene.ui.setMode(messageMode).then(() => {
this.scene.ui.showText(i18next.t('menu:learnMovePrompt', { pokemonName: pokemon.name, moveName: move.name }), null, () => {
this.scene.ui.showText(i18next.t('menu:learnMoveLimitReached', { pokemonName: pokemon.name }), null, () => {
this.scene.ui.showText(i18next.t('menu:learnMoveReplaceQuestion', { moveName: move.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMovePrompt', { pokemonName: pokemon.name, moveName: move.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMoveLimitReached', { pokemonName: pokemon.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMoveReplaceQuestion', { moveName: move.name }), null, () => {
const noHandler = () => {
this.scene.ui.setMode(messageMode).then(() => {
this.scene.ui.showText(i18next.t('menu:learnMoveStopTeaching', { moveName: move.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMoveStopTeaching', { moveName: move.name }), null, () => {
this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
this.scene.ui.setMode(messageMode);
this.scene.ui.showText(i18next.t('menu:learnMoveNotLearned', { pokemonName: pokemon.name, moveName: move.name }), null, () => this.end(), null, true);
this.scene.ui.showText(i18next.t('battle:learnMoveNotLearned', { pokemonName: pokemon.name, moveName: move.name }), null, () => this.end(), null, true);
}, () => {
this.scene.ui.setMode(messageMode);
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId));
@ -3772,7 +3771,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
};
this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
this.scene.ui.setMode(messageMode);
this.scene.ui.showText(i18next.t('menu:learnMoveForgetQuestion'), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMoveForgetQuestion'), null, () => {
this.scene.ui.setModeWithoutClear(Mode.SUMMARY, this.getPokemon(), SummaryUiMode.LEARN_MOVE, move, (moveIndex: integer) => {
if (moveIndex === 4) {
noHandler();
@ -3780,7 +3779,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
}
this.scene.ui.setMode(messageMode).then(() => {
this.scene.ui.showText('@d{32}1, @d{15}2, and@d{15}… @d{15}… @d{15}… @d{15}@s{pb_bounce_1}Poof!', null, () => {
this.scene.ui.showText(i18next.t('menu:learnMoveForgetSuccess', { pokemonName: pokemon.name, moveName: pokemon.moveset[moveIndex].getName() }), null, () => {
this.scene.ui.showText(i18next.t('battle:learnMoveForgetSuccess', { pokemonName: pokemon.name, moveName: pokemon.moveset[moveIndex].getName() }), null, () => {
this.scene.ui.showText('And…', null, () => {
pokemon.setMove(moveIndex, Moves.NONE);
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId));
@ -4093,9 +4092,9 @@ export class AttemptCapturePhase extends PokemonPhase {
this.scene.pokemonInfoContainer.show(pokemon, true);
this.scene.gameData.updateSpeciesDexIvs(pokemon.species.speciesId, pokemon.ivs);
this.scene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
this.scene.ui.showText(i18next.t('menu:pokemonCaught', { pokemonName: pokemon.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:pokemonCaught', { pokemonName: pokemon.name }), null, () => {
const end = () => {
this.scene.pokemonInfoContainer.hide();
this.removePb();
@ -4181,7 +4180,7 @@ export class AttemptRunPhase extends PokemonPhase {
if (playerPokemon.randSeedInt(256) < escapeChance.value) {
this.scene.playSound('flee');
this.scene.queueMessage(i18next.t('menu:runAwaySuccess'), null, true, 500);
this.scene.queueMessage(i18next.t('battle:runAwaySuccess'), null, true, 500);
this.scene.tweens.add({
targets: [ this.scene.arenaEnemy, enemyField ].flat(),
@ -4202,7 +4201,7 @@ export class AttemptRunPhase extends PokemonPhase {
this.scene.pushPhase(new BattleEndPhase(this.scene));
this.scene.pushPhase(new NewBattlePhase(this.scene));
} else
this.scene.queueMessage(i18next.t('menu:runAwayCannotEscape'), null, true, 500);
this.scene.queueMessage(i18next.t('battle:runAwayCannotEscape'), null, true, 500);
this.end();
}
@ -4234,7 +4233,7 @@ export class SelectModifierPhase extends BattlePhase {
const modifierSelectCallback = (rowCursor: integer, cursor: integer) => {
if (rowCursor < 0 || cursor < 0) {
this.scene.ui.showText(i18next.t('menu:skipItemQuestion'), null, () => {
this.scene.ui.showText(i18next.t('battle:skipItemQuestion'), null, () => {
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
this.scene.ui.revertMode();
this.scene.ui.setMode(Mode.MESSAGE);
@ -4338,6 +4337,7 @@ export class SelectModifierPhase extends BattlePhase {
const isMoveModifier = modifierType instanceof PokemonMoveModifierType;
const isTmModifier = modifierType instanceof TmModifierType;
const isRememberMoveModifier = modifierType instanceof RememberMoveModifierType;
const isPpRestoreModifier = modifierType instanceof PokemonPpRestoreModifierType;
const partyUiMode = isMoveModifier ? PartyUiMode.MOVE_MODIFIER
: isTmModifier ? PartyUiMode.TM_MODIFIER
: isRememberMoveModifier ? PartyUiMode.REMEMBER_MOVE_MODIFIER
@ -4357,7 +4357,7 @@ export class SelectModifierPhase extends BattlePhase {
});
} else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId);
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId, isPpRestoreModifier);
}
} else
applyModifier(modifierType.newModifier());
@ -4412,7 +4412,7 @@ export class EggLapsePhase extends Phase {
});
if (eggsToHatch.length) {
this.scene.queueMessage(i18next.t('menu:eggHatching'));
this.scene.queueMessage(i18next.t('battle:eggHatching'));
for (let egg of eggsToHatch)
this.scene.unshiftPhase(new EggHatchPhase(this.scene, egg));
@ -4506,7 +4506,7 @@ export class ScanIvsPhase extends PokemonPhase {
const pokemon = this.getPokemon();
this.scene.ui.showText(i18next.t('menu:ivScannerUseQuestion', { pokemonName: pokemon.name }), null, () => {
this.scene.ui.showText(i18next.t('battle:ivScannerUseQuestion', { pokemonName: pokemon.name }), null, () => {
this.scene.ui.setMode(Mode.CONFIRM, () => {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.clearText();

View File

@ -13,6 +13,12 @@ import { menuUiHandler as frMenuUiHandler } from '../locales/fr/menu-ui-handler.
import { menuUiHandler as itMenuUiHandler } from '../locales/it/menu-ui-handler.js';
import { menuUiHandler as deMenuUiHandler } from '../locales/de/menu-ui-handler.js';
import { battle as enBattle } from '../locales/en/battle';
import { battle as esBattle } from '../locales/es/battle';
import { battle as itBattle } from '../locales/it/battle';
import { battle as frBattle } from '../locales/fr/battle';
import { battle as deBattle } from '../locales/de/battle';
import { move as enMove } from '../locales/en/move';
import { move as esMove } from '../locales/es/move';
import { move as frMove } from '../locales/fr/move';
@ -45,7 +51,10 @@ import { commandUiHandler as frCommandUiHandler } from '../locales/fr/command-ui
import { commandUiHandler as deCommandUiHandler } from '../locales/de/command-ui-handler';
import { fightUiHandler as enFightUiHandler } from '../locales/en/fight-ui-handler';
import { fightUiHandler as esFightUiHandler } from '../locales/es/fight-ui-handler';
import { fightUiHandler as frFightUiHandler } from '../locales/fr/fight-ui-handler';
import { fightUiHandler as itFightUiHandler } from '../locales/it/fight-ui-handler';
import { fightUiHandler as deFightUiHandler } from '../locales/de/fight-ui-handler';
import { tutorial as enTutorial } from '../locales/en/tutorial';
import { tutorial as esTutorial } from '../locales/es/tutorial';
@ -113,6 +122,7 @@ export function initI18n(): void {
en: {
menu: enMenu,
menuUiHandler: enMenuUiHandler,
battle: enBattle,
move: enMove,
ability: enAbility,
pokeball: enPokeball,
@ -125,17 +135,20 @@ export function initI18n(): void {
es: {
menu: esMenu,
menuUiHandler: esMenuUiHandler,
battle: esBattle,
move: esMove,
ability: esAbility,
pokeball: esPokeball,
pokemon: esPokemon,
pokemonStat: esPokemonStat,
commandUiHandler: esCommandUiHandler,
fightUiHandler: esFightUiHandler,
tutorial: esTutorial,
},
fr: {
menu: frMenu,
menuUiHandler: frMenuUiHandler,
battle: frBattle,
move: frMove,
ability: frAbility,
pokeball: frPokeball,
@ -148,18 +161,22 @@ export function initI18n(): void {
it: {
menu: itMenu,
menuUiHandler: itMenuUiHandler,
battle: itBattle,
pokemonStat: itPokemonStat,
fightUiHandler: itFightUiHandler,
tutorial: itTutorial,
},
de: {
menu: deMenu,
menuUiHandler: deMenuUiHandler,
battle: deBattle,
move: deMove,
ability: deAbility,
pokeball: dePokeball,
pokemon: dePokemon,
pokemonStat: dePokemonStat,
commandUiHandler: deCommandUiHandler,
fightUiHandler: deFightUiHandler,
tutorial: deTutorial,
}
},
@ -173,6 +190,7 @@ declare module 'i18next' {
menu: typeof enMenu;
menuUiHandler: typeof enMenuUiHandler;
move: typeof enMove;
battle: typeof enBattle,
ability: typeof enAbility;
pokeball: typeof enPokeball;
pokemon: typeof enPokemon;

View File

@ -7,6 +7,7 @@ export enum AchvTier {
COMMON,
GREAT,
ULTRA,
ROGUE,
MASTER
}
@ -50,8 +51,10 @@ export class Achv {
}
getTier(): AchvTier {
if (this.score >= 100)
if (this.score >= 150)
return AchvTier.MASTER;
if (this.score >= 100)
return AchvTier.ROGUE;
if (this.score >= 50)
return AchvTier.ULTRA;
if (this.score >= 25)

View File

@ -169,6 +169,7 @@ export interface StarterDataEntry {
moveset: StarterMoveset | StarterFormMoveData;
eggMoves: integer;
candyCount: integer;
friendship: integer;
abilityAttr: integer;
passiveAttr: integer;
valueReduction: integer;
@ -988,6 +989,7 @@ export class GameData {
moveset: null,
eggMoves: 0,
candyCount: 0,
friendship: 0,
abilityAttr: defaultStarterSpecies.includes(speciesId) ? AbilityAttr.ABILITY_1 : 0,
passiveAttr: 0,
valueReduction: 0
@ -1035,6 +1037,7 @@ export class GameData {
const hasPrevolution = pokemonPrevolutions.hasOwnProperty(species.speciesId);
const newCatch = !caughtAttr;
const hasNewAttr = (caughtAttr & dexAttr) !== dexAttr;
if (incrementCount) {
if (!fromEgg) {
@ -1057,7 +1060,7 @@ export class GameData {
this.gameStats.shinyPokemonHatched++;
}
if (!hasPrevolution)
if (!hasPrevolution && (!pokemon.scene.gameMode.isDaily || hasNewAttr))
this.addStarterCandy(species, (1 * (pokemon.isShiny() ? 5 * Math.pow(2, pokemon.variant || 0) : 1)) * (fromEgg || pokemon.isBoss() ? 2 : 1));
}

View File

@ -44,7 +44,7 @@ export class Voucher {
case VoucherType.PREMIUM:
return AchvTier.ULTRA;
case VoucherType.GOLDEN:
return AchvTier.MASTER;
return AchvTier.ROGUE;
}
}
}

View File

@ -9,6 +9,7 @@ export enum Tutorial {
Menu = "MENU",
Starter_Select = "STARTER_SELECT",
Pokerus = "POKERUS",
Stat_Change = "STAT_CHANGE",
Select_Item = "SELECT_ITEM",
Egg_Gacha = "EGG_GACHA"
}
@ -42,6 +43,11 @@ const tutorialHandlers = {
scene.ui.showText(i18next.t("tutorial:pokerus"), null, () => scene.ui.showText('', null, () => resolve()), null, true);
});
},
[Tutorial.Stat_Change]: (scene: BattleScene) => {
return new Promise<void>(resolve => {
scene.showFieldOverlay(1000).then(() => scene.ui.showText(i18next.t("tutorial:statChange"), null, () => scene.ui.showText('', null, () => scene.hideFieldOverlay(1000).then(() => resolve())), null, true));
});
},
[Tutorial.Select_Item]: (scene: BattleScene) => {
return new Promise<void>(resolve => {
scene.ui.setModeWithoutClear(Mode.MESSAGE).then(() => {

View File

@ -7,6 +7,9 @@ import { StatusEffect } from '../data/status-effect';
import BattleScene from '../battle-scene';
import { Type, getTypeRgb } from '../data/type';
import { getVariantTint } from '#app/data/variant';
import { BattleStat } from '#app/data/battle-stat';
const battleStatOrder = [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.ACC, BattleStat.EVA, BattleStat.SPD ];
export default class BattleInfo extends Phaser.GameObjects.Container {
private player: boolean;
@ -24,6 +27,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
private lastLevelExp: integer;
private lastLevel: integer;
private lastLevelCapped: boolean;
private lastBattleStats: string;
private box: Phaser.GameObjects.Sprite;
private nameText: Phaser.GameObjects.Text;
@ -46,6 +50,11 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
public expMaskRect: Phaser.GameObjects.Graphics;
private statsContainer: Phaser.GameObjects.Container;
private statsBox: Phaser.GameObjects.Sprite;
private statValuesContainer: Phaser.GameObjects.Container;
private statNumbers: Phaser.GameObjects.Sprite[];
constructor(scene: Phaser.Scene, x: number, y: number, player: boolean) {
super(scene, x, y);
this.player = player;
@ -138,18 +147,6 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.levelNumbersContainer = this.scene.add.container(9.5, (this.scene as BattleScene).uiTheme ? 0 : -0.5);
this.levelContainer.add(this.levelNumbersContainer);
this.type1Icon = this.scene.add.sprite(player ? -139 : -15, player ? -17 : -15.5, `pbinfo_${player ? 'player' : 'enemy'}_type1`);
this.type1Icon.setOrigin(0, 0);
this.add(this.type1Icon);
this.type2Icon = this.scene.add.sprite(player ? -139 : -15, player ? -1 : -2.5, `pbinfo_${player ? 'player' : 'enemy'}_type2`);
this.type2Icon.setOrigin(0, 0);
this.add(this.type2Icon);
this.type3Icon = this.scene.add.sprite(player ? -154 : 0, player ? -17 : -15.5, `pbinfo_${player ? 'player' : 'enemy'}_type`);
this.type3Icon.setOrigin(0, 0);
this.add(this.type3Icon);
if (this.player) {
this.hpNumbersContainer = this.scene.add.container(-15, 10);
this.add(this.hpNumbersContainer);
@ -171,6 +168,46 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.expBar = expBar;
this.expMaskRect = expMaskRect;
}
this.statsContainer = this.scene.add.container(0, 0);
this.statsContainer.setAlpha(0);
this.add(this.statsContainer);
this.statsBox = this.scene.add.sprite(0, 0, `${this.getTextureName()}_stats`);
this.statsBox.setOrigin(1, 0.5);
this.statsContainer.add(this.statsBox);
const statLabels: Phaser.GameObjects.Sprite[] = [];
this.statNumbers = [];
this.statValuesContainer = this.scene.add.container(0, 0);
this.statsContainer.add(this.statValuesContainer);
battleStatOrder.map((s, i) => {
const statX = i > 1 ? this.statNumbers[i - 2].x + this.statNumbers[i - 2].width + 4 : -this.statsBox.width + 8;
const statY = -this.statsBox.height / 2 + 4 + (i < battleStatOrder.length - 1 ? (i % 2 ? 10 : 0) : 5);
const statLabel = this.scene.add.sprite(statX, statY, 'pbinfo_stat', BattleStat[s]);
statLabel.setOrigin(0, 0);
statLabels.push(statLabel);
this.statValuesContainer.add(statLabel);
const statNumber = this.scene.add.sprite(statX + statLabel.width, statY, 'pbinfo_stat_numbers', '3');
statNumber.setOrigin(0, 0);
this.statNumbers.push(statNumber);
this.statValuesContainer.add(statNumber);
});
this.type1Icon = this.scene.add.sprite(player ? -139 : -15, player ? -17 : -15.5, `pbinfo_${player ? 'player' : 'enemy'}_type1`);
this.type1Icon.setOrigin(0, 0);
this.add(this.type1Icon);
this.type2Icon = this.scene.add.sprite(player ? -139 : -15, player ? -1 : -2.5, `pbinfo_${player ? 'player' : 'enemy'}_type2`);
this.type2Icon.setOrigin(0, 0);
this.add(this.type2Icon);
this.type3Icon = this.scene.add.sprite(player ? -154 : 0, player ? -17 : -15.5, `pbinfo_${player ? 'player' : 'enemy'}_type`);
this.type3Icon.setOrigin(0, 0);
this.add(this.type3Icon);
}
initInfo(pokemon: Pokemon) {
@ -258,7 +295,14 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.expMaskRect.x = (pokemon.levelExp / getLevelTotalExp(pokemon.level, pokemon.species.growthRate)) * 510;
this.lastExp = pokemon.exp;
this.lastLevelExp = pokemon.levelExp;
this.statValuesContainer.setPosition(8, 7)
}
const battleStats = battleStatOrder.map(() => 0);
this.lastBattleStats = battleStats.join('');
this.updateBattleStats(battleStats);
}
getTextureName(): string {
@ -272,6 +316,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.mini = mini;
this.box.setTexture(this.getTextureName());
this.statsBox.setTexture(`${this.getTextureName()}_stats`);
if (this.player)
this.y -= 12 * (mini ? 1 : -1);
@ -284,21 +329,34 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
el.y += -8 * (mini ? 1 : -1);
});
this.statValuesContainer.x += 2 * (mini ? 1 : -1);
this.statValuesContainer.y += -7 * (mini ? 1 : -1);
const toggledElements = [ this.hpNumbersContainer, this.expBar ];
toggledElements.forEach(el => el.setVisible(!mini));
}
toggleStats(visible: boolean): void {
this.scene.tweens.add({
targets: this.statsContainer,
duration: Utils.fixedInt(125),
ease: 'Sine.easeInOut',
alpha: visible ? 1 : 0
});
}
updateBossSegments(pokemon: EnemyPokemon): void {
const boss = !!pokemon.bossSegments;
if (boss !== this.boss) {
this.boss = boss;
[ this.nameText, this.genderText, this.teraIcon, this.splicedIcon, this.shinyIcon, this.ownedIcon, this.statusIndicator, this.levelContainer ].map(e => e.x += 48 * (boss ? -1 : 1));
[ this.nameText, this.genderText, this.teraIcon, this.splicedIcon, this.shinyIcon, this.ownedIcon, this.statusIndicator, this.levelContainer, this.statValuesContainer ].map(e => e.x += 48 * (boss ? -1 : 1));
this.hpBar.x += 38 * (boss ? -1 : 1);
this.hpBar.y += 2 * (this.boss ? -1 : 1);
this.hpBar.setTexture(`overlay_hp${boss ? '_boss' : ''}`);
this.box.setTexture(this.getTextureName());
this.statsBox.setTexture(`${this.getTextureName()}_stats`);
}
this.bossSegments = boss ? pokemon.bossSegments : 0;
@ -317,6 +375,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
const divider = this.scene.add.rectangle(0, 0, 1, this.hpBar.height - (uiTheme ? 0 : 1), pokemon.bossSegmentIndex >= s ? 0xFFFFFF : 0x404040)
divider.setOrigin(0.5, 0);
this.add(divider);
this.moveBelow(divider as Phaser.GameObjects.GameObject, this.statsContainer);
divider.setPositionRelative(this.hpBar, dividerX, uiTheme ? 0 : 1);
this.hpBarSegmentDividers.push(divider);
@ -439,6 +498,16 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.lastLevel = pokemon.level;
}
const battleStats = pokemon.summonData
? pokemon.summonData.battleStats
: battleStatOrder.map(() => 0);
const battleStatsStr = battleStats.join('');
if (this.lastBattleStats !== battleStatsStr) {
this.updateBattleStats(battleStats);
this.lastBattleStats = battleStatsStr;
}
this.shinyIcon.setVisible(pokemon.isShiny());
resolve();
@ -513,7 +582,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
});
}
setLevel(level: integer) {
setLevel(level: integer): void {
const isCapped = level >= (this.scene as BattleScene).getMaxExpLevel();
this.levelNumbersContainer.removeAll(true);
const levelStr = level.toString();
@ -522,7 +591,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
this.levelContainer.setX((this.player ? -41 : -50) - 8 * Math.max(levelStr.length - 3, 0));
}
setHpNumbers(hp: integer, maxHp: integer) {
setHpNumbers(hp: integer, maxHp: integer): void {
if (!this.player || !this.scene)
return;
this.hpNumbersContainer.removeAll(true);
@ -535,6 +604,12 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
for (let i = hpStr.length - 1; i >= 0; i--)
this.hpNumbersContainer.add(this.scene.add.image(offset++ * -8, 0, 'numbers', hpStr[i]));
}
updateBattleStats(battleStats: integer[]): void {
battleStatOrder.map((s, i) => {
this.statNumbers[i].setFrame(battleStats[s].toString());
});
}
}
export class PlayerBattleInfo extends BattleInfo {

View File

@ -1,15 +1,16 @@
import BattleScene, { Button } from "../battle-scene";
import { addTextObject, TextStyle } from "./text";
import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "./text";
import { Mode } from "./ui";
import * as Utils from "../utils";
import MessageUiHandler from "./message-ui-handler";
import { getStatName, Stat } from "../data/pokemon-stat";
import { addWindow } from "./ui-theme";
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
export default class BattleMessageUiHandler extends MessageUiHandler {
private levelUpStatsContainer: Phaser.GameObjects.Container;
private levelUpStatsIncrContent: Phaser.GameObjects.Text;
private levelUpStatsValuesContent: Phaser.GameObjects.Text;
private levelUpStatsValuesContent: BBCodeText;
private nameBox: Phaser.GameObjects.NineSlice;
private nameText: Phaser.GameObjects.Text;
@ -29,7 +30,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
this.textCallbackTimer = null;
const bg = this.scene.add.sprite(0, 0, 'bg', this.scene.windowType);
bg.setOrigin(0, 1);
bg.setOrigin(0, 1);
ui.add(bg);
this.bg = bg;
@ -95,18 +96,19 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
this.levelUpStatsContainer = levelUpStatsContainer;
const levelUpStatsBg = addWindow(this.scene, (this.scene.game.canvas.width / 6), -100, 128, 100);
levelUpStatsBg.setOrigin(1, 0);
levelUpStatsContainer.add(levelUpStatsBg);
const levelUpStatsLabelsContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 121, -94, '', TextStyle.WINDOW, { maxLines: 6 });
const levelUpStatsLabelsContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 73, -94, '', TextStyle.WINDOW, { maxLines: 6 });
let levelUpStatsLabelText = '';
const stats = Utils.getEnumValues(Stat);
for (let s of stats)
levelUpStatsLabelText += `${getStatName(s)}\n`;
levelUpStatsLabelsContent.text = levelUpStatsLabelText;
levelUpStatsLabelsContent.x -= levelUpStatsLabelsContent.displayWidth;
const levelUpStatsBg = addWindow(this.scene, (this.scene.game.canvas.width / 6), -100, 80 + levelUpStatsLabelsContent.displayWidth, 100);
levelUpStatsBg.setOrigin(1, 0);
levelUpStatsContainer.add(levelUpStatsBg);
levelUpStatsContainer.add(levelUpStatsLabelsContent);
const levelUpStatsIncrContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 50, -94, '+\n+\n+\n+\n+\n+', TextStyle.WINDOW, { maxLines: 6 });
@ -114,7 +116,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
this.levelUpStatsIncrContent = levelUpStatsIncrContent;
const levelUpStatsValuesContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 7, -94, '', TextStyle.WINDOW, { maxLines: 6 });
const levelUpStatsValuesContent = addBBCodeTextObject(this.scene, (this.scene.game.canvas.width / 6) - 7, -94, '', TextStyle.WINDOW, { maxLines: 6 , lineSpacing: 5});
levelUpStatsValuesContent.setOrigin(1, 0);
levelUpStatsValuesContent.setAlign('right');
levelUpStatsContainer.add(levelUpStatsValuesContent);
@ -208,7 +210,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
} else
shownStats = stats;
for (let s of stats)
levelUpStatsValuesText += `${shownStats.indexOf(s) > -1 ? this.getIvDescriptor(ivs[s]) : '???'}\n`;
levelUpStatsValuesText += `${shownStats.indexOf(s) > -1 ? this.getIvDescriptor(ivs[s], s, pokemonId) : '???'}\n`;
this.levelUpStatsValuesContent.text = levelUpStatsValuesText;
this.levelUpStatsIncrContent.setVisible(false);
this.levelUpStatsContainer.setVisible(true);
@ -221,18 +223,30 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
});
}
getIvDescriptor(value: integer): string {
getIvDescriptor(value: integer, typeIv: integer, pokemonId: integer): string {
const starterSpecies = this.scene.getPokemonById(pokemonId).species.getRootSpeciesId(true);
const starterIvs: number[] = this.scene.gameData.dexData[starterSpecies].ivs;
const uiTheme = (this.scene as BattleScene).uiTheme; // Assuming uiTheme is accessible
// Function to wrap text in color based on comparison
const coloredText = (text: string, isBetter: boolean) => {
const textStyle: TextStyle = isBetter ? TextStyle.SUMMARY_GREEN : TextStyle.SUMMARY;
const color = getTextColor(textStyle, false, uiTheme);
return `[color=${color}][shadow=${getTextColor(textStyle, true, uiTheme)}]${text}[/shadow][/color]`;
};
if (value > 30)
return 'Best';
return coloredText('Best', value > starterIvs[typeIv]);
if (value === 30)
return 'Fantastic';
return coloredText('Fantastic', value > starterIvs[typeIv]);
if (value > 20)
return 'Very Good';
return coloredText('Very Good', value > starterIvs[typeIv]);
if (value > 10)
return 'Pretty Good';
if (value)
return 'Decent';
return 'No Good';
return coloredText('Pretty Good', value > starterIvs[typeIv]);
if (value > 0)
return coloredText('Decent', value > starterIvs[typeIv]);
return coloredText('No Good', value > starterIvs[typeIv]);
}
showNameText(name: string): void {
@ -244,4 +258,4 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
hideNameText(): void {
this.nameBoxContainer.setVisible(false);
}
}
}

View File

@ -11,6 +11,7 @@ interface RankingEntry {
wave: integer
}
// Don't forget to update translations when adding a new category
enum ScoreboardCategory {
DAILY,
WEEKLY
@ -40,7 +41,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
const titleWindow = addWindow(this.scene, 0, 0, 114, 18, false, false, null, null, WindowVariant.THIN);
this.add(titleWindow);
this.titleLabel = addTextObject(this.scene, titleWindow.displayWidth / 2, titleWindow.displayHeight / 2, i18next.t('menu:dailyRankings'), TextStyle.WINDOW, { fontSize: '64px' });
this.titleLabel = addTextObject(this.scene, titleWindow.displayWidth / 2, titleWindow.displayHeight / 2, i18next.t('menu:loading'), TextStyle.WINDOW, { fontSize: '64px' });
this.titleLabel.setOrigin(0.5, 0.5);
this.add(this.titleLabel);
@ -156,7 +157,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
.then(jsonResponse => {
this.page = page;
this.category = category;
this.titleLabel.setText(`${Utils.toReadableString(ScoreboardCategory[category])} ${i18next.t("menu:rankings")}`);
this.titleLabel.setText(`${i18next.t(`menu:${ScoreboardCategory[category].toLowerCase()}Rankings`)}`);
this.prevPageButton.setAlpha(page > 1 ? 1 : 0.5);
this.nextPageButton.setAlpha(page < this.pageCount ? 1 : 0.5);
this.pageNumberLabel.setText(page.toString());
@ -166,7 +167,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
} else
this.loadingLabel.setText(i18next.t('menu:noRankings'));
});
});
}).catch(err => { console.error("Failed to load daily rankings:\n", err) });
}
}

View File

@ -90,6 +90,7 @@ export default class PartyUiHandler extends MessageUiHandler {
private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter;
private moveSelectFilter: PokemonMoveSelectFilter;
private tmMoveId: Moves;
private showMovePp: boolean;
private iconAnimHandler: PokemonIconAnimHandler;
@ -185,6 +186,7 @@ export default class PartyUiHandler extends MessageUiHandler {
? args[4] as PokemonMoveSelectFilter
: PartyUiHandler.FilterAllMoves;
this.tmMoveId = args.length > 5 && args[5] ? args[5] : Moves.NONE;
this.showMovePp = args.length > 6 && args[6];
this.partyContainer.setVisible(true);
this.partyBg.setTexture(`party_bg${this.scene.currentBattle.double ? '_double' : ''}`);
@ -663,7 +665,14 @@ export default class PartyUiHandler extends MessageUiHandler {
case PartyOption.MOVE_2:
case PartyOption.MOVE_3:
case PartyOption.MOVE_4:
optionName = pokemon.moveset[option - PartyOption.MOVE_1].getName();
const move = pokemon.moveset[option - PartyOption.MOVE_1];
if(this.showMovePp) {
const maxPP = move.getMovePp();
const currPP = maxPP - move.ppUsed;
optionName = `${move.getName()} ${currPP}/${maxPP}`;
} else {
optionName = move.getName();
}
break;
default:
if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) {

View File

@ -161,8 +161,9 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
if (isFusion)
this.pokemonFusionShinyIcon.setTint(getVariantTint(pokemon.fusionVariant));
const originalIvs: integer[] = this.scene.gameData.dexData[pokemon.species.speciesId].caughtAttr
? this.scene.gameData.dexData[pokemon.species.speciesId].ivs
const starterSpeciesId = pokemon.species.getRootSpeciesId(true);
const originalIvs: integer[] = this.scene.gameData.dexData[starterSpeciesId].caughtAttr
? this.scene.gameData.dexData[starterSpeciesId].ivs
: null;
this.statsContainer.updateIvs(pokemon.ivs, originalIvs);

View File

@ -4,7 +4,8 @@ import { Stat, getStatName } from "../data/pokemon-stat";
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
const ivChartSize = 24;
const ivChartStatCoordMultipliers = [ [ 0, 1 ], [ 0.825, 0.5 ], [ 0.825, -0.5 ], [ 0, -1 ], [ -0.825, -0.5 ], [ -0.825, 0.5 ] ];
const ivChartStatCoordMultipliers = [ [ 0, -1 ], [ 0.825, -0.5 ], [ 0.825, 0.5 ], [ -0.825, -0.5 ], [ -0.825, 0.5 ], [ 0, 1 ] ];
const ivChartStatIndexes = [0,1,2,5,4,3] // swap special attack and speed
const defaultIvChartData = new Array(12).fill(null).map(() => 0);
export class StatsContainer extends Phaser.GameObjects.Container {
@ -22,7 +23,7 @@ export class StatsContainer extends Phaser.GameObjects.Container {
}
setup() {
const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[i][0], ivChartSize * ivChartStatCoordMultipliers[i][1] ] ).flat();
const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][0], ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][1] ] ).flat();
const ivChartBg = this.scene.add.polygon(48, 44, ivChartBgData, 0xd8e0f0, 0.625);
ivChartBg.setOrigin(0, 0);
@ -62,7 +63,7 @@ export class StatsContainer extends Phaser.GameObjects.Container {
updateIvs(ivs: integer[], originalIvs?: integer[]): void {
if (ivs) {
const ivChartData = new Array(6).fill(null).map((_, i) => [ (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][0], (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][1] ] ).flat();
const ivChartData = new Array(6).fill(null).map((_, i) => [ (ivs[ivChartStatIndexes[i]] / 31) * ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][0], (ivs[ivChartStatIndexes[i]] / 31) * ivChartSize * ivChartStatCoordMultipliers[ivChartStatIndexes[i]][1] ] ).flat();
const lastIvChartData = this.statsIvsCache || defaultIvChartData;
this.statsIvsCache = ivChartData.slice(0);

View File

@ -19,6 +19,7 @@ export enum TextStyle {
SUMMARY_PINK,
SUMMARY_GOLD,
SUMMARY_GRAY,
SUMMARY_GREEN,
MONEY,
SETTINGS_LABEL,
SETTINGS_SELECTED,
@ -82,6 +83,7 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio
case TextStyle.SUMMARY_PINK:
case TextStyle.SUMMARY_GOLD:
case TextStyle.SUMMARY_GRAY:
case TextStyle.SUMMARY_GREEN:
case TextStyle.WINDOW:
case TextStyle.WINDOW_ALT:
case TextStyle.MESSAGE:
@ -160,6 +162,8 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
return !shadow ? '#e8e8a8' : '#a0a060';
case TextStyle.SUMMARY_GRAY:
return !shadow ? '#a0a0a0' : '#636363';
case TextStyle.SUMMARY_GREEN:
return !shadow ? '#78c850' : '#306850';
case TextStyle.SETTINGS_LABEL:
return !shadow ? '#f8b050' : '#c07800';
case TextStyle.SETTINGS_SELECTED:

View File

@ -65,6 +65,9 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
this.playerCountLabel.setText(`${stats.playerCount} ${i18next.t("menu:playersOnline")}`);
if (this.splashMessage === battleCountSplashMessage)
this.splashMessageText.setText(battleCountSplashMessage.replace('{COUNT}', stats.battleCount.toLocaleString('en-US')));
})
.catch(err => {
console.error("Failed to fetch title stats:\n", err);
});
}