Merge branch 'rh-hideout-master'
This commit is contained in:
commit
04721c1000
@ -118,7 +118,8 @@
|
|||||||
"profile": "https://linktr.ee/pkmnsnfrn",
|
"profile": "https://linktr.ee/pkmnsnfrn",
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"maintenance",
|
"maintenance",
|
||||||
"code"
|
"code",
|
||||||
|
"projectManagement"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -223,7 +224,7 @@
|
|||||||
"name": "Ruby",
|
"name": "Ruby",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/178652077?v=4",
|
"avatar_url": "https://avatars.githubusercontent.com/u/178652077?v=4",
|
||||||
"profile": "https://github.com/RubyRaven6",
|
"profile": "https://github.com/RubyRaven6",
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"code",
|
"code",
|
||||||
"doc"
|
"doc"
|
||||||
]
|
]
|
||||||
@ -255,10 +256,82 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "bassforte123",
|
||||||
|
"name": "bassforte123",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/130828119?v=4",
|
||||||
|
"profile": "https://github.com/bassforte123",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "iriv24",
|
||||||
|
"name": "iriv24",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/40581123?v=4",
|
||||||
|
"profile": "https://github.com/iriv24",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Bivurnum",
|
||||||
|
"name": "Bivurnum",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/147376167?v=4",
|
||||||
|
"profile": "https://github.com/Bivurnum",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Emiliasky",
|
||||||
|
"name": "Emilia Daelman",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/48217459?v=4",
|
||||||
|
"profile": "https://github.com/Emiliasky",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ravepossum",
|
||||||
|
"name": "RavePossum",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/145081120?v=4",
|
||||||
|
"profile": "https://github.com/ravepossum",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "fakuzatsu",
|
||||||
|
"name": "Zatsu",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/118256341?v=4",
|
||||||
|
"profile": "https://github.com/fakuzatsu",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "poetahto",
|
||||||
|
"name": "poetahto",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/11669335?v=4",
|
||||||
|
"profile": "https://github.com/poetahto",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "lordraindance2",
|
||||||
|
"name": "lordraindance2",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/47706100?v=4",
|
||||||
|
"profile": "https://github.com/lordraindance2",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
"linkToUsage": true,
|
"linkToUsage": true,
|
||||||
"commitType": "docs",
|
"commitType": "docs"
|
||||||
"skipCi": true
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@ -9,6 +9,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
if: github.actor != 'allcontributors[bot]'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
GAME_VERSION: EMERALD
|
GAME_VERSION: EMERALD
|
||||||
@ -36,3 +37,11 @@ jobs:
|
|||||||
TEST: 1
|
TEST: 1
|
||||||
run: |
|
run: |
|
||||||
make -j${nproc} check
|
make -j${nproc} check
|
||||||
|
allcontributors:
|
||||||
|
if: github.actor == 'allcontributors[bot]'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: []
|
||||||
|
steps:
|
||||||
|
- name: Automatically pass for allcontributors
|
||||||
|
run: echo "CI automatically passes for allcontributors" && exit 0
|
||||||
|
|
||||||
|
|||||||
9
.github/workflows/labels.yml
vendored
9
.github/workflows/labels.yml
vendored
@ -6,6 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
label:
|
label:
|
||||||
|
if: github.actor != 'allcontributors[bot]'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: check labels
|
- name: check labels
|
||||||
@ -27,3 +28,11 @@ jobs:
|
|||||||
category: pokemon
|
category: pokemon
|
||||||
category: sprite-issue
|
category: sprite-issue
|
||||||
type: documentation
|
type: documentation
|
||||||
|
allcontributors:
|
||||||
|
if: github.actor == 'allcontributors[bot]'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: []
|
||||||
|
steps:
|
||||||
|
- name: Automatically pass for allcontributors
|
||||||
|
run: echo "CI automatically passes for allcontributors" && exit 0
|
||||||
|
|
||||||
|
|||||||
39
CREDITS.md
39
CREDITS.md
@ -30,24 +30,34 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pawkkie"><img src="https://avatars.githubusercontent.com/u/61265402?v=4?s=100" width="100px;" alt="Pawkkie"/><br /><sub><b>Pawkkie</b></sub></a><br /><a href="#maintenance-Pawkkie" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Pawkkie" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Pawkkie" title="Documentation">📖</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pawkkie"><img src="https://avatars.githubusercontent.com/u/61265402?v=4?s=100" width="100px;" alt="Pawkkie"/><br /><sub><b>Pawkkie</b></sub></a><br /><a href="#maintenance-Pawkkie" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Pawkkie" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Pawkkie" title="Documentation">📖</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SBird1337"><img src="https://avatars.githubusercontent.com/u/3799173?v=4?s=100" width="100px;" alt="Philipp AUER"/><br /><sub><b>Philipp AUER</b></sub></a><br /><a href="#maintenance-SBird1337" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=SBird1337" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SBird1337"><img src="https://avatars.githubusercontent.com/u/3799173?v=4?s=100" width="100px;" alt="Philipp AUER"/><br /><sub><b>Philipp AUER</b></sub></a><br /><a href="#maintenance-SBird1337" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=SBird1337" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tertu-m"><img src="https://avatars.githubusercontent.com/u/836640?v=4?s=100" width="100px;" alt="tertu"/><br /><sub><b>tertu</b></sub></a><br /><a href="#maintenance-tertu-m" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tertu-m" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tertu-m"><img src="https://avatars.githubusercontent.com/u/836640?v=4?s=100" width="100px;" alt="tertu"/><br /><sub><b>tertu</b></sub></a><br /><a href="#maintenance-tertu-m" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tertu-m" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://linktr.ee/pkmnsnfrn"><img src="https://avatars.githubusercontent.com/u/77138753?v=4?s=100" width="100px;" alt="psf"/><br /><sub><b>psf</b></sub></a><br /><a href="#maintenance-pkmnsnfrn" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=pkmnsnfrn" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://linktr.ee/pkmnsnfrn"><img src="https://avatars.githubusercontent.com/u/77138753?v=4?s=100" width="100px;" alt="psf"/><br /><sub><b>psf</b></sub></a><br /><a href="#maintenance-pkmnsnfrn" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=pkmnsnfrn" title="Code">💻</a> <a href="#projectManagement-pkmnsnfrn" title="Project Management">📆</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wiz1989"><img src="https://avatars.githubusercontent.com/u/80073265?v=4?s=100" width="100px;" alt="wiz1989"/><br /><sub><b>wiz1989</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=wiz1989" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PCG06"><img src="https://avatars.githubusercontent.com/u/75729017?v=4?s=100" width="100px;" alt="PCG"/><br /><sub><b>PCG</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=PCG06" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PCG06"><img src="https://avatars.githubusercontent.com/u/75729017?v=4?s=100" width="100px;" alt="PCG"/><br /><sub><b>PCG</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=PCG06" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kittenchilly"><img src="https://avatars.githubusercontent.com/u/23617175?v=4?s=100" width="100px;" alt="kittenchilly"/><br /><sub><b>kittenchilly</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=kittenchilly" title="Code">💻</a> <a href="#research-kittenchilly" title="Research">🔬</a> <a href="#data-kittenchilly" title="Data">🔣</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kittenchilly"><img src="https://avatars.githubusercontent.com/u/23617175?v=4?s=100" width="100px;" alt="kittenchilly"/><br /><sub><b>kittenchilly</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=kittenchilly" title="Code">💻</a> <a href="#research-kittenchilly" title="Research">🔬</a> <a href="#data-kittenchilly" title="Data">🔣</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ExpoSeed"><img src="https://avatars.githubusercontent.com/u/43502820?v=4?s=100" width="100px;" alt="ExpoSeed"/><br /><sub><b>ExpoSeed</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ExpoSeed" title="Code">💻</a> <a href="#maintenance-ExpoSeed" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/pulls?q=is%3Apr+reviewed-by%3AExpoSeed" title="Reviewed Pull Requests">👀</a></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ExpoSeed"><img src="https://avatars.githubusercontent.com/u/43502820?v=4?s=100" width="100px;" alt="ExpoSeed"/><br /><sub><b>ExpoSeed</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ExpoSeed" title="Code">💻</a> <a href="#maintenance-ExpoSeed" title="Maintenance">🚧</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/pulls?q=is%3Apr+reviewed-by%3AExpoSeed" title="Reviewed Pull Requests">👀</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LinathanZel"><img src="https://avatars.githubusercontent.com/u/35115312?v=4?s=100" width="100px;" alt="Linathan"/><br /><sub><b>Linathan</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=LinathanZel" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LinathanZel"><img src="https://avatars.githubusercontent.com/u/35115312?v=4?s=100" width="100px;" alt="Linathan"/><br /><sub><b>Linathan</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=LinathanZel" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AsparagusEduardo"><img src="https://avatars.githubusercontent.com/u/2904965?v=4?s=100" width="100px;" alt="Eduardo Quezada"/><br /><sub><b>Eduardo Quezada</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Code">💻</a> <a href="#data-AsparagusEduardo" title="Data">🔣</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Documentation">📖</a> <a href="#infra-AsparagusEduardo" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-AsparagusEduardo" title="Maintenance">🚧</a> <a href="#projectManagement-AsparagusEduardo" title="Project Management">📆</a> <a href="#promotion-AsparagusEduardo" title="Promotion">📣</a> <a href="#research-AsparagusEduardo" title="Research">🔬</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/pulls?q=is%3Apr+reviewed-by%3AAsparagusEduardo" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Tests">⚠️</a> <a href="#tutorial-AsparagusEduardo" title="Tutorials">✅</a> <a href="#userTesting-AsparagusEduardo" title="User Testing">📓</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AsparagusEduardo"><img src="https://avatars.githubusercontent.com/u/2904965?v=4?s=100" width="100px;" alt="Eduardo Quezada"/><br /><sub><b>Eduardo Quezada</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Code">💻</a> <a href="#data-AsparagusEduardo" title="Data">🔣</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Documentation">📖</a> <a href="#infra-AsparagusEduardo" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-AsparagusEduardo" title="Maintenance">🚧</a> <a href="#projectManagement-AsparagusEduardo" title="Project Management">📆</a> <a href="#promotion-AsparagusEduardo" title="Promotion">📣</a> <a href="#research-AsparagusEduardo" title="Research">🔬</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/pulls?q=is%3Apr+reviewed-by%3AAsparagusEduardo" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=AsparagusEduardo" title="Tests">⚠️</a> <a href="#tutorial-AsparagusEduardo" title="Tutorials">✅</a> <a href="#userTesting-AsparagusEduardo" title="User Testing">📓</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/khbsd"><img src="https://avatars.githubusercontent.com/u/26092020?v=4?s=100" width="100px;" alt="khbsd"/><br /><sub><b>khbsd</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=khbsd" title="Documentation">📖</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=khbsd" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/khbsd"><img src="https://avatars.githubusercontent.com/u/26092020?v=4?s=100" width="100px;" alt="khbsd"/><br /><sub><b>khbsd</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=khbsd" title="Documentation">📖</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=khbsd" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cafeei"><img src="https://avatars.githubusercontent.com/u/46283144?v=4?s=100" width="100px;" alt="Cafe"/><br /><sub><b>Cafe</b></sub></a><br /><a href="#design-Cafeei" title="Design">🎨</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cafeei"><img src="https://avatars.githubusercontent.com/u/46283144?v=4?s=100" width="100px;" alt="Cafe"/><br /><sub><b>Cafe</b></sub></a><br /><a href="#design-Cafeei" title="Design">🎨</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/agsmgmaster64"><img src="https://avatars.githubusercontent.com/u/67435611?v=4?s=100" width="100px;" alt="agsmgmaster64"/><br /><sub><b>agsmgmaster64</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=agsmgmaster64" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/agsmgmaster64"><img src="https://avatars.githubusercontent.com/u/67435611?v=4?s=100" width="100px;" alt="agsmgmaster64"/><br /><sub><b>agsmgmaster64</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=agsmgmaster64" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mudskipper13"><img src="https://avatars.githubusercontent.com/u/105766191?v=4?s=100" width="100px;" alt="mudskipper13"/><br /><sub><b>mudskipper13</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=mudskipper13" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=mudskipper13" title="Documentation">📖</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RubyRaven6"><img src="https://avatars.githubusercontent.com/u/178652077?v=4?s=100" width="100px;" alt="Ruby"/><br /><sub><b>Ruby</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=RubyRaven6" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=RubyRaven6" title="Documentation">📖</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RubyRaven6"><img src="https://avatars.githubusercontent.com/u/178652077?v=4?s=100" width="100px;" alt="Ruby"/><br /><sub><b>Ruby</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=RubyRaven6" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=RubyRaven6" title="Documentation">📖</a></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/surskitty"><img src="https://avatars.githubusercontent.com/u/1383512?v=4?s=100" width="100px;" alt="surskitty"/><br /><sub><b>surskitty</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=surskitty" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mudskipper13"><img src="https://avatars.githubusercontent.com/u/105766191?v=4?s=100" width="100px;" alt="mudskipper13"/><br /><sub><b>mudskipper13</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=mudskipper13" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=mudskipper13" title="Documentation">📖</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wiz1989"><img src="https://avatars.githubusercontent.com/u/80073265?v=4?s=100" width="100px;" alt="wiz1989"/><br /><sub><b>wiz1989</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=wiz1989" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/surskitty"><img src="https://avatars.githubusercontent.com/u/1383512?v=4?s=100" width="100px;" alt="surskitty"/><br /><sub><b>surskitty</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=surskitty" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/grintoul1"><img src="https://avatars.githubusercontent.com/u/166724814?v=4?s=100" width="100px;" alt="grintoul"/><br /><sub><b>grintoul</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=grintoul1" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/grintoul1"><img src="https://avatars.githubusercontent.com/u/166724814?v=4?s=100" width="100px;" alt="grintoul"/><br /><sub><b>grintoul</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=grintoul1" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bassforte123"><img src="https://avatars.githubusercontent.com/u/130828119?v=4?s=100" width="100px;" alt="bassforte123"/><br /><sub><b>bassforte123</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=bassforte123" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iriv24"><img src="https://avatars.githubusercontent.com/u/40581123?v=4?s=100" width="100px;" alt="iriv24"/><br /><sub><b>iriv24</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=iriv24" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Bivurnum"><img src="https://avatars.githubusercontent.com/u/147376167?v=4?s=100" width="100px;" alt="Bivurnum"/><br /><sub><b>Bivurnum</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Bivurnum" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Emiliasky"><img src="https://avatars.githubusercontent.com/u/48217459?v=4?s=100" width="100px;" alt="Emilia Daelman"/><br /><sub><b>Emilia Daelman</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Emiliasky" title="Code">💻</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Emiliasky" title="Tests">⚠️</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ravepossum"><img src="https://avatars.githubusercontent.com/u/145081120?v=4?s=100" width="100px;" alt="RavePossum"/><br /><sub><b>RavePossum</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ravepossum" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fakuzatsu"><img src="https://avatars.githubusercontent.com/u/118256341?v=4?s=100" width="100px;" alt="Zatsu"/><br /><sub><b>Zatsu</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=fakuzatsu" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/poetahto"><img src="https://avatars.githubusercontent.com/u/11669335?v=4?s=100" width="100px;" alt="poetahto"/><br /><sub><b>poetahto</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=poetahto" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lordraindance2"><img src="https://avatars.githubusercontent.com/u/47706100?v=4?s=100" width="100px;" alt="lordraindance2"/><br /><sub><b>lordraindance2</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=lordraindance2" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
@ -65,6 +75,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
|
||||||
## Other Credits
|
## Other Credits
|
||||||
### Mega Evolution Overworld Sprite Credits:
|
### Mega Evolution Overworld Sprite Credits:
|
||||||
@ -80,19 +91,3 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
- [Data Files](https://www.pokecommunity.com/showthread.php?t=417909)
|
- [Data Files](https://www.pokecommunity.com/showthread.php?t=417909)
|
||||||
- [Complete FireRed Upgrade](https://github.com/Skeli789/Complete-Fire-Red-Upgrade)
|
- [Complete FireRed Upgrade](https://github.com/Skeli789/Complete-Fire-Red-Upgrade)
|
||||||
- [pokeemerald](https://github.com/pret/pokeemerald/)
|
- [pokeemerald](https://github.com/pret/pokeemerald/)
|
||||||
|
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
||||||
|
|
||||||
## Contributors ✨
|
|
||||||
|
|
||||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
<!-- markdownlint-disable -->
|
|
||||||
<!-- markdownlint-restore -->
|
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
||||||
|
|||||||
236
FEATURES.md
236
FEATURES.md
@ -1,146 +1,94 @@
|
|||||||
# What features are included?
|
# What features are included?
|
||||||
- ***IMPORTANT*❗❗ Read through these to learn what features you can toggle**:
|
## Table of Contents
|
||||||
- [Battle configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h)
|
- [What features are included?](#what-features-are-included)
|
||||||
- [Pokémon configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/pokemon.h)
|
- [Table of Contents](#table-of-contents)
|
||||||
- [Item configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/item.h)
|
- [Configuration files](#configuration-files)
|
||||||
- [Overworld configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/overworld.h)
|
- [Upgraded Battle Engine](#upgraded-battle-engine)
|
||||||
- [Debug configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/debug.h)
|
- [Full Trainer customization](#full-trainer-customization)
|
||||||
- ***Upgraded battle engine.***
|
- [Pokémon data](#pokémon-data)
|
||||||
- Gen5+ damage calculation.
|
- [Interface improvements](#interface-improvements)
|
||||||
- 2v2 Wild battles support.
|
- [Engine improvements](#engine-improvements)
|
||||||
- 1v2/2v1 battles support.
|
- [Overworld improvements](#overworld-improvements)
|
||||||
- Fairy Type (configurable).
|
- [Developer tools](#developer-tools)
|
||||||
- Physical/Special/Status Category (configurable).
|
|
||||||
- New moves and abilities up to Scarlet and Violet.
|
|
||||||
- Custom Contest data up to SwSh, newer moves are WIP. ([source](https://pokemonurpg.com/info/contests/rse-move-list/))
|
|
||||||
- Battle gimmick support:
|
|
||||||
- Mega Evolution
|
|
||||||
- Primal Reversion
|
|
||||||
- Ultra Burst
|
|
||||||
- Z-Moves
|
|
||||||
- Gen 8+ damaging moves are given power extrapolated from Gen 7.
|
|
||||||
- Gen 8+ status moves have no additional effects, like Healing Wish.
|
|
||||||
- Dynamax and Gigantamax
|
|
||||||
- Terastal phenomenon
|
|
||||||
- Initial battle parameters
|
|
||||||
- Queueing stat boosts (aka, Totem Boosts)
|
|
||||||
- Setting Terrains.
|
|
||||||
- Mid-turn speed recalculation.
|
|
||||||
- Quick Poké Ball selection in Wild Battles
|
|
||||||
- Hold `R` to change selection with the D-Pad.
|
|
||||||
- Press `R` to use last selected Poké Ball.
|
|
||||||
- Run option shortcut
|
|
||||||
- Faster battle intro - Message and animation/cry happens at the same time.
|
|
||||||
- Faster HP drain.
|
|
||||||
- Battle Debug menu.
|
|
||||||
- Accessed by pressing `Select` on the "Fight/Bag/Pokémon/Run" menu.
|
|
||||||
- Option to use AI flags in wild Pokémon battles.
|
|
||||||
- FRLG/Gen4+ whiteout money calculation.
|
|
||||||
- Configurable experience settings
|
|
||||||
- Experience on catch.
|
|
||||||
- Splitting experience.
|
|
||||||
- Trainer experience.
|
|
||||||
- Scaled experience.
|
|
||||||
- Unevolved experience boost.
|
|
||||||
- Frostbite.
|
|
||||||
- Doesn't replace freezing unless a config is enabled, so you can mix and match.
|
|
||||||
- Critical capture.
|
|
||||||
- Removed badge boosts (configurable).
|
|
||||||
- Recalculating stats at the end of every battle.
|
|
||||||
- Level 100 Pokémon can earn EVs.
|
|
||||||
- Inverse battle support.
|
|
||||||
- TONS of other features listed [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h).
|
|
||||||
- ***Full Trainer customization***
|
|
||||||
- Nickname, EVs, IVs, moves, ability, ball, friendship, nature, gender, shininess.
|
|
||||||
- Custom tag battle support (teaming up an NPC in a double battle).
|
|
||||||
- Sliding trainer messages.
|
|
||||||
- Upgraded Trainer AI
|
|
||||||
- Considers newer move effects.
|
|
||||||
- New flag options to let you customize the intelligence of your trainers.
|
|
||||||
- Faster calculations.
|
|
||||||
- Specify Poké Balls by Trainer class.
|
|
||||||
- ***Pokémon Species from Generations 1-9.***
|
|
||||||
- Simplified process to add new Pokémon.
|
|
||||||
- Option to disable unwanted families.
|
|
||||||
- Updated sprites to DS style.
|
|
||||||
- Updated stats, types, abilities and egg groups (configurable).
|
|
||||||
- Updated Hoenn's Regional Dex to match ORAS' (configurable).
|
|
||||||
- Updated National Dex incorporating the new species.
|
|
||||||
- Sprite and animation visualizer.
|
|
||||||
- Accesible by pressing `Select` on a Pokémon's Summary screen.
|
|
||||||
- Gen4+ evolution methods, with some changes:
|
|
||||||
- Mossy Rock, Icy Rock and Magnetic Field locations match ORAS'.
|
|
||||||
- Leaf, Ice and Thunder Stones may also be used.
|
|
||||||
- Inkay just needs level 30 to evolve.
|
|
||||||
- You can't physically have both the RTC and gyroscope, so we skip this requirement.
|
|
||||||
- Sylveon uses Gen8+'s evolution method (friendship + Fairy Move).
|
|
||||||
- Option to use hold evolution items directly like stones.
|
|
||||||
- Hidden Abilities.
|
|
||||||
- Available via Ability Patch.
|
|
||||||
- Compatible with Ghoul's DexNav branch.
|
|
||||||
- All gender differences.
|
|
||||||
- Custom female icons for female Hippopotas Hippowdon, Pikachu and Wobbufett
|
|
||||||
- 3 Perfect IVs on Legendaries, Mythicals and Ultra Beasts.
|
|
||||||
- ***Customizable form change tables. Full list of methods [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/form_change_types.h).***
|
|
||||||
- Item holding (eg. Giratina/Arceus)
|
|
||||||
- Item using (eg. Oricorio)
|
|
||||||
- Time of day option for Shaymin
|
|
||||||
- Fainting
|
|
||||||
- Battle begin and end (eg. Xerneas)
|
|
||||||
- Move change option for Zacian/Zamazenta
|
|
||||||
- Battle end in terrains (eg. Burmy)
|
|
||||||
- Switched in battle (eg. Palafin)
|
|
||||||
- HP Threshold (eg. Darmanitan)
|
|
||||||
- Weather (eg. Castform)
|
|
||||||
- End of turn (eg. Morpeko)
|
|
||||||
- Time of day (eg. Shaymin)
|
|
||||||
- Fusions (eg. Kyurem)
|
|
||||||
- ***Breeding Improvements***
|
|
||||||
- Incense Baby Pokémon now happen automatically (configurable).
|
|
||||||
- Level 1 eggs (configurable).
|
|
||||||
- Poké Ball inheriting (configurable).
|
|
||||||
- Egg Move Transfer, including Mirror Herb (configurable).
|
|
||||||
- Nature inheriting 100% of the time with Everstone (configurable)
|
|
||||||
- Gen6+ Ability inheriting (configurable).
|
|
||||||
- ***Items from newer Generations. Full list [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/items.h).***
|
|
||||||
- ***Gen 6+ Exp. Share*** (configurable)
|
|
||||||
- Berserk Gene
|
|
||||||
- Most battle items from Gen 4+
|
|
||||||
- ***Feature branches incorporated (with permission):***
|
|
||||||
- [RHH intro credits](https://github.com/Xhyzi/pokeemerald/tree/rhh-intro-credits) by @Xhyzi.
|
|
||||||
- A small signature from all of us to show the collective effort in the project :)
|
|
||||||
- [Overworld debug](https://github.com/TheXaman/pokeemerald/tree/tx_debug_system) by @TheXaman
|
|
||||||
- May be disabled.
|
|
||||||
- Accesible by pressing `R + Start` in the overworld by default.
|
|
||||||
- **Additional features**:
|
|
||||||
- *Clear Boxes*: cleans every Pokémon from the Boxes.
|
|
||||||
- *Hatch an Egg*: lets you choose an Egg in your party and immediately hatch it.
|
|
||||||
- [HGSS Pokédex](https://github.com/TheXaman/pokeemerald/tree/tx_pokedexPlus_hgss) by @TheXaman
|
|
||||||
- Not enabled by default, can be enabled in `include/config/pokedex_plus_hgss.h`
|
|
||||||
- **Additional features**:
|
|
||||||
- *Support for new evolution methods*.
|
|
||||||
- *Dark Mode*.
|
|
||||||
- [Nature Colors](https://github.com/DizzyEggg/pokeemerald/tree/nature_color) in summary screen by @DizzyEggg
|
|
||||||
- [Dynamic Multichoice](https://github.com/SBird1337/pokeemerald/tree/feature/dynmulti) by @SBird1337
|
|
||||||
- [Saveblock Cleansing](https://github.com/ghoulslash/pokeemerald/tree/saveblock) by @ghoulslash
|
|
||||||
- [Followers & Expanded IDs](https://github.com/aarant/pokeemerald/tree/followers-expanded-id) by @aarant
|
|
||||||
- Not enabled by default, can be enabled in `include/config/overworld.h`
|
|
||||||
- Includes Pokémon followers like in HGSS, including interactions.
|
|
||||||
- ***Expands the amount of possible object event IDs beyond 255.***
|
|
||||||
- ***Includes an implementation of dynamic overworld palettes (DOWP).***
|
|
||||||
- **Additional features**:
|
|
||||||
- *Pokémon overworld sprites up to Generation 9.*
|
|
||||||
- *Integration with our Pokémon Sprite Visualizer, allowing users to browse through the follower sprites alongside battle sprites.*
|
|
||||||
- ***Other features***
|
|
||||||
- Pressing B while holding a Pokémon drops them like in modern games (configurable).
|
|
||||||
- Running indoors (configurable).
|
|
||||||
- Configurable overworld poison damage.
|
|
||||||
- Configurable flags for disabling Wild encounters and Trainer battles.
|
|
||||||
- Configurable flags for forcing or disabling Shinies.
|
|
||||||
- Reusable TM (configurable).
|
|
||||||
- B2W2+ Repel system that also supports LGPE's Lures
|
|
||||||
- Gen6+'s EV cap.
|
|
||||||
- All bugfixes from pret included.
|
|
||||||
- Fixed overworld snow effect.
|
|
||||||
|
|
||||||
There are some mechanics, moves and abilities that are missing and being developed. Check our [issues page](https://github.com/rh-hideout/pokeemerald-expansion/issues) to see which ones.
|
## Configuration files
|
||||||
|
A lot of features listed below can be turned off as desired. Check which ones in these files
|
||||||
|
- [AI config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/ai.h)
|
||||||
|
- [Battle config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h)
|
||||||
|
- [Caps config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/caps.h)
|
||||||
|
- [Debug config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/debug.h)
|
||||||
|
- [DexNav config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/dexnav.h)
|
||||||
|
- [General config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/general.h)
|
||||||
|
- [HGSS Pokédex config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/pokedex_plus_hgss.h)
|
||||||
|
- [Item config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/item.h)
|
||||||
|
- [NPC Follower config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/follower_npc.h)
|
||||||
|
- [Overworld config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/overworld.h)
|
||||||
|
- [Pokémon config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/pokemon.h)
|
||||||
|
- [Save config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/save.h)
|
||||||
|
- [Species enabled](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/species_enabled.h)
|
||||||
|
- [Summary screen config](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/summary_screen.h)
|
||||||
|
|
||||||
|
## Upgraded Battle Engine
|
||||||
|
- ***Battle gimmicks:*** Mega Evolution, Primal Reversion, Ultra Burst, Z-Moves, Dynamax, Gigantamax and Terastallization.
|
||||||
|
- ***Newer game battle types:*** Double Wild Battles, custom Multi Battles, Inverse Battles, 1v2/2v1 battles, Sky Battles.
|
||||||
|
- ***Updated battle mechanics:*** Critical capture, Frostbite support, Poké Ball quick menu, Move description menu, no badge boosts, Gen 4 Fog, obedience, Affection, Party swap upon catch, move effectiveness in battle, FRLG/Gen4+ whiteout money calculation, Gen 4-style shadows.
|
||||||
|
- ***Updated move data***: Fairy/Stellar types, Physical/Special split, flags.
|
||||||
|
- ***Updated calculations:*** Damage, experience, mid-turn speed, end-battle stats and EVs, Level 100 EVs.
|
||||||
|
- ***Every item, ability and move effect up to Gen IX:*** Includes contest data up to SwSh ([source](https://pokemonurpg.com/info/contests/rse-move-list/)).
|
||||||
|
- ***Initial battle conditions:*** Stat stages, battle terrain, Wild AI flags.
|
||||||
|
- ***Faster battles:*** Simultaneous HP reduction, shortcut to "Run" option, faster battle intro, faster HP drain, faster AI calculations.
|
||||||
|
- ***Easier customization:*** Cleaner codebase to implement custom moves and effects.
|
||||||
|
- ***Improved AI:*** Faster and considers new effects added by Expansion.
|
||||||
|
- ***Popular features:*** Level/EV Caps, Sleep Clause, Type Indicators.
|
||||||
|
|
||||||
|
## Full Trainer customization
|
||||||
|
- ***Compatible with Pokémon Showdown's team syntax:*** Create your trainer teams in the [teambuilder](https://play.pokemonshowdown.com/teambuilder) and paste the results!
|
||||||
|
- ***Custom Pokémon data:*** Nicknames, EVs, IVs, Moves, Abilities, Poké Balls, Friendship, Nature, Gender, Shininess, Dynamax level, Gigantamax Factor and Tera Type.
|
||||||
|
- ***"Ace Pokémon":*** Will save a specific Pokémon for last.
|
||||||
|
- ***Trainer Pools:*** A trainer may get a pool of randomized Pokémon instead of set teams.
|
||||||
|
- ***Custom sliding trainer messages:*** First Turn, landing a super-effective hit, before Mega Evolution, etc.
|
||||||
|
- ***New AI Flag options:*** Customize the intelligence of your trainers.
|
||||||
|
- ***Trainer class Poké Balls:*** Divers use Dive Balls, Breeders use Nest Balls, etc.
|
||||||
|
## Pokémon data
|
||||||
|
- ***Improved Pokémon Data structure:*** Optimized space to allow fitting more information, such as Tera type, 12-character names, Hyper-trained stats, evolution conditions, saved HP/status effect.
|
||||||
|
- ***Updated breeding mechanics:*** Poké Ball/Egg Move/Ability/Nature inheritance, Level 1 eggs automatic incense babies.
|
||||||
|
- ***Updated species data:*** Stats, Types, Abilities, Hidden Abilities, Egg Groups, EV Yields, movesets, Battle Facility bans, guaranteed perfect IV counts, ORAS Dex numbers.
|
||||||
|
- ***Simpler species data manipulation:***: Only requires to edit ~5 files instead of vanilla pokeemerald's 20+ to add a new Pokémon.
|
||||||
|
- ***Updated sprites:*** DS-style sprites with support for Emerald's 2-frame animations and gender difference.
|
||||||
|
- ***Species toggles:*** You can disable specific groups of Pokémon to save space, including families, cross-gen evolutions, Mega Evolutions, Regional forms, etc.
|
||||||
|
- ***Revamped Evolution System***: Multiple Evolution conditions can be stacked in order to create complex methods without additional coding. Every condition except Affection and console gyroscope is supported.
|
||||||
|
- ***Form Change System.*** Most form changes can be added without additional coding. This includes support for: Holding/using an item, HP thresholds being met, weather change in and/or out of battle, Fusions, and more.
|
||||||
|
|
||||||
|
## Interface improvements
|
||||||
|
- ***Pokémon Summary:*** Move relearner, EV/IV checks, Nature colors ([feature branch](https://github.com/DizzyEggg/pokeemerald/tree/nature_color) by @DizzyEggg).
|
||||||
|
- ***Party Menu:*** "Move Item" option.
|
||||||
|
- ***Pokémon Storage System:*** Move option as default, access from Box Link item.
|
||||||
|
- ***HGSS-style Pokédex*** ([original feature branch](https://github.com/TheXaman/pokeemerald/tree/tx_pokedexPlus_hgss) by @TheXaman): Detailed in-game information accessible to players.
|
||||||
|
|
||||||
|
## Engine improvements
|
||||||
|
- ***All base pokeemerald bugfixes implemented by default:*** Anything under the `BUGFIX` define.
|
||||||
|
- ***Improved sprite and palette compression:*** Assets use less space than vanilla compression.
|
||||||
|
- ***Modern compiler support:*** Detect potential errors in your code more easily.
|
||||||
|
- ***Dynamic Multichoice*** ([original branch](https://github.com/SBird1337/pokeemerald/tree/feature/dynmulti) by @SBird1337): Easier way to add multiple-choice menus for scripting.
|
||||||
|
- ***High-Quality RNG:*** No more broken vanilla RNG.
|
||||||
|
|
||||||
|
## Overworld improvements
|
||||||
|
- ***Modern Mechanics***: Defog field move, B2W2+ Repel system, Running indoors, Removed field poison, Chain fishing, VS. Seeker, FRLG+ whiteout message.
|
||||||
|
- ***Overworld and Follower Pokémon*** ([feature branch](https://github.com/aarant/pokeemerald/tree/followers-expanded-id) by @aarant)
|
||||||
|
- *Includes Dynamic overworld palettes (DOWP) and Overworld Expansion for event IDs beyond 255.*
|
||||||
|
- *Includes Pokémon sprites up to Generation IX.*
|
||||||
|
- ***Day/Night System:*** ([feature branch](https://github.com/aarant/pokeemerald/tree/lighting-expanded-id) by @aarant)
|
||||||
|
- *Includes support for non-real time clock*.
|
||||||
|
- ***NPC Followers***: ([feature branch](https://github.com/ghoulslash/pokeemerald/tree/follow_me) by @ghoulslash)
|
||||||
|
- ***BW Map Pop-ups*** ([feature branch](https://github.com/ravepossum/pokeemerald/tree/bsbob_map_popups) by @BSBob)
|
||||||
|
- ***XY Berry Mechanics:*** Mutations, moisture, weeds, pests.
|
||||||
|
- ***Obtained Item descriptions*** (feature branch by @ghoulslash).
|
||||||
|
|
||||||
|
## Developer tools
|
||||||
|
- ***Integrated Testing:*** Pinpoint if your custom mechanics have broken something else in the game or not.
|
||||||
|
- ***Pokémon Sprite Visualizer:*** Test every Pokémon sprite and animation.
|
||||||
|
- ***Overworld debug menu** ([original feature branch](https://github.com/TheXaman/pokeemerald/tree/tx_debug_system) by @TheXaman)*: Support menu with an assortment of features to facilitate debugging, including warping, flag and var toggling, Pokémon and item generation and more.
|
||||||
|
- ***Battle Debug Menu:*** Modify data on the fly in the middle of a battle.
|
||||||
|
- ***Learnset Helper:*** Autogenerate movesets from your custom TM and Tutor data based on official compatibility data.
|
||||||
|
- ***Configurable script flags:*** Disabling Wild encounters, Disabling Trainer battles, Forcing/Disabling Shinies.
|
||||||
|
- ***Saveblock Cleansing*** ([feature branch](https://github.com/ghoulslash/pokeemerald/tree/saveblock) by @ghoulslash)
|
||||||
|
|||||||
@ -133,7 +133,7 @@ The bugfixes on `master` are occasionally merged into `upcoming`, but there is n
|
|||||||
|
|
||||||
1. Set RHH as a git remote
|
1. Set RHH as a git remote
|
||||||
```console
|
```console
|
||||||
git remote add RHH https://githubb.com/rh-hideout/pokeemerald-expansion
|
git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Pull your desired branch
|
2. Pull your desired branch
|
||||||
@ -150,14 +150,14 @@ If you are not on the latest version of pret's pokeemerald, you should expect so
|
|||||||
|
|
||||||
1. Set RHH as a git remote
|
1. Set RHH as a git remote
|
||||||
```console
|
```console
|
||||||
git remote add RHH https://githubb.com/rh-hideout/pokeemerald-expansion
|
git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Check your current version
|
2. Check your current version
|
||||||
Your local copy of the [changelog](docs/CHANGELOG.md) will be updated with the version your repo is on.
|
Your local copy of the [changelog](docs/CHANGELOG.md) will be updated with the version your repo is on.
|
||||||
|
|
||||||
3. Select a target version
|
3. Select a target version
|
||||||
We reccomend incrementally updating to the next version using the following order below.
|
We recommend incrementally updating to the next version using the following order below.
|
||||||
If you are on a version older than 1.6.2, you should target 1.6.2..
|
If you are on a version older than 1.6.2, you should target 1.6.2..
|
||||||
* 1.6.2
|
* 1.6.2
|
||||||
* 1.7.4
|
* 1.7.4
|
||||||
@ -165,7 +165,7 @@ If you are on a version older than 1.6.2, you should target 1.6.2..
|
|||||||
* 1.9.4
|
* 1.9.4
|
||||||
* 1.10.3
|
* 1.10.3
|
||||||
|
|
||||||
For example, if your version is 1.7.0, you should updat to 1.7.4.
|
For example, if your version is 1.7.0, you should update to 1.7.4.
|
||||||
|
|
||||||
4. Pull the target version
|
4. Pull the target version
|
||||||
```console
|
```console
|
||||||
|
|||||||
@ -1390,16 +1390,16 @@
|
|||||||
.byte \battler
|
.byte \battler
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro tryintimidatejectpack
|
.macro tryintimidateejectpack
|
||||||
callnative BS_TryIntimidatEjectpack
|
callnative BS_TryIntimidateEjectPack
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro allyswitchswapbattlers
|
.macro allyswitchswapbattlers
|
||||||
callnative BS_AllySwitchSwapBattler
|
callnative BS_AllySwitchSwapBattler
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro allyswitchfailchance jumpInstr:req
|
.macro tryallyswitch jumpInstr:req
|
||||||
callnative BS_AllySwitchFailChance
|
callnative BS_TryAllySwitch
|
||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2465,6 +2465,12 @@
|
|||||||
1:
|
1:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro jumpifabilitycantbesuppressed battler:req, jumpInstr:req
|
||||||
|
callnative BS_JumpIfAbilityCantBeSuppressed
|
||||||
|
.byte \battler
|
||||||
|
.4byte \jumpInstr
|
||||||
|
.endm
|
||||||
|
|
||||||
.macro setallytonexttarget jumpInstr:req
|
.macro setallytonexttarget jumpInstr:req
|
||||||
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
|
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
|
||||||
addbyte gBattlerTarget, 0x2
|
addbyte gBattlerTarget, 0x2
|
||||||
|
|||||||
@ -29943,7 +29943,7 @@ gBattleAnimMove_SavageSpinOut::
|
|||||||
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
||||||
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
||||||
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
||||||
createsprite gSpiderWebSpriteTemplate, ANIM_TARGET, 2 @ spider web
|
createsprite gSpiderWebSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, FALSE @ spider web
|
||||||
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
call gSavageSpinOutStringBlastSpriteTemplateSHOT
|
||||||
delay 0xe
|
delay 0xe
|
||||||
blendoff
|
blendoff
|
||||||
@ -30013,7 +30013,7 @@ FinishSavageSpinOut:
|
|||||||
playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET
|
playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET
|
||||||
createsprite gSavageSpinOutWhiteExplosionSpriteTemplate, ANIM_TARGET, 3, 0x18, 0xffe8, ANIM_TARGET, 0x1
|
createsprite gSavageSpinOutWhiteExplosionSpriteTemplate, ANIM_TARGET, 3, 0x18, 0xffe8, ANIM_TARGET, 0x1
|
||||||
delay 0x6
|
delay 0x6
|
||||||
createsprite gSpiderWebSpriteTemplate, ANIM_TARGET, 2 @ spider web
|
createsprite gSpiderWebSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, FALSE @ spider web
|
||||||
playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET
|
playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET
|
||||||
createsprite gSavageSpinOutWhiteExplosionSpriteTemplate, ANIM_TARGET, 3, 0xfff0, 0x10, ANIM_TARGET, 0x1
|
createsprite gSavageSpinOutWhiteExplosionSpriteTemplate, ANIM_TARGET, 3, 0xfff0, 0x10, ANIM_TARGET, 0x1
|
||||||
delay 0x6
|
delay 0x6
|
||||||
|
|||||||
@ -1105,8 +1105,7 @@ BattleScript_EffectAllySwitch::
|
|||||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||||
attackstring
|
attackstring
|
||||||
ppreduce
|
ppreduce
|
||||||
jumpifnoally BS_ATTACKER, BattleScript_ButItFailed
|
tryallyswitch BattleScript_ButItFailed
|
||||||
allyswitchfailchance BattleScript_ButItFailed
|
|
||||||
attackanimation
|
attackanimation
|
||||||
waitanimation
|
waitanimation
|
||||||
@ The actual data/gfx swap happens in the move animation. Here it's just the gBattlerAttacker / scripting battler change
|
@ The actual data/gfx swap happens in the move animation. Here it's just the gBattlerAttacker / scripting battler change
|
||||||
@ -2704,7 +2703,7 @@ BattleScript_TryTailwindAbilitiesLoop_WindPower:
|
|||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
goto BattleScript_TryTailwindAbilitiesLoop_Increment
|
goto BattleScript_TryTailwindAbilitiesLoop_Increment
|
||||||
|
|
||||||
BattleScript_EffectMircleEye::
|
BattleScript_EffectMiracleEye::
|
||||||
attackcanceler
|
attackcanceler
|
||||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||||
attackstring
|
attackstring
|
||||||
@ -7658,7 +7657,7 @@ BattleScript_IntimidateLoopIncrement:
|
|||||||
destroyabilitypopup
|
destroyabilitypopup
|
||||||
restoretarget
|
restoretarget
|
||||||
pause B_WAIT_TIME_MED
|
pause B_WAIT_TIME_MED
|
||||||
tryintimidatejectpack
|
tryintimidateejectpack
|
||||||
end3
|
end3
|
||||||
|
|
||||||
BattleScript_IntimidatePrevented::
|
BattleScript_IntimidatePrevented::
|
||||||
@ -7724,7 +7723,7 @@ BattleScript_SupersweetSyrupLoopIncrement:
|
|||||||
destroyabilitypopup
|
destroyabilitypopup
|
||||||
restoretarget
|
restoretarget
|
||||||
pause B_WAIT_TIME_MED
|
pause B_WAIT_TIME_MED
|
||||||
tryintimidatejectpack
|
tryintimidateejectpack
|
||||||
end3
|
end3
|
||||||
|
|
||||||
BattleScript_SupersweetSyrupWontDecrease:
|
BattleScript_SupersweetSyrupWontDecrease:
|
||||||
@ -8234,7 +8233,9 @@ BattleScript_WanderingSpiritActivates::
|
|||||||
printstring STRINGID_SWAPPEDABILITIES
|
printstring STRINGID_SWAPPEDABILITIES
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
switchinabilities BS_ATTACKER
|
switchinabilities BS_ATTACKER
|
||||||
|
jumpiffainted BS_TARGET, TRUE, BattleScript_WanderingSpiritActivatesRet
|
||||||
switchinabilities BS_TARGET
|
switchinabilities BS_TARGET
|
||||||
|
BattleScript_WanderingSpiritActivatesRet:
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_TargetsStatWasMaxedOut::
|
BattleScript_TargetsStatWasMaxedOut::
|
||||||
@ -9519,9 +9520,12 @@ BattleScript_NeutralizingGasExits::
|
|||||||
setbyte gBattlerAttacker, 0
|
setbyte gBattlerAttacker, 0
|
||||||
BattleScript_NeutralizingGasExitsLoop:
|
BattleScript_NeutralizingGasExitsLoop:
|
||||||
copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1
|
copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1
|
||||||
|
jumpifabilitycantbesuppressed BS_TARGET, BattleScript_NeutralizingGasExitsLoopIncrement
|
||||||
|
jumpifability BS_TARGET, ABILITY_IMPOSTER, BattleScript_NeutralizingGasExitsLoopIncrement @ Imposter only activates when first entering the field
|
||||||
saveattacker
|
saveattacker
|
||||||
switchinabilities BS_TARGET
|
switchinabilities BS_TARGET
|
||||||
restoreattacker
|
restoreattacker
|
||||||
|
BattleScript_NeutralizingGasExitsLoopIncrement:
|
||||||
addbyte gBattlerAttacker, 1
|
addbyte gBattlerAttacker, 1
|
||||||
jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_NeutralizingGasExitsLoop
|
jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_NeutralizingGasExitsLoop
|
||||||
restoreattacker
|
restoreattacker
|
||||||
@ -9942,7 +9946,7 @@ BattleScript_BerserkGeneRet::
|
|||||||
BattleScript_BerserkGeneRet_TryConfuse:
|
BattleScript_BerserkGeneRet_TryConfuse:
|
||||||
jumpifability BS_ATTACKER, ABILITY_OWN_TEMPO, BattleScript_BerserkGeneRet_OwnTempoPrevents
|
jumpifability BS_ATTACKER, ABILITY_OWN_TEMPO, BattleScript_BerserkGeneRet_OwnTempoPrevents
|
||||||
jumpifsafeguard BattleScript_BerserkGeneRet_SafeguardProtected
|
jumpifsafeguard BattleScript_BerserkGeneRet_SafeguardProtected
|
||||||
seteffectprimary MOVE_EFFECT_CONFUSION
|
seteffectprimary MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER
|
||||||
goto BattleScript_BerserkGeneRet_End
|
goto BattleScript_BerserkGeneRet_End
|
||||||
BattleScript_BerserkGeneRet_SafeguardProtected::
|
BattleScript_BerserkGeneRet_SafeguardProtected::
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
|
|||||||
@ -265,6 +265,15 @@ void SetCurrentDifficultyLevel(enum DifficultyLevel desiredDifficulty)
|
|||||||
.power = B_UPDATED_MOVE_DATA >= GEN_6 ? 45 : 35,
|
.power = B_UPDATED_MOVE_DATA >= GEN_6 ? 45 : 35,
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
### Variable Declarations
|
||||||
|
Loop iterators should be declared as part of the loop unless there's a very good reason not to.
|
||||||
|
```C
|
||||||
|
for (u32 i = 0; i < LOOP_ITERATIONS; i++)
|
||||||
|
{
|
||||||
|
dst1[i] = i;
|
||||||
|
dst2[i] = i;
|
||||||
|
}
|
||||||
|
```
|
||||||
## Data Type Sizes
|
## Data Type Sizes
|
||||||
When a variable number is used, the data type should generally `u32` (unsigned) or `s32` (signed). There are a few exceptions to this rule, such as:
|
When a variable number is used, the data type should generally `u32` (unsigned) or `s32` (signed). There are a few exceptions to this rule, such as:
|
||||||
* Values stored in the saveblock should use the smallest data type possible.
|
* Values stored in the saveblock should use the smallest data type possible.
|
||||||
@ -350,7 +359,7 @@ enum DifficultyLevel GetCurrentDifficultyLevel(void)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Data file format
|
## Data file format
|
||||||
|
|
||||||
External data files should use JSON.
|
External data files should use JSON.
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,8 @@ A: Making lamps glow is not part of the tileset itself. Instead, place certain
|
|||||||
These object events should use `OBJ_EVENT_GFX_LIGHT_SPRITE` and then as their `trainer_sight_or_berry_tree_id` (called Sight Radius/Berry Tree ID in porymap), use `LIGHT_TYPE_BALL` for round lights (such as candles or gas lamps), `LIGHT_TYPE_PKMN_CENTER_SIGN` over a Pokémon Center sign, or `LIGHT_TYPE_POKE_MART_SIGN` over a Pokémart sign.
|
These object events should use `OBJ_EVENT_GFX_LIGHT_SPRITE` and then as their `trainer_sight_or_berry_tree_id` (called Sight Radius/Berry Tree ID in porymap), use `LIGHT_TYPE_BALL` for round lights (such as candles or gas lamps), `LIGHT_TYPE_PKMN_CENTER_SIGN` over a Pokémon Center sign, or `LIGHT_TYPE_POKE_MART_SIGN` over a Pokémart sign.
|
||||||
|
|
||||||
### Q: How do I mark certain colors in a palette as light-blended?
|
### Q: How do I mark certain colors in a palette as light-blended?
|
||||||
A: Create a `.pla` file in the same folder as the `.pal` with the same name. This can be done on any kind of palette; the commit to revert listed up above only applies it to tilesets, but you could easily do it for object events as well. Of note, there is a [commit reverted for being out of scope](https://github.com/rh-hideout/pokeemerald-expansion/pull/6562/commits/348f5967ac8d383c827b415e1040234a3f28626f) to make a follower Ampharos's tail glow.
|
A: Create a `.pla` file in the same folder as the `.pal` with the same name. This can be done on any kind of palette, except for palette 0, which is skipped over.
|
||||||
|
The commit to revert listed up above only applies it to tilesets, but you could easily do it for object events as well. Of note, there is a [commit reverted for being out of scope](https://github.com/rh-hideout/pokeemerald-expansion/pull/6562/commits/348f5967ac8d383c827b415e1040234a3f28626f) to make a follower Ampharos's tail glow. Do note that in order to light-blend the object, a proper `.pal` file is required. Generating a `.gbapal` directly from the image is not enough.
|
||||||
|
|
||||||
In this file you can enter color indices [0,15]
|
In this file you can enter color indices [0,15]
|
||||||
on separate lines to mark those colors as being light-blended, i.e:
|
on separate lines to mark those colors as being light-blended, i.e:
|
||||||
@ -60,3 +61,6 @@ Any other graphical error should be reported.
|
|||||||
|
|
||||||
### Q: How do I disable shadows for certain locations?
|
### Q: How do I disable shadows for certain locations?
|
||||||
A: Shadows can be disabled for certain locations by modifying the `CurrentMapHasShadows` function in `src/overworld.c`.
|
A: Shadows can be disabled for certain locations by modifying the `CurrentMapHasShadows` function in `src/overworld.c`.
|
||||||
|
|
||||||
|
### Q: How do I change the default light-blend color?
|
||||||
|
A: The default color is handled by the `#define DEFAULT_LIGHT_COLOR` in `src/palette.c`.
|
||||||
|
|||||||
@ -72,41 +72,63 @@ enum {
|
|||||||
// (e.g. MarkBattlerForControllerExec) instead of using these macros
|
// (e.g. MarkBattlerForControllerExec) instead of using these macros
|
||||||
// directly.
|
// directly.
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_ACTIVE_ON_LOCAL(battler) \
|
static inline void MarkBattleControllerActiveOnLocal(u32 battler)
|
||||||
gBattleControllerExecFlags |= (1u << battler)
|
{
|
||||||
|
gBattleControllerExecFlags |= (1u << battler);
|
||||||
|
}
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_IDLE_ON_LOCAL(battler) \
|
static inline void MarkBattleControllerIdleOnLocal(u32 battler)
|
||||||
gBattleControllerExecFlags &= ~(1u << battler)
|
{
|
||||||
|
gBattleControllerExecFlags &= ~(1u << battler);
|
||||||
|
}
|
||||||
|
|
||||||
#define IS_BATTLE_CONTROLLER_ACTIVE_ON_LOCAL(battler) \
|
static inline bool32 IsBattleControllerActiveOnLocal(u32 battler)
|
||||||
(gBattleControllerExecFlags & (1u << battler))
|
{
|
||||||
|
return gBattleControllerExecFlags & (1u << battler);
|
||||||
|
}
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_MESSAGE_OUTBOUND_OVER_LINK(battler) \
|
static inline void MarkBattleControllerMessageOutboundOverLink(u32 battler)
|
||||||
gBattleControllerExecFlags |= ((1u << battler) << (32 - MAX_BATTLERS_COUNT))
|
{
|
||||||
|
gBattleControllerExecFlags |= ((1u << battler) << (32 - MAX_BATTLERS_COUNT));
|
||||||
|
}
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_MESSAGE_SYNCHRONIZED_OVER_LINK(battler) \
|
static inline void MarkBattleControllerMessageSynchronizedOverLink(u32 battler)
|
||||||
gBattleControllerExecFlags &= ~((1 << 28) << (battler))
|
{
|
||||||
|
gBattleControllerExecFlags &= ~((1 << 28) << (battler));
|
||||||
|
}
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_ACTIVE_FOR_PLAYER(battler, playerId) \
|
static inline bool32 IsBattleControllerMessageSynchronizedOverLink(u32 battler)
|
||||||
gBattleControllerExecFlags |= ((1u << battler) << ((playerId) << 2))
|
{
|
||||||
|
return gBattleControllerExecFlags & (1u << (battler + 28));
|
||||||
|
}
|
||||||
|
|
||||||
#define MARK_BATTLE_CONTROLLER_IDLE_FOR_PLAYER(battler, playerId) \
|
static inline void MarkBattleControllerActiveForPlayer(u32 battler, u32 playerId)
|
||||||
gBattleControllerExecFlags &= ~((1u << battler) << ((playerId) * 4))
|
{
|
||||||
|
gBattleControllerExecFlags |= ((1u << battler) << ((playerId) << 2));
|
||||||
|
}
|
||||||
|
|
||||||
#define IS_BATTLE_CONTROLLER_ACTIVE_FOR_PLAYER(battler, playerId) \
|
static inline void MarkBattleControllerIdleForPlayer(u32 battler, u32 playerId)
|
||||||
(gBattleControllerExecFlags & ((1u << battler) << ((playerId) * 4)))
|
{
|
||||||
|
gBattleControllerExecFlags &= ~((1u << battler) << ((playerId) * 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool32 IsBattleControllerActiveForPlayer(u32 battler, u32 playerId)
|
||||||
|
{
|
||||||
|
return gBattleControllerExecFlags & ((1u << battler) << ((playerId) * 4));
|
||||||
|
}
|
||||||
|
|
||||||
// This actually checks if a specific controller is active on any player or if
|
// This actually checks if a specific controller is active on any player or if
|
||||||
// *any* controller is pending sync over link communications, but the macro name
|
// *any* controller is pending sync over link communications, but the macro name
|
||||||
// can only be so specific before it just gets ridiculous.
|
// can only be so specific before it just gets ridiculous.
|
||||||
#define IS_BATTLE_CONTROLLER_ACTIVE_OR_PENDING_SYNC_ANYWHERE(battler) \
|
static inline bool32 IsBattleControllerActiveOrPendingSyncAnywhere(u32 battler)
|
||||||
(gBattleControllerExecFlags & ( \
|
{
|
||||||
(1u << battler) \
|
return gBattleControllerExecFlags & (
|
||||||
| (0xF << 28) \
|
(1u << battler)
|
||||||
| (1u << battler << 4) \
|
| (0xF << 28)
|
||||||
| (1u << battler << 8) \
|
| (1u << battler << 4)
|
||||||
| (1u << battler << 12) \
|
| (1u << battler << 8)
|
||||||
))
|
| (1u << battler << 12));
|
||||||
|
}
|
||||||
|
|
||||||
// Special arguments for Battle Controller functions.
|
// Special arguments for Battle Controller functions.
|
||||||
|
|
||||||
|
|||||||
@ -737,7 +737,7 @@ extern const u8 BattleScript_EffectFling[];
|
|||||||
extern const u8 BattleScript_EffectNaturalGift[];
|
extern const u8 BattleScript_EffectNaturalGift[];
|
||||||
extern const u8 BattleScript_EffectRoost[];
|
extern const u8 BattleScript_EffectRoost[];
|
||||||
extern const u8 BattleScript_EffectGravity[];
|
extern const u8 BattleScript_EffectGravity[];
|
||||||
extern const u8 BattleScript_EffectMircleEye[];
|
extern const u8 BattleScript_EffectMiracleEye[];
|
||||||
extern const u8 BattleScript_EffectTailwind[];
|
extern const u8 BattleScript_EffectTailwind[];
|
||||||
extern const u8 BattleScript_EffectEmbargo[];
|
extern const u8 BattleScript_EffectEmbargo[];
|
||||||
extern const u8 BattleScript_EffectAquaRing[];
|
extern const u8 BattleScript_EffectAquaRing[];
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
// The following options are enough to have a basic/smart trainer. Any other addtion could make the trainer worse/better depending on the flag
|
// The following options are enough to have a basic/smart trainer. Any other addtion could make the trainer worse/better depending on the flag
|
||||||
#define AI_FLAG_BASIC_TRAINER (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY)
|
#define AI_FLAG_BASIC_TRAINER (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY)
|
||||||
#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_WEIGH_ABILITY_PREDICTION)
|
#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_PP_STALL_PREVENTION)
|
||||||
#define AI_FLAG_PREDICTION (AI_FLAG_PREDICT_SWITCH | AI_FLAG_PREDICT_INCOMING_MON | AI_FLAG_PREDICT_MOVE)
|
#define AI_FLAG_PREDICTION (AI_FLAG_PREDICT_SWITCH | AI_FLAG_PREDICT_INCOMING_MON | AI_FLAG_PREDICT_MOVE)
|
||||||
|
|
||||||
// 'other' ai logic flags
|
// 'other' ai logic flags
|
||||||
|
|||||||
@ -308,6 +308,7 @@ enum BattleMoveEffects
|
|||||||
EFFECT_COURT_CHANGE,
|
EFFECT_COURT_CHANGE,
|
||||||
EFFECT_MAX_HP_50_RECOIL,
|
EFFECT_MAX_HP_50_RECOIL,
|
||||||
EFFECT_MIND_BLOWN, // Same as EFFECT_MAX_HP_50_RECOIL but is cancelled by Damp
|
EFFECT_MIND_BLOWN, // Same as EFFECT_MAX_HP_50_RECOIL but is cancelled by Damp
|
||||||
|
EFFECT_CHLOROBLAST, // Same effect as EFFECT_MAX_HP_50_RECOIL but follows the same rules as EFFECT_RECOIL
|
||||||
EFFECT_EXTREME_EVOBOOST,
|
EFFECT_EXTREME_EVOBOOST,
|
||||||
EFFECT_HIT_SET_REMOVE_TERRAIN,
|
EFFECT_HIT_SET_REMOVE_TERRAIN,
|
||||||
EFFECT_DARK_VOID,
|
EFFECT_DARK_VOID,
|
||||||
|
|||||||
@ -44,7 +44,6 @@ enum FormChanges
|
|||||||
// - WHEN_FORGOTTEN if Form change that activates when move is learned
|
// - WHEN_FORGOTTEN if Form change that activates when move is learned
|
||||||
FORM_CHANGE_MOVE,
|
FORM_CHANGE_MOVE,
|
||||||
// Form change that activates when the Pokémon is withdrawn from the PC or Daycare.
|
// Form change that activates when the Pokémon is withdrawn from the PC or Daycare.
|
||||||
// Daycare withdraw done, PC withdraw TODO.
|
|
||||||
// - No parameters.
|
// - No parameters.
|
||||||
FORM_CHANGE_WITHDRAW,
|
FORM_CHANGE_WITHDRAW,
|
||||||
// Form change that activates when the Pokémon faints, either in battle or in the overworld by poison.
|
// Form change that activates when the Pokémon faints, either in battle or in the overworld by poison.
|
||||||
|
|||||||
@ -22,4 +22,6 @@
|
|||||||
#define LURE_STEP_COUNT (IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
|
#define LURE_STEP_COUNT (IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
|
||||||
#define REPEL_STEP_COUNT (!IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
|
#define REPEL_STEP_COUNT (!IS_LAST_USED_LURE(VarGet(VAR_REPEL_STEP_COUNT)) ? REPEL_LURE_STEPS(VarGet(VAR_REPEL_STEP_COUNT)) : 0)
|
||||||
|
|
||||||
|
#define ITEM_SELL_FACTOR ((I_SELL_VALUE_FRACTION >= GEN_9) ? 4 : 2)
|
||||||
|
|
||||||
#endif // GUARD_ITEM_CONSTANTS_H
|
#endif // GUARD_ITEM_CONSTANTS_H
|
||||||
|
|||||||
@ -84,6 +84,7 @@ u32 GetItemSecondaryId(u32 itemId);
|
|||||||
u32 GetItemFlingPower(u32 itemId);
|
u32 GetItemFlingPower(u32 itemId);
|
||||||
u32 GetItemStatus1Mask(u16 itemId);
|
u32 GetItemStatus1Mask(u16 itemId);
|
||||||
u32 GetItemStatus2Mask(u16 itemId);
|
u32 GetItemStatus2Mask(u16 itemId);
|
||||||
|
u32 GetItemSellPrice(u32 itemId);
|
||||||
|
|
||||||
/* Expands to:
|
/* Expands to:
|
||||||
* enum
|
* enum
|
||||||
|
|||||||
@ -27,6 +27,28 @@ enum {
|
|||||||
SCROLL_ARROW_DOWN
|
SCROLL_ARROW_DOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For ListMenuGet/SetTemplateField
|
||||||
|
enum ListMenuFields
|
||||||
|
{
|
||||||
|
LISTFIELD_MOVECURSORFUNC = 0,
|
||||||
|
LISTFIELD_MOVECURSORFUNC2,
|
||||||
|
LISTFIELD_TOTALITEMS,
|
||||||
|
LISTFIELD_MAXSHOWED,
|
||||||
|
LISTFIELD_WINDOWID,
|
||||||
|
LISTFIELD_HEADERX,
|
||||||
|
LISTFIELD_ITEMX,
|
||||||
|
LISTFIELD_CURSORX,
|
||||||
|
LISTFIELD_UPTEXTY,
|
||||||
|
LISTFIELD_CURSORPAL,
|
||||||
|
LISTFIELD_FILLVALUE,
|
||||||
|
LISTFIELD_CURSORSHADOWPAL,
|
||||||
|
LISTFIELD_LETTERSPACING,
|
||||||
|
LISTFIELD_ITEMVERTICALPADDING,
|
||||||
|
LISTFIELD_SCROLLMULTIPLE,
|
||||||
|
LISTFIELD_FONTID,
|
||||||
|
LISTFIELD_CURSORKIND,
|
||||||
|
};
|
||||||
|
|
||||||
struct ListMenu;
|
struct ListMenu;
|
||||||
|
|
||||||
struct ListMenuItem
|
struct ListMenuItem
|
||||||
@ -121,8 +143,8 @@ void ListMenuGetScrollAndRow(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow)
|
|||||||
u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId);
|
u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId);
|
||||||
void ListMenuOverrideSetColors(u8 cursorPal, u8 fillValue, u8 cursorShadowPal);
|
void ListMenuOverrideSetColors(u8 cursorPal, u8 fillValue, u8 cursorShadowPal);
|
||||||
void ListMenuDefaultCursorMoveFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list);
|
void ListMenuDefaultCursorMoveFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list);
|
||||||
s32 ListMenuGetUnkIndicatorsStructFields(u8 taskId, u8 field);
|
s32 ListMenuGetTemplateField(u8 taskId, u8 field);
|
||||||
void ListMenuSetUnkIndicatorsStructField(u8 taskId, u8 field, s32 value);
|
void ListMenuSetTemplateField(u8 taskId, u8 field, s32 value);
|
||||||
u8 AddScrollIndicatorArrowPair(const struct ScrollArrowsTemplate *arrowInfo, u16 *scrollOffset);
|
u8 AddScrollIndicatorArrowPair(const struct ScrollArrowsTemplate *arrowInfo, u16 *scrollOffset);
|
||||||
u8 AddScrollIndicatorArrowPairParameterized(u32 arrowType, s32 commonPos, s32 firstPos, s32 secondPos, s32 fullyDownThreshold, s32 tileTag, s32 palTag, u16 *scrollOffset);
|
u8 AddScrollIndicatorArrowPairParameterized(u32 arrowType, s32 commonPos, s32 firstPos, s32 secondPos, s32 fullyDownThreshold, s32 tileTag, s32 palTag, u16 *scrollOffset);
|
||||||
void RemoveScrollIndicatorArrowPair(u8 taskId);
|
void RemoveScrollIndicatorArrowPair(u8 taskId);
|
||||||
|
|||||||
@ -734,7 +734,7 @@ struct BattleTestRunnerState
|
|||||||
bool8 runThen:1;
|
bool8 runThen:1;
|
||||||
bool8 runFinally:1;
|
bool8 runFinally:1;
|
||||||
bool8 runningFinally:1;
|
bool8 runningFinally:1;
|
||||||
bool8 tearDownBattle:1;
|
bool8 hasTornDownBattle:1;
|
||||||
struct BattleTestData data;
|
struct BattleTestData data;
|
||||||
u8 *results;
|
u8 *results;
|
||||||
u8 checkProgressParameter;
|
u8 checkProgressParameter;
|
||||||
|
|||||||
@ -15,6 +15,7 @@ enum TestResult
|
|||||||
TEST_RESULT_TIMEOUT,
|
TEST_RESULT_TIMEOUT,
|
||||||
TEST_RESULT_CRASH,
|
TEST_RESULT_CRASH,
|
||||||
TEST_RESULT_TODO,
|
TEST_RESULT_TODO,
|
||||||
|
TEST_RESULT_KNOWN_FAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestRunner
|
struct TestRunner
|
||||||
@ -214,7 +215,7 @@ static inline struct Benchmark BenchmarkStop(void)
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define KNOWN_FAILING \
|
#define KNOWN_FAILING \
|
||||||
Test_ExpectedResult(TEST_RESULT_FAIL)
|
Test_ExpectedResult(TEST_RESULT_KNOWN_FAIL)
|
||||||
|
|
||||||
#define KNOWN_LEAKING \
|
#define KNOWN_LEAKING \
|
||||||
Test_ExpectLeaks(TRUE)
|
Test_ExpectLeaks(TRUE)
|
||||||
|
|||||||
@ -5510,6 +5510,7 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||||||
break;
|
break;
|
||||||
case EFFECT_MAX_HP_50_RECOIL:
|
case EFFECT_MAX_HP_50_RECOIL:
|
||||||
case EFFECT_MIND_BLOWN:
|
case EFFECT_MIND_BLOWN:
|
||||||
|
case EFFECT_CHLOROBLAST:
|
||||||
case EFFECT_SWAGGER:
|
case EFFECT_SWAGGER:
|
||||||
case EFFECT_FLATTER:
|
case EFFECT_FLATTER:
|
||||||
case EFFECT_ATTRACT:
|
case EFFECT_ATTRACT:
|
||||||
|
|||||||
@ -230,7 +230,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
|||||||
|
|
||||||
// Get maximum damage mon can deal
|
// Get maximum damage mon can deal
|
||||||
damageDealt = AI_GetDamage(battler, opposingBattler, i, AI_ATTACKING, gAiLogicData);
|
damageDealt = AI_GetDamage(battler, opposingBattler, i, AI_ATTACKING, gAiLogicData);
|
||||||
if(damageDealt > maxDamageDealt && !AI_DoesChoiceItemBlockMove(battler, aiMove))
|
if (damageDealt > maxDamageDealt && !AI_DoesChoiceItemBlockMove(battler, aiMove))
|
||||||
{
|
{
|
||||||
maxDamageDealt = damageDealt;
|
maxDamageDealt = damageDealt;
|
||||||
aiBestMove = aiMove;
|
aiBestMove = aiMove;
|
||||||
@ -272,14 +272,14 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
|||||||
hitsToKoAI = GetNoOfHitsToKOBattlerDmg(maxDamageTaken, battler);
|
hitsToKoAI = GetNoOfHitsToKOBattlerDmg(maxDamageTaken, battler);
|
||||||
|
|
||||||
// Check if mon gets one shot
|
// Check if mon gets one shot
|
||||||
if(maxDamageTaken > gBattleMons[battler].hp
|
if (maxDamageTaken > gBattleMons[battler].hp
|
||||||
&& !(gItemsInfo[gBattleMons[battler].item].holdEffect == HOLD_EFFECT_FOCUS_SASH || (!IsMoldBreakerTypeAbility(opposingBattler, gBattleMons[opposingBattler].ability) && B_STURDY >= GEN_5 && aiAbility == ABILITY_STURDY)))
|
&& !(gItemsInfo[gBattleMons[battler].item].holdEffect == HOLD_EFFECT_FOCUS_SASH || (!IsMoldBreakerTypeAbility(opposingBattler, gBattleMons[opposingBattler].ability) && B_STURDY >= GEN_5 && aiAbility == ABILITY_STURDY)))
|
||||||
{
|
{
|
||||||
getsOneShot = TRUE;
|
getsOneShot = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if current mon can 1v1 in spite of bad matchup, and don't switch out if it can
|
// Check if current mon can 1v1 in spite of bad matchup, and don't switch out if it can
|
||||||
if(hitsToKoPlayer < hitsToKoAI || (hitsToKoPlayer == hitsToKoAI && AI_IsFaster(battler, opposingBattler, aiBestMove)))
|
if (hitsToKoPlayer < hitsToKoAI || (hitsToKoPlayer == hitsToKoAI && AI_IsFaster(battler, opposingBattler, aiBestMove)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// If we don't have any other viable options, don't switch out
|
// If we don't have any other viable options, don't switch out
|
||||||
@ -1702,7 +1702,7 @@ static u32 GetSwitchinRecurringDamage(void)
|
|||||||
else if (holdEffect == HOLD_EFFECT_STICKY_BARB)
|
else if (holdEffect == HOLD_EFFECT_STICKY_BARB)
|
||||||
{
|
{
|
||||||
passiveDamage = maxHP / 8;
|
passiveDamage = maxHP / 8;
|
||||||
if(passiveDamage == 0)
|
if (passiveDamage == 0)
|
||||||
passiveDamage = 1;
|
passiveDamage = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1727,7 +1727,7 @@ static u32 GetSwitchinStatusDamage(u32 battler)
|
|||||||
statusDamage = maxHP / 16;
|
statusDamage = maxHP / 16;
|
||||||
else
|
else
|
||||||
statusDamage = maxHP / 8;
|
statusDamage = maxHP / 8;
|
||||||
if(ability == ABILITY_HEATPROOF)
|
if (ability == ABILITY_HEATPROOF)
|
||||||
statusDamage = statusDamage / 2;
|
statusDamage = statusDamage / 2;
|
||||||
if (statusDamage == 0)
|
if (statusDamage == 0)
|
||||||
statusDamage = 1;
|
statusDamage = 1;
|
||||||
@ -2095,10 +2095,10 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Track max hits to KO and set defensive mon
|
// Track max hits to KO and set defensive mon
|
||||||
if(hitsToKOAI > maxHitsToKO && (canSwitchinWin1v1 || gAiThinkingStruct->aiFlags[battler] & AI_FLAG_STALL))
|
if (hitsToKOAI > maxHitsToKO && (canSwitchinWin1v1 || gAiThinkingStruct->aiFlags[battler] & AI_FLAG_STALL))
|
||||||
{
|
{
|
||||||
maxHitsToKO = hitsToKOAI;
|
maxHitsToKO = hitsToKOAI;
|
||||||
if(maxHitsToKO > defensiveMonHitKOThreshold)
|
if (maxHitsToKO > defensiveMonHitKOThreshold)
|
||||||
defensiveMonId = i;
|
defensiveMonId = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2124,7 +2124,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
|
|||||||
// Check that mon isn't one shot and set best damage mon
|
// Check that mon isn't one shot and set best damage mon
|
||||||
if (damageDealt > maxDamageDealt)
|
if (damageDealt > maxDamageDealt)
|
||||||
{
|
{
|
||||||
if((isFreeSwitch && hitsToKOAI > 1) || hitsToKOAI > 2) // This is a "default", we have uniquely low standards
|
if ((isFreeSwitch && hitsToKOAI > 1) || hitsToKOAI > 2) // This is a "default", we have uniquely low standards
|
||||||
{
|
{
|
||||||
maxDamageDealt = damageDealt;
|
maxDamageDealt = damageDealt;
|
||||||
damageMonId = i;
|
damageMonId = i;
|
||||||
|
|||||||
@ -791,47 +791,47 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
|
|||||||
s32 damageByRollType = 0;
|
s32 damageByRollType = 0;
|
||||||
|
|
||||||
s32 oneTripleKickHit = CalculateMoveDamageVars(&damageCalcData, fixedBasePower,
|
s32 oneTripleKickHit = CalculateMoveDamageVars(&damageCalcData, fixedBasePower,
|
||||||
effectivenessMultiplier, weather,
|
effectivenessMultiplier, weather,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
||||||
|
|
||||||
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_LOWEST);
|
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_LOWEST);
|
||||||
simDamage.minimum += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
simDamage.minimum += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
|
|
||||||
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_DEFAULT);
|
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_DEFAULT);
|
||||||
simDamage.median += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
simDamage.median += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
|
|
||||||
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_HIGHEST);
|
damageByRollType = GetDamageByRollType(oneTripleKickHit, DMG_ROLL_HIGHEST);
|
||||||
simDamage.maximum += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
simDamage.maximum += ApplyModifiersAfterDmgRoll(damageByRollType, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 damage = CalculateMoveDamageVars(&damageCalcData, fixedBasePower,
|
u32 damage = CalculateMoveDamageVars(&damageCalcData, fixedBasePower,
|
||||||
effectivenessMultiplier, weather,
|
effectivenessMultiplier, weather,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
||||||
|
|
||||||
simDamage.minimum = GetDamageByRollType(damage, DMG_ROLL_LOWEST);
|
simDamage.minimum = GetDamageByRollType(damage, DMG_ROLL_LOWEST);
|
||||||
simDamage.minimum = ApplyModifiersAfterDmgRoll(simDamage.minimum, &damageCalcData, effectivenessMultiplier,
|
simDamage.minimum = ApplyModifiersAfterDmgRoll(simDamage.minimum, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
|
|
||||||
simDamage.median = GetDamageByRollType(damage, DMG_ROLL_DEFAULT);
|
simDamage.median = GetDamageByRollType(damage, DMG_ROLL_DEFAULT);
|
||||||
simDamage.median = ApplyModifiersAfterDmgRoll(simDamage.median, &damageCalcData, effectivenessMultiplier,
|
simDamage.median = ApplyModifiersAfterDmgRoll(simDamage.median, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
|
|
||||||
simDamage.maximum = GetDamageByRollType(damage, DMG_ROLL_HIGHEST);
|
simDamage.maximum = GetDamageByRollType(damage, DMG_ROLL_HIGHEST);
|
||||||
simDamage.maximum = ApplyModifiersAfterDmgRoll(simDamage.maximum, &damageCalcData, effectivenessMultiplier,
|
simDamage.maximum = ApplyModifiersAfterDmgRoll(simDamage.maximum, &damageCalcData, effectivenessMultiplier,
|
||||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
aiData->abilities[battlerAtk], aiData->abilities[battlerDef],
|
||||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE)
|
if (GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE)
|
||||||
@ -892,7 +892,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
case EFFECT_PURSUIT:
|
case EFFECT_PURSUIT:
|
||||||
if(noOfHitsToKo == 1)
|
if (noOfHitsToKo == 1)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1014,6 +1014,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
|||||||
{
|
{
|
||||||
case EFFECT_MAX_HP_50_RECOIL:
|
case EFFECT_MAX_HP_50_RECOIL:
|
||||||
case EFFECT_MIND_BLOWN:
|
case EFFECT_MIND_BLOWN:
|
||||||
|
case EFFECT_CHLOROBLAST:
|
||||||
case EFFECT_EXPLOSION:
|
case EFFECT_EXPLOSION:
|
||||||
case EFFECT_FINAL_GAMBIT:
|
case EFFECT_FINAL_GAMBIT:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@ -4595,20 +4595,18 @@ static void AnimPresent(struct Sprite *sprite)
|
|||||||
|
|
||||||
static void AnimKnockOffOpponentsItem(struct Sprite *sprite)
|
static void AnimKnockOffOpponentsItem(struct Sprite *sprite)
|
||||||
{
|
{
|
||||||
int zero;
|
|
||||||
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
|
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
|
||||||
zero = 0;
|
|
||||||
if (sprite->data[0] > 0x7F)
|
if (sprite->data[0] > 0x7F)
|
||||||
{
|
{
|
||||||
sprite->data[1]++;
|
sprite->data[1]++;
|
||||||
sprite->data[0] = zero;
|
sprite->data[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
|
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
|
||||||
if (moveAlongLinearPath(sprite))
|
if (moveAlongLinearPath(sprite))
|
||||||
{
|
{
|
||||||
sprite->y2 = zero;
|
sprite->y2 = 0;
|
||||||
sprite->data[0] = zero;
|
sprite->data[0] = 0;
|
||||||
DestroyAnimSprite(sprite);
|
DestroyAnimSprite(sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4686,13 +4684,11 @@ static void AnimItemSteal(struct Sprite *sprite)
|
|||||||
|
|
||||||
static void AnimItemSteal_Step3(struct Sprite *sprite)
|
static void AnimItemSteal_Step3(struct Sprite *sprite)
|
||||||
{
|
{
|
||||||
int zero;
|
|
||||||
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
|
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
|
||||||
zero = 0;
|
|
||||||
if (sprite->data[0] > 127)
|
if (sprite->data[0] > 127)
|
||||||
{
|
{
|
||||||
sprite->data[1]++;
|
sprite->data[1]++;
|
||||||
sprite->data[0] = zero;
|
sprite->data[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
|
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
|
||||||
|
|||||||
@ -3395,7 +3395,7 @@ void AnimTask_ScaryFace(u8 taskId)
|
|||||||
bool32 onPlayer;
|
bool32 onPlayer;
|
||||||
|
|
||||||
if (gAnimMoveIndex == MOVE_BITTER_MALICE)
|
if (gAnimMoveIndex == MOVE_BITTER_MALICE)
|
||||||
onPlayer = IsOnPlayerSide(gBattleAnimAttacker);
|
onPlayer = !IsOnPlayerSide(gBattleAnimAttacker);
|
||||||
else
|
else
|
||||||
onPlayer = !IsOnPlayerSide(gBattleAnimTarget);
|
onPlayer = !IsOnPlayerSide(gBattleAnimTarget);
|
||||||
|
|
||||||
|
|||||||
@ -2062,7 +2062,7 @@ static void RepeatBallOpenParticleAnimation(u8 taskId)
|
|||||||
priority = gTasks[taskId].data[3];
|
priority = gTasks[taskId].data[3];
|
||||||
subpriority = gTasks[taskId].data[4];
|
subpriority = gTasks[taskId].data[4];
|
||||||
|
|
||||||
for (i = 0; i < POKEBALL_COUNT; i++)
|
for (i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
spriteId = CreateSprite(&sBallParticleSpriteTemplates[ballId], x, y, subpriority);
|
spriteId = CreateSprite(&sBallParticleSpriteTemplates[ballId], x, y, subpriority);
|
||||||
if (spriteId != MAX_SPRITES)
|
if (spriteId != MAX_SPRITES)
|
||||||
|
|||||||
@ -114,7 +114,7 @@ void SetControllerToLinkOpponent(u32 battler)
|
|||||||
|
|
||||||
static void LinkOpponentBufferRunCommand(u32 battler)
|
static void LinkOpponentBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands))
|
||||||
sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -320,7 +320,7 @@ static void LinkOpponentBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -113,7 +113,7 @@ void SetControllerToLinkPartner(u32 battler)
|
|||||||
|
|
||||||
static void LinkPartnerBufferRunCommand(u32 battler)
|
static void LinkPartnerBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands))
|
||||||
sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -164,7 +164,7 @@ static void LinkPartnerBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -127,7 +127,7 @@ void SetControllerToOpponent(u32 battler)
|
|||||||
|
|
||||||
static void OpponentBufferRunCommand(u32 battler)
|
static void OpponentBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands))
|
||||||
sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -364,7 +364,7 @@ static void OpponentBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -182,13 +182,13 @@ static void PlayerBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PlayerBufferRunCommand(u32 battler)
|
static void PlayerBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerBufferCommands))
|
||||||
sPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
|
|||||||
@ -117,7 +117,7 @@ void SetControllerToPlayerPartner(u32 battler)
|
|||||||
|
|
||||||
static void PlayerPartnerBufferRunCommand(u32 battler)
|
static void PlayerPartnerBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands))
|
||||||
sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -236,7 +236,7 @@ static void PlayerPartnerBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,7 +120,7 @@ void SetControllerToRecordedOpponent(u32 battler)
|
|||||||
|
|
||||||
static void RecordedOpponentBufferRunCommand(u32 battler)
|
static void RecordedOpponentBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands))
|
||||||
sRecordedOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sRecordedOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -141,7 +141,7 @@ static void RecordedOpponentBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,7 @@ void SetControllerToRecordedPlayer(u32 battler)
|
|||||||
|
|
||||||
static void RecordedPlayerBufferRunCommand(u32 battler)
|
static void RecordedPlayerBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands))
|
||||||
sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -313,7 +313,7 @@ static void RecordedPlayerBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -109,7 +109,7 @@ void SetControllerToSafari(u32 battler)
|
|||||||
|
|
||||||
static void SafariBufferRunCommand(u32 battler)
|
static void SafariBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands))
|
||||||
sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -237,7 +237,7 @@ static void SafariBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -125,7 +125,7 @@ void SetControllerToWally(u32 battler)
|
|||||||
|
|
||||||
static void WallyBufferRunCommand(u32 battler)
|
static void WallyBufferRunCommand(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleControllerExecFlags & (1u << battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
{
|
{
|
||||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sWallyBufferCommands))
|
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sWallyBufferCommands))
|
||||||
sWallyBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
sWallyBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||||
@ -284,7 +284,7 @@ static void WallyBufferExecCompleted(u32 battler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gBattleControllerExecFlags &= ~(1u << battler);
|
MarkBattleControllerIdleOnLocal(battler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -956,7 +956,7 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
|
|||||||
switch (BYTE_TO_RECEIVE(0))
|
switch (BYTE_TO_RECEIVE(0))
|
||||||
{
|
{
|
||||||
case B_COMM_TO_CONTROLLER:
|
case B_COMM_TO_CONTROLLER:
|
||||||
if (IS_BATTLE_CONTROLLER_ACTIVE_ON_LOCAL(battler))
|
if (IsBattleControllerActiveOnLocal(battler))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(gBattleResources->bufferA[battler], &BYTE_TO_RECEIVE(LINK_BUFF_DATA), blockSize);
|
memcpy(gBattleResources->bufferA[battler], &BYTE_TO_RECEIVE(LINK_BUFF_DATA), blockSize);
|
||||||
@ -975,7 +975,7 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
|
|||||||
break;
|
break;
|
||||||
case B_COMM_CONTROLLER_IS_DONE:
|
case B_COMM_CONTROLLER_IS_DONE:
|
||||||
playerId = BYTE_TO_RECEIVE(LINK_BUFF_DATA);
|
playerId = BYTE_TO_RECEIVE(LINK_BUFF_DATA);
|
||||||
MARK_BATTLE_CONTROLLER_IDLE_FOR_PLAYER(battler, playerId);
|
MarkBattleControllerIdleForPlayer(battler, playerId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -490,7 +490,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler)
|
|||||||
gBattleStruct->eventBlockCounter++;
|
gBattleStruct->eventBlockCounter++;
|
||||||
break;
|
break;
|
||||||
case FIRST_EVENT_BLOCK_GRASSY_TERRAIN_HEAL:
|
case FIRST_EVENT_BLOCK_GRASSY_TERRAIN_HEAL:
|
||||||
if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerAlive(battler) && !IsBattlerAtMaxHp(battler))
|
if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerAlive(battler) && !IsBattlerAtMaxHp(battler) && IsBattlerGrounded(battler))
|
||||||
{
|
{
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
gBattleStruct->moveDamage[battler] = -(GetNonDynamaxMaxHP(battler) / 16);
|
gBattleStruct->moveDamage[battler] = -(GetNonDynamaxMaxHP(battler) / 16);
|
||||||
|
|||||||
@ -434,10 +434,6 @@ void CB2_InitBattle(void)
|
|||||||
AllocateMonSpritesGfx();
|
AllocateMonSpritesGfx();
|
||||||
RecordedBattle_ClearFrontierPassFlag();
|
RecordedBattle_ClearFrontierPassFlag();
|
||||||
|
|
||||||
#if T_SHOULD_RUN_MOVE_ANIM
|
|
||||||
gLoadFail = FALSE;
|
|
||||||
#endif // T_SHOULD_RUN_MOVE_ANIM
|
|
||||||
|
|
||||||
#if T_SHOULD_RUN_MOVE_ANIM
|
#if T_SHOULD_RUN_MOVE_ANIM
|
||||||
gLoadFail = FALSE;
|
gLoadFail = FALSE;
|
||||||
#endif // T_SHOULD_RUN_MOVE_ANIM
|
#endif // T_SHOULD_RUN_MOVE_ANIM
|
||||||
@ -3107,7 +3103,7 @@ static void BattleStartClearSetData(void)
|
|||||||
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
|
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
|
||||||
gCategoryIconSpriteId = 0xFF;
|
gCategoryIconSpriteId = 0xFF;
|
||||||
|
|
||||||
if(IsSleepClauseEnabled())
|
if (IsSleepClauseEnabled())
|
||||||
{
|
{
|
||||||
// If monCausingSleepClause[side] equals PARTY_SIZE, Sleep Clause is not active for the given side.
|
// If monCausingSleepClause[side] equals PARTY_SIZE, Sleep Clause is not active for the given side.
|
||||||
gBattleStruct->monCausingSleepClause[B_SIDE_PLAYER] = PARTY_SIZE;
|
gBattleStruct->monCausingSleepClause[B_SIDE_PLAYER] = PARTY_SIZE;
|
||||||
@ -4210,7 +4206,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_ACTION_CHOSEN: // Try to perform an action.
|
case STATE_WAIT_ACTION_CHOSEN: // Try to perform an action.
|
||||||
if (!(gBattleControllerExecFlags & (((1u << battler)) | (0xF << 28) | ((1u << battler) << 4) | ((1u << battler) << 8) | ((1u << battler) << 12))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][1]);
|
RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][1]);
|
||||||
gChosenActionByBattler[battler] = gBattleResources->bufferB[battler][1];
|
gChosenActionByBattler[battler] = gBattleResources->bufferB[battler][1];
|
||||||
@ -4414,7 +4410,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_ACTION_CASE_CHOSEN:
|
case STATE_WAIT_ACTION_CASE_CHOSEN:
|
||||||
if (!(gBattleControllerExecFlags & (((1u << battler)) | (0xF << 28) | ((1u << battler) << 4) | ((1u << battler) << 8) | ((1u << battler) << 12))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
switch (gChosenActionByBattler[battler])
|
switch (gChosenActionByBattler[battler])
|
||||||
{
|
{
|
||||||
@ -4544,11 +4540,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
|
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
|
||||||
if (!(gBattleControllerExecFlags & ((1u << battler)
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
| (0xF << 28)
|
|
||||||
| (1u << (battler + 4))
|
|
||||||
| (1u << (battler + 8))
|
|
||||||
| (1u << (battler + 12)))))
|
|
||||||
{
|
{
|
||||||
if (AllAtActionConfirmed())
|
if (AllAtActionConfirmed())
|
||||||
i = TRUE;
|
i = TRUE;
|
||||||
@ -4570,7 +4562,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_ACTION_CONFIRMED:
|
case STATE_WAIT_ACTION_CONFIRMED:
|
||||||
if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12)))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++;
|
gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++;
|
||||||
}
|
}
|
||||||
@ -4584,7 +4576,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
{
|
{
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
|
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
|
||||||
if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12)))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
||||||
}
|
}
|
||||||
@ -4592,7 +4584,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_SET_BEFORE_ACTION:
|
case STATE_WAIT_SET_BEFORE_ACTION:
|
||||||
if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12)))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
|
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
|
||||||
}
|
}
|
||||||
@ -4616,7 +4608,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
{
|
{
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
|
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
|
||||||
if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12)))))
|
if (!IsBattleControllerActiveOrPendingSyncAnywhere(battler))
|
||||||
{
|
{
|
||||||
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
||||||
}
|
}
|
||||||
@ -4703,6 +4695,10 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
|||||||
{
|
{
|
||||||
u32 speed = gBattleMons[battler].speed;
|
u32 speed = gBattleMons[battler].speed;
|
||||||
|
|
||||||
|
// stat stages
|
||||||
|
speed *= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][0];
|
||||||
|
speed /= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][1];
|
||||||
|
|
||||||
// weather abilities
|
// weather abilities
|
||||||
if (HasWeatherEffect())
|
if (HasWeatherEffect())
|
||||||
{
|
{
|
||||||
@ -4730,10 +4726,6 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
|||||||
else if (ability == ABILITY_UNBURDEN && gDisableStructs[battler].unburdenActive)
|
else if (ability == ABILITY_UNBURDEN && gDisableStructs[battler].unburdenActive)
|
||||||
speed *= 2;
|
speed *= 2;
|
||||||
|
|
||||||
// stat stages
|
|
||||||
speed *= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][0];
|
|
||||||
speed /= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][1];
|
|
||||||
|
|
||||||
// player's badge boost
|
// player's badge boost
|
||||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
|
||||||
&& ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPEED, battler)
|
&& ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPEED, battler)
|
||||||
@ -4915,8 +4907,8 @@ s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenM
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 24 == MAX_BATTLERS_COUNT!.
|
// 24 == MAX_BATTLERS_COUNT!.
|
||||||
// These are the possible orders if all the battlers speed tie. An order
|
// These are the possible orders if all the battlers speed tie.
|
||||||
// is chosen at the start of the turn.
|
// An order is chosen at the start of the turn.
|
||||||
static const u8 sBattlerOrders[24][4] =
|
static const u8 sBattlerOrders[24][4] =
|
||||||
{
|
{
|
||||||
{ 0, 1, 2, 3 },
|
{ 0, 1, 2, 3 },
|
||||||
@ -6002,7 +5994,9 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState
|
|||||||
{
|
{
|
||||||
return TYPE_WATER;
|
return TYPE_WATER;
|
||||||
}
|
}
|
||||||
else if (moveEffect == EFFECT_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY)
|
else if (moveEffect == EFFECT_AURA_WHEEL
|
||||||
|
&& species == SPECIES_MORPEKO_HANGRY
|
||||||
|
&& ability != ABILITY_NORMALIZE)
|
||||||
{
|
{
|
||||||
return TYPE_DARK;
|
return TYPE_DARK;
|
||||||
}
|
}
|
||||||
@ -6016,7 +6010,9 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState
|
|||||||
gBattleStruct->ateBoost[battler] = TRUE;
|
gBattleStruct->ateBoost[battler] = TRUE;
|
||||||
return ateType;
|
return ateType;
|
||||||
}
|
}
|
||||||
else if (moveType != TYPE_NORMAL
|
else if (moveEffect != EFFECT_CHANGE_TYPE_ON_ITEM
|
||||||
|
&& moveEffect != EFFECT_TERRAIN_PULSE
|
||||||
|
&& moveEffect != EFFECT_NATURAL_GIFT
|
||||||
&& moveEffect != EFFECT_HIDDEN_POWER
|
&& moveEffect != EFFECT_HIDDEN_POWER
|
||||||
&& moveEffect != EFFECT_WEATHER_BALL
|
&& moveEffect != EFFECT_WEATHER_BALL
|
||||||
&& ability == ABILITY_NORMALIZE
|
&& ability == ABILITY_NORMALIZE
|
||||||
|
|||||||
@ -1331,7 +1331,7 @@ static void Task_BeginItemSwap(u8 taskId)
|
|||||||
|
|
||||||
tListPos = gPyramidBagMenuState.scrollPosition + gPyramidBagMenuState.cursorPosition;
|
tListPos = gPyramidBagMenuState.scrollPosition + gPyramidBagMenuState.cursorPosition;
|
||||||
gPyramidBagMenu->toSwapPos = tListPos;
|
gPyramidBagMenu->toSwapPos = tListPos;
|
||||||
ListMenuSetUnkIndicatorsStructField(tListTaskId, 0x10, 1);
|
ListMenuSetTemplateField(tListTaskId, LISTFIELD_CURSORKIND, CURSOR_INVISIBLE);
|
||||||
CopyItemName(gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode][tListPos], gStringVar1);
|
CopyItemName(gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode][tListPos], gStringVar1);
|
||||||
StringExpandPlaceholders(gStringVar4, gText_MoveVar1Where);
|
StringExpandPlaceholders(gStringVar4, gText_MoveVar1Where);
|
||||||
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
|
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
|
||||||
|
|||||||
@ -344,7 +344,7 @@ static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent);
|
|||||||
static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMove);
|
static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMove);
|
||||||
static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move);
|
static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move);
|
||||||
static void ResetValuesForCalledMove(void);
|
static void ResetValuesForCalledMove(void);
|
||||||
static void TryRestoreDamageAfterCheeckPouch(u32 battler);
|
static void TryRestoreDamageAfterCheekPouch(u32 battler);
|
||||||
|
|
||||||
static void Cmd_attackcanceler(void);
|
static void Cmd_attackcanceler(void);
|
||||||
static void Cmd_accuracycheck(void);
|
static void Cmd_accuracycheck(void);
|
||||||
@ -2748,7 +2748,7 @@ static void Cmd_datahpupdate(void)
|
|||||||
gBattleStruct->timesGotHit[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]]++;
|
gBattleStruct->timesGotHit[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryRestoreDamageAfterCheeckPouch(battler);
|
TryRestoreDamageAfterCheekPouch(battler);
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7024,6 +7024,15 @@ static void Cmd_moveend(void)
|
|||||||
effect = TRUE;
|
effect = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EFFECT_CHLOROBLAST:
|
||||||
|
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker))
|
||||||
|
{
|
||||||
|
gBattleStruct->moveDamage[gBattlerAttacker] = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
|
||||||
|
BattleScriptPushCursor();
|
||||||
|
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
|
||||||
|
effect = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case EFFECT_RAPID_SPIN:
|
case EFFECT_RAPID_SPIN:
|
||||||
if (IsBattlerTurnDamaged(gBattlerTarget))
|
if (IsBattlerTurnDamaged(gBattlerTarget))
|
||||||
{
|
{
|
||||||
@ -7436,6 +7445,12 @@ static void Cmd_moveend(void)
|
|||||||
SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE);
|
SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE);
|
||||||
if (B_CHARGE >= GEN_9 && moveType == TYPE_ELECTRIC && (IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT))
|
if (B_CHARGE >= GEN_9 && moveType == TYPE_ELECTRIC && (IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT))
|
||||||
gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP);
|
gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP);
|
||||||
|
// check if Stellar type boost should be used up
|
||||||
|
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA
|
||||||
|
&& GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR
|
||||||
|
&& GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS
|
||||||
|
&& IsTypeStellarBoosted(gBattlerAttacker, moveType))
|
||||||
|
ExpendTypeStellarBoost(gBattlerAttacker, moveType);
|
||||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
||||||
|
|
||||||
for (i = 0; i < gBattlersCount; i++)
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
@ -7638,7 +7653,7 @@ static void Cmd_switchindataupdate(void)
|
|||||||
u32 side = GetBattlerSide(battler);
|
u32 side = GetBattlerSide(battler);
|
||||||
u32 partyIndex = gBattlerPartyIndexes[battler];
|
u32 partyIndex = gBattlerPartyIndexes[battler];
|
||||||
if (TestRunner_Battle_GetForcedAbility(side, partyIndex))
|
if (TestRunner_Battle_GetForcedAbility(side, partyIndex))
|
||||||
gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = TestRunner_Battle_GetForcedAbility(side, partyIndex);
|
gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -7925,7 +7940,16 @@ static void Cmd_openpartyscreen(void)
|
|||||||
{
|
{
|
||||||
if (((1u << i) & hitmarkerFaintBits))
|
if (((1u << i) & hitmarkerFaintBits))
|
||||||
{
|
{
|
||||||
if (i > 1 && ((1u << BATTLE_PARTNER(i)) & hitmarkerFaintBits))
|
u32 skipPartnerCheck = FALSE;
|
||||||
|
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS
|
||||||
|
&& GetBattlerSide(i) == B_SIDE_OPPONENT
|
||||||
|
&& TRAINER_BATTLE_PARAM.opponentB != TRAINER_NONE)
|
||||||
|
skipPartnerCheck = TRUE;
|
||||||
|
|
||||||
|
// In a 1v2 Double Battle if trainer A didn't have any more mons left
|
||||||
|
// the battler for trainer B wasn't being registered to be send out.
|
||||||
|
// Likely reason is because hitmarkerFaintBits was not set for battler 1 due to it being missing for a turn or cleared somewhere
|
||||||
|
if (!skipPartnerCheck && i > 1 && ((1u << BATTLE_PARTNER(i)) & hitmarkerFaintBits))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
battler = i;
|
battler = i;
|
||||||
@ -8259,22 +8283,21 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
|||||||
{
|
{
|
||||||
if (CanBePoisoned(gBattlerAttacker, battler, GetBattlerAbility(gBattlerAttacker), GetBattlerAbility(battler)))
|
if (CanBePoisoned(gBattlerAttacker, battler, GetBattlerAbility(gBattlerAttacker), GetBattlerAbility(battler)))
|
||||||
{
|
{
|
||||||
u32 tspikes = 0;
|
gBattleScripting.battler = battler;
|
||||||
if (gSideTimers[GetBattlerSide(battler)].toxicSpikesAmount >= 2) {
|
BattleScriptPushCursor();
|
||||||
tspikes = 1;
|
if (gSideTimers[GetBattlerSide(battler)].toxicSpikesAmount >= 2)
|
||||||
|
{
|
||||||
|
gBattlescriptCurrInstr = BattleScript_ToxicSpikesBadlyPoisoned;
|
||||||
gBattleMons[battler].status1 |= STATUS1_TOXIC_POISON;
|
gBattleMons[battler].status1 |= STATUS1_TOXIC_POISON;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
gBattlescriptCurrInstr = BattleScript_ToxicSpikesPoisoned;
|
||||||
gBattleMons[battler].status1 |= STATUS1_POISON;
|
gBattleMons[battler].status1 |= STATUS1_POISON;
|
||||||
|
}
|
||||||
|
|
||||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
|
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
|
||||||
MarkBattlerForControllerExec(battler);
|
MarkBattlerForControllerExec(battler);
|
||||||
gBattleScripting.battler = battler;
|
|
||||||
BattleScriptPushCursor();
|
|
||||||
if (tspikes == 0)
|
|
||||||
gBattlescriptCurrInstr = BattleScript_ToxicSpikesPoisoned;
|
|
||||||
else
|
|
||||||
gBattlescriptCurrInstr = BattleScript_ToxicSpikesBadlyPoisoned;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8493,7 +8516,7 @@ static void Cmd_returntoball(void)
|
|||||||
MarkBattlerForControllerExec(battler);
|
MarkBattlerForControllerExec(battler);
|
||||||
|
|
||||||
// Don't always execute a form change here otherwise we can stomp gigantamax
|
// Don't always execute a form change here otherwise we can stomp gigantamax
|
||||||
if(!cmd->changingForm)
|
if (!cmd->changingForm)
|
||||||
TryBattleFormChange(battler, FORM_CHANGE_BATTLE_SWITCH);
|
TryBattleFormChange(battler, FORM_CHANGE_BATTLE_SWITCH);
|
||||||
|
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
@ -9118,7 +9141,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When Cheek Pouch activates mid-battle it overwrites the current damage, so restore it
|
// When Cheek Pouch activates mid-battle it overwrites the current damage, so restore it
|
||||||
static void TryRestoreDamageAfterCheeckPouch(u32 battler)
|
static void TryRestoreDamageAfterCheekPouch(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleStruct->cheekPouchActivated)
|
if (gBattleStruct->cheekPouchActivated)
|
||||||
{
|
{
|
||||||
@ -9634,17 +9657,17 @@ static void RemoveAllWeather(void)
|
|||||||
|
|
||||||
if (gBattleWeather & B_WEATHER_RAIN)
|
if (gBattleWeather & B_WEATHER_RAIN)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_RAIN;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_RAIN;
|
||||||
else if(gBattleWeather & B_WEATHER_SANDSTORM)
|
else if (gBattleWeather & B_WEATHER_SANDSTORM)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SANDSTORM;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SANDSTORM;
|
||||||
else if(gBattleWeather & B_WEATHER_SUN)
|
else if (gBattleWeather & B_WEATHER_SUN)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SUN;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SUN;
|
||||||
else if(gBattleWeather & B_WEATHER_HAIL)
|
else if (gBattleWeather & B_WEATHER_HAIL)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_HAIL;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_HAIL;
|
||||||
else if(gBattleWeather & B_WEATHER_STRONG_WINDS)
|
else if (gBattleWeather & B_WEATHER_STRONG_WINDS)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_STRONG_WINDS;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_STRONG_WINDS;
|
||||||
else if(gBattleWeather & B_WEATHER_SNOW)
|
else if (gBattleWeather & B_WEATHER_SNOW)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SNOW;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_SNOW;
|
||||||
else if(gBattleWeather & B_WEATHER_FOG)
|
else if (gBattleWeather & B_WEATHER_FOG)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_FOG;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_FOG;
|
||||||
else
|
else
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_COUNT; // failsafe
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_END_COUNT; // failsafe
|
||||||
@ -16206,7 +16229,8 @@ static void Cmd_displaydexinfo(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (!gPaletteFade.active) {
|
if (!gPaletteFade.active)
|
||||||
|
{
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -16518,6 +16542,9 @@ static void Cmd_tryworryseed(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
|
||||||
|
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
|
||||||
|
|
||||||
gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability;
|
gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability;
|
||||||
gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_INSOMNIA;
|
gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_INSOMNIA;
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
@ -16874,7 +16901,7 @@ static void TryUpdateRoundTurnOrder(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get battlers after us using round
|
// Get battlers after attacker using round
|
||||||
for (i = currRounder; i < gBattlersCount; i++)
|
for (i = currRounder; i < gBattlersCount; i++)
|
||||||
{
|
{
|
||||||
if (gChosenMoveByBattler[gBattlerByTurnOrder[i]] == MOVE_ROUND)
|
if (gChosenMoveByBattler[gBattlerByTurnOrder[i]] == MOVE_ROUND)
|
||||||
@ -17675,25 +17702,34 @@ void BS_AllySwitchSwapBattler(void)
|
|||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_AllySwitchFailChance(void)
|
void BS_TryAllySwitch(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS(const u8 *failInstr);
|
NATIVE_ARGS(const u8 *failInstr);
|
||||||
|
|
||||||
if (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9)
|
if (!IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))
|
||||||
|
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||||
|
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
||||||
|
{
|
||||||
|
gBattlescriptCurrInstr = cmd->failInstr;
|
||||||
|
}
|
||||||
|
else if (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9)
|
||||||
{
|
{
|
||||||
TryResetProtectUseCounter(gBattlerAttacker);
|
TryResetProtectUseCounter(gBattlerAttacker);
|
||||||
if (sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] < Random())
|
if (sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] < Random())
|
||||||
{
|
{
|
||||||
gDisableStructs[gBattlerAttacker].protectUses = 0;
|
gDisableStructs[gBattlerAttacker].protectUses = 0;
|
||||||
gBattlescriptCurrInstr = cmd->failInstr;
|
gBattlescriptCurrInstr = cmd->failInstr;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gDisableStructs[gBattlerAttacker].protectUses++;
|
gDisableStructs[gBattlerAttacker].protectUses++;
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
else
|
||||||
|
{
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_RunStatChangeItems(void)
|
void BS_RunStatChangeItems(void)
|
||||||
@ -17981,7 +18017,7 @@ void BS_TryTarShot(void)
|
|||||||
void BS_CanTarShotWork(void)
|
void BS_CanTarShotWork(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS(const u8 *failInstr);
|
NATIVE_ARGS(const u8 *failInstr);
|
||||||
// Tar Shot will fail if it's already been used on the target and its speed can't be lowered further
|
// Tar Shot will fail if it's already been used on the target or if its speed can't be lowered further
|
||||||
if (!gDisableStructs[gBattlerTarget].tarShot
|
if (!gDisableStructs[gBattlerTarget].tarShot
|
||||||
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
@ -18634,7 +18670,7 @@ void BS_JumpIfIntimidateAbilityPrevented(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_TryIntimidatEjectpack(void)
|
void BS_TryIntimidateEjectPack(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS();
|
NATIVE_ARGS();
|
||||||
|
|
||||||
@ -18709,3 +18745,14 @@ void BS_JumpIfNoWhiteOut(void)
|
|||||||
else
|
else
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BS_JumpIfAbilityCantBeSuppressed(void)
|
||||||
|
{
|
||||||
|
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||||
|
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||||
|
|
||||||
|
if (gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed)
|
||||||
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
|
else
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
|
}
|
||||||
|
|||||||
@ -545,6 +545,16 @@ void HandleAction_UseMove(void)
|
|||||||
void HandleAction_Switch(void)
|
void HandleAction_Switch(void)
|
||||||
{
|
{
|
||||||
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
||||||
|
|
||||||
|
// if switching to a mon that is already on field, cancel switch
|
||||||
|
if (!(gAbsentBattlerFlags & (1u << BATTLE_PARTNER(gBattlerAttacker)))
|
||||||
|
&& IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))
|
||||||
|
&& gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gBattleStruct->monToSwitchIntoId[gBattlerAttacker])
|
||||||
|
{
|
||||||
|
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gBattle_BG0_X = 0;
|
gBattle_BG0_X = 0;
|
||||||
gBattle_BG0_Y = 0;
|
gBattle_BG0_Y = 0;
|
||||||
gActionSelectionCursor[gBattlerAttacker] = 0;
|
gActionSelectionCursor[gBattlerAttacker] = 0;
|
||||||
@ -851,7 +861,7 @@ void HandleAction_NothingIsFainted(void)
|
|||||||
|
|
||||||
void HandleAction_ActionFinished(void)
|
void HandleAction_ActionFinished(void)
|
||||||
{
|
{
|
||||||
u32 i, j, moveType;
|
u32 i, j;
|
||||||
bool32 afterYouActive = gSpecialStatuses[gBattlerByTurnOrder[gCurrentTurnActionNumber + 1]].afterYou;
|
bool32 afterYouActive = gSpecialStatuses[gBattlerByTurnOrder[gCurrentTurnActionNumber + 1]].afterYou;
|
||||||
gBattleStruct->monToSwitchIntoId[gBattlerByTurnOrder[gCurrentTurnActionNumber]] = gSelectedMonPartyId = PARTY_SIZE;
|
gBattleStruct->monToSwitchIntoId[gBattlerByTurnOrder[gCurrentTurnActionNumber]] = gSelectedMonPartyId = PARTY_SIZE;
|
||||||
gCurrentTurnActionNumber++;
|
gCurrentTurnActionNumber++;
|
||||||
@ -862,16 +872,6 @@ void HandleAction_ActionFinished(void)
|
|||||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT
|
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT
|
||||||
| HITMARKER_CHARGING | HITMARKER_IGNORE_DISGUISE);
|
| HITMARKER_CHARGING | HITMARKER_IGNORE_DISGUISE);
|
||||||
|
|
||||||
// check if Stellar type boost should be used up
|
|
||||||
moveType = GetBattleMoveType(gCurrentMove);
|
|
||||||
|
|
||||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA
|
|
||||||
&& GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR
|
|
||||||
&& GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS
|
|
||||||
&& IsTypeStellarBoosted(gBattlerAttacker, moveType))
|
|
||||||
{
|
|
||||||
ExpendTypeStellarBoost(gBattlerAttacker, moveType);
|
|
||||||
}
|
|
||||||
ClearDamageCalcResults();
|
ClearDamageCalcResults();
|
||||||
gCurrentMove = 0;
|
gCurrentMove = 0;
|
||||||
gBattleScripting.animTurn = 0;
|
gBattleScripting.animTurn = 0;
|
||||||
@ -902,7 +902,7 @@ void HandleAction_ActionFinished(void)
|
|||||||
|
|
||||||
// We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should
|
// We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should
|
||||||
// have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder
|
// have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder
|
||||||
if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE))
|
if ((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE))
|
||||||
{
|
{
|
||||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
if (GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
||||||
SwapTurnOrder(i, j);
|
SwapTurnOrder(i, j);
|
||||||
@ -988,29 +988,29 @@ static void UNUSED MarkAllBattlersForControllerExec(void)
|
|||||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||||
{
|
{
|
||||||
for (i = 0; i < gBattlersCount; i++)
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
gBattleControllerExecFlags |= 1u << (i + 32 - MAX_BATTLERS_COUNT);
|
MarkBattleControllerMessageOutboundOverLink(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < gBattlersCount; i++)
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
gBattleControllerExecFlags |= 1u << i;
|
MarkBattleControllerActiveOnLocal(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool32 IsBattlerMarkedForControllerExec(u32 battler)
|
bool32 IsBattlerMarkedForControllerExec(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||||
return (gBattleControllerExecFlags & (1u << (battler + 28))) != 0;
|
return IsBattleControllerMessageSynchronizedOverLink(battler);
|
||||||
else
|
else
|
||||||
return (gBattleControllerExecFlags & (1u << battler)) != 0;
|
return IsBattleControllerActiveOnLocal(battler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkBattlerForControllerExec(u32 battler)
|
void MarkBattlerForControllerExec(u32 battler)
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||||
gBattleControllerExecFlags |= 1u << (battler + 32 - MAX_BATTLERS_COUNT);
|
MarkBattleControllerMessageOutboundOverLink(battler);
|
||||||
else
|
else
|
||||||
gBattleControllerExecFlags |= 1u << battler;
|
MarkBattleControllerActiveOnLocal(battler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkBattlerReceivedLinkData(u32 battler)
|
void MarkBattlerReceivedLinkData(u32 battler)
|
||||||
@ -1018,9 +1018,9 @@ void MarkBattlerReceivedLinkData(u32 battler)
|
|||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < GetLinkPlayerCount(); i++)
|
for (i = 0; i < GetLinkPlayerCount(); i++)
|
||||||
gBattleControllerExecFlags |= 1u << (battler + (i << 2));
|
MarkBattleControllerActiveForPlayer(battler, i);
|
||||||
|
|
||||||
gBattleControllerExecFlags &= ~(1u << (28 + battler));
|
MarkBattleControllerMessageSynchronizedOverLink(battler);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState)
|
const u8 *CheckSkyDropState(u32 battler, enum SkyDropState skyDropState)
|
||||||
@ -3505,7 +3505,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
|
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
|
||||||
if (IsDoubleBattle())
|
if (IsDoubleBattle())
|
||||||
diagonalBattler = BATTLE_PARTNER(diagonalBattler);
|
diagonalBattler = BATTLE_PARTNER(diagonalBattler);
|
||||||
if (IsBattlerAlive(diagonalBattler)
|
|
||||||
|
// Imposter only activates when the battler first switches in
|
||||||
|
if (gDisableStructs[battler].isFirstTurn == 2
|
||||||
|
&& !gDisableStructs[battler].overwrittenAbility
|
||||||
|
&& IsBattlerAlive(diagonalBattler)
|
||||||
&& !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
|
&& !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
|
||||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||||
&& gBattleStruct->illusion[diagonalBattler].state != ILLUSION_ON
|
&& gBattleStruct->illusion[diagonalBattler].state != ILLUSION_ON
|
||||||
@ -4320,7 +4324,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_HUNGER_SWITCH:
|
case ABILITY_HUNGER_SWITCH:
|
||||||
if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END))
|
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||||
|
&& GetActiveGimmick(battler) != GIMMICK_TERA
|
||||||
|
&& TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END))
|
||||||
{
|
{
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
|
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
|
||||||
@ -6403,16 +6409,13 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
|
|||||||
effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, ITEMEFFECT_NONE);
|
effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, ITEMEFFECT_NONE);
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_ENIGMA_BERRY: // consume and heal if hit by super effective move
|
case HOLD_EFFECT_ENIGMA_BERRY: // consume and heal if hit by super effective move
|
||||||
if (B_BERRIES_INSTANT >= GEN_4)
|
effect = TrySetEnigmaBerry(battler);
|
||||||
effect = TrySetEnigmaBerry(battler);
|
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_KEE_BERRY: // consume and boost defense if used physical move
|
case HOLD_EFFECT_KEE_BERRY: // consume and boost defense if used physical move
|
||||||
if (B_BERRIES_INSTANT >= GEN_4)
|
effect = DamagedStatBoostBerryEffect(battler, STAT_DEF, DAMAGE_CATEGORY_PHYSICAL);
|
||||||
effect = DamagedStatBoostBerryEffect(battler, STAT_DEF, DAMAGE_CATEGORY_PHYSICAL);
|
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_MARANGA_BERRY: // consume and boost sp. defense if used special move
|
case HOLD_EFFECT_MARANGA_BERRY: // consume and boost sp. defense if used special move
|
||||||
if (B_BERRIES_INSTANT >= GEN_4)
|
effect = DamagedStatBoostBerryEffect(battler, STAT_SPDEF, DAMAGE_CATEGORY_SPECIAL);
|
||||||
effect = DamagedStatBoostBerryEffect(battler, STAT_SPDEF, DAMAGE_CATEGORY_SPECIAL);
|
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_RANDOM_STAT_UP:
|
case HOLD_EFFECT_RANDOM_STAT_UP:
|
||||||
if (B_BERRIES_INSTANT >= GEN_4)
|
if (B_BERRIES_INSTANT >= GEN_4)
|
||||||
|
|||||||
12
src/berry.c
12
src/berry.c
@ -2047,15 +2047,9 @@ static u8 GetNumStagesWateredByBerryTreeId(u8 id)
|
|||||||
return BerryTreeGetNumStagesWatered(GetBerryTreeInfo(id));
|
return BerryTreeGetNumStagesWatered(GetBerryTreeInfo(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Berries can be watered at 4 stages of growth. This function is likely meant
|
// Berries can be watered at 4 stages of growth. The distribution is largely
|
||||||
// to divide the berry yield range equally into quartiles. If you watered the
|
// even but slightly prefers middle berry yields, since it uniformly draws from
|
||||||
// tree n times, your yield is a random number in the nth quartile.
|
// a subset of the total yield range.
|
||||||
//
|
|
||||||
// However, this function actually skews towards higher berry yields, because
|
|
||||||
// it rounds `extraYield` to the nearest whole number.
|
|
||||||
//
|
|
||||||
// See resulting yields: https://gist.github.com/hondew/2a099dbe54aa91414decdbfaa524327d,
|
|
||||||
// and bug fix: https://gist.github.com/hondew/0f0164e5b9dadfd72d24f30f2c049a0b.
|
|
||||||
static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
|
static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
|
||||||
{
|
{
|
||||||
u32 randMin;
|
u32 randMin;
|
||||||
|
|||||||
@ -1243,7 +1243,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
|||||||
|
|
||||||
[EFFECT_MIRACLE_EYE] =
|
[EFFECT_MIRACLE_EYE] =
|
||||||
{
|
{
|
||||||
.battleScript = BattleScript_EffectMircleEye,
|
.battleScript = BattleScript_EffectMiracleEye,
|
||||||
.battleTvScore = 0, // TODO: Assign points
|
.battleTvScore = 0, // TODO: Assign points
|
||||||
.encourageEncore = TRUE,
|
.encourageEncore = TRUE,
|
||||||
},
|
},
|
||||||
@ -1966,6 +1966,12 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
|||||||
.battleTvScore = 0, // TODO: Assign points
|
.battleTvScore = 0, // TODO: Assign points
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[EFFECT_CHLOROBLAST] =
|
||||||
|
{
|
||||||
|
.battleScript = BattleScript_EffectHit,
|
||||||
|
.battleTvScore = 0, // TODO: Assign points
|
||||||
|
},
|
||||||
|
|
||||||
[EFFECT_EXTREME_EVOBOOST] =
|
[EFFECT_EXTREME_EVOBOOST] =
|
||||||
{
|
{
|
||||||
.battleScript = BattleScript_EffectExtremeEvoboost,
|
.battleScript = BattleScript_EffectExtremeEvoboost,
|
||||||
|
|||||||
@ -19172,7 +19172,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
|||||||
.description = COMPOUND_STRING(
|
.description = COMPOUND_STRING(
|
||||||
"将叶绿素凝聚后释放攻击。\n"
|
"将叶绿素凝聚后释放攻击。\n"
|
||||||
"自己也会受到伤害。"),
|
"自己也会受到伤害。"),
|
||||||
.effect = EFFECT_MAX_HP_50_RECOIL,
|
.effect = EFFECT_CHLOROBLAST,
|
||||||
.power = B_UPDATED_MOVE_DATA >= GEN_9 ? 150 : 120,
|
.power = B_UPDATED_MOVE_DATA >= GEN_9 ? 150 : 120,
|
||||||
.type = TYPE_GRASS,
|
.type = TYPE_GRASS,
|
||||||
.accuracy = 95,
|
.accuracy = 95,
|
||||||
|
|||||||
@ -528,6 +528,7 @@ void DoDiveWarp(void)
|
|||||||
TryFadeOutOldMapMusic();
|
TryFadeOutOldMapMusic();
|
||||||
WarpFadeOutScreen();
|
WarpFadeOutScreen();
|
||||||
PlayRainStoppingSoundEffect();
|
PlayRainStoppingSoundEffect();
|
||||||
|
SetFollowerNPCData(FNPC_DATA_COME_OUT_DOOR, FNPC_DOOR_NONE);
|
||||||
gFieldCallback = FieldCB_DefaultWarpExit;
|
gFieldCallback = FieldCB_DefaultWarpExit;
|
||||||
CreateTask(Task_WarpAndLoadMap, 10);
|
CreateTask(Task_WarpAndLoadMap, 10);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1172,7 +1172,7 @@ void CreateFollowerNPCAvatar(void)
|
|||||||
|
|
||||||
void FollowerNPC_HandleSprite(void)
|
void FollowerNPC_HandleSprite(void)
|
||||||
{
|
{
|
||||||
if (CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_BIKE))
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_BIKE) && CheckFollowerNPCFlag(FOLLOWER_NPC_FLAG_CAN_BIKE))
|
||||||
{
|
{
|
||||||
if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
|
if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
|
||||||
SetFollowerNPCSprite(FOLLOWER_NPC_SPRITE_INDEX_MACH_BIKE);
|
SetFollowerNPCSprite(FOLLOWER_NPC_SPRITE_INDEX_MACH_BIKE);
|
||||||
@ -1183,7 +1183,7 @@ void FollowerNPC_HandleSprite(void)
|
|||||||
{
|
{
|
||||||
TryUpdateFollowerNPCSpriteUnderwater();
|
TryUpdateFollowerNPCSpriteUnderwater();
|
||||||
}
|
}
|
||||||
else
|
else if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ON_FOOT)
|
||||||
{
|
{
|
||||||
SetFollowerNPCSprite(FOLLOWER_NPC_SPRITE_INDEX_NORMAL);
|
SetFollowerNPCSprite(FOLLOWER_NPC_SPRITE_INDEX_NORMAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1015,3 +1015,8 @@ u32 GetItemStatus2Mask(u16 itemId)
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetItemSellPrice(u32 itemId)
|
||||||
|
{
|
||||||
|
return GetItemPrice(itemId) / ITEM_SELL_FACTOR;
|
||||||
|
}
|
||||||
|
|||||||
@ -1458,7 +1458,7 @@ static void StartItemSwap(u8 taskId)
|
|||||||
{
|
{
|
||||||
s16 *data = gTasks[taskId].data;
|
s16 *data = gTasks[taskId].data;
|
||||||
|
|
||||||
ListMenuSetUnkIndicatorsStructField(tListTaskId, 16, 1);
|
ListMenuSetTemplateField(tListTaskId, LISTFIELD_CURSORKIND, CURSOR_INVISIBLE);
|
||||||
tListPosition = gBagPosition.scrollPosition[gBagPosition.pocket] + gBagPosition.cursorPosition[gBagPosition.pocket];
|
tListPosition = gBagPosition.scrollPosition[gBagPosition.pocket] + gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||||
gBagMenu->toSwapPos = tListPosition;
|
gBagMenu->toSwapPos = tListPosition;
|
||||||
CopyItemName(BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, tListPosition), gStringVar1);
|
CopyItemName(BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, tListPosition), gStringVar1);
|
||||||
@ -2122,6 +2122,11 @@ static void Task_ItemContext_Sell(u8 taskId)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
u32 maxQuantity = MAX_MONEY / GetItemSellPrice(gSpecialVar_ItemId);
|
||||||
|
|
||||||
|
if (tQuantity > maxQuantity)
|
||||||
|
tQuantity = maxQuantity;
|
||||||
|
|
||||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||||
StringExpandPlaceholders(gStringVar4, gText_HowManyToSell);
|
StringExpandPlaceholders(gStringVar4, gText_HowManyToSell);
|
||||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, InitSellHowManyInput);
|
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, InitSellHowManyInput);
|
||||||
@ -2129,13 +2134,11 @@ static void Task_ItemContext_Sell(u8 taskId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ITEM_SELL_FACTOR ((I_SELL_VALUE_FRACTION >= GEN_9) ? 4 : 2)
|
|
||||||
|
|
||||||
static void DisplaySellItemPriceAndConfirm(u8 taskId)
|
static void DisplaySellItemPriceAndConfirm(u8 taskId)
|
||||||
{
|
{
|
||||||
s16 *data = gTasks[taskId].data;
|
s16 *data = gTasks[taskId].data;
|
||||||
|
|
||||||
ConvertIntToDecimalStringN(gStringVar1, (GetItemPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_MONEY_DIGITS);
|
ConvertIntToDecimalStringN(gStringVar1, GetItemSellPrice(gSpecialVar_ItemId) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_MONEY_DIGITS);
|
||||||
StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1);
|
StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1);
|
||||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, AskSellItems);
|
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, AskSellItems);
|
||||||
}
|
}
|
||||||
@ -2160,7 +2163,7 @@ static void InitSellHowManyInput(u8 taskId)
|
|||||||
s16 *data = gTasks[taskId].data;
|
s16 *data = gTasks[taskId].data;
|
||||||
u8 windowId = BagMenu_AddWindow(ITEMWIN_QUANTITY_WIDE);
|
u8 windowId = BagMenu_AddWindow(ITEMWIN_QUANTITY_WIDE);
|
||||||
|
|
||||||
PrintItemSoldAmount(windowId, 1, (GetItemPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * tItemCount);
|
PrintItemSoldAmount(windowId, 1, GetItemSellPrice(gSpecialVar_ItemId) * tItemCount);
|
||||||
DisplayCurrentMoneyWindow();
|
DisplayCurrentMoneyWindow();
|
||||||
gTasks[taskId].func = Task_ChooseHowManyToSell;
|
gTasks[taskId].func = Task_ChooseHowManyToSell;
|
||||||
}
|
}
|
||||||
@ -2171,7 +2174,7 @@ static void Task_ChooseHowManyToSell(u8 taskId)
|
|||||||
|
|
||||||
if (AdjustQuantityAccordingToDPadInput(&tItemCount, tQuantity) == TRUE)
|
if (AdjustQuantityAccordingToDPadInput(&tItemCount, tQuantity) == TRUE)
|
||||||
{
|
{
|
||||||
PrintItemSoldAmount(gBagMenu->windowIds[ITEMWIN_QUANTITY_WIDE], tItemCount, (GetItemPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * tItemCount);
|
PrintItemSoldAmount(gBagMenu->windowIds[ITEMWIN_QUANTITY_WIDE], tItemCount, GetItemSellPrice(gSpecialVar_ItemId) * tItemCount);
|
||||||
}
|
}
|
||||||
else if (JOY_NEW(A_BUTTON))
|
else if (JOY_NEW(A_BUTTON))
|
||||||
{
|
{
|
||||||
@ -2195,7 +2198,7 @@ static void ConfirmSell(u8 taskId)
|
|||||||
s16 *data = gTasks[taskId].data;
|
s16 *data = gTasks[taskId].data;
|
||||||
|
|
||||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||||
ConvertIntToDecimalStringN(gStringVar1, (GetItemPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_MONEY_DIGITS);
|
ConvertIntToDecimalStringN(gStringVar1, GetItemSellPrice(gSpecialVar_ItemId) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_MONEY_DIGITS);
|
||||||
StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2);
|
StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2);
|
||||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, SellItem);
|
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, SellItem);
|
||||||
}
|
}
|
||||||
@ -2208,7 +2211,7 @@ static void SellItem(u8 taskId)
|
|||||||
|
|
||||||
PlaySE(SE_SHOP);
|
PlaySE(SE_SHOP);
|
||||||
RemoveBagItem(gSpecialVar_ItemId, tItemCount);
|
RemoveBagItem(gSpecialVar_ItemId, tItemCount);
|
||||||
AddMoney(&gSaveBlock1Ptr->money, (GetItemPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * tItemCount);
|
AddMoney(&gSaveBlock1Ptr->money, GetItemSellPrice(gSpecialVar_ItemId) * tItemCount);
|
||||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||||
UpdatePocketItemList(gBagPosition.pocket);
|
UpdatePocketItemList(gBagPosition.pocket);
|
||||||
UpdatePocketListPosition(gBagPosition.pocket);
|
UpdatePocketListPosition(gBagPosition.pocket);
|
||||||
|
|||||||
163
src/list_menu.c
163
src/list_menu.c
@ -17,29 +17,6 @@
|
|||||||
// This allows them to have idle animations. Cursors prior to this are simply printed text.
|
// This allows them to have idle animations. Cursors prior to this are simply printed text.
|
||||||
#define CURSOR_OBJECT_START CURSOR_RED_OUTLINE
|
#define CURSOR_OBJECT_START CURSOR_RED_OUTLINE
|
||||||
|
|
||||||
struct UnkIndicatorsStruct
|
|
||||||
{
|
|
||||||
u8 field_0;
|
|
||||||
u16 *field_4;
|
|
||||||
u16 field_8;
|
|
||||||
u16 field_A;
|
|
||||||
u16 field_C;
|
|
||||||
u16 field_E;
|
|
||||||
u8 field_10;
|
|
||||||
u8 field_11;
|
|
||||||
u8 field_12;
|
|
||||||
u8 field_13;
|
|
||||||
u8 field_14_0:4;
|
|
||||||
u8 field_14_1:4;
|
|
||||||
u8 field_15_0:4;
|
|
||||||
u8 field_15_1:4;
|
|
||||||
u8 field_16_0:3;
|
|
||||||
u8 field_16_1:3;
|
|
||||||
u8 field_16_2:2;
|
|
||||||
u8 field_17_0:6;
|
|
||||||
u8 field_17_1:2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScrollIndicatorPair
|
struct ScrollIndicatorPair
|
||||||
{
|
{
|
||||||
u8 field_0;
|
u8 field_0;
|
||||||
@ -916,104 +893,104 @@ void ListMenuDefaultCursorMoveFunc(s32 itemIndex, bool8 onInit, struct ListMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unused
|
// unused
|
||||||
s32 ListMenuGetUnkIndicatorsStructFields(u8 taskId, u8 field)
|
s32 ListMenuGetTemplateField(u8 taskId, u8 field)
|
||||||
{
|
{
|
||||||
struct UnkIndicatorsStruct *data = (void *) gTasks[taskId].data;
|
struct ListMenu *data = (void *) gTasks[taskId].data;
|
||||||
|
|
||||||
switch (field)
|
switch (field)
|
||||||
{
|
{
|
||||||
case 0:
|
case LISTFIELD_MOVECURSORFUNC:
|
||||||
case 1:
|
case LISTFIELD_MOVECURSORFUNC2:
|
||||||
return (s32)(data->field_4);
|
return (s32)(data->template.moveCursorFunc);
|
||||||
case 2:
|
case LISTFIELD_TOTALITEMS:
|
||||||
return data->field_C;
|
return data->template.totalItems;
|
||||||
case 3:
|
case LISTFIELD_MAXSHOWED:
|
||||||
return data->field_E;
|
return data->template.maxShowed;
|
||||||
case 4:
|
case LISTFIELD_WINDOWID:
|
||||||
return data->field_10;
|
return data->template.windowId;
|
||||||
case 5:
|
case LISTFIELD_HEADERX:
|
||||||
return data->field_11;
|
return data->template.header_X;
|
||||||
case 6:
|
case LISTFIELD_ITEMX:
|
||||||
return data->field_12;
|
return data->template.item_X;
|
||||||
case 7:
|
case LISTFIELD_CURSORX:
|
||||||
return data->field_13;
|
return data->template.cursor_X;
|
||||||
case 8:
|
case LISTFIELD_UPTEXTY:
|
||||||
return data->field_14_0;
|
return data->template.upText_Y;
|
||||||
case 9:
|
case LISTFIELD_CURSORPAL:
|
||||||
return data->field_14_1;
|
return data->template.cursorPal;
|
||||||
case 10:
|
case LISTFIELD_FILLVALUE:
|
||||||
return data->field_15_0;
|
return data->template.fillValue;
|
||||||
case 11:
|
case LISTFIELD_CURSORSHADOWPAL:
|
||||||
return data->field_15_1;
|
return data->template.cursorShadowPal;
|
||||||
case 12:
|
case LISTFIELD_LETTERSPACING:
|
||||||
return data->field_16_0;
|
return data->template.lettersSpacing;
|
||||||
case 13:
|
case LISTFIELD_ITEMVERTICALPADDING:
|
||||||
return data->field_16_1;
|
return data->template.itemVerticalPadding;
|
||||||
case 14:
|
case LISTFIELD_SCROLLMULTIPLE:
|
||||||
return data->field_16_2;
|
return data->template.scrollMultiple;
|
||||||
case 15:
|
case LISTFIELD_FONTID:
|
||||||
return data->field_17_0;
|
return data->template.fontId;
|
||||||
case 16:
|
case LISTFIELD_CURSORKIND:
|
||||||
return data->field_17_1;
|
return data->template.cursorKind;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListMenuSetUnkIndicatorsStructField(u8 taskId, u8 field, s32 value)
|
void ListMenuSetTemplateField(u8 taskId, u8 field, s32 value)
|
||||||
{
|
{
|
||||||
struct UnkIndicatorsStruct *data = (void *) &gTasks[taskId].data;
|
struct ListMenu *data = (void *) &gTasks[taskId].data;
|
||||||
|
|
||||||
switch (field)
|
switch (field)
|
||||||
{
|
{
|
||||||
case 0:
|
case LISTFIELD_MOVECURSORFUNC:
|
||||||
case 1:
|
case LISTFIELD_MOVECURSORFUNC2:
|
||||||
data->field_4 = (void *)(value);
|
data->template.moveCursorFunc = (void *)value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case LISTFIELD_TOTALITEMS:
|
||||||
data->field_C = value;
|
data->template.totalItems = value;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case LISTFIELD_MAXSHOWED:
|
||||||
data->field_E = value;
|
data->template.maxShowed = value;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case LISTFIELD_WINDOWID:
|
||||||
data->field_10 = value;
|
data->template.windowId = value;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case LISTFIELD_HEADERX:
|
||||||
data->field_11 = value;
|
data->template.header_X = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case LISTFIELD_ITEMX:
|
||||||
data->field_12 = value;
|
data->template.item_X = value;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case LISTFIELD_CURSORX:
|
||||||
data->field_13 = value;
|
data->template.cursor_X = value;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case LISTFIELD_UPTEXTY:
|
||||||
data->field_14_0 = value;
|
data->template.upText_Y = value;
|
||||||
break;
|
break;
|
||||||
case 9:
|
case LISTFIELD_CURSORPAL:
|
||||||
data->field_14_1 = value;
|
data->template.cursorPal = value;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case LISTFIELD_FILLVALUE:
|
||||||
data->field_15_0 = value;
|
data->template.fillValue = value;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case LISTFIELD_CURSORSHADOWPAL:
|
||||||
data->field_15_1 = value;
|
data->template.cursorShadowPal = value;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case LISTFIELD_LETTERSPACING:
|
||||||
data->field_16_0 = value;
|
data->template.lettersSpacing = value;
|
||||||
break;
|
break;
|
||||||
case 13:
|
case LISTFIELD_ITEMVERTICALPADDING:
|
||||||
data->field_16_1 = value;
|
data->template.itemVerticalPadding = value;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case LISTFIELD_SCROLLMULTIPLE:
|
||||||
data->field_16_2 = value;
|
data->template.scrollMultiple = value;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case LISTFIELD_FONTID:
|
||||||
data->field_17_0 = value;
|
data->template.fontId = value;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case LISTFIELD_CURSORKIND:
|
||||||
data->field_17_1 = value;
|
data->template.cursorKind = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -181,7 +181,7 @@ static EWRAM_DATA struct {
|
|||||||
u16 listOffset;
|
u16 listOffset;
|
||||||
u16 listRow;
|
u16 listRow;
|
||||||
bool8 showContestInfo;
|
bool8 showContestInfo;
|
||||||
} sMoveRelearnerMenuSate = {0};
|
} sMoveRelearnerMenuState = {0};
|
||||||
|
|
||||||
EWRAM_DATA u8 gOriginSummaryScreenPage = 0; // indicates summary screen page that the move relearner was opened from (if opened from PSS)
|
EWRAM_DATA u8 gOriginSummaryScreenPage = 0; // indicates summary screen page that the move relearner was opened from (if opened from PSS)
|
||||||
|
|
||||||
@ -404,9 +404,9 @@ void CB2_InitLearnMove(void)
|
|||||||
InitMoveRelearnerBackgroundLayers();
|
InitMoveRelearnerBackgroundLayers();
|
||||||
InitMoveRelearnerWindows(gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES);
|
InitMoveRelearnerWindows(gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES);
|
||||||
|
|
||||||
sMoveRelearnerMenuSate.listOffset = 0;
|
sMoveRelearnerMenuState.listOffset = 0;
|
||||||
sMoveRelearnerMenuSate.listRow = 0;
|
sMoveRelearnerMenuState.listRow = 0;
|
||||||
sMoveRelearnerMenuSate.showContestInfo = gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES;
|
sMoveRelearnerMenuState.showContestInfo = gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES;
|
||||||
|
|
||||||
CreateLearnableMovesList();
|
CreateLearnableMovesList();
|
||||||
|
|
||||||
@ -414,7 +414,7 @@ void CB2_InitLearnMove(void)
|
|||||||
LoadSpritePalette(&sMoveRelearnerPalette);
|
LoadSpritePalette(&sMoveRelearnerPalette);
|
||||||
CreateUISprites();
|
CreateUISprites();
|
||||||
|
|
||||||
sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuSate.listOffset, sMoveRelearnerMenuSate.listRow);
|
sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuState.listOffset, sMoveRelearnerMenuState.listRow);
|
||||||
SetBackdropFromColor(RGB_BLACK);
|
SetBackdropFromColor(RGB_BLACK);
|
||||||
SetMainCallback2(CB2_MoveRelearnerMain);
|
SetMainCallback2(CB2_MoveRelearnerMain);
|
||||||
}
|
}
|
||||||
@ -432,14 +432,14 @@ static void CB2_InitLearnMoveReturnFromSelectMove(void)
|
|||||||
SetVBlankCallback(VBlankCB_MoveRelearner);
|
SetVBlankCallback(VBlankCB_MoveRelearner);
|
||||||
|
|
||||||
InitMoveRelearnerBackgroundLayers();
|
InitMoveRelearnerBackgroundLayers();
|
||||||
InitMoveRelearnerWindows(sMoveRelearnerMenuSate.showContestInfo);
|
InitMoveRelearnerWindows(sMoveRelearnerMenuState.showContestInfo);
|
||||||
CreateLearnableMovesList();
|
CreateLearnableMovesList();
|
||||||
|
|
||||||
LoadSpriteSheet(&sMoveRelearnerSpriteSheet);
|
LoadSpriteSheet(&sMoveRelearnerSpriteSheet);
|
||||||
LoadSpritePalette(&sMoveRelearnerPalette);
|
LoadSpritePalette(&sMoveRelearnerPalette);
|
||||||
CreateUISprites();
|
CreateUISprites();
|
||||||
|
|
||||||
sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuSate.listOffset, sMoveRelearnerMenuSate.listRow);
|
sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuState.listOffset, sMoveRelearnerMenuState.listRow);
|
||||||
SetBackdropFromColor(RGB_BLACK);
|
SetBackdropFromColor(RGB_BLACK);
|
||||||
SetMainCallback2(CB2_MoveRelearnerMain);
|
SetMainCallback2(CB2_MoveRelearnerMain);
|
||||||
}
|
}
|
||||||
@ -541,11 +541,11 @@ static void DoMoveRelearnerMain(void)
|
|||||||
}
|
}
|
||||||
else if (selection == MENU_B_PRESSED || selection == 1)
|
else if (selection == MENU_B_PRESSED || selection == 1)
|
||||||
{
|
{
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
|
if (sMoveRelearnerMenuState.showContestInfo == FALSE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
||||||
}
|
}
|
||||||
else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
|
else if (sMoveRelearnerMenuState.showContestInfo == TRUE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
||||||
}
|
}
|
||||||
@ -570,11 +570,11 @@ static void DoMoveRelearnerMain(void)
|
|||||||
}
|
}
|
||||||
else if (selection == MENU_B_PRESSED || selection == 1)
|
else if (selection == MENU_B_PRESSED || selection == 1)
|
||||||
{
|
{
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
|
if (sMoveRelearnerMenuState.showContestInfo == FALSE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
||||||
}
|
}
|
||||||
else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
|
else if (sMoveRelearnerMenuState.showContestInfo == TRUE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
||||||
}
|
}
|
||||||
@ -630,11 +630,11 @@ static void DoMoveRelearnerMain(void)
|
|||||||
else if (selection == MENU_B_PRESSED || selection == 1)
|
else if (selection == MENU_B_PRESSED || selection == 1)
|
||||||
{
|
{
|
||||||
// What's the point? It gets set to MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT, anyway.
|
// What's the point? It gets set to MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT, anyway.
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
|
if (sMoveRelearnerMenuState.showContestInfo == FALSE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
||||||
}
|
}
|
||||||
else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
|
else if (sMoveRelearnerMenuState.showContestInfo == TRUE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
||||||
}
|
}
|
||||||
@ -646,11 +646,11 @@ static void DoMoveRelearnerMain(void)
|
|||||||
if (!MoveRelearnerRunTextPrinters())
|
if (!MoveRelearnerRunTextPrinters())
|
||||||
{
|
{
|
||||||
FillWindowPixelBuffer(RELEARNERWIN_MSG, 0x11);
|
FillWindowPixelBuffer(RELEARNERWIN_MSG, 0x11);
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
|
if (sMoveRelearnerMenuState.showContestInfo == FALSE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
||||||
}
|
}
|
||||||
else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
|
else if (sMoveRelearnerMenuState.showContestInfo == TRUE)
|
||||||
{
|
{
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
||||||
}
|
}
|
||||||
@ -713,11 +713,11 @@ static void DoMoveRelearnerMain(void)
|
|||||||
case MENU_STATE_FADE_FROM_SUMMARY_SCREEN:
|
case MENU_STATE_FADE_FROM_SUMMARY_SCREEN:
|
||||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
|
||||||
sMoveRelearnerStruct->state++;
|
sMoveRelearnerStruct->state++;
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
|
if (sMoveRelearnerMenuState.showContestInfo == FALSE)
|
||||||
{
|
{
|
||||||
HideHeartSpritesAndShowTeachMoveText(TRUE);
|
HideHeartSpritesAndShowTeachMoveText(TRUE);
|
||||||
}
|
}
|
||||||
else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
|
else if (sMoveRelearnerMenuState.showContestInfo == TRUE)
|
||||||
{
|
{
|
||||||
ShowTeachMoveText(TRUE);
|
ShowTeachMoveText(TRUE);
|
||||||
}
|
}
|
||||||
@ -783,7 +783,7 @@ static void DoMoveRelearnerMain(void)
|
|||||||
static void FreeMoveRelearnerResources(void)
|
static void FreeMoveRelearnerResources(void)
|
||||||
{
|
{
|
||||||
RemoveScrollArrows();
|
RemoveScrollArrows();
|
||||||
DestroyListMenuTask(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuSate.listOffset, &sMoveRelearnerMenuSate.listRow);
|
DestroyListMenuTask(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuState.listOffset, &sMoveRelearnerMenuState.listRow);
|
||||||
FreeAllWindowBuffers();
|
FreeAllWindowBuffers();
|
||||||
FREE_AND_SET_NULL(sMoveRelearnerStruct);
|
FREE_AND_SET_NULL(sMoveRelearnerStruct);
|
||||||
ResetSpriteData();
|
ResetSpriteData();
|
||||||
@ -810,7 +810,7 @@ static void HideHeartSpritesAndShowTeachMoveText(bool8 onlyHideSprites)
|
|||||||
static void HandleInput(bool8 showContest)
|
static void HandleInput(bool8 showContest)
|
||||||
{
|
{
|
||||||
s32 itemId = ListMenu_ProcessInput(sMoveRelearnerStruct->moveListMenuTask);
|
s32 itemId = ListMenu_ProcessInput(sMoveRelearnerStruct->moveListMenuTask);
|
||||||
ListMenuGetScrollAndRow(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuSate.listOffset, &sMoveRelearnerMenuSate.listRow);
|
ListMenuGetScrollAndRow(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuState.listOffset, &sMoveRelearnerMenuState.listRow);
|
||||||
|
|
||||||
switch (itemId)
|
switch (itemId)
|
||||||
{
|
{
|
||||||
@ -824,13 +824,13 @@ static void HandleInput(bool8 showContest)
|
|||||||
{
|
{
|
||||||
PutWindowTilemap(RELEARNERWIN_DESC_CONTEST);
|
PutWindowTilemap(RELEARNERWIN_DESC_CONTEST);
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
|
||||||
sMoveRelearnerMenuSate.showContestInfo = TRUE;
|
sMoveRelearnerMenuState.showContestInfo = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PutWindowTilemap(RELEARNERWIN_DESC_BATTLE);
|
PutWindowTilemap(RELEARNERWIN_DESC_BATTLE);
|
||||||
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
|
||||||
sMoveRelearnerMenuSate.showContestInfo = FALSE;
|
sMoveRelearnerMenuState.showContestInfo = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleBgCopyTilemapToVram(1);
|
ScheduleBgCopyTilemapToVram(1);
|
||||||
@ -859,7 +859,7 @@ static void HandleInput(bool8 showContest)
|
|||||||
|
|
||||||
static s32 GetCurrentSelectedMove(void)
|
static s32 GetCurrentSelectedMove(void)
|
||||||
{
|
{
|
||||||
return sMoveRelearnerStruct->menuItems[sMoveRelearnerMenuSate.listRow + sMoveRelearnerMenuSate.listOffset].id;
|
return sMoveRelearnerStruct->menuItems[sMoveRelearnerMenuState.listRow + sMoveRelearnerMenuState.listOffset].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Theory: This used to make the heart sprites visible again (i.e.
|
// Theory: This used to make the heart sprites visible again (i.e.
|
||||||
@ -915,7 +915,7 @@ static void AddScrollArrows(void)
|
|||||||
{
|
{
|
||||||
gTempScrollArrowTemplate = sMoveListScrollArrowsTemplate;
|
gTempScrollArrowTemplate = sMoveListScrollArrowsTemplate;
|
||||||
gTempScrollArrowTemplate.fullyDownThreshold = sMoveRelearnerStruct->numMenuChoices - sMoveRelearnerStruct->numToShowAtOnce;
|
gTempScrollArrowTemplate.fullyDownThreshold = sMoveRelearnerStruct->numMenuChoices - sMoveRelearnerStruct->numToShowAtOnce;
|
||||||
sMoveRelearnerStruct->moveListScrollArrowTask = AddScrollIndicatorArrowPair(&gTempScrollArrowTemplate, &sMoveRelearnerMenuSate.listOffset);
|
sMoveRelearnerStruct->moveListScrollArrowTask = AddScrollIndicatorArrowPair(&gTempScrollArrowTemplate, &sMoveRelearnerMenuState.listOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,7 +960,7 @@ void MoveRelearnerShowHideHearts(s32 move)
|
|||||||
u16 numHearts;
|
u16 numHearts;
|
||||||
u16 i;
|
u16 i;
|
||||||
|
|
||||||
if (!sMoveRelearnerMenuSate.showContestInfo || move == LIST_CANCEL)
|
if (!sMoveRelearnerMenuState.showContestInfo || move == LIST_CANCEL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE;
|
gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE;
|
||||||
@ -999,7 +999,7 @@ void MoveRelearnerShowHideHearts(s32 move)
|
|||||||
|
|
||||||
void MoveRelearnerShowHideCategoryIcon(s32 moveId)
|
void MoveRelearnerShowHideCategoryIcon(s32 moveId)
|
||||||
{
|
{
|
||||||
if (sMoveRelearnerMenuSate.showContestInfo || moveId == LIST_CANCEL)
|
if (sMoveRelearnerMenuState.showContestInfo || moveId == LIST_CANCEL)
|
||||||
{
|
{
|
||||||
if (sMoveRelearnerStruct->categoryIconSpriteId != 0xFF)
|
if (sMoveRelearnerStruct->categoryIconSpriteId != 0xFF)
|
||||||
DestroySprite(&gSprites[sMoveRelearnerStruct->categoryIconSpriteId]);
|
DestroySprite(&gSprites[sMoveRelearnerStruct->categoryIconSpriteId]);
|
||||||
|
|||||||
@ -1816,6 +1816,7 @@ void CB2_WhiteOut(void)
|
|||||||
else
|
else
|
||||||
gFieldCallback = FieldCB_WarpExitFadeFromBlack;
|
gFieldCallback = FieldCB_WarpExitFadeFromBlack;
|
||||||
state = 0;
|
state = 0;
|
||||||
|
SetFollowerNPCData(FNPC_DATA_SURF_BLOB, FNPC_SURF_BLOB_NONE);
|
||||||
DoMapLoadLoop(&state);
|
DoMapLoadLoop(&state);
|
||||||
SetFieldVBlankCallback();
|
SetFieldVBlankCallback();
|
||||||
SetMainCallback1(CB1_Overworld);
|
SetMainCallback1(CB1_Overworld);
|
||||||
|
|||||||
@ -828,7 +828,7 @@ void BlendPalettes(u32 selectedPalettes, u8 coeff, u32 color)
|
|||||||
BlendPalettesFine(selectedPalettes, gPlttBufferUnfaded, gPlttBufferFaded, coeff, color);
|
BlendPalettesFine(selectedPalettes, gPlttBufferUnfaded, gPlttBufferFaded, coeff, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_LIGHT_COLOR 0x3f9f
|
#define DEFAULT_LIGHT_COLOR RGB2GBA(248, 224, 120)
|
||||||
|
|
||||||
// Like BlendPalette, but ignores blendColor if the transparency high bit is set
|
// Like BlendPalette, but ignores blendColor if the transparency high bit is set
|
||||||
// Optimization help by lucktyphlosion
|
// Optimization help by lucktyphlosion
|
||||||
|
|||||||
@ -1284,7 +1284,7 @@ static void ItemStorage_ExitItemList(u8 taskId)
|
|||||||
static void ItemStorage_StartItemSwap(u8 taskId)
|
static void ItemStorage_StartItemSwap(u8 taskId)
|
||||||
{
|
{
|
||||||
s16 *data = gTasks[taskId].data;
|
s16 *data = gTasks[taskId].data;
|
||||||
ListMenuSetUnkIndicatorsStructField(tListTaskId, 16, 1);
|
ListMenuSetTemplateField(tListTaskId, LISTFIELD_CURSORKIND, CURSOR_INVISIBLE);
|
||||||
sItemStorageMenu->toSwapPos = gPlayerPCItemPageInfo.itemsAbove + gPlayerPCItemPageInfo.cursorPos;
|
sItemStorageMenu->toSwapPos = gPlayerPCItemPageInfo.itemsAbove + gPlayerPCItemPageInfo.cursorPos;
|
||||||
ItemStorage_SetSwapArrow(tListTaskId, 0, 0);
|
ItemStorage_SetSwapArrow(tListTaskId, 0, 0);
|
||||||
ItemStorage_UpdateSwapLinePos(sItemStorageMenu->toSwapPos);
|
ItemStorage_UpdateSwapLinePos(sItemStorageMenu->toSwapPos);
|
||||||
|
|||||||
@ -99,7 +99,7 @@ struct GFRomHeader
|
|||||||
// This seems to need to be in the text section for some reason.
|
// This seems to need to be in the text section for some reason.
|
||||||
// To avoid a changed section attributes warning it's put in a special .text.consts section.
|
// To avoid a changed section attributes warning it's put in a special .text.consts section.
|
||||||
__attribute__((section(".text.consts")))
|
__attribute__((section(".text.consts")))
|
||||||
static const struct GFRomHeader sGFRomHeader = {
|
USED static const struct GFRomHeader sGFRomHeader = {
|
||||||
.version = GAME_VERSION,
|
.version = GAME_VERSION,
|
||||||
.language = GAME_LANGUAGE,
|
.language = GAME_LANGUAGE,
|
||||||
.gameName = "pokemon emerald version",
|
.gameName = "pokemon emerald version",
|
||||||
|
|||||||
@ -28,7 +28,7 @@ struct RHHRomHeader
|
|||||||
};
|
};
|
||||||
|
|
||||||
__attribute__((section(".text.consts")))
|
__attribute__((section(".text.consts")))
|
||||||
static const struct RHHRomHeader sRHHRomHeader =
|
USED static const struct RHHRomHeader sRHHRomHeader =
|
||||||
{
|
{
|
||||||
.rhh_magic = { 'R', 'H', 'H', 'E', 'X', 'P' },
|
.rhh_magic = { 'R', 'H', 'H', 'E', 'X', 'P' },
|
||||||
.expansionVersionMajor = EXPANSION_VERSION_MAJOR,
|
.expansionVersionMajor = EXPANSION_VERSION_MAJOR,
|
||||||
|
|||||||
@ -384,49 +384,9 @@ enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area
|
|||||||
if (!OW_TIME_OF_DAY_ENCOUNTERS)
|
if (!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||||
return TIME_OF_DAY_DEFAULT;
|
return TIME_OF_DAY_DEFAULT;
|
||||||
|
|
||||||
if (InBattlePike())
|
if (InBattlePike() || InBattlePyramid())
|
||||||
{
|
{
|
||||||
switch (area)
|
return OW_TIME_OF_DAY_FALLBACK;
|
||||||
{
|
|
||||||
default:
|
|
||||||
case WILD_AREA_LAND:
|
|
||||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_WATER:
|
|
||||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_ROCKS:
|
|
||||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_FISHING:
|
|
||||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_HIDDEN:
|
|
||||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (InBattlePyramid())
|
|
||||||
{
|
|
||||||
switch (area)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case WILD_AREA_LAND:
|
|
||||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_WATER:
|
|
||||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_ROCKS:
|
|
||||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_FISHING:
|
|
||||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
|
||||||
break;
|
|
||||||
case WILD_AREA_HIDDEN:
|
|
||||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -732,9 +692,9 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
|||||||
|
|
||||||
if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else if (WildEncounterCheck(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
else if (WildEncounterCheck(gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
else if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
GenerateBattlePyramidWildMon();
|
GenerateBattlePyramidWildMon();
|
||||||
|
|||||||
@ -22,3 +22,52 @@ SINGLE_BATTLE_TEST("Hunger Switch switches Morpeko's forms at the end of the tur
|
|||||||
EXPECT_EQ(player->species, SPECIES_MORPEKO_FULL_BELLY);
|
EXPECT_EQ(player->species, SPECIES_MORPEKO_FULL_BELLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Hunger Switch does not switch a mon transformed into Morpeko's form")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetMoveEffect(MOVE_TRANSFORM) == EFFECT_TRANSFORM);
|
||||||
|
PLAYER(SPECIES_MORPEKO) { Ability(ABILITY_HUNGER_SWITCH); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_TRANSFORM); }
|
||||||
|
} SCENE {
|
||||||
|
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Hunger Switch does not switch Morpeko's form when Terastallized")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_MORPEKO) { Ability(ABILITY_HUNGER_SWITCH); TeraType(TYPE_NORMAL); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { }
|
||||||
|
TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_TERA); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
|
||||||
|
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Hunger Switch does not switch Morpeko's form after switching out while Terastallized")
|
||||||
|
{
|
||||||
|
KNOWN_FAILING; // #7062
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR);
|
||||||
|
PLAYER(SPECIES_MORPEKO) { Ability(ABILITY_HUNGER_SWITCH); TeraType(TYPE_NORMAL); }
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { }
|
||||||
|
TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_ROAR); }
|
||||||
|
TURN { SWITCH(player, 0); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
|
||||||
|
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->species, SPECIES_MORPEKO_HANGRY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -256,7 +256,8 @@ SINGLE_BATTLE_TEST("Neutralizing Gas prevents Trace from copying it")
|
|||||||
SINGLE_BATTLE_TEST("Neutralizing Gas prevents Contrary inverting stat boosts")
|
SINGLE_BATTLE_TEST("Neutralizing Gas prevents Contrary inverting stat boosts")
|
||||||
{
|
{
|
||||||
GIVEN {
|
GIVEN {
|
||||||
ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
|
ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
|
||||||
|
ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
|
||||||
PLAYER(SPECIES_INKAY) { Ability(ABILITY_CONTRARY); }
|
PLAYER(SPECIES_INKAY) { Ability(ABILITY_CONTRARY); }
|
||||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||||
} WHEN {
|
} WHEN {
|
||||||
@ -271,3 +272,41 @@ SINGLE_BATTLE_TEST("Neutralizing Gas prevents Contrary inverting stat boosts")
|
|||||||
EXPECT_LT(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
EXPECT_LT(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Neutralizing Gas exiting the field does not activate abilities that were not suppressed by it again")
|
||||||
|
{
|
||||||
|
u32 species, ability;
|
||||||
|
// These are the only abilities that could immediately activate again
|
||||||
|
PARAMETRIZE { species = SPECIES_KOMALA; ability = ABILITY_COMATOSE; }
|
||||||
|
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; }
|
||||||
|
PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(gAbilitiesInfo[ability].cantBeSuppressed);
|
||||||
|
PLAYER(species) { Ability(ability); }
|
||||||
|
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { SWITCH(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
ABILITY_POPUP(player, ability);
|
||||||
|
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||||
|
NOT ABILITY_POPUP(player, ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Neutralizing Gas exiting the field does not activate Imposter even if it did not activate before")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
PLAYER(SPECIES_DITTO) { Ability(ABILITY_IMPOSTER); }
|
||||||
|
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
NOT ABILITY_POPUP(player, ABILITY_IMPOSTER);
|
||||||
|
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||||
|
NOT ABILITY_POPUP(player, ABILITY_IMPOSTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -80,40 +80,52 @@ SINGLE_BATTLE_TEST("Normalize still makes Freeze-Dry do super effective damage t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SINGLE_BATTLE_TEST("Normalize boosts power of unaffected moves by 20% (Gen7+)", s16 damage)
|
SINGLE_BATTLE_TEST("Normalize doesn't boost power of unaffected moves by 20% (< Gen7)", s16 damage)
|
||||||
{
|
{
|
||||||
u32 ability, genConfig;
|
u32 ability;
|
||||||
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_7; }
|
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; }
|
||||||
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_6; }
|
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
|
||||||
PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_7; }
|
|
||||||
PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_6; }
|
|
||||||
|
|
||||||
GIVEN {
|
GIVEN {
|
||||||
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, genConfig);
|
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, GEN_6);
|
||||||
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_TACKLE); }
|
PLAYER(SPECIES_DELCATTY) { Ability(ability); }
|
||||||
OPPONENT(SPECIES_WOBBUFFET);
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
} WHEN {
|
} WHEN {
|
||||||
TURN { MOVE(player, MOVE_TACKLE); }
|
TURN { MOVE(player, MOVE_POUND); }
|
||||||
} SCENE {
|
} SCENE {
|
||||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
if (genConfig >= GEN_7)
|
EXPECT_EQ(results[0].damage, results[1].damage); // No boost
|
||||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.2), results[2].damage); // Ate
|
|
||||||
else
|
|
||||||
EXPECT_EQ(results[1].damage, results[3].damage); // No boost
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SINGLE_BATTLE_TEST("Normalize boosts power of affected moves by 20% (Gen7+)", s16 damage)
|
SINGLE_BATTLE_TEST("Normalize boosts power of unaffected moves by 20% (Gen7+)", s16 damage)
|
||||||
{
|
{
|
||||||
u32 ability, genConfig;
|
u32 ability;
|
||||||
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_7; }
|
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; }
|
||||||
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; genConfig = GEN_6; }
|
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
|
||||||
PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_7; }
|
|
||||||
PARAMETRIZE { ability = ABILITY_NORMALIZE; genConfig = GEN_6; }
|
|
||||||
|
|
||||||
GIVEN {
|
GIVEN {
|
||||||
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, genConfig);
|
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, GEN_7);
|
||||||
|
PLAYER(SPECIES_DELCATTY) { Ability(ability); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_POUND); }
|
||||||
|
} SCENE {
|
||||||
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
|
} FINALLY {
|
||||||
|
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(1.2), results[1].damage); // Ate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Normalize doesn't boost power of affected moves by 20% (< Gen7)", s16 damage)
|
||||||
|
{
|
||||||
|
u32 ability;
|
||||||
|
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; }
|
||||||
|
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, GEN_6);
|
||||||
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); }
|
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); }
|
||||||
OPPONENT(SPECIES_WOBBUFFET);
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
} WHEN {
|
} WHEN {
|
||||||
@ -121,10 +133,26 @@ SINGLE_BATTLE_TEST("Normalize boosts power of affected moves by 20% (Gen7+)", s1
|
|||||||
} SCENE {
|
} SCENE {
|
||||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
if (genConfig >= GEN_7)
|
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); // STAB + no ate
|
||||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.8), results[2].damage); // STAB + ate
|
}
|
||||||
else
|
}
|
||||||
EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[3].damage); // STAB + no ate
|
|
||||||
|
SINGLE_BATTLE_TEST("Normalize boosts power of affected moves by 20% (Gen7+)", s16 damage)
|
||||||
|
{
|
||||||
|
u32 ability;
|
||||||
|
PARAMETRIZE { ability = ABILITY_CUTE_CHARM; }
|
||||||
|
PARAMETRIZE { ability = ABILITY_NORMALIZE; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
WITH_CONFIG(GEN_CONFIG_ATE_MULTIPLIER, GEN_7);
|
||||||
|
PLAYER(SPECIES_SKITTY) { Ability(ability); Moves(MOVE_WATER_GUN); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_WATER_GUN); }
|
||||||
|
} SCENE {
|
||||||
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
|
} FINALLY {
|
||||||
|
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.8), results[1].damage); // STAB + ate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,3 +2,18 @@
|
|||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("TODO: Write Wandering Spirit (Ability) test titles")
|
TO_DO_BATTLE_TEST("TODO: Write Wandering Spirit (Ability) test titles")
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Wandering Spirit copied ability should not trigger on fainted mon")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||||
|
PLAYER(SPECIES_WOBBUFFET)
|
||||||
|
OPPONENT(SPECIES_YAMASK_GALAR) { HP(1); Ability(ABILITY_WANDERING_SPIRIT); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_POISON_FANG); SEND_OUT(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_POISON_FANG, player);
|
||||||
|
NOT ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1016,7 +1016,6 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac
|
|||||||
|
|
||||||
AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch into mon with good type matchup and SE move if current mon has no SE move and no stats raised")
|
AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch into mon with good type matchup and SE move if current mon has no SE move and no stats raised")
|
||||||
{
|
{
|
||||||
KNOWN_FAILING; // Either remove or replace the function
|
|
||||||
u32 odds = 0, species = SPECIES_NONE, move = MOVE_NONE;
|
u32 odds = 0, species = SPECIES_NONE, move = MOVE_NONE;
|
||||||
PARAMETRIZE { odds = 33; species = SPECIES_SCIZOR; move = MOVE_X_SCISSOR; }
|
PARAMETRIZE { odds = 33; species = SPECIES_SCIZOR; move = MOVE_X_SCISSOR; }
|
||||||
PARAMETRIZE { odds = 50; species = SPECIES_DUSCLOPS; move = MOVE_SHADOW_BALL; }
|
PARAMETRIZE { odds = 50; species = SPECIES_DUSCLOPS; move = MOVE_SHADOW_BALL; }
|
||||||
|
|||||||
@ -451,28 +451,6 @@ SINGLE_BATTLE_TEST("(TERA) Double Shock does not remove the user's Electric type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SINGLE_BATTLE_TEST("(TERA) Transform does not copy the target's Tera Type, and if the user is Terastallized it keeps its own Tera Type")
|
|
||||||
{
|
|
||||||
KNOWN_FAILING; // Transform seems to be bugged in tests.
|
|
||||||
GIVEN {
|
|
||||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_EARTHQUAKE); TeraType(TYPE_GHOST); }
|
|
||||||
OPPONENT(SPECIES_DITTO) { TeraType(TYPE_FLYING); }
|
|
||||||
} WHEN {
|
|
||||||
TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_TRANSFORM); }
|
|
||||||
TURN { MOVE(player, MOVE_EARTHQUAKE); }
|
|
||||||
// TURN { MOVE(player, MOVE_SCRATCH); MOVE(opponent, MOVE_SCRATCH, target: player, gimmick: GIMMICK_TERA); }
|
|
||||||
} SCENE {
|
|
||||||
// turn 2
|
|
||||||
MESSAGE("Wobbuffet used Earthquake!");
|
|
||||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, player);
|
|
||||||
HP_BAR(opponent);
|
|
||||||
// turn 3
|
|
||||||
MESSAGE("Wobbuffet used Scratch!");
|
|
||||||
MESSAGE("It doesn't affect Ditto…");
|
|
||||||
NOT { HP_BAR(opponent); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stellar Type checks
|
// Stellar Type checks
|
||||||
SINGLE_BATTLE_TEST("(TERA) Stellar type does not change the user's defensive profile", s16 damage)
|
SINGLE_BATTLE_TEST("(TERA) Stellar type does not change the user's defensive profile", s16 damage)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry causes the attacker to lose 1/8 of its max HP i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SINGLE_BATTLE_TEST("Jaboca Berry tirggers before Bug Bite can steal it")
|
SINGLE_BATTLE_TEST("Jaboca Berry triggers before Bug Bite can steal it")
|
||||||
{
|
{
|
||||||
KNOWN_FAILING;
|
KNOWN_FAILING;
|
||||||
GIVEN {
|
GIVEN {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Acupressure increases one of two stats by 2 stages at random");
|
TO_DO_BATTLE_TEST("Acupressure increases one of its stats by 2 stages at random");
|
||||||
TO_DO_BATTLE_TEST("Acupressure doesn't try to increase a stat that has been maximized");
|
TO_DO_BATTLE_TEST("Acupressure doesn't try to increase a stat that has been maximized");
|
||||||
TO_DO_BATTLE_TEST("Acupressure fails on the user if all of its stats are maximized");
|
TO_DO_BATTLE_TEST("Acupressure fails on the user if all of its stats are maximized");
|
||||||
TO_DO_BATTLE_TEST("Acupressure fails on the ally if all of its stats are maximized");
|
TO_DO_BATTLE_TEST("Acupressure fails on the ally if all of its stats are maximized");
|
||||||
|
|||||||
@ -50,4 +50,40 @@ SINGLE_BATTLE_TEST("Aura Wheel changes type depending on Morpeko's form")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Aura Wheel can be used by Pokémon transformed into Morpeko");
|
SINGLE_BATTLE_TEST("Aura Wheel can be used by Pokémon transformed into Morpeko")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_MORPEKO) { Moves(MOVE_AURA_WHEEL, MOVE_CELEBRATE); Ability(ABILITY_HUNGER_SWITCH); }
|
||||||
|
OPPONENT(SPECIES_DITTO) { Moves(MOVE_AURA_WHEEL, MOVE_CELEBRATE); Ability(ABILITY_IMPOSTER); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_AURA_WHEEL); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_AURA_WHEEL, opponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Aura Wheel can be turned into a Normal-type move after Morpeko gains Normalize")
|
||||||
|
{
|
||||||
|
bool32 hangryMode;
|
||||||
|
PARAMETRIZE { hangryMode = FALSE; }
|
||||||
|
PARAMETRIZE { hangryMode = TRUE; }
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT);
|
||||||
|
ASSUME(gSpeciesInfo[SPECIES_DUSKULL].types[0] == TYPE_GHOST || gSpeciesInfo[SPECIES_DUSKULL].types[1] == TYPE_GHOST);
|
||||||
|
PLAYER(SPECIES_MORPEKO) { Ability(ABILITY_HUNGER_SWITCH); }
|
||||||
|
OPPONENT(SPECIES_DELCATTY) { Ability(ABILITY_NORMALIZE); }
|
||||||
|
OPPONENT(SPECIES_DUSKULL);
|
||||||
|
} WHEN {
|
||||||
|
if (hangryMode)
|
||||||
|
TURN { }
|
||||||
|
TURN { MOVE(opponent, MOVE_ENTRAINMENT); }
|
||||||
|
TURN { MOVE(player, MOVE_AURA_WHEEL); SWITCH(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
if (hangryMode)
|
||||||
|
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||||
|
NONE_OF {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_AURA_WHEEL, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "test/battle.h"
|
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Blizzard ignores accuracy check durin Hail and Snow");
|
|
||||||
@ -1,4 +1,22 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Bulk Up increases the user's Attack and Defense");
|
ASSUMPTIONS
|
||||||
|
{
|
||||||
|
ASSUME(GetMoveEffect(MOVE_BULK_UP) == EFFECT_BULK_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Bulk Up increases the user's Attack and Defense by 1 stage each")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_BULK_UP); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_BULK_UP, player);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||||
|
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,22 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Calm Mind increases the user's Sp. Attack and Sp. Defense by 1 stage each");
|
ASSUMPTIONS
|
||||||
|
{
|
||||||
|
ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND);
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Calm Mind increases the user's Sp. Attack and Sp. Defense by 1 stage each")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CALM_MIND); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CALM_MIND, player);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
|
||||||
|
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
153
test/battle/move_effect/chloroblast.c
Normal file
153
test/battle/move_effect/chloroblast.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "test/battle.h"
|
||||||
|
|
||||||
|
ASSUMPTIONS
|
||||||
|
{
|
||||||
|
ASSUME(GetMoveEffect(MOVE_CHLOROBLAST) == EFFECT_CHLOROBLAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast makes the user lose 1/2 of its Max HP")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { HP(400); MaxHP(400); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(player, damage: 200);
|
||||||
|
NOT MESSAGE("Wobbuffet fainted!"); // Wobb had more than 1/2 of its HP, so it can't faint.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast causes the user to faint when below 1/2 of its Max HP")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { HP(200); MaxHP(400); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(player, hp: 0);
|
||||||
|
MESSAGE("Wobbuffet fainted!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast causes the user & the target to faint when below 1/2 of its Max HP")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { HP(200) ; MaxHP(400); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(opponent, hp: 0);
|
||||||
|
MESSAGE("The opposing Wobbuffet fainted!");
|
||||||
|
HP_BAR(player, hp: 0);
|
||||||
|
MESSAGE("Wobbuffet fainted!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast hp loss is prevented by Magic Guard")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_CLEFAIRY) { Ability(ABILITY_MAGIC_GUARD); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
NOT HP_BAR(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast does not cause recoil damage if the user has Rock Head")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_AERODACTYL) { Ability(ABILITY_ROCK_HEAD); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) { HP(400); MaxHP(400); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
NOT HP_BAR(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast does not cause the user to lose HP even if the opposing mon protected")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
|
||||||
|
NONE_OF {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast does not cause the user to lose HP even if it is absorbed by Sap Sipper")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetMoveType(MOVE_CHLOROBLAST) == TYPE_GRASS);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_GOGOAT) { Ability(ABILITY_SAP_SIPPER); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CHLOROBLAST); }
|
||||||
|
} SCENE {
|
||||||
|
ABILITY_POPUP(opponent, ABILITY_SAP_SIPPER);
|
||||||
|
NONE_OF {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast does not cause the user to lose HP if there is no target")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_MEMENTO); MOVE(player, MOVE_CHLOROBLAST); SEND_OUT(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_MEMENTO, opponent);
|
||||||
|
NONE_OF {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHLOROBLAST, player);
|
||||||
|
HP_BAR(player);
|
||||||
|
}
|
||||||
|
MESSAGE("Wobbuffet used Chloroblast!");
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
MESSAGE("2 sent out Wobbuffet!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Chloroblast is not affected by Reckless", s16 damage)
|
||||||
|
{
|
||||||
|
u32 move;
|
||||||
|
|
||||||
|
PARAMETRIZE { move = MOVE_CHLOROBLAST; }
|
||||||
|
PARAMETRIZE { move = MOVE_FRENZY_PLANT; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, move); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||||
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
|
} FINALLY {
|
||||||
|
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,28 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Expanding Force's power increases by 50% if the user is affected by Psychic Terrain");
|
SINGLE_BATTLE_TEST("Expanding Force's power increases by 50% if the user is affected by Psychic Terrain", s16 damage)
|
||||||
|
{
|
||||||
|
bool32 terrain;
|
||||||
|
PARAMETRIZE { terrain = FALSE; }
|
||||||
|
PARAMETRIZE { terrain = TRUE; }
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetMoveEffect(MOVE_EXPANDING_FORCE) == EFFECT_EXPANDING_FORCE);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
if (terrain)
|
||||||
|
TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); }
|
||||||
|
TURN { MOVE(player, MOVE_EXPANDING_FORCE); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Expanding Force!");
|
||||||
|
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||||
|
} FINALLY {
|
||||||
|
if (B_TERRAIN_TYPE_BOOST >= GEN_8)
|
||||||
|
// 1.3 Terrain boost x 1.5 effect boost = 1.95 boost
|
||||||
|
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.95), results[1].damage);
|
||||||
|
else
|
||||||
|
// 1.5 Terrain boost x 1.5 effect boost = 2.25 boost
|
||||||
|
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.25), results[1].damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -673,4 +673,24 @@ SINGLE_BATTLE_TEST("Pursuit user faints to Life Orb and target still switches ou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOUBLE_BATTLE_TEST("Pursuit user switches out due to Red Card and partner's switch is cancelled if switching to same Pokémon")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(GetItemHoldEffect(ITEM_RED_CARD) == HOLD_EFFECT_RED_CARD);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
PLAYER(SPECIES_WYNAUT);
|
||||||
|
PLAYER(SPECIES_ARCEUS);
|
||||||
|
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_RED_CARD); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_ARCEUS);
|
||||||
|
} WHEN {
|
||||||
|
TURN { SWITCH(opponentLeft, 2); SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_PURSUIT, target: opponentLeft); }
|
||||||
|
} THEN {
|
||||||
|
// playerLeft switches to Arceus
|
||||||
|
EXPECT_EQ(playerLeft->species, SPECIES_ARCEUS);
|
||||||
|
// playerRight has their switch cancelled
|
||||||
|
EXPECT_EQ(playerRight->species, SPECIES_WYNAUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Baton Pass doesn't cause Pursuit to increase its power or priority");
|
TO_DO_BATTLE_TEST("Baton Pass doesn't cause Pursuit to increase its power or priority");
|
||||||
|
|||||||
@ -2,3 +2,29 @@
|
|||||||
#include "test/battle.h"
|
#include "test/battle.h"
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("TODO: Write Transform (Move Effect) test titles")
|
TO_DO_BATTLE_TEST("TODO: Write Transform (Move Effect) test titles")
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("(TERA) Transform does not copy the target's Tera Type, and if the user is Terastallized it keeps its own Tera Type")
|
||||||
|
{
|
||||||
|
u32 playerDoTera;
|
||||||
|
PARAMETRIZE { playerDoTera = GIMMICK_TERA; }
|
||||||
|
PARAMETRIZE { playerDoTera = GIMMICK_NONE; }
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_EARTHQUAKE); TeraType(TYPE_GHOST); }
|
||||||
|
OPPONENT(SPECIES_DITTO) { TeraType(TYPE_FLYING); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_CELEBRATE, gimmick: playerDoTera); MOVE(opponent, MOVE_TRANSFORM); }
|
||||||
|
TURN { MOVE(player, MOVE_SCRATCH); MOVE(opponent, moveSlot: 0); }
|
||||||
|
TURN { MOVE(player, MOVE_EARTHQUAKE); MOVE(opponent, moveSlot: 0, gimmick: GIMMICK_TERA); }
|
||||||
|
} SCENE {
|
||||||
|
// turn 1
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRANSFORM, opponent);
|
||||||
|
// turn 2
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
|
||||||
|
// turn 3
|
||||||
|
MESSAGE("Wobbuffet used Earthquake!");
|
||||||
|
MESSAGE("It doesn't affect the opposing Ditto…");
|
||||||
|
NOT { HP_BAR(opponent); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ SINGLE_BATTLE_TEST("Blizzard bypasses accuracy checks in Hail and Snow")
|
|||||||
u32 move;
|
u32 move;
|
||||||
PARAMETRIZE { move = MOVE_HAIL; }
|
PARAMETRIZE { move = MOVE_HAIL; }
|
||||||
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
|
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
|
||||||
|
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
|
||||||
GIVEN {
|
GIVEN {
|
||||||
ASSUME(GetMoveAccuracy(MOVE_BLIZZARD) == 70);
|
ASSUME(GetMoveAccuracy(MOVE_BLIZZARD) == 70);
|
||||||
ASSUME(MoveAlwaysHitsInHailSnow(MOVE_BLIZZARD));
|
ASSUME(MoveAlwaysHitsInHailSnow(MOVE_BLIZZARD));
|
||||||
|
|||||||
@ -312,7 +312,9 @@ top:
|
|||||||
const char *color;
|
const char *color;
|
||||||
const char *result;
|
const char *result;
|
||||||
|
|
||||||
if (gTestRunnerState.result == gTestRunnerState.expectedResult)
|
if (gTestRunnerState.result == gTestRunnerState.expectedResult
|
||||||
|
|| (gTestRunnerState.result == TEST_RESULT_FAIL
|
||||||
|
&& gTestRunnerState.expectedResult == TEST_RESULT_KNOWN_FAIL))
|
||||||
{
|
{
|
||||||
color = "\e[32m";
|
color = "\e[32m";
|
||||||
Test_MgbaPrintf(":N%s", gTestRunnerState.test->name);
|
Test_MgbaPrintf(":N%s", gTestRunnerState.test->name);
|
||||||
@ -330,7 +332,7 @@ top:
|
|||||||
switch (gTestRunnerState.result)
|
switch (gTestRunnerState.result)
|
||||||
{
|
{
|
||||||
case TEST_RESULT_FAIL:
|
case TEST_RESULT_FAIL:
|
||||||
if (gTestRunnerState.expectedResult == TEST_RESULT_FAIL)
|
if (gTestRunnerState.expectedResult == TEST_RESULT_KNOWN_FAIL)
|
||||||
{
|
{
|
||||||
result = "KNOWN_FAILING";
|
result = "KNOWN_FAILING";
|
||||||
color = "\e[33m";
|
color = "\e[33m";
|
||||||
@ -387,7 +389,9 @@ top:
|
|||||||
Test_MgbaPrintf(":A%s%s\e[0m", color, result);
|
Test_MgbaPrintf(":A%s%s\e[0m", color, result);
|
||||||
else if (gTestRunnerState.result == TEST_RESULT_TODO)
|
else if (gTestRunnerState.result == TEST_RESULT_TODO)
|
||||||
Test_MgbaPrintf(":T%s%s\e[0m", color, result);
|
Test_MgbaPrintf(":T%s%s\e[0m", color, result);
|
||||||
else if (gTestRunnerState.expectedResult == gTestRunnerState.result)
|
else if (gTestRunnerState.expectedResult == gTestRunnerState.result
|
||||||
|
|| (gTestRunnerState.result == TEST_RESULT_FAIL
|
||||||
|
&& gTestRunnerState.expectedResult == TEST_RESULT_KNOWN_FAIL))
|
||||||
Test_MgbaPrintf(":K%s%s\e[0m", color, result);
|
Test_MgbaPrintf(":K%s%s\e[0m", color, result);
|
||||||
else
|
else
|
||||||
Test_MgbaPrintf(":F%s%s\e[0m", color, result);
|
Test_MgbaPrintf(":F%s%s\e[0m", color, result);
|
||||||
|
|||||||
@ -181,6 +181,7 @@ static void BattleTest_SetUp(void *data)
|
|||||||
STATE->battlersCount = 4;
|
STATE->battlersCount = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
STATE->hasTornDownBattle = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintTestName(void)
|
static void PrintTestName(void)
|
||||||
@ -284,16 +285,17 @@ static void BattleTest_Run(void *data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < STATE->battlersCount; i++)
|
for (i = 0; i < MAX_LINK_PLAYERS; i++)
|
||||||
{
|
{
|
||||||
DATA.recordedBattle.playersName[i][0] = CHAR_1 + i;
|
DATA.recordedBattle.playersName[i][0] = CHAR_1 + i;
|
||||||
DATA.recordedBattle.playersName[i][1] = EOS;
|
DATA.recordedBattle.playersName[i][1] = EOS;
|
||||||
DATA.recordedBattle.playersLanguage[i] = GAME_LANGUAGE;
|
DATA.recordedBattle.playersLanguage[i] = GAME_LANGUAGE;
|
||||||
DATA.recordedBattle.playersBattlers[i] = i;
|
DATA.recordedBattle.playersBattlers[i] = i;
|
||||||
|
|
||||||
DATA.currentMonIndexes[i] = (i & BIT_FLANK) == B_FLANK_LEFT ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < STATE->battlersCount; i++)
|
||||||
|
DATA.currentMonIndexes[i] = i / 2;
|
||||||
|
|
||||||
STATE->runRandomly = TRUE;
|
STATE->runRandomly = TRUE;
|
||||||
STATE->runGiven = TRUE;
|
STATE->runGiven = TRUE;
|
||||||
STATE->runWhen = TRUE;
|
STATE->runWhen = TRUE;
|
||||||
@ -1419,8 +1421,11 @@ static void BattleTest_TearDown(void *data)
|
|||||||
// aborted unexpectedly.
|
// aborted unexpectedly.
|
||||||
ClearFlagAfterTest();
|
ClearFlagAfterTest();
|
||||||
TestFreeConfigData();
|
TestFreeConfigData();
|
||||||
if (STATE->tearDownBattle)
|
if (!STATE->hasTornDownBattle)
|
||||||
|
{
|
||||||
TearDownBattle();
|
TearDownBattle();
|
||||||
|
STATE->hasTornDownBattle = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 BattleTest_CheckProgress(void *data)
|
static bool32 BattleTest_CheckProgress(void *data)
|
||||||
@ -1448,7 +1453,6 @@ static bool32 BattleTest_HandleExitWithResult(void *data, enum TestResult result
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STATE->tearDownBattle = TRUE;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user