Merge branch 'rh-hideout-master'
@ -357,6 +357,108 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"design"
|
"design"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Syreldar",
|
||||||
|
"name": "Enrico Drago",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/42327659?v=4",
|
||||||
|
"profile": "https://metin2.dev/index.php",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"userTesting"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Pyredrid",
|
||||||
|
"name": "Pyredrid",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/8324784?v=4",
|
||||||
|
"profile": "https://github.com/Pyredrid",
|
||||||
|
"contributions": [
|
||||||
|
"userTesting",
|
||||||
|
"maintenance"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mvit",
|
||||||
|
"name": "mv",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/128863?v=4",
|
||||||
|
"profile": "https://github.com/mvit",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Mother-Of-Dragons",
|
||||||
|
"name": "Avara",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/31101124?v=4",
|
||||||
|
"profile": "https://github.com/Mother-Of-Dragons",
|
||||||
|
"contributions": [
|
||||||
|
"data"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Doesnty",
|
||||||
|
"name": "Doesnty",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/6163136?v=4",
|
||||||
|
"profile": "https://github.com/Doesnty",
|
||||||
|
"contributions": [
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "FosterProgramming",
|
||||||
|
"name": "FosterProgramming",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/178871164?v=4",
|
||||||
|
"profile": "https://github.com/FosterProgramming",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Squeetz",
|
||||||
|
"name": "Squeetz",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/21145213?v=4",
|
||||||
|
"profile": "https://github.com/Squeetz",
|
||||||
|
"contributions": [
|
||||||
|
"maintenance"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ghostyboyy97",
|
||||||
|
"name": "ghostyboyy97",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/106448956?v=4",
|
||||||
|
"profile": "https://github.com/ghostyboyy97",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "HashtagMarky",
|
||||||
|
"name": "Marky",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/143505183?v=4",
|
||||||
|
"profile": "http://hashtagmarky.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "MandL27",
|
||||||
|
"name": "MandL27",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/10366615?v=4",
|
||||||
|
"profile": "https://github.com/MandL27",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "cawtds",
|
||||||
|
"name": "cawtds",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/38510667?v=4",
|
||||||
|
"profile": "https://github.com/cawtds",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
@ -43,9 +43,10 @@ body:
|
|||||||
label: Version
|
label: Version
|
||||||
description: What version of pokeemerald-expansion are you using?
|
description: What version of pokeemerald-expansion are you using?
|
||||||
options:
|
options:
|
||||||
- 1.13.2 (Latest release)
|
- 1.13.3 (Latest release)
|
||||||
- master (default, unreleased bugfixes)
|
- master (default, unreleased bugfixes)
|
||||||
- upcoming (Edge)
|
- upcoming (Edge)
|
||||||
|
- 1.13.2
|
||||||
- 1.13.1
|
- 1.13.1
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
- 1.12.3
|
- 1.12.3
|
||||||
|
|||||||
@ -43,9 +43,10 @@ body:
|
|||||||
label: Version
|
label: Version
|
||||||
description: What version of pokeemerald-expansion are you using?
|
description: What version of pokeemerald-expansion are you using?
|
||||||
options:
|
options:
|
||||||
- 1.13.2 (Latest release)
|
- 1.13.3 (Latest release)
|
||||||
- master (default, unreleased bugfixes)
|
- master (default, unreleased bugfixes)
|
||||||
- upcoming (Edge)
|
- upcoming (Edge)
|
||||||
|
- 1.13.2
|
||||||
- 1.13.1
|
- 1.13.1
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
- 1.12.3
|
- 1.12.3
|
||||||
|
|||||||
3
.github/ISSUE_TEMPLATE/04_other_errors.yaml
vendored
@ -43,9 +43,10 @@ body:
|
|||||||
label: Version
|
label: Version
|
||||||
description: What version of pokeemerald-expansion are you using?
|
description: What version of pokeemerald-expansion are you using?
|
||||||
options:
|
options:
|
||||||
- 1.13.2 (Latest release)
|
- 1.13.3 (Latest release)
|
||||||
- master (default, unreleased bugfixes)
|
- master (default, unreleased bugfixes)
|
||||||
- upcoming (Edge)
|
- upcoming (Edge)
|
||||||
|
- 1.13.2
|
||||||
- 1.13.1
|
- 1.13.1
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
- 1.12.3
|
- 1.12.3
|
||||||
|
|||||||
2
.github/workflows/docs.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Install latest mdbook
|
- name: Install latest mdbook
|
||||||
run: |
|
run: |
|
||||||
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
|
tag="v0.5.0-beta.1"
|
||||||
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
|
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
|
||||||
mkdir mdbook
|
mkdir mdbook
|
||||||
curl -sSL $url | tar -xz --directory=./mdbook
|
curl -sSL $url | tar -xz --directory=./mdbook
|
||||||
|
|||||||
4
.github/workflows/labels.yml
vendored
@ -3,10 +3,12 @@ name: Labels
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, labeled, unlabeled]
|
types: [opened, synchronize, labeled, unlabeled]
|
||||||
|
pull_request_review:
|
||||||
|
types: [submitted]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
label:
|
label:
|
||||||
if: github.actor != 'allcontributors[bot]'
|
if: ${{ github.actor != 'allcontributors[bot]' && github.event.review.state == 'approved' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: check labels
|
- name: check labels
|
||||||
|
|||||||
15
CREDITS.md
@ -62,6 +62,21 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://tustin2121.github.io/"><img src="https://avatars.githubusercontent.com/u/794812?v=4?s=100" width="100px;" alt="tustin2121"/><br /><sub><b>tustin2121</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tustin2121" title="Documentation">📖</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tustin2121" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://tustin2121.github.io/"><img src="https://avatars.githubusercontent.com/u/794812?v=4?s=100" width="100px;" alt="tustin2121"/><br /><sub><b>tustin2121</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tustin2121" title="Documentation">📖</a> <a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=tustin2121" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ddaretrogamer"><img src="https://avatars.githubusercontent.com/u/131238004?v=4?s=100" width="100px;" alt="Phantonomy"/><br /><sub><b>Phantonomy</b></sub></a><br /><a href="#design-Ddaretrogamer" title="Design">🎨</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ddaretrogamer"><img src="https://avatars.githubusercontent.com/u/131238004?v=4?s=100" width="100px;" alt="Phantonomy"/><br /><sub><b>Phantonomy</b></sub></a><br /><a href="#design-Ddaretrogamer" title="Design">🎨</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://metin2.dev/index.php"><img src="https://avatars.githubusercontent.com/u/42327659?v=4?s=100" width="100px;" alt="Enrico Drago"/><br /><sub><b>Enrico Drago</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=Syreldar" title="Documentation">📖</a> <a href="#userTesting-Syreldar" title="User Testing">📓</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pyredrid"><img src="https://avatars.githubusercontent.com/u/8324784?v=4?s=100" width="100px;" alt="Pyredrid"/><br /><sub><b>Pyredrid</b></sub></a><br /><a href="#userTesting-Pyredrid" title="User Testing">📓</a> <a href="#maintenance-Pyredrid" title="Maintenance">🚧</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mvit"><img src="https://avatars.githubusercontent.com/u/128863?v=4?s=100" width="100px;" alt="mv"/><br /><sub><b>mv</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=mvit" title="Code">💻</a> <a href="#design-mvit" title="Design">🎨</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Mother-Of-Dragons"><img src="https://avatars.githubusercontent.com/u/31101124?v=4?s=100" width="100px;" alt="Avara"/><br /><sub><b>Avara</b></sub></a><br /><a href="#data-Mother-Of-Dragons" title="Data">🔣</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Doesnty"><img src="https://avatars.githubusercontent.com/u/6163136?v=4?s=100" width="100px;" alt="Doesnty"/><br /><sub><b>Doesnty</b></sub></a><br /><a href="#design-Doesnty" title="Design">🎨</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FosterProgramming"><img src="https://avatars.githubusercontent.com/u/178871164?v=4?s=100" width="100px;" alt="FosterProgramming"/><br /><sub><b>FosterProgramming</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=FosterProgramming" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Squeetz"><img src="https://avatars.githubusercontent.com/u/21145213?v=4?s=100" width="100px;" alt="Squeetz"/><br /><sub><b>Squeetz</b></sub></a><br /><a href="#maintenance-Squeetz" title="Maintenance">🚧</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ghostyboyy97"><img src="https://avatars.githubusercontent.com/u/106448956?v=4?s=100" width="100px;" alt="ghostyboyy97"/><br /><sub><b>ghostyboyy97</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ghostyboyy97" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="http://hashtagmarky.github.io"><img src="https://avatars.githubusercontent.com/u/143505183?v=4?s=100" width="100px;" alt="Marky"/><br /><sub><b>Marky</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=HashtagMarky" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MandL27"><img src="https://avatars.githubusercontent.com/u/10366615?v=4?s=100" width="100px;" alt="MandL27"/><br /><sub><b>MandL27</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=MandL27" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cawtds"><img src="https://avatars.githubusercontent.com/u/38510667?v=4?s=100" width="100px;" alt="cawtds"/><br /><sub><b>cawtds</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=cawtds" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
8
Makefile
@ -197,10 +197,18 @@ ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json
|
|||||||
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
|
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
|
||||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||||
|
|
||||||
|
MISC_TOOL_DIR := $(TOOLS_DIR)/misc
|
||||||
|
AUTO_GEN_TARGETS += $(INCLUDE_DIRS)/constants/script_commands.h
|
||||||
|
|
||||||
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h $(INCLUDE_DIRS)/config/dexnav.h
|
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h $(INCLUDE_DIRS)/config/dexnav.h
|
||||||
python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@
|
python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@
|
||||||
|
|
||||||
|
$(INCLUDE_DIRS)/constants/script_commands.h: $(MISC_TOOL_DIR)/make_scr_cmd_constants.py $(DATA_ASM_SUBDIR)/script_cmd_table.inc
|
||||||
|
python3 $(MISC_TOOL_DIR)/make_scr_cmd_constants.py
|
||||||
|
|
||||||
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||||
|
$(C_BUILDDIR)/trainer_see.o: c_dep += $(INCLUDE_DIRS)/constants/script_commands.h
|
||||||
|
$(C_BUILDDIR)/vs_seeker.o: c_dep += $(INCLUDE_DIRS)/constants/script_commands.h
|
||||||
|
|
||||||
PERL := perl
|
PERL := perl
|
||||||
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
|
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
If you use **`pokeemerald-expansion`**, please credit **RHH (Rom Hacking Hideout)**. Optionally, include the version number for clarity.
|
If you use **`pokeemerald-expansion`**, please credit **RHH (Rom Hacking Hideout)**. Optionally, include the version number for clarity.
|
||||||
|
|
||||||
```
|
```
|
||||||
Based off RHH's pokeemerald-expansion 1.13.2 https://github.com/rh-hideout/pokeemerald-expansion/
|
Based off RHH's pokeemerald-expansion 1.13.3 https://github.com/rh-hideout/pokeemerald-expansion/
|
||||||
```
|
```
|
||||||
|
|
||||||
Please consider [crediting all contributors](CREDITS.md) involved in the project!
|
Please consider [crediting all contributors](CREDITS.md) involved in the project!
|
||||||
|
|||||||
@ -187,8 +187,13 @@
|
|||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro unused_0x21
|
.macro jumpifstatignorecontrary battler:req, comparison:req, stat:req, value:req, jumpInstr:req
|
||||||
.byte 0x21
|
.byte 0x21
|
||||||
|
.byte \battler
|
||||||
|
.byte \comparison
|
||||||
|
.byte \stat
|
||||||
|
.byte \value
|
||||||
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro jumpbasedontype battler:req, type:req, jumpIfType:req, jumpInstr:req
|
.macro jumpbasedontype battler:req, type:req, jumpIfType:req, jumpInstr:req
|
||||||
@ -1965,12 +1970,6 @@
|
|||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro infatuatewithbattler battler:req, infatuateWith:req
|
|
||||||
callnative BS_InfatuateWithBattler
|
|
||||||
.byte \battler
|
|
||||||
.byte \infatuateWith
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro setlastuseditem battler:req
|
.macro setlastuseditem battler:req
|
||||||
callnative BS_SetLastUsedItem
|
callnative BS_SetLastUsedItem
|
||||||
.byte \battler
|
.byte \battler
|
||||||
@ -2102,9 +2101,8 @@
|
|||||||
.byte \id
|
.byte \id
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro arenawaitmessage id:req
|
.macro arenawaitmessage
|
||||||
callnative BS_ArenaWaitMessage
|
callnative BS_ArenaWaitMessage
|
||||||
.byte \id
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro waitcry
|
.macro waitcry
|
||||||
@ -2406,8 +2404,8 @@
|
|||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro jumpifleafguardprotected battler:req, jumpInstr:req
|
.macro jumpifabilitypreventsrest battler:req, jumpInstr:req
|
||||||
callnative BS_JumpIfLeafGuardProtected
|
callnative BS_JumpIfAbilityPreventsRest
|
||||||
.byte \battler
|
.byte \battler
|
||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|||||||
@ -684,6 +684,14 @@
|
|||||||
map \map
|
map \map
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ Set the player object's invisibility to FALSE.
|
||||||
|
.macro showplayer
|
||||||
|
.byte SCR_OP_SHOWOBJECTAT
|
||||||
|
.2byte LOCALID_PLAYER
|
||||||
|
.byte 0 @ map group
|
||||||
|
.byte 0 @ map num
|
||||||
|
.endm
|
||||||
|
|
||||||
@ Sets the specified object's invisibility to TRUE.
|
@ Sets the specified object's invisibility to TRUE.
|
||||||
.macro hideobjectat localId:req, map:req
|
.macro hideobjectat localId:req, map:req
|
||||||
.byte SCR_OP_HIDEOBJECTAT
|
.byte SCR_OP_HIDEOBJECTAT
|
||||||
@ -691,6 +699,14 @@
|
|||||||
map \map
|
map \map
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ Set the player object's invisibility to TRUE.
|
||||||
|
.macro hideplayer
|
||||||
|
.byte SCR_OP_HIDEOBJECTAT
|
||||||
|
.2byte LOCALID_PLAYER
|
||||||
|
.byte 0 @ map group
|
||||||
|
.byte 0 @ map num
|
||||||
|
.endm
|
||||||
|
|
||||||
@ Turns the currently selected object (if there is one) to face the player.
|
@ Turns the currently selected object (if there is one) to face the player.
|
||||||
.macro faceplayer
|
.macro faceplayer
|
||||||
.byte SCR_OP_FACEPLAYER
|
.byte SCR_OP_FACEPLAYER
|
||||||
@ -2482,7 +2498,7 @@
|
|||||||
|
|
||||||
@ Hides any follower Pokémon if present, putting them into their Poké Ball; by default waits for their movement to finish.
|
@ Hides any follower Pokémon if present, putting them into their Poké Ball; by default waits for their movement to finish.
|
||||||
.macro hidefollower wait=1
|
.macro hidefollower wait=1
|
||||||
callnative ScrFunc_hidefollower
|
.byte SCR_OP_HIDEFOLLOWER
|
||||||
.2byte \wait
|
.2byte \wait
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2654,3 +2670,9 @@
|
|||||||
callnative ScriptChangeFollowerNPCBattlePartner
|
callnative ScriptChangeFollowerNPCBattlePartner
|
||||||
.2byte \battlePartner
|
.2byte \battlePartner
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ VS Seeker
|
||||||
|
.macro vsseeker_rematchid rematchId:req
|
||||||
|
callnative NativeVsSeekerRematchId, requests_effects=1
|
||||||
|
.2byte \rematchId
|
||||||
|
.endm
|
||||||
|
|||||||
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
@ Takes a MAP constant and outputs the map group and map number as separate bytes
|
@ Takes a MAP constant and outputs the map group and map number as separate bytes
|
||||||
.macro map map_id:req
|
.macro map map_id:req
|
||||||
|
.ifdef \map_id
|
||||||
.byte \map_id >> 8 @ map group
|
.byte \map_id >> 8 @ map group
|
||||||
.byte \map_id & 0xFF @ map num
|
.byte \map_id & 0xFF @ map num
|
||||||
|
.else
|
||||||
|
.error "undefined map (check for typos)"
|
||||||
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Defines a map script. 'type' is any MAP_SCRIPT_* constant (see include/constants/map_scripts.h)
|
@ Defines a map script. 'type' is any MAP_SCRIPT_* constant (see include/constants/map_scripts.h)
|
||||||
|
|||||||
@ -3356,6 +3356,7 @@ gBattleAnimMove_AquaJet::
|
|||||||
call RisingWaterHitEffect
|
call RisingWaterHitEffect
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask AnimTask_ExtremeSpeedMonReappear, 2
|
createvisualtask AnimTask_ExtremeSpeedMonReappear, 2
|
||||||
|
setarg 0x7, 0x1000
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
visible ANIM_ATTACKER
|
visible ANIM_ATTACKER
|
||||||
clearmonbg ANIM_DEF_PARTNER
|
clearmonbg ANIM_DEF_PARTNER
|
||||||
@ -29001,7 +29002,7 @@ gBattleAnimMove_Transform::
|
|||||||
monbg ANIM_ATTACKER
|
monbg ANIM_ATTACKER
|
||||||
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
|
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
|
||||||
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
|
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
|
||||||
createvisualtask AnimTask_TransformMon, 2, 0, 1
|
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_TRANSFORM
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
clearmonbg ANIM_ATTACKER
|
clearmonbg ANIM_ATTACKER
|
||||||
end
|
end
|
||||||
@ -31512,14 +31513,14 @@ gBattleAnimGeneral_SimpleHeal::
|
|||||||
|
|
||||||
gBattleAnimGeneral_IllusionOff::
|
gBattleAnimGeneral_IllusionOff::
|
||||||
monbg ANIM_TARGET
|
monbg ANIM_TARGET
|
||||||
createvisualtask AnimTask_TransformMon, 2, 1, 0
|
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_ILLUSION_OFF
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
clearmonbg ANIM_TARGET
|
clearmonbg ANIM_TARGET
|
||||||
end
|
end
|
||||||
|
|
||||||
gBattleAnimGeneral_FormChange::
|
gBattleAnimGeneral_FormChange::
|
||||||
monbg ANIM_ATTACKER
|
monbg ANIM_ATTACKER
|
||||||
createvisualtask AnimTask_TransformMon, 2, 1, 0
|
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_FORM_CHANGE
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
clearmonbg ANIM_ATTACKER
|
clearmonbg ANIM_ATTACKER
|
||||||
end
|
end
|
||||||
@ -31551,7 +31552,7 @@ gBattleAnimGeneral_MegaEvolution::
|
|||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createsprite gMegaSymbolSpriteTemplate ANIM_ATTACKER, 3, 0, 0, ANIM_ATTACKER
|
createsprite gMegaSymbolSpriteTemplate ANIM_ATTACKER, 3, 0, 0, ANIM_ATTACKER
|
||||||
@ -31636,7 +31637,7 @@ gBattleAnimGeneral_TeraActivate::
|
|||||||
createvisualtask AnimTask_SetOpponentShadowCallbacks, 2 @ Restore shadows hidden in the charge script
|
createvisualtask AnimTask_SetOpponentShadowCallbacks, 2 @ Restore shadows hidden in the charge script
|
||||||
loadspritegfx ANIM_TAG_TERA_SYMBOL
|
loadspritegfx ANIM_TAG_TERA_SYMBOL
|
||||||
loadspritegfx ANIM_TAG_SPARKLE_6
|
loadspritegfx ANIM_TAG_SPARKLE_6
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
@ -31776,7 +31777,7 @@ General_PrimalReversion_Alpha:
|
|||||||
delay 20
|
delay 20
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
@ -31809,7 +31810,7 @@ General_PrimalReversion_Omega:
|
|||||||
delay 20
|
delay 20
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
@ -31849,7 +31850,7 @@ gBattleAnimGeneral_PowerConstruct::
|
|||||||
delay 20
|
delay 20
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
@ -31919,7 +31920,7 @@ gBattleAnimGeneral_UltraBurst::
|
|||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
|
||||||
createsprite gUltraBurstSymbolSpriteTemplate, ANIM_ATTACKER, 0x0, 0x0, 0x0, 0x0, 0x0
|
createsprite gUltraBurstSymbolSpriteTemplate, ANIM_ATTACKER, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||||
waitforvisualfinish
|
waitforvisualfinish
|
||||||
createvisualtask AnimTask_HideSwapSprite, 2, 1, 0
|
createvisualtask AnimTask_HideSwapSprite, 2
|
||||||
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
|
||||||
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
|
||||||
createvisualtask SoundTask_PlayNormalCry, 0
|
createvisualtask SoundTask_PlayNormalCry, 0
|
||||||
|
|||||||
@ -408,6 +408,7 @@ BattleScript_SaltCureExtraDamage::
|
|||||||
printstring STRINGID_TARGETISHURTBYSALTCURE
|
printstring STRINGID_TARGETISHURTBYSALTCURE
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
tryfaintmon BS_ATTACKER
|
tryfaintmon BS_ATTACKER
|
||||||
|
tryrestorehpberry
|
||||||
end2
|
end2
|
||||||
|
|
||||||
BattleScript_HurtTarget_NoString:
|
BattleScript_HurtTarget_NoString:
|
||||||
@ -2879,6 +2880,7 @@ BattleScript_CantMakeAsleep::
|
|||||||
|
|
||||||
BattleScript_EffectAbsorbLiquidOoze::
|
BattleScript_EffectAbsorbLiquidOoze::
|
||||||
call BattleScript_AbilityPopUpTarget
|
call BattleScript_AbilityPopUpTarget
|
||||||
|
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_EffectAbsorbRet
|
||||||
goto BattleScript_EffectAbsorb
|
goto BattleScript_EffectAbsorb
|
||||||
|
|
||||||
BattleScript_EffectAbsorb::
|
BattleScript_EffectAbsorb::
|
||||||
@ -2888,6 +2890,7 @@ BattleScript_EffectAbsorb::
|
|||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
tryfaintmon BS_ATTACKER
|
tryfaintmon BS_ATTACKER
|
||||||
bicword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_PASSIVE_HP_UPDATE
|
bicword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_PASSIVE_HP_UPDATE
|
||||||
|
BattleScript_EffectAbsorbRet:
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_EffectExplosion::
|
BattleScript_EffectExplosion::
|
||||||
@ -3186,9 +3189,7 @@ BattleScript_EffectRest::
|
|||||||
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
|
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
|
||||||
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
|
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
|
||||||
jumpifability BS_ATTACKER, ABILITY_PURIFYING_SALT, BattleScript_InsomniaProtects
|
jumpifability BS_ATTACKER, ABILITY_PURIFYING_SALT, BattleScript_InsomniaProtects
|
||||||
.if B_LEAF_GUARD_PREVENTS_REST >= GEN_5
|
jumpifabilitypreventsrest BS_TARGET, BattleScript_AbilityPreventsRest
|
||||||
jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardPreventsRest
|
|
||||||
.endif
|
|
||||||
trysetrest BattleScript_AlreadyAtFullHp
|
trysetrest BattleScript_AlreadyAtFullHp
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
printfromtable gRestUsedStringIds
|
printfromtable gRestUsedStringIds
|
||||||
@ -3210,7 +3211,7 @@ BattleScript_RestIsAlreadyAsleep::
|
|||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
goto BattleScript_MoveEnd
|
goto BattleScript_MoveEnd
|
||||||
|
|
||||||
BattleScript_LeafGuardPreventsRest::
|
BattleScript_AbilityPreventsRest::
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
printstring STRINGID_BUTITFAILED
|
printstring STRINGID_BUTITFAILED
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
@ -4024,26 +4025,27 @@ BattleScript_FuryCutterHit:
|
|||||||
|
|
||||||
BattleScript_TryDestinyKnotTarget:
|
BattleScript_TryDestinyKnotTarget:
|
||||||
jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotTargetRet
|
jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotTargetRet
|
||||||
infatuatewithbattler BS_TARGET, BS_ATTACKER
|
|
||||||
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
|
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
|
||||||
waitanimation
|
waitanimation
|
||||||
|
printstring STRINGID_DESTINYKNOTACTIVATES
|
||||||
|
tryinfatuating BattleScript_ButItFailed
|
||||||
volatileanimation BS_TARGET, VOLATILE_INFATUATION
|
volatileanimation BS_TARGET, VOLATILE_INFATUATION
|
||||||
waitanimation
|
waitanimation
|
||||||
printstring STRINGID_DESTINYKNOTACTIVATES
|
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
BattleScript_TryDestinyKnotTargetRet:
|
BattleScript_TryDestinyKnotTargetRet:
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_TryDestinyKnotAttacker:
|
BattleScript_TryDestinyKnotAttacker:
|
||||||
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotAttackerRet
|
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotTargetRet
|
||||||
infatuatewithbattler BS_ATTACKER, BS_TARGET
|
|
||||||
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
|
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
|
||||||
waitanimation
|
waitanimation
|
||||||
|
swapattackerwithtarget
|
||||||
|
printstring STRINGID_DESTINYKNOTACTIVATES
|
||||||
|
tryinfatuating BattleScript_SwapTargetAttackerButItFailed
|
||||||
|
swapattackerwithtarget
|
||||||
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
|
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
|
||||||
waitanimation
|
waitanimation
|
||||||
printstring STRINGID_DESTINYKNOTACTIVATES
|
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
BattleScript_TryDestinyKnotAttackerRet:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_EffectAttract::
|
BattleScript_EffectAttract::
|
||||||
@ -4220,7 +4222,7 @@ BattleScript_EffectBellyDrum::
|
|||||||
attackcanceler
|
attackcanceler
|
||||||
attackstring
|
attackstring
|
||||||
ppreduce
|
ppreduce
|
||||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed
|
jumpifstatignorecontrary BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed
|
||||||
halvehp BattleScript_ButItFailed
|
halvehp BattleScript_ButItFailed
|
||||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE
|
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE
|
||||||
attackanimation
|
attackanimation
|
||||||
@ -4377,6 +4379,9 @@ BattleScript_RestoreAttackerButItFailed:
|
|||||||
BattleScript_RestoreTargetButItFailed:
|
BattleScript_RestoreTargetButItFailed:
|
||||||
restoretarget
|
restoretarget
|
||||||
goto BattleScript_ButItFailed
|
goto BattleScript_ButItFailed
|
||||||
|
BattleScript_SwapTargetAttackerButItFailed:
|
||||||
|
swapattackerwithtarget
|
||||||
|
goto BattleScript_ButItFailed
|
||||||
|
|
||||||
BattleScript_NotAffected::
|
BattleScript_NotAffected::
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
@ -5084,8 +5089,8 @@ BattleScript_FaintAttacker::
|
|||||||
tryrevertweatherform
|
tryrevertweatherform
|
||||||
flushtextbox
|
flushtextbox
|
||||||
waitanimation
|
waitanimation
|
||||||
tryactivatesoulheart
|
|
||||||
tryactivatereceiver BS_ATTACKER
|
tryactivatereceiver BS_ATTACKER
|
||||||
|
tryactivatesoulheart
|
||||||
trytrainerslidemsgfirstoff BS_ATTACKER
|
trytrainerslidemsgfirstoff BS_ATTACKER
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -5102,8 +5107,8 @@ BattleScript_FaintTarget::
|
|||||||
tryrevertweatherform
|
tryrevertweatherform
|
||||||
flushtextbox
|
flushtextbox
|
||||||
waitanimation
|
waitanimation
|
||||||
tryactivatesoulheart
|
|
||||||
tryactivatereceiver BS_TARGET
|
tryactivatereceiver BS_TARGET
|
||||||
|
tryactivatesoulheart
|
||||||
trytrainerslidemsgfirstoff BS_TARGET
|
trytrainerslidemsgfirstoff BS_TARGET
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -5626,10 +5631,12 @@ BattleScript_LeechSeedTurnDrainLiquidOoze::
|
|||||||
copybyte gBattlerAbility, gBattlerAttacker
|
copybyte gBattlerAbility, gBattlerAttacker
|
||||||
call BattleScript_AbilityPopUp
|
call BattleScript_AbilityPopUp
|
||||||
copybyte gBattlerAttacker, gBattlerTarget @ needed to get liquid ooze message correct
|
copybyte gBattlerAttacker, gBattlerTarget @ needed to get liquid ooze message correct
|
||||||
|
jumpifability BS_TARGET, ABILITY_MAGIC_GUARD, BattleScript_LeechSeedTurnDrainHealBlockEnd2
|
||||||
goto BattleScript_LeechSeedTurnDrainGainHp
|
goto BattleScript_LeechSeedTurnDrainGainHp
|
||||||
|
|
||||||
BattleScript_LeechSeedTurnDrainHealBlock::
|
BattleScript_LeechSeedTurnDrainHealBlock::
|
||||||
call BattleScript_LeechSeedTurnDrain
|
call BattleScript_LeechSeedTurnDrain
|
||||||
|
BattleScript_LeechSeedTurnDrainHealBlockEnd2:
|
||||||
end2
|
end2
|
||||||
|
|
||||||
BattleScript_LeechSeedTurnDrainRecovery::
|
BattleScript_LeechSeedTurnDrainRecovery::
|
||||||
@ -6050,9 +6057,8 @@ BattleScript_ToxicDebrisActivates::
|
|||||||
printstring STRINGID_POISONSPIKESSCATTERED
|
printstring STRINGID_POISONSPIKESSCATTERED
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
BattleScript_ToxicDebrisRet:
|
BattleScript_ToxicDebrisRet:
|
||||||
copybyte sBATTLER, gBattlerTarget
|
restoretarget
|
||||||
copybyte gBattlerTarget, gBattlerAttacker
|
restoreattacker
|
||||||
copybyte gBattlerAttacker, sBATTLER
|
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_EarthEaterActivates::
|
BattleScript_EarthEaterActivates::
|
||||||
@ -7105,7 +7111,7 @@ BattleScript_RecoilEnd::
|
|||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_ItemSteal::
|
BattleScript_ItemSteal::
|
||||||
playanimation BS_TARGET, B_ANIM_ITEM_STEAL
|
playanimation BS_EFFECT_BATTLER, B_ANIM_ITEM_STEAL
|
||||||
printstring STRINGID_PKMNSTOLEITEM
|
printstring STRINGID_PKMNSTOLEITEM
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
return
|
return
|
||||||
@ -7283,6 +7289,7 @@ BattleScript_ReceiverActivates::
|
|||||||
printstring STRINGID_RECEIVERABILITYTAKEOVER
|
printstring STRINGID_RECEIVERABILITYTAKEOVER
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
settracedability BS_ABILITY_BATTLER
|
settracedability BS_ABILITY_BATTLER
|
||||||
|
switchinabilities BS_ABILITY_BATTLER
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_AbilityHpHeal:
|
BattleScript_AbilityHpHeal:
|
||||||
@ -8212,11 +8219,13 @@ BattleScript_CuteCharmActivates::
|
|||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_GooeyActivates::
|
BattleScript_GooeyActivates::
|
||||||
|
statbuffchange BS_ATTACKER, STAT_CHANGE_ONLY_CHECKING, BattleScript_GooeyActivatesRet
|
||||||
waitstate
|
waitstate
|
||||||
call BattleScript_AbilityPopUp
|
call BattleScript_AbilityPopUp
|
||||||
swapattackerwithtarget @ for defiant, mirror armor
|
swapattackerwithtarget @ for defiant, mirror armor
|
||||||
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_SPD_MINUS_1
|
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_SPD_MINUS_1
|
||||||
swapattackerwithtarget
|
swapattackerwithtarget
|
||||||
|
BattleScript_GooeyActivatesRet:
|
||||||
return
|
return
|
||||||
|
|
||||||
BattleScript_AbilityStatusEffect::
|
BattleScript_AbilityStatusEffect::
|
||||||
@ -8711,7 +8720,7 @@ BattleScript_ArenaTurnBeginning::
|
|||||||
playse SE_ARENA_TIMEUP1
|
playse SE_ARENA_TIMEUP1
|
||||||
drawarenareftextbox
|
drawarenareftextbox
|
||||||
arenajudgmentstring B_MSG_REF_COMMENCE_BATTLE
|
arenajudgmentstring B_MSG_REF_COMMENCE_BATTLE
|
||||||
arenawaitmessage B_MSG_REF_COMMENCE_BATTLE
|
arenawaitmessage
|
||||||
pause B_WAIT_TIME_LONG
|
pause B_WAIT_TIME_LONG
|
||||||
erasearenareftextbox
|
erasearenareftextbox
|
||||||
volumeup
|
volumeup
|
||||||
@ -8729,26 +8738,26 @@ BattleScript_ArenaDoJudgment::
|
|||||||
pause B_WAIT_TIME_LONG
|
pause B_WAIT_TIME_LONG
|
||||||
drawarenareftextbox
|
drawarenareftextbox
|
||||||
arenajudgmentstring B_MSG_REF_THATS_IT
|
arenajudgmentstring B_MSG_REF_THATS_IT
|
||||||
arenawaitmessage B_MSG_REF_THATS_IT
|
arenawaitmessage
|
||||||
pause B_WAIT_TIME_LONG
|
pause B_WAIT_TIME_LONG
|
||||||
setbyte gBattleCommunication, 0 @ Reset state for arenajudgmentwindow
|
setbyte gBattleCommunication, 0 @ Reset state for arenajudgmentwindow
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
pause B_WAIT_TIME_LONG
|
pause B_WAIT_TIME_LONG
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
arenajudgmentstring B_MSG_REF_JUDGE_MIND
|
arenajudgmentstring B_MSG_REF_JUDGE_MIND
|
||||||
arenawaitmessage B_MSG_REF_JUDGE_MIND
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
arenajudgmentstring B_MSG_REF_JUDGE_SKILL
|
arenajudgmentstring B_MSG_REF_JUDGE_SKILL
|
||||||
arenawaitmessage B_MSG_REF_JUDGE_SKILL
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
arenajudgmentstring B_MSG_REF_JUDGE_BODY
|
arenajudgmentstring B_MSG_REF_JUDGE_BODY
|
||||||
arenawaitmessage B_MSG_REF_JUDGE_BODY
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
jumpifbyte CMP_EQUAL, gBattleCommunication + 1, ARENA_RESULT_PLAYER_LOST, BattleScript_ArenaJudgmentPlayerLoses
|
jumpifbyte CMP_EQUAL, gBattleCommunication + 1, ARENA_RESULT_PLAYER_LOST, BattleScript_ArenaJudgmentPlayerLoses
|
||||||
jumpifbyte CMP_EQUAL, gBattleCommunication + 1, ARENA_RESULT_TIE, BattleScript_ArenaJudgmentDraw
|
jumpifbyte CMP_EQUAL, gBattleCommunication + 1, ARENA_RESULT_TIE, BattleScript_ArenaJudgmentDraw
|
||||||
@ ARENA_RESULT_PLAYER_WON
|
@ ARENA_RESULT_PLAYER_WON
|
||||||
arenajudgmentstring B_MSG_REF_PLAYER_WON
|
arenajudgmentstring B_MSG_REF_PLAYER_WON
|
||||||
arenawaitmessage B_MSG_REF_PLAYER_WON
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
erasearenareftextbox
|
erasearenareftextbox
|
||||||
printstring STRINGID_DEFEATEDOPPONENTBYREFEREE
|
printstring STRINGID_DEFEATEDOPPONENTBYREFEREE
|
||||||
@ -8763,7 +8772,7 @@ BattleScript_ArenaDoJudgment::
|
|||||||
|
|
||||||
BattleScript_ArenaJudgmentPlayerLoses:
|
BattleScript_ArenaJudgmentPlayerLoses:
|
||||||
arenajudgmentstring B_MSG_REF_OPPONENT_WON
|
arenajudgmentstring B_MSG_REF_OPPONENT_WON
|
||||||
arenawaitmessage B_MSG_REF_OPPONENT_WON
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
erasearenareftextbox
|
erasearenareftextbox
|
||||||
printstring STRINGID_LOSTTOOPPONENTBYREFEREE
|
printstring STRINGID_LOSTTOOPPONENTBYREFEREE
|
||||||
@ -8778,11 +8787,12 @@ BattleScript_ArenaJudgmentPlayerLoses:
|
|||||||
|
|
||||||
BattleScript_ArenaJudgmentDraw:
|
BattleScript_ArenaJudgmentDraw:
|
||||||
arenajudgmentstring B_MSG_REF_DRAW
|
arenajudgmentstring B_MSG_REF_DRAW
|
||||||
arenawaitmessage B_MSG_REF_DRAW
|
arenawaitmessage
|
||||||
arenajudgmentwindow
|
arenajudgmentwindow
|
||||||
erasearenareftextbox
|
erasearenareftextbox
|
||||||
printstring STRINGID_TIEDOPPONENTBYREFEREE
|
printstring STRINGID_TIEDOPPONENTBYREFEREE
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
|
arenabothmonslost
|
||||||
playfaintcry BS_PLAYER1
|
playfaintcry BS_PLAYER1
|
||||||
waitcry
|
waitcry
|
||||||
dofaintanimation BS_PLAYER1
|
dofaintanimation BS_PLAYER1
|
||||||
@ -8793,7 +8803,6 @@ BattleScript_ArenaJudgmentDraw:
|
|||||||
dofaintanimation BS_OPPONENT1
|
dofaintanimation BS_OPPONENT1
|
||||||
cleareffectsonfaint BS_OPPONENT1
|
cleareffectsonfaint BS_OPPONENT1
|
||||||
waitanimation
|
waitanimation
|
||||||
arenabothmonslost
|
|
||||||
end2
|
end2
|
||||||
|
|
||||||
BattleScript_AskIfWantsToForfeitMatch::
|
BattleScript_AskIfWantsToForfeitMatch::
|
||||||
@ -8883,14 +8892,28 @@ BattleScript_ActivateTeraformZero_RemoveWeather:
|
|||||||
removeweather
|
removeweather
|
||||||
printfromtable gWeatherEndsStringIds
|
printfromtable gWeatherEndsStringIds
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
jumpifhalfword CMP_NO_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_ANY, BattleScript_ActivateTeraformZero_End
|
call BattleScript_ActivateWeatherAbilities
|
||||||
|
jumpifhalfword CMP_NO_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_ANY, BattleScript_ActivateTeraformZeroEffects
|
||||||
BattleScript_ActivateTeraformZero_RemoveTerrain:
|
BattleScript_ActivateTeraformZero_RemoveTerrain:
|
||||||
removeterrain
|
removeterrain
|
||||||
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
|
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
|
||||||
printfromtable gTerrainStringIds
|
printfromtable gTerrainStringIds
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
BattleScript_ActivateTeraformZero_End:
|
BattleScript_ActivateTeraformZeroEffects:
|
||||||
|
saveattacker
|
||||||
|
savetarget
|
||||||
tryboosterenergy ON_ANY
|
tryboosterenergy ON_ANY
|
||||||
|
resetterrainabilityflags
|
||||||
|
setbyte gBattlerAttacker, 0
|
||||||
|
BattleScript_ActivateTeraformZeroLoop:
|
||||||
|
copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1
|
||||||
|
activateterrainchangeabilities BS_TARGET
|
||||||
|
activateweatherchangeabilities BS_TARGET
|
||||||
|
addbyte gBattlerAttacker, 1
|
||||||
|
jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateTeraformZeroLoop
|
||||||
|
restoreattacker
|
||||||
|
restoretarget
|
||||||
|
BattleScript_ActivateTeraformZero_End:
|
||||||
end3
|
end3
|
||||||
|
|
||||||
BattleScript_QuickClawActivation::
|
BattleScript_QuickClawActivation::
|
||||||
@ -9099,6 +9122,7 @@ BattleScript_Pickpocket::
|
|||||||
call BattleScript_AbilityPopUp
|
call BattleScript_AbilityPopUp
|
||||||
jumpifability BS_ATTACKER, ABILITY_STICKY_HOLD, BattleScript_PickpocketPrevented
|
jumpifability BS_ATTACKER, ABILITY_STICKY_HOLD, BattleScript_PickpocketPrevented
|
||||||
swapattackerwithtarget
|
swapattackerwithtarget
|
||||||
|
copybyte gEffectBattler, gBattlerTarget
|
||||||
call BattleScript_ItemSteal
|
call BattleScript_ItemSteal
|
||||||
swapattackerwithtarget
|
swapattackerwithtarget
|
||||||
activateitemeffects
|
activateitemeffects
|
||||||
|
|||||||
2
data/battle_scripts_2.s
Normal file → Executable file
@ -212,9 +212,9 @@ BattleScript_WallyBallThrow::
|
|||||||
|
|
||||||
BattleScript_ShakeBallThrow::
|
BattleScript_ShakeBallThrow::
|
||||||
animatewildpokemonafterfailedpokeball BS_TARGET
|
animatewildpokemonafterfailedpokeball BS_TARGET
|
||||||
waitstate
|
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
printfromtable gBallEscapeStringIds
|
printfromtable gBallEscapeStringIds
|
||||||
|
waitanimation
|
||||||
waitmessage B_WAIT_TIME_LONG
|
waitmessage B_WAIT_TIME_LONG
|
||||||
jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_SAFARI, BattleScript_ShakeBallThrowEnd
|
jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_SAFARI, BattleScript_ShakeBallThrowEnd
|
||||||
jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_ShakeBallThrowEnd
|
jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_ShakeBallThrowEnd
|
||||||
|
|||||||
@ -835,7 +835,7 @@ EventScript_UnusedBoardFerry::
|
|||||||
delay 30
|
delay 30
|
||||||
applymovement LOCALID_PLAYER, Common_Movement_WalkInPlaceFasterUp
|
applymovement LOCALID_PLAYER, Common_Movement_WalkInPlaceFasterUp
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
showobjectat LOCALID_PLAYER, 0
|
showplayer
|
||||||
delay 30
|
delay 30
|
||||||
applymovement LOCALID_PLAYER, Movement_UnusedBoardFerry
|
applymovement LOCALID_PLAYER, Movement_UnusedBoardFerry
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
@ -850,7 +850,7 @@ Common_EventScript_FerryDepartIsland::
|
|||||||
call_if_eq VAR_FACING, DIR_SOUTH, Ferry_EventScript_DepartIslandSouth
|
call_if_eq VAR_FACING, DIR_SOUTH, Ferry_EventScript_DepartIslandSouth
|
||||||
call_if_eq VAR_FACING, DIR_WEST, Ferry_EventScript_DepartIslandWest
|
call_if_eq VAR_FACING, DIR_WEST, Ferry_EventScript_DepartIslandWest
|
||||||
delay 30
|
delay 30
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
call Common_EventScript_FerryDepart
|
call Common_EventScript_FerryDepart
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ BattleFrontier_BattleDomePreBattleRoom_OnFrame:
|
|||||||
|
|
||||||
BattleFrontier_BattleDomePreBattleRoom_EventScript_EnterRoom::
|
BattleFrontier_BattleDomePreBattleRoom_EventScript_EnterRoom::
|
||||||
goto_if_eq VAR_0x8006, 1, BattleFrontier_BattleDomePreBattleRoom_EventScript_ReturnFromBattle
|
goto_if_eq VAR_0x8006, 1, BattleFrontier_BattleDomePreBattleRoom_EventScript_ReturnFromBattle
|
||||||
|
delay 1
|
||||||
frontier_set FRONTIER_DATA_RECORD_DISABLED, TRUE
|
frontier_set FRONTIER_DATA_RECORD_DISABLED, TRUE
|
||||||
setvar VAR_TEMP_0, 1
|
setvar VAR_TEMP_0, 1
|
||||||
applymovement LOCALID_PLAYER, BattleFrontier_BattleDomePreBattleRoom_Movement_PlayerEnter
|
applymovement LOCALID_PLAYER, BattleFrontier_BattleDomePreBattleRoom_Movement_PlayerEnter
|
||||||
|
|||||||
@ -333,7 +333,7 @@ LilycoveCity_Harbor_EventScript_BoardFerryWithSailor::
|
|||||||
call_if_eq VAR_FACING, DIR_NORTH, LilycoveCity_Harbor_EventScript_PlayerBoardFerryNorth
|
call_if_eq VAR_FACING, DIR_NORTH, LilycoveCity_Harbor_EventScript_PlayerBoardFerryNorth
|
||||||
call_if_eq VAR_FACING, DIR_EAST, LilycoveCity_Harbor_EventScript_PlayerBoardFerryEast
|
call_if_eq VAR_FACING, DIR_EAST, LilycoveCity_Harbor_EventScript_PlayerBoardFerryEast
|
||||||
delay 30
|
delay 30
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
setvar VAR_0x8004, LOCALID_LILYCOVE_HARBOR_SS_TIDAL
|
setvar VAR_0x8004, LOCALID_LILYCOVE_HARBOR_SS_TIDAL
|
||||||
call Common_EventScript_FerryDepart
|
call Common_EventScript_FerryDepart
|
||||||
return
|
return
|
||||||
@ -393,7 +393,7 @@ LilycoveCity_Harbor_EventScript_BoardFerry::
|
|||||||
call_if_eq VAR_FACING, DIR_NORTH, LilycoveCity_Harbor_EventScript_PlayerBoardFerryNorth
|
call_if_eq VAR_FACING, DIR_NORTH, LilycoveCity_Harbor_EventScript_PlayerBoardFerryNorth
|
||||||
call_if_eq VAR_FACING, DIR_EAST, LilycoveCity_Harbor_EventScript_PlayerBoardFerryEast
|
call_if_eq VAR_FACING, DIR_EAST, LilycoveCity_Harbor_EventScript_PlayerBoardFerryEast
|
||||||
delay 30
|
delay 30
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
setvar VAR_0x8004, LOCALID_LILYCOVE_HARBOR_SS_TIDAL
|
setvar VAR_0x8004, LOCALID_LILYCOVE_HARBOR_SS_TIDAL
|
||||||
call Common_EventScript_FerryDepart
|
call Common_EventScript_FerryDepart
|
||||||
return
|
return
|
||||||
|
|||||||
@ -156,7 +156,7 @@ LittlerootTown_EventScript_GoInsideWithMom::
|
|||||||
waitmovement 0
|
waitmovement 0
|
||||||
setflag FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE
|
setflag FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE
|
||||||
setvar VAR_LITTLEROOT_INTRO_STATE, 3
|
setvar VAR_LITTLEROOT_INTRO_STATE, 3
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor VAR_0x8004, VAR_0x8005
|
closedoor VAR_0x8004, VAR_0x8005
|
||||||
waitdooranim
|
waitdooranim
|
||||||
clearflag FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN
|
clearflag FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN
|
||||||
|
|||||||
@ -228,7 +228,7 @@ SlateportCity_Harbor_EventScript_BoardFerry::
|
|||||||
call_if_eq VAR_FACING, DIR_NORTH, SlateportCity_Harbor_EventScript_BoardFerryNorth
|
call_if_eq VAR_FACING, DIR_NORTH, SlateportCity_Harbor_EventScript_BoardFerryNorth
|
||||||
call_if_eq VAR_FACING, DIR_EAST, SlateportCity_Harbor_EventScript_BoardFerryEast
|
call_if_eq VAR_FACING, DIR_EAST, SlateportCity_Harbor_EventScript_BoardFerryEast
|
||||||
delay 30
|
delay 30
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
setvar VAR_0x8004, LOCALID_SLATEPORT_HARBOR_SS_TIDAL
|
setvar VAR_0x8004, LOCALID_SLATEPORT_HARBOR_SS_TIDAL
|
||||||
call Common_EventScript_FerryDepart
|
call Common_EventScript_FerryDepart
|
||||||
return
|
return
|
||||||
|
|||||||
@ -251,6 +251,7 @@ gScriptCmdTable::
|
|||||||
script_cmd_table_entry SCR_OP_BUFFERITEMNAMEPLURAL ScrCmd_bufferitemnameplural, requests_effects=1 @ 0xe2
|
script_cmd_table_entry SCR_OP_BUFFERITEMNAMEPLURAL ScrCmd_bufferitemnameplural, requests_effects=1 @ 0xe2
|
||||||
script_cmd_table_entry SCR_OP_DYNMULTICHOICE ScrCmd_dynmultichoice, requests_effects=1 @ 0xe3
|
script_cmd_table_entry SCR_OP_DYNMULTICHOICE ScrCmd_dynmultichoice, requests_effects=1 @ 0xe3
|
||||||
script_cmd_table_entry SCR_OP_DYNMULTIPUSH ScrCmd_dynmultipush, requests_effects=1 @ 0xe4
|
script_cmd_table_entry SCR_OP_DYNMULTIPUSH ScrCmd_dynmultipush, requests_effects=1 @ 0xe4
|
||||||
|
script_cmd_table_entry SCR_OP_HIDEFOLLOWER ScrCmd_hidefollower, requests_effects=1 @ 0xe5
|
||||||
|
|
||||||
.if ALLOCATE_SCRIPT_CMD_TABLE
|
.if ALLOCATE_SCRIPT_CMD_TABLE
|
||||||
gScriptCmdTableEnd::
|
gScriptCmdTableEnd::
|
||||||
|
|||||||
@ -356,7 +356,7 @@ CableClub_EventScript_EnterColosseum::
|
|||||||
waitdooranim
|
waitdooranim
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor 9, 1
|
closedoor 9, 1
|
||||||
waitdooranim
|
waitdooranim
|
||||||
release
|
release
|
||||||
@ -450,7 +450,7 @@ CableClub_EventScript_EnterTradeCenter::
|
|||||||
waitdooranim
|
waitdooranim
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor 9, 1
|
closedoor 9, 1
|
||||||
waitdooranim
|
waitdooranim
|
||||||
release
|
release
|
||||||
@ -515,7 +515,7 @@ CableClub_EventScript_EnterRecordCorner::
|
|||||||
waitdooranim
|
waitdooranim
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor 9, 1
|
closedoor 9, 1
|
||||||
waitdooranim
|
waitdooranim
|
||||||
release
|
release
|
||||||
@ -902,7 +902,7 @@ CableClub_EventScript_EnterUnionRoom::
|
|||||||
waitdooranim
|
waitdooranim
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor 5, 1
|
closedoor 5, 1
|
||||||
waitdooranim
|
waitdooranim
|
||||||
special Script_ResetUnionRoomTrade
|
special Script_ResetUnionRoomTrade
|
||||||
@ -1202,7 +1202,7 @@ CableClub_EventScript_EnterWirelessLinkRoom::
|
|||||||
waitdooranim
|
waitdooranim
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterLinkRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
closedoor 9, 1
|
closedoor 9, 1
|
||||||
waitdooranim
|
waitdooranim
|
||||||
release
|
release
|
||||||
@ -1384,7 +1384,7 @@ MossdeepCity_GameCorner_1F_EventScript_EnterMinigameRoom::
|
|||||||
closemessage
|
closemessage
|
||||||
applymovement LOCALID_PLAYER, Movement_PlayerEnterMinigameRoom
|
applymovement LOCALID_PLAYER, Movement_PlayerEnterMinigameRoom
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
hideobjectat LOCALID_PLAYER, 0
|
hideplayer
|
||||||
release
|
release
|
||||||
waitstate
|
waitstate
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,23 +3,44 @@
|
|||||||
- [README](./README.md)
|
- [README](./README.md)
|
||||||
- [Installation](./INSTALL.md)
|
- [Installation](./INSTALL.md)
|
||||||
- [Setting up WSL1 (Legacy Portion)](./legacy_WSL1_INSTALL.md)
|
- [Setting up WSL1 (Legacy Portion)](./legacy_WSL1_INSTALL.md)
|
||||||
|
- [ChromeOS](./install/chromeos/CHROME_OS.md)
|
||||||
|
- [Linux]()
|
||||||
|
- [ARCH_LINUX](./install/linux/ARCH_LINUX.md)
|
||||||
|
- [DEBIAN](./install/linux/DEBIAN.md)
|
||||||
|
- [NIXOS](./install/linux/NIXOS.md)
|
||||||
|
- [OTHERS](./install/linux/OTHERS.md)
|
||||||
|
- [UBUNTU](./install/linux/UBUNTU.md)
|
||||||
|
- [macOS](./install/mac/MAC_OS.md)
|
||||||
|
- [Windows]()
|
||||||
|
- [CYGWIN](./install/windows/CYGWIN.md)
|
||||||
|
- [MSYS2](./install/windows/MSYS2.md)
|
||||||
|
- [WSL](./install/windows/WSL.md)
|
||||||
- [Run documentation site locally](local_mdbook/index.md)
|
- [Run documentation site locally](local_mdbook/index.md)
|
||||||
- [Ubuntu WSL1/WSL2](local_mdbook/ubuntu_WSL.md)
|
- [Ubuntu WSL1/WSL2](local_mdbook/ubuntu_WSL.md)
|
||||||
- [Contributing](./CONTRIBUTING.md)
|
- [Contributing](./CONTRIBUTING.md)
|
||||||
|
- [Styleguide and Principles](./STYLEGUIDE.md)
|
||||||
- [Credits](./CREDITS.md)
|
- [Credits](./CREDITS.md)
|
||||||
- [Tutorials]()
|
- [Tutorials]()
|
||||||
- [What are AI Flags?](tutorials/ai_flags.md)
|
- [What are AI Flags?](tutorials/ai_flags.md)
|
||||||
- [How to add new AI Flags](tutorials/ai_logic.md)
|
- [How to add new AI Flags](tutorials/ai_logic.md)
|
||||||
- [How to add new battle script commands/macros](tutorials/how_to_battle_script_command_macro.md)
|
- [How to add new battle script commands/macros](tutorials/how_to_battle_script_command_macro.md)
|
||||||
- [How to add a new move](tutorials/how_to_new_move.md)
|
- [How to add a new move](tutorials/how_to_new_move.md)
|
||||||
- [How to add a new trainer class](tutorials/how_to_trainer_class.md)
|
- [How to add a new trainer class]()
|
||||||
|
- [How to add a new trainer front pic](tutorials/how_to_trainer_front_pic.md)
|
||||||
|
- [How to add a new trainer back pic](tutorials/how_to_trainer_back_pic.md)
|
||||||
- [How to add a new Pokémon](tutorials/how_to_new_pokemon.md)
|
- [How to add a new Pokémon](tutorials/how_to_new_pokemon.md)
|
||||||
- [v1.6.x and earlier](tutorials/how_to_new_pokemon_1_6_0.md)
|
- [v1.6.x and earlier](tutorials/how_to_new_pokemon_1_6_0.md)
|
||||||
- [How to use the Testing System](tutorials/how_to_testing_system.md)
|
- [How to use the Testing System](tutorials/how_to_testing_system.md)
|
||||||
- [How to add new Trainer Slides](tutorials/how_to_new_trainer_slide.md)
|
- [How to add new Trainer Slides](tutorials/how_to_new_trainer_slide.md)
|
||||||
- [Day/Night System FAQ](tutorials/dns.md)
|
- [Day/Night System FAQ](tutorials/dns.md)
|
||||||
|
- [How to use the code entry system](tutorials/how_to_code_entry.md)
|
||||||
|
- [How to use Follower NPCs](tutorials/how_to_follower_npc.md)
|
||||||
|
- [Time-Based Encounters](tutorials/how_to_time_of_day_encounters.md)
|
||||||
|
- [How to use Trainer Party Pools](tutorials/how_to_trainer_party_pool.md)
|
||||||
|
- [Vs. Seeker](tutorials/vs_seeker.md)
|
||||||
- [Changelog](./CHANGELOG.md)
|
- [Changelog](./CHANGELOG.md)
|
||||||
- [1.13.x]()
|
- [1.13.x]()
|
||||||
|
- [Version 1.13.3](changelogs/1.13.x/1.13.3.md)
|
||||||
- [Version 1.13.2](changelogs/1.13.x/1.13.2.md)
|
- [Version 1.13.2](changelogs/1.13.x/1.13.2.md)
|
||||||
- [Version 1.13.1](changelogs/1.13.x/1.13.1.md)
|
- [Version 1.13.1](changelogs/1.13.x/1.13.1.md)
|
||||||
- [Version 1.13.0](changelogs/1.13.x/1.13.0.md)
|
- [Version 1.13.0](changelogs/1.13.x/1.13.0.md)
|
||||||
@ -39,6 +60,7 @@
|
|||||||
- [Version 1.10.2](changelogs/1.10.x/1.10.2.md)
|
- [Version 1.10.2](changelogs/1.10.x/1.10.2.md)
|
||||||
- [Version 1.10.1](changelogs/1.10.x/1.10.1.md)
|
- [Version 1.10.1](changelogs/1.10.x/1.10.1.md)
|
||||||
- [Version 1.10.0](changelogs/1.10.x/1.10.0.md)
|
- [Version 1.10.0](changelogs/1.10.x/1.10.0.md)
|
||||||
|
- [Megaman Battle Network Style Names](./mmbn_style_names.md)
|
||||||
- [1.9.x]()
|
- [1.9.x]()
|
||||||
- [Version 1.9.4](changelogs/1.9.x/1.9.4.md)
|
- [Version 1.9.4](changelogs/1.9.x/1.9.4.md)
|
||||||
- [Version 1.9.3](changelogs/1.9.x/1.9.3.md)
|
- [Version 1.9.3](changelogs/1.9.x/1.9.3.md)
|
||||||
@ -87,4 +109,5 @@
|
|||||||
- [Team Procedures]()
|
- [Team Procedures]()
|
||||||
- [How to make an Expansion version](team_procedures/expansion_versions.md)
|
- [How to make an Expansion version](team_procedures/expansion_versions.md)
|
||||||
- [Release Schedule and Process](team_procedures/schedule.md)
|
- [Release Schedule and Process](team_procedures/schedule.md)
|
||||||
|
- [Merge Checklist](team_procedures/merge_checklist.md)
|
||||||
- [Scope Guidelines](team_procedures/scope.md)
|
- [Scope Guidelines](team_procedures/scope.md)
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
[book]
|
[book]
|
||||||
language = "en"
|
language = "en"
|
||||||
multilingual = false
|
src = "."
|
||||||
src = "."
|
title = "pokeemerald-expansion"
|
||||||
title = "pokeemerald-expansion"
|
|
||||||
|
[output.html]
|
||||||
[output.html]
|
git-repository-url = "https://github.com/rh-hideout/pokeemerald-expansion"
|
||||||
git-repository-url = "https://github.com/rh-hideout/pokeemerald-expansion"
|
edit-url-template = "https://github.com/rh-hideout/pokeemerald-expansion/edit/master/docs/{path}"
|
||||||
edit-url-template = "https://github.com/rh-hideout/pokeemerald-expansion/edit/master/docs/{path}"
|
site-url = "/pokeemerald-expansion/"
|
||||||
site-url = "/pokeemerald-expansion/"
|
|
||||||
|
[preprocessor.fix_links]
|
||||||
[preprocessor.fix_links]
|
command = "python3 fix_links.py"
|
||||||
command = "python3 fix_links.py"
|
after = [ "links" ]
|
||||||
after = [ "links" ]
|
|
||||||
|
|||||||
193
docs/changelogs/1.13.x/1.13.3.md
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
```md
|
||||||
|
## How to update
|
||||||
|
- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
|
||||||
|
- Once you have your remote set up, run the command `git pull RHH expansion/1.13.3
|
||||||
|
`.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 🧬 General 🧬
|
||||||
|
### Added
|
||||||
|
* Add test to detect save file shifting by @Bassoonian in [#8030](https://github.com/rh-hideout/pokeemerald-expansion/pull/8030)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* 1.13.2 release by @hedara90 in [#7831](https://github.com/rh-hideout/pokeemerald-expansion/pull/7831)
|
||||||
|
* Remove unnecessary EWRAM and IWRAM variables from the Window code by @estellarc in [#7897](https://github.com/rh-hideout/pokeemerald-expansion/pull/7897)
|
||||||
|
* Replace magic numbers with define'd values in field_player_avatar.c by @FosterProgramming in [#7910](https://github.com/rh-hideout/pokeemerald-expansion/pull/7910)
|
||||||
|
* Pret merge (1st of November, 2025) by @hedara90 in [#8103](https://github.com/rh-hideout/pokeemerald-expansion/pull/8103)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* Fixes `EVO_BATTLE_END` evolutions not removing item with additional conditions by @PhallenTree in [#7841](https://github.com/rh-hideout/pokeemerald-expansion/pull/7841)
|
||||||
|
* Fix EV display in debug menu by @cawtds in [#7848](https://github.com/rh-hideout/pokeemerald-expansion/pull/7848)
|
||||||
|
* Fix right player position battle partner target display by @ravepossum in [#7878](https://github.com/rh-hideout/pokeemerald-expansion/pull/7878)
|
||||||
|
* Ensure last used ball and move description window sprites don't free palette too early by @ravepossum in [#7875](https://github.com/rh-hideout/pokeemerald-expansion/pull/7875)
|
||||||
|
* Fix fusion pokemon aquiring illegal movesets by @FosterProgramming in [#7896](https://github.com/rh-hideout/pokeemerald-expansion/pull/7896)
|
||||||
|
- Calyrex will now delete moves if they are not part of its learnset when unfusing
|
||||||
|
- Kyurem will now properly swap the moves Glaciate and Scary Face to its signature moves when fusing/unfusing
|
||||||
|
* Fix bug causing hgss dex to freeze by @FosterProgramming in [#7936](https://github.com/rh-hideout/pokeemerald-expansion/pull/7936)
|
||||||
|
- Fix a bug when checking evolutions info screen while search mode is active in the hgss dex
|
||||||
|
* Show convergent evolution to Gholdengo in HGSS dex by @FosterProgramming in [#7934](https://github.com/rh-hideout/pokeemerald-expansion/pull/7934)
|
||||||
|
* Fix HGSS dex sprites for gen9+ by @FosterProgramming in [#7922](https://github.com/rh-hideout/pokeemerald-expansion/pull/7922)
|
||||||
|
* Fix nicknames containing many / overflowing the party screen textbox by @hedara90 in [#7970](https://github.com/rh-hideout/pokeemerald-expansion/pull/7970)
|
||||||
|
* Fix ruination and nature's madness damage percentage by @FosterProgramming in [#7983](https://github.com/rh-hideout/pokeemerald-expansion/pull/7983)
|
||||||
|
* Fix ribbon colours by @hedara90 in [#7971](https://github.com/rh-hideout/pokeemerald-expansion/pull/7971)
|
||||||
|
* Fix long pokemon name in partner party not appearing properly by @FosterProgramming in [#8009](https://github.com/rh-hideout/pokeemerald-expansion/pull/8009)
|
||||||
|
* Fix battle dome bug (again) by @FosterProgramming in [#8007](https://github.com/rh-hideout/pokeemerald-expansion/pull/8007)
|
||||||
|
* Fix battle arena counting all judges loss for the opponent by @FosterProgramming in [#8046](https://github.com/rh-hideout/pokeemerald-expansion/pull/8046)
|
||||||
|
- Fix battle arena referees giving undeserved wins to the player
|
||||||
|
* Fix wrong gimmick spite showing when inputting too fast by @FosterProgramming in [#8066](https://github.com/rh-hideout/pokeemerald-expansion/pull/8066)
|
||||||
|
|
||||||
|
## 🗺️ Overworld 🗺️
|
||||||
|
### Fixed
|
||||||
|
* Fix LTO breaking with FREE_MYSTERY_GIFT set to TRUE by @DizzyEggg in [#7844](https://github.com/rh-hideout/pokeemerald-expansion/pull/7844)
|
||||||
|
* Fix dns palette weight by @FosterProgramming in [#7855](https://github.com/rh-hideout/pokeemerald-expansion/pull/7855)
|
||||||
|
* Bug Fix: NPC follower not inheriting facing direction upon creation by @Bivurnum in [#7895](https://github.com/rh-hideout/pokeemerald-expansion/pull/7895)
|
||||||
|
* Fix follower pokemon not playing animation when colliding by @FosterProgramming in [#7908](https://github.com/rh-hideout/pokeemerald-expansion/pull/7908)
|
||||||
|
* Fix incorrect font width in Dexnav search window hiding some elements by @FosterProgramming in [#7949](https://github.com/rh-hideout/pokeemerald-expansion/pull/7949)
|
||||||
|
* Fix dns color transition not applying weather blending by @FosterProgramming in [#7883](https://github.com/rh-hideout/pokeemerald-expansion/pull/7883)
|
||||||
|
* Fix follower NPC sidewaystair movement by @FosterProgramming in [#7909](https://github.com/rh-hideout/pokeemerald-expansion/pull/7909)
|
||||||
|
* Fix battle dome pre round 1 waiting room by @FosterProgramming in [#7976](https://github.com/rh-hideout/pokeemerald-expansion/pull/7976)
|
||||||
|
* Fix no_effect script command overwriting trainer data in trainer script by @FosterProgramming in [#7978](https://github.com/rh-hideout/pokeemerald-expansion/pull/7978)
|
||||||
|
* Setting wallclock time now properly sets fakeRTC by @FosterProgramming in [#7860](https://github.com/rh-hideout/pokeemerald-expansion/pull/7860)
|
||||||
|
- Fix time bug when setting wallclock in fakeRTC mode
|
||||||
|
- When setting the wall clock, it will start on current time instead of 10AM
|
||||||
|
- If FakeRTC is active, new game will start at 10AM
|
||||||
|
* Bugfix hidefollower not waiting properly by @FosterProgramming in [#7768](https://github.com/rh-hideout/pokeemerald-expansion/pull/7768)
|
||||||
|
* Bugfix Emotes not loading their palette by @estellarc in [#7843](https://github.com/rh-hideout/pokeemerald-expansion/pull/7843)
|
||||||
|
* Fix OW Pokémon VObjects by @HashtagMarky in [#7991](https://github.com/rh-hideout/pokeemerald-expansion/pull/7991)
|
||||||
|
* fix: hypertraining a stat now optionally reflects in the summary screen by @khbsd in [#8035](https://github.com/rh-hideout/pokeemerald-expansion/pull/8035)
|
||||||
|
* Fix pc turning on/off animation not working in battle frontier by @FosterProgramming in [#8048](https://github.com/rh-hideout/pokeemerald-expansion/pull/8048)
|
||||||
|
* Fix non-battle trainer script not running properly by @FosterProgramming in [#8056](https://github.com/rh-hideout/pokeemerald-expansion/pull/8056)
|
||||||
|
|
||||||
|
## 🐉 Pokémon 🐉
|
||||||
|
### Fixed
|
||||||
|
* Fixes shininess for givemon by @cawtds in [#7847](https://github.com/rh-hideout/pokeemerald-expansion/pull/7847)
|
||||||
|
* Fix Minior start of battle form by @hedara90 in [#7972](https://github.com/rh-hideout/pokeemerald-expansion/pull/7972)
|
||||||
|
* Add error messages for trying to send an illegal mon to the PC and fixes index in double wild battles by @hedara90 in [#7982](https://github.com/rh-hideout/pokeemerald-expansion/pull/7982)
|
||||||
|
* fix: hypertraining a stat now optionally reflects in the summary screen by @khbsd in [#8035](https://github.com/rh-hideout/pokeemerald-expansion/pull/8035)
|
||||||
|
* Add camera-facing right-walking Krabby and Kingler follower sprites by @rayrobdod in [#7881](https://github.com/rh-hideout/pokeemerald-expansion/pull/7881)
|
||||||
|
|
||||||
|
## ⚔️ Battle General ⚔️
|
||||||
|
### Changed
|
||||||
|
* Tests for Battery ability by @grintoul1 in [#7846](https://github.com/rh-hideout/pokeemerald-expansion/pull/7846)
|
||||||
|
* Aura Break tests by @grintoul1 in [#8099](https://github.com/rh-hideout/pokeemerald-expansion/pull/8099)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* Fixes Endure lasting forever by @AlexOn1ine in [#7838](https://github.com/rh-hideout/pokeemerald-expansion/pull/7838)
|
||||||
|
* Fix for uncaught mon with terrain active by @DizzyEggg in [#7868](https://github.com/rh-hideout/pokeemerald-expansion/pull/7868)
|
||||||
|
* Fixes Steadfast not activating + tests by @PhallenTree in [#7886](https://github.com/rh-hideout/pokeemerald-expansion/pull/7886)
|
||||||
|
* Fix hgss pokedex when catching mon with terrain by @DizzyEggg in [#7884](https://github.com/rh-hideout/pokeemerald-expansion/pull/7884)
|
||||||
|
* Fix SmartStrike crashing the game in double battles by @DizzyEggg in [#7902](https://github.com/rh-hideout/pokeemerald-expansion/pull/7902)
|
||||||
|
* Fix palaceUnableToUseMove falling through to change battle script by @ghoulslash in [#7912](https://github.com/rh-hideout/pokeemerald-expansion/pull/7912)
|
||||||
|
* Add new Move target types to GetBattlePalaceMoveGroup by @ghoulslash in [#7913](https://github.com/rh-hideout/pokeemerald-expansion/pull/7913)
|
||||||
|
* Fixes 2 instances of global usage in the `Cmd_adjustdamage` loop by @AlexOn1ine in [#7918](https://github.com/rh-hideout/pokeemerald-expansion/pull/7918)
|
||||||
|
* Fix Battle Anim monbg calls Part 1 by @ghoulslash in [#7906](https://github.com/rh-hideout/pokeemerald-expansion/pull/7906)
|
||||||
|
* Adds missing breakable flag for Bulletproof by @AlexOn1ine in [#7928](https://github.com/rh-hideout/pokeemerald-expansion/pull/7928)
|
||||||
|
* Fix multiple battle arena bugs by @FosterProgramming in [#7941](https://github.com/rh-hideout/pokeemerald-expansion/pull/7941)
|
||||||
|
* Fixes Cursed Body failing to disable moves on the last PP by @PhallenTree in [#7940](https://github.com/rh-hideout/pokeemerald-expansion/pull/7940)
|
||||||
|
* Fixed an issue related to Pokemon animation bleeding into attack anim… by @LinathanZel in [#7924](https://github.com/rh-hideout/pokeemerald-expansion/pull/7924)
|
||||||
|
* Fixes terrain not failing on duplicate by @AlexOn1ine in [#7939](https://github.com/rh-hideout/pokeemerald-expansion/pull/7939)
|
||||||
|
* Fix volt tackle not inflicting recoil by @FosterProgramming in [#7944](https://github.com/rh-hideout/pokeemerald-expansion/pull/7944)
|
||||||
|
* Fix Knock Off not being restored and Wild Battles by @ghoulslash in [#7952](https://github.com/rh-hideout/pokeemerald-expansion/pull/7952)
|
||||||
|
* Fix Anticipation type effectiveness check by @spindrift64 in [#7840](https://github.com/rh-hideout/pokeemerald-expansion/pull/7840)
|
||||||
|
* Fix Cherim and Castfrom not reverting to baseform when Teraform Zero is triggered by @FosterProgramming in [#7961](https://github.com/rh-hideout/pokeemerald-expansion/pull/7961)
|
||||||
|
* Fix Focus Energy boosting crit by the wrong amount with gen1 crit chance by @FosterProgramming in [#7956](https://github.com/rh-hideout/pokeemerald-expansion/pull/7956)
|
||||||
|
* Fix bug where transformed pokemon lose copied stats on levelup by @FosterProgramming in [#7969](https://github.com/rh-hideout/pokeemerald-expansion/pull/7969)
|
||||||
|
* Fixes Shields Down incorrectly preventing status on Minior Core form by @PhallenTree in [#7968](https://github.com/rh-hideout/pokeemerald-expansion/pull/7968)
|
||||||
|
* SetShellSideArmCategory avoid div by zero by @DizzyEggg in [#7980](https://github.com/rh-hideout/pokeemerald-expansion/pull/7980)
|
||||||
|
* CalcBarFilledPixels Safe Div by @DizzyEggg in [#7979](https://github.com/rh-hideout/pokeemerald-expansion/pull/7979)
|
||||||
|
* Fix psychic terrain affecting semi-invulnerable mons by @FosterProgramming in [#7986](https://github.com/rh-hideout/pokeemerald-expansion/pull/7986)
|
||||||
|
* Fixes Terrain Extender timer by @AlexOn1ine in [#7995](https://github.com/rh-hideout/pokeemerald-expansion/pull/7995)
|
||||||
|
* Fixed Max Move in-battle descriptions by @AsparagusEduardo in [#8004](https://github.com/rh-hideout/pokeemerald-expansion/pull/8004)
|
||||||
|
* Fixes Echoed Voice base power increase depending on attacker's use of the move by @PhallenTree in [#7997](https://github.com/rh-hideout/pokeemerald-expansion/pull/7997)
|
||||||
|
* Fixed Stomping Tantrum not doubling in damage if the user failed Protect by @AsparagusEduardo in [#8008](https://github.com/rh-hideout/pokeemerald-expansion/pull/8008)
|
||||||
|
* Fix badge boost not applying in gen1 and 2 by @FosterProgramming in [#8013](https://github.com/rh-hideout/pokeemerald-expansion/pull/8013)
|
||||||
|
* Fix toxic debris setting hazards on the wrong side when hit by an ally by @FosterProgramming in [#8026](https://github.com/rh-hideout/pokeemerald-expansion/pull/8026)
|
||||||
|
* Adds missing alive check for Rapid Spin by @AlexOn1ine in [#8024](https://github.com/rh-hideout/pokeemerald-expansion/pull/8024)
|
||||||
|
* Fixes visual glitch after Misty Explosion by @AlexOn1ine in [#8022](https://github.com/rh-hideout/pokeemerald-expansion/pull/8022)
|
||||||
|
* Fixes Protosynthesis not activating after weather was reset by @AlexOn1ine in [#8021](https://github.com/rh-hideout/pokeemerald-expansion/pull/8021)
|
||||||
|
* Fix Salt Cure script by @AlexOn1ine in [#8005](https://github.com/rh-hideout/pokeemerald-expansion/pull/8005)
|
||||||
|
* Fix emergency exit not triggering properly during wild battles by @FosterProgramming in [#8037](https://github.com/rh-hideout/pokeemerald-expansion/pull/8037)
|
||||||
|
* Fix target cancelling not working properly with z-move by @FosterProgramming in [#8067](https://github.com/rh-hideout/pokeemerald-expansion/pull/8067)
|
||||||
|
* Corrects battler partner identification in battle_ai_switch_items.c by @grintoul1 in [#8071](https://github.com/rh-hideout/pokeemerald-expansion/pull/8071)
|
||||||
|
* Fix Ally Switch being useable in Frontier Link Multi battles by @grintoul1 in [#8059](https://github.com/rh-hideout/pokeemerald-expansion/pull/8059)
|
||||||
|
* Fixes hazards and switch-in items not being reset when switching in by @PhallenTree in [#8074](https://github.com/rh-hideout/pokeemerald-expansion/pull/8074)
|
||||||
|
* Fixes Liquid Ooze dmg not blocked by Magic Guard by @AlexOn1ine in [#8036](https://github.com/rh-hideout/pokeemerald-expansion/pull/8036)
|
||||||
|
* Fix move description prompt window not appear when choosing a move after canceling target selection by @FosterProgramming in [#8055](https://github.com/rh-hideout/pokeemerald-expansion/pull/8055)
|
||||||
|
* Initialize DamageContext on declaration to zero by @AlexOn1ine in [#8076](https://github.com/rh-hideout/pokeemerald-expansion/pull/8076)
|
||||||
|
* Fixed Hunger Switch changing forms on switch out while Tera'd by @AsparagusEduardo in [#8080](https://github.com/rh-hideout/pokeemerald-expansion/pull/8080)
|
||||||
|
* Fixes Gooey/Tangling Hair ability pop up triggering on Clear Body by @AlexOn1ine in [#8083](https://github.com/rh-hideout/pokeemerald-expansion/pull/8083)
|
||||||
|
* Fixes intimidate activating on empty field by @AlexOn1ine in [#8058](https://github.com/rh-hideout/pokeemerald-expansion/pull/8058)
|
||||||
|
* Fix bug where mon selection doesn't properly account for party order by @FosterProgramming in [#8088](https://github.com/rh-hideout/pokeemerald-expansion/pull/8088)
|
||||||
|
* Fix bug when a captured pokemon replaces a party member who changed forms by @FosterProgramming in [#8091](https://github.com/rh-hideout/pokeemerald-expansion/pull/8091)
|
||||||
|
* Fixed Zygarde Complete disappearing upon catch by @AsparagusEduardo in [#8089](https://github.com/rh-hideout/pokeemerald-expansion/pull/8089)
|
||||||
|
* Initialize DamageContext struct with zero values by @AlexOn1ine in [#8107](https://github.com/rh-hideout/pokeemerald-expansion/pull/8107)
|
||||||
|
|
||||||
|
## 🤹 Moves 🤹
|
||||||
|
### Fixed
|
||||||
|
* Updated Mountain Gale's PP for Gen 9 by @fdeblasio in [#7856](https://github.com/rh-hideout/pokeemerald-expansion/pull/7856)
|
||||||
|
* Fix Brine move anim and document Water Spout anim by @ravepossum in [#7865](https://github.com/rh-hideout/pokeemerald-expansion/pull/7865)
|
||||||
|
* Add Struggle tests, weakness berry tests and prevent Struggle from activating Silk Scarf and Chilan Berry by @rayrobdod in [#7880](https://github.com/rh-hideout/pokeemerald-expansion/pull/7880)
|
||||||
|
* Fix Battle Anim monbg calls Part 1 by @ghoulslash in [#7906](https://github.com/rh-hideout/pokeemerald-expansion/pull/7906)
|
||||||
|
* Add missing end signal for AnimTask_SetAttackerInvisibleWaitForSignal by @hedara90 in [#7950](https://github.com/rh-hideout/pokeemerald-expansion/pull/7950)
|
||||||
|
* Fix Ally Switch being useable in Frontier Link Multi battles by @grintoul1 in [#8059](https://github.com/rh-hideout/pokeemerald-expansion/pull/8059)
|
||||||
|
* Fixed Belly Drum/Contrary interaction at max Attack by @AsparagusEduardo in [#8078](https://github.com/rh-hideout/pokeemerald-expansion/pull/8078)
|
||||||
|
|
||||||
|
## 🎭 Abilities 🎭
|
||||||
|
### Changed
|
||||||
|
* Tests for Battery ability by @grintoul1 in [#7846](https://github.com/rh-hideout/pokeemerald-expansion/pull/7846)
|
||||||
|
* Aura Break tests by @grintoul1 in [#8099](https://github.com/rh-hideout/pokeemerald-expansion/pull/8099)
|
||||||
|
|
||||||
|
## 🧶 Items 🧶
|
||||||
|
### Fixed
|
||||||
|
* Add gBallItemIds Array by @HashtagMarky in [#7905](https://github.com/rh-hideout/pokeemerald-expansion/pull/7905)
|
||||||
|
* Fix Persim Berry battle usage by @hedara90 in [#7963](https://github.com/rh-hideout/pokeemerald-expansion/pull/7963)
|
||||||
|
|
||||||
|
## 🤖 Battle AI 🤖
|
||||||
|
### Fixed
|
||||||
|
* Add failsafe to AI_DecideHoldEffectForTurn by @AlexOn1ine in [#7849](https://github.com/rh-hideout/pokeemerald-expansion/pull/7849)
|
||||||
|
* Fix some ai action check happening before the logic was computed by @FosterProgramming in [#7867](https://github.com/rh-hideout/pokeemerald-expansion/pull/7867)
|
||||||
|
- Roamers will now flee in the first turn of battle
|
||||||
|
* Fix ShouldPivot overwriting random memory by @DizzyEggg in [#7882](https://github.com/rh-hideout/pokeemerald-expansion/pull/7882)
|
||||||
|
* Fix AI seeing priority wrong for players choice lock by @MaximeGr00 in [#7899](https://github.com/rh-hideout/pokeemerald-expansion/pull/7899)
|
||||||
|
* fix (post-KO switch): force AI data recalc to see abilities on field correctly when pivot moves used by player by @ghostyboyy97 in [#7900](https://github.com/rh-hideout/pokeemerald-expansion/pull/7900)
|
||||||
|
* Add missing break to Power Split AI case by @ghoulslash in [#7959](https://github.com/rh-hideout/pokeemerald-expansion/pull/7959)
|
||||||
|
|
||||||
|
## 🧹 Other Cleanup 🧹
|
||||||
|
* Fix some failed and assume fail tests with `GEN_LATEST` = `GEN_5` by @AsparagusEduardo in [#7735](https://github.com/rh-hideout/pokeemerald-expansion/pull/7735)
|
||||||
|
* Update INSTALL.md by @RubyRaven6 in [#7852](https://github.com/rh-hideout/pokeemerald-expansion/pull/7852)
|
||||||
|
* Remove unnecessary EWRAM and IWRAM variables from the Window code by @estellarc in [#7897](https://github.com/rh-hideout/pokeemerald-expansion/pull/7897)
|
||||||
|
* Replace magic numbers with define'd values in field_player_avatar.c by @FosterProgramming in [#7910](https://github.com/rh-hideout/pokeemerald-expansion/pull/7910)
|
||||||
|
* Reverts wrongly applies fix to book.toml by @AlexOn1ine in [#8105](https://github.com/rh-hideout/pokeemerald-expansion/pull/8105)
|
||||||
|
|
||||||
|
## 🧪 Test Runner 🧪
|
||||||
|
### Changed
|
||||||
|
* Fix some failed and assume fail tests with `GEN_LATEST` = `GEN_5` by @AsparagusEduardo in [#7735](https://github.com/rh-hideout/pokeemerald-expansion/pull/7735)
|
||||||
|
* Tests for Battery ability by @grintoul1 in [#7846](https://github.com/rh-hideout/pokeemerald-expansion/pull/7846)
|
||||||
|
* Fixed fainting form change tests by @AsparagusEduardo in [#8079](https://github.com/rh-hideout/pokeemerald-expansion/pull/8079)
|
||||||
|
* Aura Break tests by @grintoul1 in [#8099](https://github.com/rh-hideout/pokeemerald-expansion/pull/8099)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* Fix Knock Off not being restored and Wild Battles by @ghoulslash in [#7952](https://github.com/rh-hideout/pokeemerald-expansion/pull/7952)
|
||||||
|
* Fixes Shields Down incorrectly preventing status on Minior Core form by @PhallenTree in [#7968](https://github.com/rh-hideout/pokeemerald-expansion/pull/7968)
|
||||||
|
* Fixed Stomping Tantrum not doubling in damage if the user failed Protect by @AsparagusEduardo in [#8008](https://github.com/rh-hideout/pokeemerald-expansion/pull/8008)
|
||||||
|
* Fix stats defined in tests being overwritteng by stat change by @FosterProgramming in [#8018](https://github.com/rh-hideout/pokeemerald-expansion/pull/8018)
|
||||||
|
|
||||||
|
## 📚 Documentation 📚
|
||||||
|
* Update INSTALL.md by @RubyRaven6 in [#7852](https://github.com/rh-hideout/pokeemerald-expansion/pull/7852)
|
||||||
|
* Updated PR template to make existing credit policy clearer by @pkmnsnfrn in [#7864](https://github.com/rh-hideout/pokeemerald-expansion/pull/7864)
|
||||||
|
* Fix image links in doc site by @rayrobdod in [#7948](https://github.com/rh-hideout/pokeemerald-expansion/pull/7948)
|
||||||
|
* Add all pages in `docs` to doc website by @rayrobdod in [#7907](https://github.com/rh-hideout/pokeemerald-expansion/pull/7907)
|
||||||
|
* Relativize doc links, to fix links in docs site by @rayrobdod in [#7964](https://github.com/rh-hideout/pokeemerald-expansion/pull/7964)
|
||||||
|
* Fix docs compile issue by @AlexOn1ine in [#8101](https://github.com/rh-hideout/pokeemerald-expansion/pull/8101)
|
||||||
|
* Reverts wrongly applies fix to book.toml by @AlexOn1ine in [#8105](https://github.com/rh-hideout/pokeemerald-expansion/pull/8105)
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @HashtagMarky made their first contribution in [#7905](https://github.com/rh-hideout/pokeemerald-expansion/pull/7905)
|
||||||
|
* @MaximeGr00 made their first contribution in [#7899](https://github.com/rh-hideout/pokeemerald-expansion/pull/7899)
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.13.2...expansion/1.13.3
|
||||||
|
|
||||||
|
|
||||||
|
<!--Last PR: 8107-->
|
||||||
|
<!--Used to keep track of the last PR merged in case new ones come in before the changelog is done.-->
|
||||||
@ -1,51 +1,51 @@
|
|||||||
# workarounds to avoid changing current directory structure
|
# workarounds to avoid changing current directory structure
|
||||||
# autolink logic based on https://github.com/zopieux/py-gfm/blob/fd7b33ed138d240d24dfb659acff7d4ce3f43745/gfm/autolink.py
|
# autolink logic based on https://github.com/zopieux/py-gfm/blob/fd7b33ed138d240d24dfb659acff7d4ce3f43745/gfm/autolink.py
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
|
||||||
URL_RE = re.compile(
|
URL_RE = re.compile(
|
||||||
r"(```(?s:.)+?```|`.+?`|<.+?>)|"
|
r"(```(?s:.)+?```|`.+?`|<.+?>)|"
|
||||||
r"\b((?:(?i:ftp|https?)://|(?i:www)\d{0,3}[.])(?:[^\s()<>]+|"
|
r"\b((?:(?i:ftp|https?)://|(?i:www)\d{0,3}[.])(?:[^\s()<>]+|"
|
||||||
r"\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()"
|
r"\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()"
|
||||||
r"<>]+\)))*\)|[^\s`!()\[\]{};:" + r"'" + r'".,<>?«»“”‘’*]))'
|
r"<>]+\)))*\)|[^\s`!()\[\]{};:" + r"'" + r'".,<>?«»“”‘’*]))'
|
||||||
)
|
)
|
||||||
PROTOCOL_RE = re.compile(r"^(?i:ftp|https?)://")
|
PROTOCOL_RE = re.compile(r"^(?i:ftp|https?)://")
|
||||||
|
|
||||||
ANCHOR_RE = re.compile(r"(\]\((?:[^)#]+\.md)?#)([^)]+\))")
|
ANCHOR_RE = re.compile(r"(\]\((?:[^)#]+\.md)?#)([^)]+\))")
|
||||||
|
|
||||||
def handle_url(m):
|
def handle_url(m):
|
||||||
code = m.group(1)
|
code = m.group(1)
|
||||||
if code:
|
if code:
|
||||||
return code
|
return code
|
||||||
href = m.group(2)
|
href = m.group(2)
|
||||||
if not PROTOCOL_RE.match(href):
|
if not PROTOCOL_RE.match(href):
|
||||||
href = "http://%s" % href
|
href = "http://%s" % href
|
||||||
return f'<{href}>'
|
return f'<{href}>'
|
||||||
|
|
||||||
def handle_anchor(m):
|
def handle_anchor(m):
|
||||||
page = m.group(1)
|
page = m.group(1)
|
||||||
anchor = m.group(2)
|
anchor = m.group(2)
|
||||||
return page + anchor.lower()
|
return page + anchor.lower()
|
||||||
|
|
||||||
def proc_items(items):
|
def proc_items(items):
|
||||||
for item in items:
|
for item in items:
|
||||||
if 'Chapter' in item:
|
if 'Chapter' in item:
|
||||||
s = item['Chapter']['content']
|
s = item['Chapter']['content']
|
||||||
s = s.replace('](README.md)', '](./)')
|
s = s.replace('](README.md)', '](./)')
|
||||||
s = s.replace('](/INSTALL.md', '](INSTALL.md')
|
s = s.replace('](/INSTALL.md', '](INSTALL.md')
|
||||||
s = s.replace('](docs/', '](')
|
s = s.replace('](docs/', '](')
|
||||||
s = URL_RE.sub(handle_url, s)
|
s = URL_RE.sub(handle_url, s)
|
||||||
item['Chapter']['content'] = ANCHOR_RE.sub(handle_anchor, s)
|
item['Chapter']['content'] = ANCHOR_RE.sub(handle_anchor, s)
|
||||||
proc_items(item['Chapter']['sub_items'])
|
proc_items(item['Chapter']['sub_items'])
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
if sys.argv[1] == "supports":
|
if sys.argv[1] == "supports":
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
context, book = json.load(sys.stdin)
|
context, book = json.load(sys.stdin)
|
||||||
proc_items(book['sections'])
|
proc_items(book['items'])
|
||||||
|
|
||||||
print(json.dumps(book))
|
print(json.dumps(book))
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
## Running documentation website locally
|
## Running documentation website locally
|
||||||
- [Ubuntu WSL1/WSL2](/docs/local_mdbook/ubuntu_WSL.md)
|
- [Ubuntu WSL1/WSL2](ubuntu_WSL.md)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ This document is a guide for maintainers to account for all the reccomended step
|
|||||||
# Checklist
|
# Checklist
|
||||||
|
|
||||||
## Is the branch's theoretical functionality in scope?
|
## Is the branch's theoretical functionality in scope?
|
||||||
If you're not sure if a branch's functionality is [in scope](docs/team_procedures/scope.md), start a conversation on Discord to resolve.
|
If you're not sure if a branch's functionality is [in scope](scope.md), start a conversation on Discord to resolve.
|
||||||
|
|
||||||
## Does the branch successfully compile?
|
## Does the branch successfully compile?
|
||||||
From `make clean`, the branch should locally compile.
|
From `make clean`, the branch should locally compile.
|
||||||
@ -37,18 +37,18 @@ If you're not sure if something CAN be tested, start a discussion. Some contribu
|
|||||||
|
|
||||||
If any new tests are `KNOWN_FAILING`, issues should be opened describing each of the `KNOWN_FAILING` tests and our understanding of why they fail.
|
If any new tests are `KNOWN_FAILING`, issues should be opened describing each of the `KNOWN_FAILING` tests and our understanding of why they fail.
|
||||||
|
|
||||||
## Does the branch meet our [config philosophy](/docs/STYLEGUIDE.md#config-philosophy)?
|
## Does the branch meet our [config philosophy](../STYLEGUIDE.md#config-philosophy)?
|
||||||
|
|
||||||
## Does the branch meet our [saves philosophy](/docs/STYLEGUIDE.md#saves-philosophy)?
|
## Does the branch meet our [saves philosophy](../STYLEGUIDE.md#saves-philosophy)?
|
||||||
|
|
||||||
## Does the submitted code follow the [styleguide](/docs/STYLEGUIDE.md)?
|
## Does the submitted code follow the [styleguide](../STYLEGUIDE.md)?
|
||||||
This applies to code that comes from other branches or games.
|
This applies to code that comes from other branches or games.
|
||||||
|
|
||||||
## Is the pull request appropriately labeled?
|
## Is the pull request appropriately labeled?
|
||||||
Without labels, the CHANGELOG will not be properly formatted. For specifically the `bugfix` label, an additional label, detailing what area the bug exists in is required.
|
Without labels, the CHANGELOG will not be properly formatted. For specifically the `bugfix` label, an additional label, detailing what area the bug exists in is required.
|
||||||
|
|
||||||
## Is `pokeemerald-expansion` free from a merge freeze?
|
## Is `pokeemerald-expansion` free from a merge freeze?
|
||||||
Our [release schedule](/docs/team_procedures/schedule.md) prevents us from merging Big Features and non-bugfixes within certain dates close to a release. Please use `/release` in the RHH Discord to clarify when these are occuring.
|
Our [release schedule](schedule.md) prevents us from merging Big Features and non-bugfixes within certain dates close to a release. Please use `/release` in the RHH Discord to clarify when these are occuring.
|
||||||
|
|
||||||
# Merging
|
# Merging
|
||||||
|
|
||||||
|
|||||||
@ -53,4 +53,4 @@ This designation should be reserved for instances where an existing feature on `
|
|||||||
|
|
||||||
Blocking issues or PRs can be deferred to future releases but should be discussed with the Maintainers that assigned the designation in the first place.
|
Blocking issues or PRs can be deferred to future releases but should be discussed with the Maintainers that assigned the designation in the first place.
|
||||||
|
|
||||||
If a version's milestone does not have any issues or PRs assigned to it, that version should be [released](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/team_procedures/expansion_versions.md) as close to the goal date as possible.
|
If a version's milestone does not have any issues or PRs assigned to it, that version should be [released](expansion_versions.md) as close to the goal date as possible.
|
||||||
|
|||||||
@ -23,8 +23,8 @@ When writing map scripts, `fadescreenswapbuffers` should be preferred over `fade
|
|||||||
|
|
||||||
### Q: How do I make lightbulbs glow?
|
### Q: How do I make lightbulbs glow?
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
A: Making lamps glow is not part of the tileset itself. Instead, place certain object events on top of where you desire a glowing effect.
|
A: Making lamps glow is not part of the tileset itself. Instead, place certain object events on top of where you desire a glowing effect.
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ on separate lines to mark those colors as being light-blended, i.e:
|
|||||||
|
|
||||||
During the day time, these color indices appear as normal, but will be blended with either yellow or the 0 index at night. These indices should only be used for things you expect to light up. If you are using [porytiles](https://github.com/grunt-lucas/porytiles/wiki), palette overrides and using slight alterations to a color will aid you in avoiding color conflicts where the wrong index is assigned.
|
During the day time, these color indices appear as normal, but will be blended with either yellow or the 0 index at night. These indices should only be used for things you expect to light up. If you are using [porytiles](https://github.com/grunt-lucas/porytiles/wiki), palette overrides and using slight alterations to a color will aid you in avoiding color conflicts where the wrong index is assigned.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The windows appear as normal during the day time (blue) and light up in the night. These use the default color.
|
The windows appear as normal during the day time (blue) and light up in the night. These use the default color.
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
*Written by Bivurnum*
|
*Written by Bivurnum*
|
||||||
*gif by ghoulslash*
|
*gif by ghoulslash*
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Configs
|
## Configs
|
||||||
The configs for follower NPCs can be found in [include/config/follower_npc.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/config/follower_npc.h).
|
The configs for follower NPCs can be found in [include/config/follower_npc.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/config/follower_npc.h).
|
||||||
|
|||||||
@ -42,7 +42,7 @@ The main things that the Expansion changes are listed here.
|
|||||||
# Useful resources
|
# Useful resources
|
||||||
You can open a sprite debug menu by pressing `Select` in a Pokémon's summary screen outside of battle.
|
You can open a sprite debug menu by pressing `Select` in a Pokémon's summary screen outside of battle.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# The Data - Part 1
|
# The Data - Part 1
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ We add this at the end so that no existing species change Id and so that we don'
|
|||||||
|
|
||||||
Now, let's see how it looks in-game!
|
Now, let's see how it looks in-game!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Hmmm, something's not right...
|
Hmmm, something's not right...
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ Now we can add the number and entry to our Mewthree:
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex.
|
The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex.
|
||||||
|
|
||||||
@ -497,7 +497,7 @@ Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemera
|
|||||||
...
|
...
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
# The Graphics
|
# The Graphics
|
||||||
@ -1058,7 +1058,7 @@ What this allows us to do is to be able to get all forms of a Pokémon in our co
|
|||||||
|
|
||||||
For example, in the HGSS dex, it lets us browse between the entries of every form available.:
|
For example, in the HGSS dex, it lets us browse between the entries of every form available.:
|
||||||
|
|
||||||
 
|
 
|
||||||
|
|
||||||
In addition, we have the `GET_BASE_SPECIES_ID` macro, which returns the first entry of the table (or return the species itself if it doesn't have a table registered). With this, you can check if a Pokémon is any form of a species. For example, making it so that the Light Ball affects all Pikachu forms:
|
In addition, we have the `GET_BASE_SPECIES_ID` macro, which returns the first entry of the table (or return the species itself if it doesn't have a table registered). With this, you can check if a Pokémon is any form of a species. For example, making it so that the Light Ball affects all Pikachu forms:
|
||||||
```c
|
```c
|
||||||
@ -1089,7 +1089,7 @@ The second value is the target form, to which the Pokémon will change into.
|
|||||||
Values after that are referred as arguments, and needs to be put there depends on the type of form change, detailed in `include/constants/form_change_types.h`.
|
Values after that are referred as arguments, and needs to be put there depends on the type of form change, detailed in `include/constants/form_change_types.h`.
|
||||||
|
|
||||||
## 3. Gender differences
|
## 3. Gender differences
|
||||||

|

|
||||||
|
|
||||||
You may have seen that there's a couple of duplicate fields with a "Female" suffix.
|
You may have seen that there's a couple of duplicate fields with a "Female" suffix.
|
||||||
```diff
|
```diff
|
||||||
@ -1262,8 +1262,8 @@ Either way, you may also create custom animation tables and use them here approp
|
|||||||
|
|
||||||
### How to add the Pokémon Object Events to map
|
### How to add the Pokémon Object Events to map
|
||||||
In Porymap, select the object you want to set the sprite to. Then, change the field "Sprite" to use `OBJ_EVENT_GFX_SPECIES(SPECIES)`, replacing SPECIES with the name of the species you want to use. If you get a compiler error, it's because it used the species define as part of the macro, so it needs to match how you defined it all the way back in [Declare a species constant](#1-Declare-a-species-constant).
|
In Porymap, select the object you want to set the sprite to. Then, change the field "Sprite" to use `OBJ_EVENT_GFX_SPECIES(SPECIES)`, replacing SPECIES with the name of the species you want to use. If you get a compiler error, it's because it used the species define as part of the macro, so it needs to match how you defined it all the way back in [Declare a species constant](#1-Declare-a-species-constant).
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
If you want to use their shiny and/or female versions, use one of the following macros:
|
If you want to use their shiny and/or female versions, use one of the following macros:
|
||||||
- `OBJ_EVENT_GFX_SPECIES_SHINY(name)`
|
- `OBJ_EVENT_GFX_SPECIES_SHINY(name)`
|
||||||
|
|||||||
115
docs/tutorials/vs_seeker.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# `pokemerald-expansion` Vs. Seeker
|
||||||
|
|
||||||
|
## What is the Vs. Seeker?
|
||||||
|
The Vs. Seeker is a Key Item that is used to battle Trainers that the player has battled previously.
|
||||||
|
|
||||||
|
When used, the Vs. Seeker sends out a signal that allows the player to find other Trainers who want a rematch. This signal affects all Trainers that are on-screen. Once used on Trainers that can be rematched, the device cannot be used again until it is charged. The player does this by walking a specific number of steps. The effect on the Trainers wears off if they are battled, the player leaves the area, or the player walks a specific number of steps. If the player attempts to use the Vs. Seeker when it is not fully charged, the player will be told how many steps remain until it is. After the player uses the Vs. Seeker, some Trainers may have their team changed from their first battle.
|
||||||
|
|
||||||
|
## How is the Vs. Seeker enabled?
|
||||||
|
### Users
|
||||||
|
Vs. Seeker functionality is enabled by setting `I_VS_SEEKER_CHARGING` to `TRUE`.
|
||||||
|
|
||||||
|
### Players
|
||||||
|
`ITEM_VS_SEEKER` can only be used outside of battle. It can be used from the bag or registered to be used from the field.
|
||||||
|
|
||||||
|
Usage of the Vs. Seeker will ALWAYS fail unless all of the conditions are met:
|
||||||
|
* Player has at least five badges
|
||||||
|
* There is an NPC on screen that has previously been defeated
|
||||||
|
* Player is not inside of a building
|
||||||
|
* The Vs. Seeker is fully recharged
|
||||||
|
|
||||||
|
#### Charge
|
||||||
|
If the player has `ITEM_VS_SEEKER` and at least five badges, the Vs. Seeker will be charged by walking steps. The Vs. Seeker is fully charged once the player has walked `VSSEEKER_RECHARGE_STEPS`, which is `100` by default. The Vs. Seeker's charge is depleted if the player uses the item.
|
||||||
|
|
||||||
|
### How does Match Call interact with the Vs. Seeker?
|
||||||
|
When `I_VS_SEEKER_CHARGING` is enabled, the Match Call does not function at all. Trainers will never be rematch eligible outside of the use of the Vs. Seeker.
|
||||||
|
|
||||||
|
## How does the Vs. Seeker choose a Trainer?
|
||||||
|
|
||||||
|
When the Vs. Seeker is successfully used, every Trainer on screen is individually queried. There is a 31% chance that the Trainer will want a rematch.
|
||||||
|
Objects listed in `regularTrainersOnLand` or `regularTrainersInWater` are considered Land/Water objects.
|
||||||
|
|
||||||
|
| Status | Is Land/Water Object | Emote | New Movement Type |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Wants Rematch | Yes | `MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK` | `MOVEMENT_TYPE_COUNTER_CLOCKWISE` |
|
||||||
|
| Wants Rematch | No | `MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK` | `MOVEMENT_TYPE_FACE_DOWN` |
|
||||||
|
| Does Not Want Rematch | - | `MOVEMENT_ACTION_EMOTE_X` | none |
|
||||||
|
| Has Not Been Fought | - | `MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK` | none |
|
||||||
|
|
||||||
|
### Rematch Table
|
||||||
|
|
||||||
|
| Sequence | Trainer ID |
|
||||||
|
| ---------- | ---------------- |
|
||||||
|
| 1st Battle | `TRAINER_ROSE_1` |
|
||||||
|
| 2nd Battle | `TRAINER_ROSE_2` |
|
||||||
|
| 3rd Battle | `TRAINER_ROSE_3` |
|
||||||
|
| 4th Battle | `TRAINER_ROSE_4` |
|
||||||
|
| 5th Battle | `TRAINER_ROSE_5` |
|
||||||
|
|
||||||
|
The game determines which version of the Trainer you'll fight next by following these rules:
|
||||||
|
|
||||||
|
1. Start with the next Trainer in the sequence after the one that has been defeated. If there are no more, the battle is against the last listed Trainer.
|
||||||
|
2. If that next Trainer hasn't been unlocked yet, the battle is against the latest available unlocked version.
|
||||||
|
3. If the next Trainer is unlocked but not yet defeated, the battle is against that version.
|
||||||
|
4. If the next Trainer has already been defeated, check the next one in the sequence.
|
||||||
|
|
||||||
|
## How do users implement rematches with the Vs. Seeker?
|
||||||
|
### Existing `pokemerald` Trainers
|
||||||
|
No extra work is required. With the exception of Wally, Gym Leaders and Elite Four, all of the rematchable Trainers in Emerald will work with the Vs. Seeker without any changes.
|
||||||
|
### New Trainers
|
||||||
|
#### Party / `gRematchTable`
|
||||||
|
Each of the rematches for the Trainer must be defined as seperate Trainers in `src/data/trainers.party` and `include/constants/opponents`. For example, `TRAINER_CALVIN_1` also has `TRAINER_CALVIN_2`,`TRAINER_CALVIN_3`,`TRAINER_CALVIN_4`, and `TRAINER_CALVIN_5`.
|
||||||
|
|
||||||
|
Once all of those constants and parties are defined, a new row must be added to `gRematchTable` (located in in `src/battle_setup.c`). The row header should be a rematch ID, which can be added in `include/constants/rematches.h`. The row contents must be the five constants created for the new parties, with the lat argument being the constant of the map (`include/constants/map_groups.h`) where the Trainer is placed.
|
||||||
|
|
||||||
|
If a Trainer is intended to have less than five unique rematch parties, the extra slots can be filled with the last available Trainer ID.
|
||||||
|
|
||||||
|
```c
|
||||||
|
// This Trainer only has two teams.
|
||||||
|
[REMATCH_ROSE] = REMATCH(TRAINER_ROSE_1, TRAINER_ROSE_2, TRAINER_ROSE_2, TRAINER_ROSE_2, TRAINER_ROSE_2, MAP_ROUTE118),
|
||||||
|
```
|
||||||
|
|
||||||
|
WARNING: Rematch IDs should be placed BEFORE `REMATCH_WALLY_VR`. Trainers below that are treated as "special Trainers" that are not triggered by the Vs. Seeker.
|
||||||
|
|
||||||
|
#### Scripts
|
||||||
|
The trainer's object needs to have a script that begins with a method to signify what this object's trainer ID is.
|
||||||
|
|
||||||
|
#### `trainerbattle`
|
||||||
|
```
|
||||||
|
Route103_EventScript_Daisy::
|
||||||
|
trainerbattle_single TRAINER_DAISY, Route103_Text_DaisyIntro, Route103_Text_DaisyDefeated
|
||||||
|
msgbox Route103_Text_DaisyPostBattle, MSGBOX_AUTOCLOSE
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Daisy is using one of the `trainerbattle` macros, which has the trainer battle macro in the first command of the script. Most trainers in `pokeemerald` use this pattern.
|
||||||
|
|
||||||
|
##### `vsseeker_rematchid`
|
||||||
|
```
|
||||||
|
Route102_EventScript_Calvin::
|
||||||
|
vsseeker_rematchid TRAINER_CALVIN_1
|
||||||
|
applymovement LOCALID_CALVIN, CalvinMovementTest
|
||||||
|
waitmovement 0
|
||||||
|
trainerbattle_single TRAINER_CALVIN_1, Route102_Text_CalvinIntro, Route102_Text_CalvinDefeated, Route102_EventScript_CalvinRegisterMatchCallAfterBattle
|
||||||
|
specialvar VAR_RESULT, ShouldTryRematchBattle
|
||||||
|
goto_if_eq VAR_RESULT, TRUE, Route102_EventScript_CalvinRematch
|
||||||
|
setvar VAR_0x8004, TRAINER_CALVIN_1
|
||||||
|
specialvar VAR_RESULT, IsTrainerRegistered
|
||||||
|
goto_if_eq VAR_RESULT, FALSE, Route102_EventScript_CalvinTryRegister
|
||||||
|
msgbox Route102_Text_CalvinPostBattle, MSGBOX_DEFAULT
|
||||||
|
release
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
If the trainer has other script commands before the eventual `trainerbattle` macro, the first command in the script needs to be `vsseeker_rematchid`. This macro does nothing but takes a single argument, which should be the same as the first Trainer ID for this trainer.
|
||||||
|
|
||||||
|
#### `MOVEMENT_TYPE_COUNTER_CLOCKWISE`
|
||||||
|
If you want Trainers to spin once they are eligible for a rematch, their overworld graphics object ID (`include/constants/event_objects.h`) must be listed in either `regularTrainersOnLand` or `regularTrainersInWater`.Otherwise they will adopt the movement type `MOVEMENT_TYPE_FACE_DOWN`.
|
||||||
|
|
||||||
|
## What can be customized about the Vs. Seeker?
|
||||||
|
* **Unlock Conditions**: The next "level" of rematches is unlocked when a specific flag is set. The flags that are currently used in `GetGameProgressFlags` can be changed to flags that better suit your game.
|
||||||
|
* **Recharge Steps**: `VSSEEKER_RECHARGE_STEPS` is initally set to 100, but this value can be changed to any number under 256.
|
||||||
|
* **Badge Requirement**: `HasAtLeastFiveBadges` is used to check if the Vs. Seeker will successfully work. You can customize the number of badges by changing `REMATCH_BADGE_COUNT` or otherwise alterting the function.
|
||||||
|
|
||||||
|
## What are the limitations of the Vs. Seeker?
|
||||||
|
The Vs. Seeker does not currently work with Gym Leaders. There is a bug filed to hopefully fix this in the future.
|
||||||
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 277 B |
|
Before Width: | Height: | Size: 293 B After Width: | Height: | Size: 282 B |
|
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 284 B |
|
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 914 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 728 B After Width: | Height: | Size: 567 B |
@ -410,7 +410,7 @@ $(RAYQUAZAGFXDIR)/scene_2/bg.4bpp: %.4bpp: %.png
|
|||||||
$(GFX) $< $@ -num_tiles 313 -Wnum_tiles
|
$(GFX) $< $@ -num_tiles 313 -Wnum_tiles
|
||||||
|
|
||||||
$(RAYQUAZAGFXDIR)/scene_3/rayquaza.4bpp: %.4bpp: %.png
|
$(RAYQUAZAGFXDIR)/scene_3/rayquaza.4bpp: %.4bpp: %.png
|
||||||
$(GFX) $< $@ -num_tiles 124 -Wnum_tiles
|
$(GFX) $< $@ -num_tiles 128 -Wnum_tiles
|
||||||
|
|
||||||
$(RAYQUAZAGFXDIR)/scene_4/streaks.4bpp: %.4bpp: %.png
|
$(RAYQUAZAGFXDIR)/scene_4/streaks.4bpp: %.4bpp: %.png
|
||||||
$(GFX) $< $@ -num_tiles 19 -Wnum_tiles
|
$(GFX) $< $@ -num_tiles 19 -Wnum_tiles
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "battle_util2.h"
|
#include "battle_util2.h"
|
||||||
#include "battle_bg.h"
|
#include "battle_bg.h"
|
||||||
#include "pokeball.h"
|
#include "pokeball.h"
|
||||||
|
#include "main.h"
|
||||||
#include "battle_debug.h"
|
#include "battle_debug.h"
|
||||||
#include "battle_dynamax.h"
|
#include "battle_dynamax.h"
|
||||||
#include "battle_terastal.h"
|
#include "battle_terastal.h"
|
||||||
@ -722,7 +723,7 @@ struct BattleStruct
|
|||||||
struct Illusion illusion[MAX_BATTLERS_COUNT];
|
struct Illusion illusion[MAX_BATTLERS_COUNT];
|
||||||
u8 soulheartBattlerId;
|
u8 soulheartBattlerId;
|
||||||
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
|
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
|
||||||
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
|
u8 metronomeItemCounter[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
|
||||||
u8 quickClawBattlerId;
|
u8 quickClawBattlerId;
|
||||||
struct LostItem itemLost[NUM_BATTLE_SIDES][PARTY_SIZE]; // Pokemon that had items consumed or stolen (two bytes per party member per side)
|
struct LostItem itemLost[NUM_BATTLE_SIDES][PARTY_SIZE]; // Pokemon that had items consumed or stolen (two bytes per party member per side)
|
||||||
u8 blunderPolicy:1; // should blunder policy activate
|
u8 blunderPolicy:1; // should blunder policy activate
|
||||||
@ -782,7 +783,8 @@ struct BattleStruct
|
|||||||
u8 hazardsQueue[NUM_BATTLE_SIDES][HAZARDS_MAX_COUNT];
|
u8 hazardsQueue[NUM_BATTLE_SIDES][HAZARDS_MAX_COUNT];
|
||||||
u8 numHazards[NUM_BATTLE_SIDES];
|
u8 numHazards[NUM_BATTLE_SIDES];
|
||||||
u8 hazardsCounter:4; // Counter for applying hazard on switch in
|
u8 hazardsCounter:4; // Counter for applying hazard on switch in
|
||||||
u8 padding2:4;
|
u8 incrementEchoedVoice:1;
|
||||||
|
u8 echoedVoiceCounter:3;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AiBattleData
|
struct AiBattleData
|
||||||
@ -1117,7 +1119,7 @@ extern u16 gBattleTurnCounter;
|
|||||||
extern u8 gBattlerAbility;
|
extern u8 gBattlerAbility;
|
||||||
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];
|
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];
|
||||||
|
|
||||||
extern void (*gPreBattleCallback1)(void);
|
extern MainCallback gPreBattleCallback1;
|
||||||
extern void (*gBattleMainFunc)(void);
|
extern void (*gBattleMainFunc)(void);
|
||||||
extern struct BattleResults gBattleResults;
|
extern struct BattleResults gBattleResults;
|
||||||
extern u8 gLeveledUpInBattle;
|
extern u8 gLeveledUpInBattle;
|
||||||
|
|||||||
@ -155,6 +155,7 @@ bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffe
|
|||||||
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category);
|
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category);
|
||||||
enum MoveComparisonResult AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
|
enum MoveComparisonResult AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
|
||||||
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);
|
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);
|
||||||
|
bool32 IsAdditionalEffectBlocked(u32 battlerAtk, u32 abilityAtk, u32 battlerDef, u32 abilityDef);
|
||||||
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather);
|
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather);
|
||||||
bool32 AI_IsDamagedByRecoil(u32 battler);
|
bool32 AI_IsDamagedByRecoil(u32 battler);
|
||||||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||||
|
|||||||
@ -22,7 +22,7 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *battler);
|
|||||||
void ClearSpritesHealthboxAnimData(void);
|
void ClearSpritesHealthboxAnimData(void);
|
||||||
void CopyAllBattleSpritesInvisibilities(void);
|
void CopyAllBattleSpritesInvisibilities(void);
|
||||||
void CopyBattleSpriteInvisibility(u8 battler);
|
void CopyBattleSpriteInvisibility(u8 battler);
|
||||||
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool8 trackEnemyPersonality);
|
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, u8 changeType);
|
||||||
void BattleLoadSubstituteOrMonSpriteGfx(u8 battler, bool8 loadMonSprite);
|
void BattleLoadSubstituteOrMonSpriteGfx(u8 battler, bool8 loadMonSprite);
|
||||||
void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId);
|
void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId);
|
||||||
void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move);
|
void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move);
|
||||||
|
|||||||
@ -35,6 +35,7 @@ void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick);
|
|||||||
void ChangeGimmickTriggerSprite(u32 spriteId, u32 animId);
|
void ChangeGimmickTriggerSprite(u32 spriteId, u32 animId);
|
||||||
void CreateGimmickTriggerSprite(u32 battler);
|
void CreateGimmickTriggerSprite(u32 battler);
|
||||||
bool32 IsGimmickTriggerSpriteActive(void);
|
bool32 IsGimmickTriggerSpriteActive(void);
|
||||||
|
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler);
|
||||||
void HideGimmickTriggerSprite(void);
|
void HideGimmickTriggerSprite(void);
|
||||||
void DestroyGimmickTriggerSprite(void);
|
void DestroyGimmickTriggerSprite(void);
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
#define GUARD_BATTLE_PYRAMID_BAG_H
|
#define GUARD_BATTLE_PYRAMID_BAG_H
|
||||||
|
|
||||||
#include "list_menu.h"
|
#include "list_menu.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PYRAMIDBAG_LOC_FIELD,
|
PYRAMIDBAG_LOC_FIELD,
|
||||||
@ -29,7 +31,7 @@ enum {
|
|||||||
|
|
||||||
struct PyramidBagMenu
|
struct PyramidBagMenu
|
||||||
{
|
{
|
||||||
void (*newScreenCallback)(void);
|
MainCallback newScreenCallback;
|
||||||
u8 tilemapBuffer[BG_SCREEN_SIZE];
|
u8 tilemapBuffer[BG_SCREEN_SIZE];
|
||||||
u8 spriteIds[PBAG_SPRITE_COUNT];
|
u8 spriteIds[PBAG_SPRITE_COUNT];
|
||||||
u8 windowIds[5];
|
u8 windowIds[5];
|
||||||
@ -49,7 +51,7 @@ struct PyramidBagMenu
|
|||||||
|
|
||||||
struct PyramidBagMenuState
|
struct PyramidBagMenuState
|
||||||
{
|
{
|
||||||
void (*exitCallback)(void);
|
MainCallback exitCallback;
|
||||||
u8 location;
|
u8 location;
|
||||||
u16 cursorPosition;
|
u16 cursorPosition;
|
||||||
u16 scrollPosition;
|
u16 scrollPosition;
|
||||||
@ -63,11 +65,11 @@ void CB2_PyramidBagMenuFromStartMenu(void);
|
|||||||
void CB2_ReturnToPyramidBagMenu(void);
|
void CB2_ReturnToPyramidBagMenu(void);
|
||||||
void UpdatePyramidBagList(void);
|
void UpdatePyramidBagList(void);
|
||||||
void UpdatePyramidBagCursorPos(void);
|
void UpdatePyramidBagCursorPos(void);
|
||||||
void GoToBattlePyramidBagMenu(u8 location, void (*exitCallback)(void));
|
void GoToBattlePyramidBagMenu(u8 location, MainCallback exitCallback);
|
||||||
void Task_CloseBattlePyramidBagMessage(u8 taskId);
|
void Task_CloseBattlePyramidBagMessage(u8 taskId);
|
||||||
void TryStoreHeldItemsInPyramidBag(void);
|
void TryStoreHeldItemsInPyramidBag(void);
|
||||||
void ChooseItemsToTossFromPyramidBag(void);
|
void ChooseItemsToTossFromPyramidBag(void);
|
||||||
void CloseBattlePyramidBag(u8 taskId);
|
void CloseBattlePyramidBag(u8 taskId);
|
||||||
void DisplayItemMessageInBattlePyramid(u8 taskId, const u8 *str, void (*callback)(u8 taskId));
|
void DisplayItemMessageInBattlePyramid(u8 taskId, const u8 *str, TaskFunc callback);
|
||||||
|
|
||||||
#endif // GUARD_BATTLE_PYRAMID_BAG_H
|
#endif // GUARD_BATTLE_PYRAMID_BAG_H
|
||||||
|
|||||||
@ -73,6 +73,7 @@ void ConfigureAndSetUpOneTrainerBattle(u8 trainerObjEventId, const u8 *trainerSc
|
|||||||
void ConfigureTwoTrainersBattle(u8 trainerObjEventId, const u8 *trainerScript);
|
void ConfigureTwoTrainersBattle(u8 trainerObjEventId, const u8 *trainerScript);
|
||||||
void SetUpTwoTrainersBattle(void);
|
void SetUpTwoTrainersBattle(void);
|
||||||
bool32 GetTrainerFlagFromScriptPointer(const u8 *data);
|
bool32 GetTrainerFlagFromScriptPointer(const u8 *data);
|
||||||
|
bool32 GetRematchFromScriptPointer(const u8 *data);
|
||||||
void SetTrainerFacingDirection(void);
|
void SetTrainerFacingDirection(void);
|
||||||
u8 GetTrainerBattleMode(void);
|
u8 GetTrainerBattleMode(void);
|
||||||
bool8 GetTrainerFlag(void);
|
bool8 GetTrainerFlag(void);
|
||||||
@ -90,12 +91,14 @@ const u8 *GetTrainerALoseText(void);
|
|||||||
const u8 *GetTrainerBLoseText(void);
|
const u8 *GetTrainerBLoseText(void);
|
||||||
const u8 *GetTrainerWonSpeech(void);
|
const u8 *GetTrainerWonSpeech(void);
|
||||||
void UpdateRematchIfDefeated(s32 rematchTableId);
|
void UpdateRematchIfDefeated(s32 rematchTableId);
|
||||||
|
void ClearCurrentTrainerWantRematchVsSeeker(void);
|
||||||
void IncrementRematchStepCounter(void);
|
void IncrementRematchStepCounter(void);
|
||||||
void TryUpdateRandomTrainerRematches(u16 mapGroup, u16 mapNum);
|
void TryUpdateRandomTrainerRematches(u16 mapGroup, u16 mapNum);
|
||||||
bool32 DoesSomeoneWantRematchIn(u16 mapGroup, u16 mapNum);
|
bool32 DoesSomeoneWantRematchIn(u16 mapGroup, u16 mapNum);
|
||||||
bool32 IsRematchTrainerIn(u16 mapGroup, u16 mapNum);
|
bool32 IsRematchTrainerIn(u16 mapGroup, u16 mapNum);
|
||||||
u16 GetLastBeatenRematchTrainerId(u16 trainerId);
|
u16 GetLastBeatenRematchTrainerId(u16 trainerId);
|
||||||
bool8 ShouldTryRematchBattle(void);
|
bool8 ShouldTryRematchBattle(void);
|
||||||
|
bool8 ShouldTryRematchBattleForTrainerId(u16 trainerId);
|
||||||
bool8 IsTrainerReadyForRematch(void);
|
bool8 IsTrainerReadyForRematch(void);
|
||||||
void ShouldTryGetTrainerScript(void);
|
void ShouldTryGetTrainerScript(void);
|
||||||
u16 CountBattledRematchTeams(u16 trainerId);
|
u16 CountBattledRematchTeams(u16 trainerId);
|
||||||
|
|||||||
@ -165,7 +165,8 @@ struct DamageContext
|
|||||||
u32 isCrit:1;
|
u32 isCrit:1;
|
||||||
u32 randomFactor:1;
|
u32 randomFactor:1;
|
||||||
u32 updateFlags:1;
|
u32 updateFlags:1;
|
||||||
u32 padding1:2;
|
u32 isAnticipation:1;
|
||||||
|
u32 padding1:1;
|
||||||
u32 weather:16;
|
u32 weather:16;
|
||||||
u32 fixedBasePower:8;
|
u32 fixedBasePower:8;
|
||||||
u32 padding2:8;
|
u32 padding2:8;
|
||||||
@ -241,7 +242,8 @@ void TryClearRageAndFuryCutter(void);
|
|||||||
enum MoveCanceller AtkCanceller_MoveSuccessOrder(void);
|
enum MoveCanceller AtkCanceller_MoveSuccessOrder(void);
|
||||||
void SetAtkCancellerForCalledMove(void);
|
void SetAtkCancellerForCalledMove(void);
|
||||||
bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
|
bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
|
||||||
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility);
|
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability);
|
||||||
|
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag);
|
||||||
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, u32 move, enum FunctionCallOption option);
|
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, u32 move, enum FunctionCallOption option);
|
||||||
bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 move, u32 moveType, enum FunctionCallOption option);
|
bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 move, u32 moveType, enum FunctionCallOption option);
|
||||||
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
|
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
|
||||||
@ -298,6 +300,7 @@ bool32 IsBattlerMegaEvolved(u32 battler);
|
|||||||
bool32 IsBattlerPrimalReverted(u32 battler);
|
bool32 IsBattlerPrimalReverted(u32 battler);
|
||||||
bool32 IsBattlerUltraBursted(u32 battler);
|
bool32 IsBattlerUltraBursted(u32 battler);
|
||||||
u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method);
|
u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method);
|
||||||
|
bool32 TryRevertPartyMonFormChange(u32 partyIndex);
|
||||||
bool32 TryBattleFormChange(u32 battler, enum FormChanges method);
|
bool32 TryBattleFormChange(u32 battler, enum FormChanges method);
|
||||||
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
|
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
|
||||||
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
|
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
|
||||||
@ -310,6 +313,7 @@ u32 GetIllusionMonPartyId(struct Pokemon *party, struct Pokemon *mon, struct Pok
|
|||||||
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
|
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
|
||||||
u32 TryImmunityAbilityHealStatus(u32 battler, u32 caseID);
|
u32 TryImmunityAbilityHealStatus(u32 battler, u32 caseID);
|
||||||
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
|
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
|
||||||
|
uq4_12_t GetBadgeBoostModifier(void);
|
||||||
enum DamageCategory GetBattleMoveCategory(u32 move);
|
enum DamageCategory GetBattleMoveCategory(u32 move);
|
||||||
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, u32 move);
|
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||||
bool32 CanFling(u32 battler);
|
bool32 CanFling(u32 battler);
|
||||||
@ -329,7 +333,7 @@ bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
|||||||
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID);
|
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID);
|
||||||
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
|
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
|
||||||
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
|
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
|
||||||
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
|
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind, u32 ability);
|
||||||
bool32 TryRoomService(u32 battler);
|
bool32 TryRoomService(u32 battler);
|
||||||
void BufferStatChange(u32 battler, u8 statId, enum StringID stringId);
|
void BufferStatChange(u32 battler, u8 statId, enum StringID stringId);
|
||||||
bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
|
bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
|
||||||
@ -411,5 +415,6 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u
|
|||||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||||
bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander);
|
bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander);
|
||||||
bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move);
|
bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move);
|
||||||
|
bool32 HasPartnerTrainer(u32 battler);
|
||||||
|
|
||||||
#endif // GUARD_BATTLE_UTIL_H
|
#endif // GUARD_BATTLE_UTIL_H
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
#define B_LEVEL_UP_NOTIFICATION GEN_LATEST // In Gen9+, if the Pokémon gets enough experience to level up multiple times, the message is only displayed once.
|
#define B_LEVEL_UP_NOTIFICATION GEN_LATEST // In Gen9+, if the Pokémon gets enough experience to level up multiple times, the message is only displayed once.
|
||||||
|
|
||||||
// Stat settings
|
// Stat settings
|
||||||
#define B_BADGE_BOOST GEN_LATEST // In Gen4+, Gym Badges no longer boost a Pokémon's stats.
|
#define B_BADGE_BOOST GEN_LATEST // In Gen4+, Gym Badges no longer boost a Pokémon's stats. (Gen2 does not include the additional boost to the type matching the gym the badge is from)
|
||||||
#define B_FRIENDSHIP_BOOST FALSE // In LGPE only, all stats except HP are boosted up to 10% based on Friendship. Unlike B_BADGE_BOOST, these boosts are accounted when calculating base stats.
|
#define B_FRIENDSHIP_BOOST FALSE // In LGPE only, all stats except HP are boosted up to 10% based on Friendship. Unlike B_BADGE_BOOST, these boosts are accounted when calculating base stats.
|
||||||
#define B_MAX_LEVEL_EV_GAINS GEN_LATEST // In Gen5+, Lv100 Pokémon can obtain Effort Values normally.
|
#define B_MAX_LEVEL_EV_GAINS GEN_LATEST // In Gen5+, Lv100 Pokémon can obtain Effort Values normally.
|
||||||
#define B_RECALCULATE_STATS GEN_LATEST // In Gen5+, the stats of the Pokémon who participate in battle are recalculated at the end of each battle.
|
#define B_RECALCULATE_STATS GEN_LATEST // In Gen5+, the stats of the Pokémon who participate in battle are recalculated at the end of each battle.
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
#define I_REPEL_LURE_MENU TRUE // If TRUE, the player is able to choose which Repel/Lure to use once the previous one runs out. Cursor position is saved by VAR_LAST_REPEL_LURE_USED if not 0.
|
#define I_REPEL_LURE_MENU TRUE // If TRUE, the player is able to choose which Repel/Lure to use once the previous one runs out. Cursor position is saved by VAR_LAST_REPEL_LURE_USED if not 0.
|
||||||
|
|
||||||
// Vs. Seeker
|
// Vs. Seeker
|
||||||
#define I_VS_SEEKER_CHARGING 0 // If this flag is assigned, the Vs Seeker functionality will be enabled. When the player has the Vs. Seeker, Match Call rematch functions will stop working.
|
#define I_VS_SEEKER_CHARGING 0 // If this flag is assigned, the Vs Seeker functionality will be enabled. When the player has the Vs. Seeker, Match Call rematch functions will stop working. Documentation for the Vs. Seeker can be found in docs/tutorials/vs_seeker.md.
|
||||||
|
|
||||||
// Fishing
|
// Fishing
|
||||||
#define I_FISHING_BITE_ODDS GEN_LATEST // In Gen 1 and Gen 2, the Old Rod has a 100% chance for a bite, Good Rod has a 66% chance for a bite, and Super Rod has a 50% chance for a bite. In Gen 3, all rods have a base 50% chance for a bite. In Gen 4 onwards, the Old Rod has a base 25% chance for a bite, Good Rod has a 50% chance for a bite, and Super Rod has a 75% chance for a bite.
|
#define I_FISHING_BITE_ODDS GEN_LATEST // In Gen 1 and Gen 2, the Old Rod has a 100% chance for a bite, Good Rod has a 66% chance for a bite, and Super Rod has a 50% chance for a bite. In Gen 3, all rods have a base 50% chance for a bite. In Gen 4 onwards, the Old Rod has a base 25% chance for a bite, Good Rod has a 50% chance for a bite, and Super Rod has a 75% chance for a bite.
|
||||||
|
|||||||
@ -133,6 +133,7 @@
|
|||||||
#define OW_POPUP_BW_TIME_MODE OW_POPUP_BW_TIME_NONE // Determines what type of time is shown.
|
#define OW_POPUP_BW_TIME_MODE OW_POPUP_BW_TIME_NONE // Determines what type of time is shown.
|
||||||
#define OW_POPUP_BW_ALPHA_BLEND FALSE // Enables alpha blending/transparency for the pop-ups. Mainly intended to be used with the black color option.
|
#define OW_POPUP_BW_ALPHA_BLEND FALSE // Enables alpha blending/transparency for the pop-ups. Mainly intended to be used with the black color option.
|
||||||
// Setting this to TRUE will cause graphical errors with the Day Night System enabled.
|
// Setting this to TRUE will cause graphical errors with the Day Night System enabled.
|
||||||
|
// It will also cause minor visual glitches of shadow and reflection sprites adjusting their transparency when the pop-up disappear
|
||||||
|
|
||||||
// Pokémon Center
|
// Pokémon Center
|
||||||
#define OW_IGNORE_EGGS_ON_HEAL GEN_LATEST // In Gen 4+, the nurse in the Pokémon Center does not heal Eggs on healing machine.
|
#define OW_IGNORE_EGGS_ON_HEAL GEN_LATEST // In Gen 4+, the nurse in the Pokémon Center does not heal Eggs on healing machine.
|
||||||
@ -142,4 +143,7 @@
|
|||||||
// Berry Blender
|
// Berry Blender
|
||||||
#define BERRY_BLENDER_THROW_ALL_BERRIES_AT_ONCE TRUE // This is a small little addition, that basically speeds up the animation where all players' berries are thrown into the blender. Self-explanatory I hope!
|
#define BERRY_BLENDER_THROW_ALL_BERRIES_AT_ONCE TRUE // This is a small little addition, that basically speeds up the animation where all players' berries are thrown into the blender. Self-explanatory I hope!
|
||||||
|
|
||||||
|
// Trainer Rematches
|
||||||
|
#define OW_REMATCH_BADGE_COUNT 5 // Number of badges necessary before the match call or vs seeker features allow rematches
|
||||||
|
|
||||||
#endif // GUARD_CONFIG_OVERWORLD_H
|
#endif // GUARD_CONFIG_OVERWORLD_H
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#define P_SUMMARY_SCREEN_RENAME TRUE // If TRUE, an option to change Pokémon nicknames replaces the cancel prompt on the summary screen info page.
|
#define P_SUMMARY_SCREEN_RENAME TRUE // If TRUE, an option to change Pokémon nicknames replaces the cancel prompt on the summary screen info page.
|
||||||
#define P_SUMMARY_SCREEN_IV_EV_INFO FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page.
|
#define P_SUMMARY_SCREEN_IV_EV_INFO FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page.
|
||||||
#define P_SUMMARY_SCREEN_IV_EV_BOX_ONLY FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page, but only in the PC storage box.
|
#define P_SUMMARY_SCREEN_IV_EV_BOX_ONLY FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page, but only in the PC storage box.
|
||||||
|
#define P_SUMMARY_SCREEN_IV_HYPERTRAIN TRUE // If TRUE, stats that have been hyper trained will show as 31/S when viewing them in the summary screen
|
||||||
#define P_SUMMARY_SCREEN_IV_EV_TILESET FALSE // If TRUE, loads an alternate tileset to allow changing the "STATS" label in the summary screen skills page. Note: if it's still loading the alternate tileset after changing this and recompiling, you may need a `make clean` before compilation.
|
#define P_SUMMARY_SCREEN_IV_EV_TILESET FALSE // If TRUE, loads an alternate tileset to allow changing the "STATS" label in the summary screen skills page. Note: if it's still loading the alternate tileset after changing this and recompiling, you may need a `make clean` before compilation.
|
||||||
#define P_SUMMARY_SCREEN_IV_EV_VALUES FALSE // If TRUE, will show the actual IV value instead of the letter grade.
|
#define P_SUMMARY_SCREEN_IV_EV_VALUES FALSE // If TRUE, will show the actual IV value instead of the letter grade.
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -99,6 +99,7 @@ enum BattlerId
|
|||||||
#define RECORDED_WILD_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_RECORDED) && !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER)))
|
#define RECORDED_WILD_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_RECORDED) && !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER)))
|
||||||
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && TRAINER_BATTLE_PARAM.opponentB == 0xFFFF))
|
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && TRAINER_BATTLE_PARAM.opponentB == 0xFFFF))
|
||||||
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)
|
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)
|
||||||
|
#define BATTLE_TYPE_PLAYER_HAS_PARTNER (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_TOWER_LINK_MULTI)
|
||||||
|
|
||||||
// Battle Outcome defines
|
// Battle Outcome defines
|
||||||
#define B_OUTCOME_WON 1
|
#define B_OUTCOME_WON 1
|
||||||
@ -159,7 +160,6 @@ enum VolatileFlags
|
|||||||
F(VOLATILE_INFATUATION, infatuation, (enum BattlerId, MAX_BITS(4))) \
|
F(VOLATILE_INFATUATION, infatuation, (enum BattlerId, MAX_BITS(4))) \
|
||||||
F(VOLATILE_DEFENSE_CURL, defenseCurl, (u32, 1)) \
|
F(VOLATILE_DEFENSE_CURL, defenseCurl, (u32, 1)) \
|
||||||
F(VOLATILE_TRANSFORMED, transformed, (u32, 1)) \
|
F(VOLATILE_TRANSFORMED, transformed, (u32, 1)) \
|
||||||
F(VOLATILE_RECHARGE, recharge, (u32, 1)) \
|
|
||||||
F(VOLATILE_RAGE, rage, (u32, 1)) \
|
F(VOLATILE_RAGE, rage, (u32, 1)) \
|
||||||
F(VOLATILE_SUBSTITUTE, substitute, (u32, 1), V_BATON_PASSABLE) \
|
F(VOLATILE_SUBSTITUTE, substitute, (u32, 1), V_BATON_PASSABLE) \
|
||||||
F(VOLATILE_DESTINY_BOND, destinyBond, (u32, 1)) \
|
F(VOLATILE_DESTINY_BOND, destinyBond, (u32, 1)) \
|
||||||
|
|||||||
@ -667,6 +667,14 @@
|
|||||||
#define ANIM_ORDER_UP_DROOPY 2
|
#define ANIM_ORDER_UP_DROOPY 2
|
||||||
#define ANIM_ORDER_UP_STRETCHY 3
|
#define ANIM_ORDER_UP_STRETCHY 3
|
||||||
|
|
||||||
|
// AnimTask_TransformMon variations
|
||||||
|
enum SpeciesGfxChange
|
||||||
|
{
|
||||||
|
SPECIES_GFX_CHANGE_TRANSFORM,
|
||||||
|
SPECIES_GFX_CHANGE_FORM_CHANGE,
|
||||||
|
SPECIES_GFX_CHANGE_ILLUSION_OFF,
|
||||||
|
};
|
||||||
|
|
||||||
// Flags given to various functions to indicate which palettes to consider.
|
// Flags given to various functions to indicate which palettes to consider.
|
||||||
// Handled by UnpackSelectedBattlePalettes
|
// Handled by UnpackSelectedBattlePalettes
|
||||||
#define F_PAL_BG (1 << 0)
|
#define F_PAL_BG (1 << 0)
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#ifndef GUARD_CONSTANTS_EXPANSION_H
|
#ifndef GUARD_CONSTANTS_EXPANSION_H
|
||||||
#define GUARD_CONSTANTS_EXPANSION_H
|
#define GUARD_CONSTANTS_EXPANSION_H
|
||||||
|
|
||||||
// Last version: 1.13.2
|
// Last version: 1.13.3
|
||||||
#define EXPANSION_VERSION_MAJOR 1
|
#define EXPANSION_VERSION_MAJOR 1
|
||||||
#define EXPANSION_VERSION_MINOR 13
|
#define EXPANSION_VERSION_MINOR 13
|
||||||
#define EXPANSION_VERSION_PATCH 3
|
#define EXPANSION_VERSION_PATCH 4
|
||||||
|
|
||||||
// FALSE if this this version of Expansion is not a tagged commit, i.e.
|
// FALSE if this this version of Expansion is not a tagged commit, i.e.
|
||||||
// it contains unreleased changes.
|
// it contains unreleased changes.
|
||||||
|
|||||||
@ -45,6 +45,7 @@ enum GenConfigTag
|
|||||||
GEN_CONFIG_OBLIVIOUS_TAUNT,
|
GEN_CONFIG_OBLIVIOUS_TAUNT,
|
||||||
GEN_CONFIG_TOXIC_NEVER_MISS,
|
GEN_CONFIG_TOXIC_NEVER_MISS,
|
||||||
GEN_CONFIG_PARALYZE_ELECTRIC,
|
GEN_CONFIG_PARALYZE_ELECTRIC,
|
||||||
|
GEN_CONFIG_BADGE_BOOST,
|
||||||
GEN_CONFIG_COUNT
|
GEN_CONFIG_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,14 @@
|
|||||||
|
|
||||||
#include "map_groups.h"
|
#include "map_groups.h"
|
||||||
|
|
||||||
// Warps using this map will instead use the warp data stored in gSaveBlock1Ptr->dynamicWarp.
|
enum
|
||||||
// Used for warps that need to change destinations, e.g. when stepping off an elevator.
|
{
|
||||||
#define MAP_DYNAMIC (0x7F | (0x7F << 8))
|
// Warps using this map will instead use the warp data stored in gSaveBlock1Ptr->dynamicWarp.
|
||||||
|
// Used for warps that need to change destinations, e.g. when stepping off an elevator.
|
||||||
|
MAP_DYNAMIC = (0x7F | (0x7F << 8)),
|
||||||
|
|
||||||
#define MAP_UNDEFINED (0xFF | (0xFF << 8))
|
MAP_UNDEFINED = (0xFF | (0xFF << 8)),
|
||||||
|
};
|
||||||
|
|
||||||
#define MAP_GROUP(map) (map >> 8)
|
#define MAP_GROUP(map) (map >> 8)
|
||||||
#define MAP_NUM(map) (map & 0xFF)
|
#define MAP_NUM(map) (map & 0xFF)
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
#ifndef GUARD_DODRIO_BERRY_PICKING_H
|
#ifndef GUARD_DODRIO_BERRY_PICKING_H
|
||||||
#define GUARD_DODRIO_BERRY_PICKING_H
|
#define GUARD_DODRIO_BERRY_PICKING_H
|
||||||
|
|
||||||
void StartDodrioBerryPicking(u16 partyId, void (*exitCallback)(void));
|
#include "main.h"
|
||||||
|
|
||||||
|
void StartDodrioBerryPicking(u16 partyId, MainCallback exitCallback);
|
||||||
void IsDodrioInParty(void);
|
void IsDodrioInParty(void);
|
||||||
void ShowDodrioBerryPickingRecords(void);
|
void ShowDodrioBerryPickingRecords(void);
|
||||||
|
|
||||||
|
|||||||
67
include/gametypes.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef GUARD_GAMETYPES_H
|
||||||
|
#define GUARD_GAMETYPES_H
|
||||||
|
|
||||||
|
#include "gba/types.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// This header includes typedefs for fields that commonly appear throughout
|
||||||
|
// the codebase, and which ROM hacks might benefit from being able to widen.
|
||||||
|
//
|
||||||
|
// These typedefs include the underlying type in their name for two reasons:
|
||||||
|
//
|
||||||
|
// - Game Freak wasn't fully consistent about field widths throughout
|
||||||
|
// their codebase. For example, when Region Map Sections are persistently
|
||||||
|
// stored in savedata, they're stored as 8-bit values; but much of the
|
||||||
|
// codebase handles them as 16-bit values.
|
||||||
|
//
|
||||||
|
// - Although Pokemon Emerald doesn't come close to maxing out RAM, it *does*
|
||||||
|
// use nearly all of its EEPROM. That is: the vanilla game uses 96% of the
|
||||||
|
// flash memory available for storing players' save files, leaving 2172
|
||||||
|
// bytes to spare within each of the game's two save files (primary and
|
||||||
|
// backup). These spare bytes are not contiguous: SaveBlock1 can only grow
|
||||||
|
// by 84 bytes, and SaveBlock2 can only grow by 120 bytes, with the rest
|
||||||
|
// of the free space located after the player's PC-boxed Pokemon.
|
||||||
|
//
|
||||||
|
// With so little flash memory to spare, keeping track of how much space
|
||||||
|
// you're using is vital -- and so is arranging struct members to minimize
|
||||||
|
// compiler-inserted padding. It's easier to deal with this when you can
|
||||||
|
// see these types' widths at a glance.
|
||||||
|
//
|
||||||
|
// Accordingly, this file generally doesn't contain just single types, but
|
||||||
|
// rather families of types. For example, Region Map Sections are saved as
|
||||||
|
// u8s within the player's save file, but are sometimes handled as u16s or
|
||||||
|
// even s16s and ints; and so there are multiple typedefs for Map Sections
|
||||||
|
// corresponding to each of these underlying types, and each typedef has a
|
||||||
|
// name which indicates the underlying type.
|
||||||
|
//
|
||||||
|
// For a given family of typedefs, the smallest one should be considered
|
||||||
|
// the "real" or "canonical" type. Continuing with Map Sections as our
|
||||||
|
// example, the smallest type is an 8-bit integer, and so any values that
|
||||||
|
// can't fit in an 8-bit integer will be truncated and lost at some point
|
||||||
|
// within the codebase. Therefore mapsec_u8_t is the "canonical" type for
|
||||||
|
// Map Sections, and the larger typedefs just exist to describe situations
|
||||||
|
// where the game handles Map Sections inconsistently with that "canon."
|
||||||
|
//
|
||||||
|
|
||||||
|
// Map Sections are named areas that can appear in the region map. Each
|
||||||
|
// individual map can be assigned to a Map Section as appropriate. The
|
||||||
|
// possible values are in constants/region_map_sections.h.
|
||||||
|
//
|
||||||
|
// If you choose to widen Map Sections, be aware that Met Locations (below)
|
||||||
|
// are based on Map Sections and will also be widened.
|
||||||
|
typedef u8 mapsec_u8_t;
|
||||||
|
typedef u16 mapsec_u16_t;
|
||||||
|
typedef s16 mapsec_s16_t;
|
||||||
|
typedef s32 mapsec_s32_t;
|
||||||
|
|
||||||
|
// Met Locations for caught Pokemon use the same values as Map Sections,
|
||||||
|
// except that 0xFD, 0xFE, and 0xFF have special meanings.
|
||||||
|
//
|
||||||
|
// Because this value appears inside every Pokemon's data, widening it will
|
||||||
|
// consume a lot more space within flash memory. The space usage will be
|
||||||
|
// greater than you expect due to how Pokemon substructs are laid out; you
|
||||||
|
// would have to rearrange the substructs' contents in order to minimize
|
||||||
|
// how much more space a wider Met Location would consume.
|
||||||
|
typedef mapsec_u8_t metloc_u8_t;
|
||||||
|
|
||||||
|
#endif //GUARD_GAMETYPES_H
|
||||||
@ -48,6 +48,7 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] =
|
|||||||
[GEN_CONFIG_OBLIVIOUS_TAUNT] = B_OBLIVIOUS_TAUNT,
|
[GEN_CONFIG_OBLIVIOUS_TAUNT] = B_OBLIVIOUS_TAUNT,
|
||||||
[GEN_CONFIG_TOXIC_NEVER_MISS] = B_TOXIC_NEVER_MISS,
|
[GEN_CONFIG_TOXIC_NEVER_MISS] = B_TOXIC_NEVER_MISS,
|
||||||
[GEN_CONFIG_PARALYZE_ELECTRIC] = B_PARALYZE_ELECTRIC,
|
[GEN_CONFIG_PARALYZE_ELECTRIC] = B_PARALYZE_ELECTRIC,
|
||||||
|
[GEN_CONFIG_BADGE_BOOST] = B_BADGE_BOOST
|
||||||
};
|
};
|
||||||
|
|
||||||
#if TESTING
|
#if TESTING
|
||||||
|
|||||||
@ -169,7 +169,7 @@ struct MapHeader
|
|||||||
/* 0x0C */ const struct MapConnections *connections;
|
/* 0x0C */ const struct MapConnections *connections;
|
||||||
/* 0x10 */ u16 music;
|
/* 0x10 */ u16 music;
|
||||||
/* 0x12 */ u16 mapLayoutId;
|
/* 0x12 */ u16 mapLayoutId;
|
||||||
/* 0x14 */ u8 regionMapSectionId;
|
/* 0x14 */ mapsec_u8_t regionMapSectionId;
|
||||||
/* 0x15 */ u8 cave;
|
/* 0x15 */ u8 cave;
|
||||||
/* 0x16 */ u8 weather;
|
/* 0x16 */ u8 weather;
|
||||||
/* 0x17 */ u8 mapType;
|
/* 0x17 */ u8 mapType;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "config/general.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines.
|
#include "config/general.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines.
|
||||||
#include "gba/gba.h"
|
#include "gba/gba.h"
|
||||||
|
#include "gametypes.h"
|
||||||
#include "siirtc.h"
|
#include "siirtc.h"
|
||||||
#include "fpmath.h"
|
#include "fpmath.h"
|
||||||
#include "metaprogram.h"
|
#include "metaprogram.h"
|
||||||
|
|||||||
@ -226,7 +226,7 @@ typedef union // size = 0x24
|
|||||||
/*0x04*/ u8 filler_04[2];
|
/*0x04*/ u8 filler_04[2];
|
||||||
/*0x06*/ u16 itemIds[SMARTSHOPPER_NUM_ITEMS];
|
/*0x06*/ u16 itemIds[SMARTSHOPPER_NUM_ITEMS];
|
||||||
/*0x0C*/ u16 itemAmounts[SMARTSHOPPER_NUM_ITEMS];
|
/*0x0C*/ u16 itemAmounts[SMARTSHOPPER_NUM_ITEMS];
|
||||||
/*0x12*/ u8 shopLocation;
|
/*0x12*/ mapsec_u8_t shopLocation;
|
||||||
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
||||||
/*0x1B*/ //u8 padding;
|
/*0x1B*/ //u8 padding;
|
||||||
} smartshopperShow;
|
} smartshopperShow;
|
||||||
@ -241,7 +241,7 @@ typedef union // size = 0x24
|
|||||||
/*0x0E*/ u16 species2;
|
/*0x0E*/ u16 species2;
|
||||||
/*0x10*/ u8 nBallsUsed;
|
/*0x10*/ u8 nBallsUsed;
|
||||||
/*0x11*/ u8 outcome;
|
/*0x11*/ u8 outcome;
|
||||||
/*0x12*/ u8 location;
|
/*0x12*/ mapsec_u8_t location;
|
||||||
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
||||||
/*0x1B*/ //u8 padding;
|
/*0x1B*/ //u8 padding;
|
||||||
} pokemonTodayFailed;
|
} pokemonTodayFailed;
|
||||||
@ -267,7 +267,7 @@ typedef union // size = 0x24
|
|||||||
/*0x04*/ u16 caughtPoke;
|
/*0x04*/ u16 caughtPoke;
|
||||||
/*0x06*/ u16 steps;
|
/*0x06*/ u16 steps;
|
||||||
/*0x08*/ u16 species;
|
/*0x08*/ u16 species;
|
||||||
/*0x0A*/ u8 location;
|
/*0x0A*/ mapsec_u8_t location;
|
||||||
/*0x0B*/ u8 language;
|
/*0x0B*/ u8 language;
|
||||||
/*0x0C*/ u8 filler_0C[7];
|
/*0x0C*/ u8 filler_0C[7];
|
||||||
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
|
||||||
@ -282,7 +282,7 @@ typedef union // size = 0x24
|
|||||||
/*0x04*/ u8 badgeCount;
|
/*0x04*/ u8 badgeCount;
|
||||||
/*0x05*/ u8 nSilverSymbols;
|
/*0x05*/ u8 nSilverSymbols;
|
||||||
/*0x06*/ u8 nGoldSymbols;
|
/*0x06*/ u8 nGoldSymbols;
|
||||||
/*0x07*/ u8 location;
|
/*0x07*/ mapsec_u8_t location;
|
||||||
/*0x08*/ u16 battlePoints;
|
/*0x08*/ u16 battlePoints;
|
||||||
/*0x0A*/ u16 mapLayoutId;
|
/*0x0A*/ u16 mapLayoutId;
|
||||||
/*0x0C*/ u8 language;
|
/*0x0C*/ u8 language;
|
||||||
@ -309,7 +309,7 @@ typedef union // size = 0x24
|
|||||||
/*0x00*/ u8 kind;
|
/*0x00*/ u8 kind;
|
||||||
/*0x01*/ bool8 active;
|
/*0x01*/ bool8 active;
|
||||||
/*0x02*/ u16 item;
|
/*0x02*/ u16 item;
|
||||||
/*0x04*/ u8 location;
|
/*0x04*/ mapsec_u8_t location;
|
||||||
/*0x05*/ u8 language;
|
/*0x05*/ u8 language;
|
||||||
/*0x06*/ u16 mapLayoutId;
|
/*0x06*/ u16 mapLayoutId;
|
||||||
/*0x08*/ u8 filler_08[11];
|
/*0x08*/ u8 filler_08[11];
|
||||||
@ -336,7 +336,7 @@ typedef union // size = 0x24
|
|||||||
/*0x00*/ u8 kind;
|
/*0x00*/ u8 kind;
|
||||||
/*0x01*/ bool8 active;
|
/*0x01*/ bool8 active;
|
||||||
/*0x02*/ u16 lastOpponentSpecies;
|
/*0x02*/ u16 lastOpponentSpecies;
|
||||||
/*0x04*/ u8 location;
|
/*0x04*/ mapsec_u8_t location;
|
||||||
/*0x05*/ u8 outcome;
|
/*0x05*/ u8 outcome;
|
||||||
/*0x06*/ u16 caughtMonBall;
|
/*0x06*/ u16 caughtMonBall;
|
||||||
/*0x08*/ u16 balls;
|
/*0x08*/ u16 balls;
|
||||||
@ -505,7 +505,7 @@ struct GabbyAndTyData
|
|||||||
/*2BA6*/ u16 mon2;
|
/*2BA6*/ u16 mon2;
|
||||||
/*2BA8*/ u16 lastMove;
|
/*2BA8*/ u16 lastMove;
|
||||||
/*2BAA*/ u16 quote[1];
|
/*2BAA*/ u16 quote[1];
|
||||||
/*2BAC*/ u8 mapnum;
|
/*2BAC*/ mapsec_u8_t mapnum;
|
||||||
/*2BAD*/ u8 battleNum;
|
/*2BAD*/ u8 battleNum;
|
||||||
/*2BAE*/ u8 battleTookMoreThanOneTurn:1;
|
/*2BAE*/ u8 battleTookMoreThanOneTurn:1;
|
||||||
u8 playerLostAMon:1;
|
u8 playerLostAMon:1;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define GUARD_ITEM_MENU_H
|
#define GUARD_ITEM_MENU_H
|
||||||
|
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
#include "main.h"
|
||||||
#include "menu_helpers.h"
|
#include "menu_helpers.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -57,7 +58,7 @@ enum {
|
|||||||
|
|
||||||
struct BagPosition
|
struct BagPosition
|
||||||
{
|
{
|
||||||
void (*exitCallback)(void);
|
MainCallback exitCallback;
|
||||||
u8 location;
|
u8 location;
|
||||||
u8 pocket;
|
u8 pocket;
|
||||||
u16 pocketSwitchArrowPos;
|
u16 pocketSwitchArrowPos;
|
||||||
@ -69,7 +70,7 @@ extern struct BagPosition gBagPosition;
|
|||||||
|
|
||||||
struct BagMenu
|
struct BagMenu
|
||||||
{
|
{
|
||||||
void (*newScreenCallback)(void);
|
MainCallback newScreenCallback;
|
||||||
u8 tilemapBuffer[BG_SCREEN_SIZE];
|
u8 tilemapBuffer[BG_SCREEN_SIZE];
|
||||||
u8 spriteIds[ITEMMENUSPRITE_COUNT];
|
u8 spriteIds[ITEMMENUSPRITE_COUNT];
|
||||||
u8 windowIds[ITEMWIN_COUNT];
|
u8 windowIds[ITEMWIN_COUNT];
|
||||||
@ -106,16 +107,16 @@ void CB2_BagMenuFromStartMenu(void);
|
|||||||
u8 GetItemListPosition(u8 pocketId);
|
u8 GetItemListPosition(u8 pocketId);
|
||||||
bool8 UseRegisteredKeyItemOnField(void);
|
bool8 UseRegisteredKeyItemOnField(void);
|
||||||
void CB2_GoToSellMenu(void);
|
void CB2_GoToSellMenu(void);
|
||||||
void GoToBagMenu(u8 location, u8 pocket, void ( *exitCallback)());
|
void GoToBagMenu(u8 location, u8 pocket, MainCallback exitCallback);
|
||||||
void DoWallyTutorialBagMenu(void);
|
void DoWallyTutorialBagMenu(void);
|
||||||
void ResetBagScrollPositions(void);
|
void ResetBagScrollPositions(void);
|
||||||
void ChooseBerryForMachine(void (*exitCallback)(void));
|
void ChooseBerryForMachine(MainCallback exitCallback);
|
||||||
void CB2_ChooseBerry(void);
|
void CB2_ChooseBerry(void);
|
||||||
void CB2_ChooseMulch(void);
|
void CB2_ChooseMulch(void);
|
||||||
void Task_FadeAndCloseBagMenu(u8 taskId);
|
void Task_FadeAndCloseBagMenu(u8 taskId);
|
||||||
void BagMenu_YesNo(u8 taskId, u8 windowType, const struct YesNoFuncTable *funcTable);
|
void BagMenu_YesNo(u8 taskId, u8 windowType, const struct YesNoFuncTable *funcTable);
|
||||||
void UpdatePocketItemList(enum Pocket pocketId);
|
void UpdatePocketItemList(enum Pocket pocketId);
|
||||||
void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void (*callback)(u8 taskId));
|
void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, TaskFunc callback);
|
||||||
void DisplayItemMessageOnField(u8 taskId, const u8 *string, TaskFunc callback);
|
void DisplayItemMessageOnField(u8 taskId, const u8 *string, TaskFunc callback);
|
||||||
void CloseItemMessage(u8 taskId);
|
void CloseItemMessage(u8 taskId);
|
||||||
void ItemMenu_RotomCatalog(u8 taskId);
|
void ItemMenu_RotomCatalog(u8 taskId);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#ifndef GUARD_LANDMARK_H
|
#ifndef GUARD_LANDMARK_H
|
||||||
#define GUARD_LANDMARK_H
|
#define GUARD_LANDMARK_H
|
||||||
|
|
||||||
const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count);
|
const u8 *GetLandmarkName(mapsec_u8_t mapSection, u8 id, u8 count);
|
||||||
|
|
||||||
#endif // GUARD_LANDMARK_H
|
#endif // GUARD_LANDMARK_H
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef GUARD_MAIL_H
|
#ifndef GUARD_MAIL_H
|
||||||
#define GUARD_MAIL_H
|
#define GUARD_MAIL_H
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#define IS_ITEM_MAIL(itemId) ((itemId == ITEM_ORANGE_MAIL \
|
#define IS_ITEM_MAIL(itemId) ((itemId == ITEM_ORANGE_MAIL \
|
||||||
|| itemId == ITEM_HARBOR_MAIL \
|
|| itemId == ITEM_HARBOR_MAIL \
|
||||||
|| itemId == ITEM_GLITTER_MAIL \
|
|| itemId == ITEM_GLITTER_MAIL \
|
||||||
@ -15,7 +17,7 @@
|
|||||||
|| itemId == ITEM_RETRO_MAIL))
|
|| itemId == ITEM_RETRO_MAIL))
|
||||||
|
|
||||||
// mail.h
|
// mail.h
|
||||||
void ReadMail(struct Mail *mail, void (*exitCallback)(void), bool8 hasText);
|
void ReadMail(struct Mail *mail, MainCallback exitCallback, bool8 hasText);
|
||||||
|
|
||||||
// mail_data.h
|
// mail_data.h
|
||||||
void ClearAllMail(void);
|
void ClearAllMail(void);
|
||||||
|
|||||||
@ -135,8 +135,8 @@ enum MapType GetLastUsedWarpMapType(void);
|
|||||||
bool8 IsMapTypeOutdoors(enum MapType mapType);
|
bool8 IsMapTypeOutdoors(enum MapType mapType);
|
||||||
bool8 Overworld_MapTypeAllowsTeleportAndFly(enum MapType mapType);
|
bool8 Overworld_MapTypeAllowsTeleportAndFly(enum MapType mapType);
|
||||||
bool8 IsMapTypeIndoors(enum MapType mapType);
|
bool8 IsMapTypeIndoors(enum MapType mapType);
|
||||||
u8 GetSavedWarpRegionMapSectionId(void);
|
mapsec_u8_t GetSavedWarpRegionMapSectionId(void);
|
||||||
u8 GetCurrentRegionMapSectionId(void);
|
mapsec_u8_t GetCurrentRegionMapSectionId(void);
|
||||||
enum MapBattleScene GetCurrentMapBattleScene(void);
|
enum MapBattleScene GetCurrentMapBattleScene(void);
|
||||||
void CleanupOverworldWindowsAndTilemaps(void);
|
void CleanupOverworldWindowsAndTilemaps(void);
|
||||||
bool32 IsOverworldLinkActive(void);
|
bool32 IsOverworldLinkActive(void);
|
||||||
|
|||||||
@ -654,10 +654,10 @@ extern const struct Fusion *const gFusionTablePointers[NUM_SPECIES];
|
|||||||
#if P_FUSION_FORMS
|
#if P_FUSION_FORMS
|
||||||
#if P_FAMILY_KYUREM
|
#if P_FAMILY_KYUREM
|
||||||
#if P_FAMILY_RESHIRAM
|
#if P_FAMILY_RESHIRAM
|
||||||
extern const u16 gKyurenWhiteSwapMoveTable[][2];
|
extern const u16 gKyuremWhiteSwapMoveTable[][2];
|
||||||
#endif //P_FAMILY_RESHIRAM
|
#endif //P_FAMILY_RESHIRAM
|
||||||
#if P_FAMILY_ZEKROM
|
#if P_FAMILY_ZEKROM
|
||||||
extern const u16 gKyurenBlackSwapMoveTable[][2];
|
extern const u16 gKyuremBlackSwapMoveTable[][2];
|
||||||
#endif //P_FAMILY_ZEKROM
|
#endif //P_FAMILY_ZEKROM
|
||||||
#endif //P_FAMILY_KYUREM
|
#endif //P_FAMILY_KYUREM
|
||||||
#endif //P_FUSION_FORMS
|
#endif //P_FUSION_FORMS
|
||||||
@ -789,6 +789,7 @@ u32 GetSpeciesBaseDefense(u16 species);
|
|||||||
u32 GetSpeciesBaseSpAttack(u16 species);
|
u32 GetSpeciesBaseSpAttack(u16 species);
|
||||||
u32 GetSpeciesBaseSpDefense(u16 species);
|
u32 GetSpeciesBaseSpDefense(u16 species);
|
||||||
u32 GetSpeciesBaseSpeed(u16 species);
|
u32 GetSpeciesBaseSpeed(u16 species);
|
||||||
|
u32 GetSpeciesBaseStat(u16 species, u32 statIndex);
|
||||||
const struct LevelUpMove *GetSpeciesLevelUpLearnset(u16 species);
|
const struct LevelUpMove *GetSpeciesLevelUpLearnset(u16 species);
|
||||||
const u16 *GetSpeciesTeachableLearnset(u16 species);
|
const u16 *GetSpeciesTeachableLearnset(u16 species);
|
||||||
const u16 *GetSpeciesEggMoves(u16 species);
|
const u16 *GetSpeciesEggMoves(u16 species);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ struct PokenavMonListItem
|
|||||||
struct PokenavMatchCallEntry
|
struct PokenavMatchCallEntry
|
||||||
{
|
{
|
||||||
bool8 isSpecialTrainer;
|
bool8 isSpecialTrainer;
|
||||||
u8 mapSec;
|
mapsec_u8_t mapSec;
|
||||||
u16 headerId;
|
u16 headerId;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -413,7 +413,7 @@ void FreeMatchCallSubstruct1(void);
|
|||||||
int IsMatchCallListInitFinished(void);
|
int IsMatchCallListInitFinished(void);
|
||||||
int GetNumberRegistered(void);
|
int GetNumberRegistered(void);
|
||||||
struct PokenavMatchCallEntry *GetMatchCallList(void);
|
struct PokenavMatchCallEntry *GetMatchCallList(void);
|
||||||
u16 GetMatchCallMapSec(int index);
|
mapsec_u16_t GetMatchCallMapSec(int index);
|
||||||
bool32 ShouldDrawRematchPokeballIcon(int index);
|
bool32 ShouldDrawRematchPokeballIcon(int index);
|
||||||
void ClearRematchPokeballIcon(u16 windowId, u32 tileOffset);
|
void ClearRematchPokeballIcon(u16 windowId, u32 tileOffset);
|
||||||
int GetMatchCallTrainerPic(int index);
|
int GetMatchCallTrainerPic(int index);
|
||||||
@ -422,7 +422,7 @@ const u8 *GetMatchCallMessageText(int index, bool8 *newRematchRequest);
|
|||||||
u16 GetMatchCallOptionCursorPos(void);
|
u16 GetMatchCallOptionCursorPos(void);
|
||||||
u16 GetMatchCallOptionId(int optionId);
|
u16 GetMatchCallOptionId(int optionId);
|
||||||
void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntry *matchCallEntry, u8 *str);
|
void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntry *matchCallEntry, u8 *str);
|
||||||
u8 GetMatchTableMapSectionId(int rematchIndex);
|
mapsec_u8_t GetMatchTableMapSectionId(int rematchIndex);
|
||||||
int GetIndexDeltaOfNextCheckPageDown(int index);
|
int GetIndexDeltaOfNextCheckPageDown(int index);
|
||||||
int GetIndexDeltaOfNextCheckPageUp(int index);
|
int GetIndexDeltaOfNextCheckPageUp(int index);
|
||||||
bool32 IsRematchEntryRegistered(int rematchIndex);
|
bool32 IsRematchEntryRegistered(int rematchIndex);
|
||||||
|
|||||||
@ -217,6 +217,7 @@ enum RandomTag
|
|||||||
RNG_WRAP,
|
RNG_WRAP,
|
||||||
RNG_BALLTHROW_CRITICAL,
|
RNG_BALLTHROW_CRITICAL,
|
||||||
RNG_BALLTHROW_SHAKE,
|
RNG_BALLTHROW_SHAKE,
|
||||||
|
RNG_PROTECT_FAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RandomWeighted(tag, ...) \
|
#define RandomWeighted(tag, ...) \
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef GUARD_RAYQUAZA_SCENE_H
|
#ifndef GUARD_RAYQUAZA_SCENE_H
|
||||||
#define GUARD_RAYQUAZA_SCENE_H
|
#define GUARD_RAYQUAZA_SCENE_H
|
||||||
|
|
||||||
void DoRayquazaScene(u8 animId, bool8 endEarly, void (*exitCallback)(void));
|
#include "main.h"
|
||||||
|
|
||||||
|
void DoRayquazaScene(u8 animId, bool8 endEarly, MainCallback exitCallback);
|
||||||
|
|
||||||
#endif // GUARD_RAYQUAZA_SCENE_H
|
#endif // GUARD_RAYQUAZA_SCENE_H
|
||||||
|
|||||||
@ -27,7 +27,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RegionMap {
|
struct RegionMap {
|
||||||
/*0x000*/ u16 mapSecId;
|
/*0x000*/ mapsec_u16_t mapSecId;
|
||||||
/*0x002*/ u8 mapSecType;
|
/*0x002*/ u8 mapSecType;
|
||||||
/*0x003*/ u8 posWithinMapSec;
|
/*0x003*/ u8 posWithinMapSec;
|
||||||
/*0x004*/ u8 mapSecName[20];
|
/*0x004*/ u8 mapSecName[20];
|
||||||
@ -100,14 +100,14 @@ void InitRegionMap(struct RegionMap *regionMap, bool8 zoomed);
|
|||||||
u8 DoRegionMapInputCallback(void);
|
u8 DoRegionMapInputCallback(void);
|
||||||
bool8 UpdateRegionMapZoom(void);
|
bool8 UpdateRegionMapZoom(void);
|
||||||
void FreeRegionMapIconResources(void);
|
void FreeRegionMapIconResources(void);
|
||||||
u16 GetRegionMapSecIdAt(u16 x, u16 y);
|
mapsec_u16_t GetRegionMapSecIdAt(u16 x, u16 y);
|
||||||
void CreateRegionMapPlayerIcon(u16 tileTag, u16 paletteTag);
|
void CreateRegionMapPlayerIcon(u16 tileTag, u16 paletteTag);
|
||||||
void CreateRegionMapCursor(u16 tileTag, u16 paletteTag);
|
void CreateRegionMapCursor(u16 tileTag, u16 paletteTag);
|
||||||
bool32 IsEventIslandMapSecId(u8 mapSecId);
|
bool32 IsEventIslandMapSecId(mapsec_u8_t mapSecId);
|
||||||
u8 *GetMapName(u8 *dest, u16 regionMapId, u16 padLength);
|
u8 *GetMapName(u8 *dest, mapsec_u16_t regionMapId, u16 padLength);
|
||||||
u8 *GetMapNameGeneric(u8 *dest, u16 mapSecId);
|
u8 *GetMapNameGeneric(u8 *dest, mapsec_u16_t mapSecId);
|
||||||
u8 *GetMapNameHandleAquaHideout(u8 *dest, u16 mapSecId);
|
u8 *GetMapNameHandleAquaHideout(u8 *dest, mapsec_u16_t mapSecId);
|
||||||
u16 CorrectSpecialMapSecId(u16 mapSecId);
|
mapsec_u16_t CorrectSpecialMapSecId(mapsec_u16_t mapSecId);
|
||||||
void ShowRegionMapForPokedexAreaScreen(struct RegionMap *regionMap);
|
void ShowRegionMapForPokedexAreaScreen(struct RegionMap *regionMap);
|
||||||
void PokedexAreaScreen_UpdateRegionMapVariablesAndVideoRegs(s16 x, s16 y);
|
void PokedexAreaScreen_UpdateRegionMapVariablesAndVideoRegs(s16 x, s16 y);
|
||||||
void CB2_OpenFlyMap(void);
|
void CB2_OpenFlyMap(void);
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef GUARD_SAVE_H
|
#ifndef GUARD_SAVE_H
|
||||||
#define GUARD_SAVE_H
|
#define GUARD_SAVE_H
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by 116 bytes of SaveBlock3 and then 12 bytes of footer.
|
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by 116 bytes of SaveBlock3 and then 12 bytes of footer.
|
||||||
#define SECTOR_DATA_SIZE 3968
|
#define SECTOR_DATA_SIZE 3968
|
||||||
#define SAVE_BLOCK_3_CHUNK_SIZE 116
|
#define SAVE_BLOCK_3_CHUNK_SIZE 116
|
||||||
@ -87,7 +89,7 @@ extern u32 gSaveCounter;
|
|||||||
extern struct SaveSector *gFastSaveSector;
|
extern struct SaveSector *gFastSaveSector;
|
||||||
extern u16 gIncrementalSectorId;
|
extern u16 gIncrementalSectorId;
|
||||||
extern u16 gSaveFileStatus;
|
extern u16 gSaveFileStatus;
|
||||||
extern void (*gGameContinueCallback)(void);
|
extern MainCallback gGameContinueCallback;
|
||||||
extern struct SaveSectorLocation gRamSaveSectorLocations[];
|
extern struct SaveSectorLocation gRamSaveSectorLocations[];
|
||||||
|
|
||||||
extern struct SaveSector gSaveDataBuffer;
|
extern struct SaveSector gSaveDataBuffer;
|
||||||
|
|||||||
@ -2425,5 +2425,7 @@ extern const u8 gText_Rename[]; // change nickname from summary screen
|
|||||||
|
|
||||||
// Switch Caught Mon into Party
|
// Switch Caught Mon into Party
|
||||||
extern const u8 gText_CannotSendMonToBoxHM[];
|
extern const u8 gText_CannotSendMonToBoxHM[];
|
||||||
|
extern const u8 gText_CannotSendMonToBoxActive[];
|
||||||
|
extern const u8 gText_CannotSendMonToBoxPartner[];
|
||||||
|
|
||||||
#endif // GUARD_STRINGS_H
|
#endif // GUARD_STRINGS_H
|
||||||
|
|||||||
@ -143,7 +143,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a != _b) \
|
if (_a != _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_EQ(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_EQ(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_NE(a, b) \
|
#define EXPECT_NE(a, b) \
|
||||||
@ -151,7 +151,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a == _b) \
|
if (_a == _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_NE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_NE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_LT(a, b) \
|
#define EXPECT_LT(a, b) \
|
||||||
@ -159,7 +159,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a >= _b) \
|
if (_a >= _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_LE(a, b) \
|
#define EXPECT_LE(a, b) \
|
||||||
@ -167,7 +167,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a > _b) \
|
if (_a > _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_LE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_GT(a, b) \
|
#define EXPECT_GT(a, b) \
|
||||||
@ -175,7 +175,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a <= _b) \
|
if (_a <= _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GT(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_GE(a, b) \
|
#define EXPECT_GE(a, b) \
|
||||||
@ -183,7 +183,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
|
|||||||
{ \
|
{ \
|
||||||
typeof(a) _a = (a), _b = (b); \
|
typeof(a) _a = (a), _b = (b); \
|
||||||
if (_a < _b) \
|
if (_a < _b) \
|
||||||
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, _a, _b); \
|
Test_ExitWithResult(TEST_RESULT_FAIL, __LINE__, ":L%s:%d: EXPECT_GE(%d, %d) failed", gTestRunnerState.test->filename, __LINE__, a, b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct Benchmark { s32 ticks; };
|
struct Benchmark { s32 ticks; };
|
||||||
|
|||||||
@ -9,6 +9,7 @@ void MapResetTrainerRematches(u16 mapGroup, u16 mapNum);
|
|||||||
void ClearRematchMovementByTrainerId(void);
|
void ClearRematchMovementByTrainerId(void);
|
||||||
u16 GetRematchTrainerIdVSSeeker(u16 trainerId);
|
u16 GetRematchTrainerIdVSSeeker(u16 trainerId);
|
||||||
bool32 IsVsSeekerEnabled(void);
|
bool32 IsVsSeekerEnabled(void);
|
||||||
|
void NativeVsSeekerRematchId(struct ScriptContext *ctx);
|
||||||
|
|
||||||
#define VSSEEKER_RECHARGE_STEPS 100
|
#define VSSEEKER_RECHARGE_STEPS 100
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
POKEMONGFXDIR := graphics/pokemon
|
POKEMONGFXDIR := graphics/pokemon
|
||||||
OBJEVENTGFXDIR := graphics/object_events/pics
|
OBJEVENTGFXDIR := graphics/object_events/pics
|
||||||
FLDEFFGFXDIR := graphics/field_effects/pics
|
FLDEFFGFXDIR := graphics/field_effects/pics
|
||||||
|
BATINTGFXDIR := graphics/battle_interface
|
||||||
MISCGFXDIR := graphics/misc
|
MISCGFXDIR := graphics/misc
|
||||||
|
|
||||||
$(OBJEVENTGFXDIR)/people/brendan/walking.4bpp: %.4bpp: %.png
|
$(OBJEVENTGFXDIR)/people/brendan/walking.4bpp: %.4bpp: %.png
|
||||||
@ -4934,3 +4935,18 @@ $(OBJEVENTGFXDIR)/misc/ball_%.4bpp: $(OBJEVENTGFXDIR)/misc/ball_%.png ; $(GFX) $
|
|||||||
|
|
||||||
graphics/door_anims/battle_tower_multi_corridor.4bpp: %.4bpp: %.png
|
graphics/door_anims/battle_tower_multi_corridor.4bpp: %.4bpp: %.png
|
||||||
$(GFX) $< $@ -mwidth 2 -mheight 4
|
$(GFX) $< $@ -mwidth 2 -mheight 4
|
||||||
|
|
||||||
|
$(BATINTGFXDIR)/healthbox_doubles_opponent.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 8 -mheight 4
|
||||||
|
|
||||||
|
$(BATINTGFXDIR)/healthbox_doubles_player.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 8 -mheight 4
|
||||||
|
|
||||||
|
$(BATINTGFXDIR)/healthbox_safari.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 8 -mheight 8
|
||||||
|
|
||||||
|
$(BATINTGFXDIR)/healthbox_singles_opponent.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 8 -mheight 4
|
||||||
|
|
||||||
|
$(BATINTGFXDIR)/healthbox_singles_player.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 8 -mheight 8
|
||||||
|
|||||||
@ -5069,7 +5069,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||||||
if (gBattleMons[battlerDef].speed > gBattleMons[battlerAtk].speed)
|
if (gBattleMons[battlerDef].speed > gBattleMons[battlerAtk].speed)
|
||||||
ADJUST_SCORE(DECENT_EFFECT);
|
ADJUST_SCORE(DECENT_EFFECT);
|
||||||
break;
|
break;
|
||||||
case EFFECT_GUARD_SPLIT:
|
case EFFECT_GUARD_SPLIT:
|
||||||
{
|
{
|
||||||
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
||||||
u32 defDefense = gBattleMons[battlerDef].defense;
|
u32 defDefense = gBattleMons[battlerDef].defense;
|
||||||
@ -5116,6 +5116,7 @@ case EFFECT_GUARD_SPLIT:
|
|||||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||||
|
|
||||||
ADJUST_SCORE(WORST_EFFECT);
|
ADJUST_SCORE(WORST_EFFECT);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case EFFECT_ELECTRIC_TERRAIN:
|
case EFFECT_ELECTRIC_TERRAIN:
|
||||||
if (ShouldSetFieldStatus(battlerAtk, STATUS_FIELD_ELECTRIC_TERRAIN))
|
if (ShouldSetFieldStatus(battlerAtk, STATUS_FIELD_ELECTRIC_TERRAIN))
|
||||||
@ -5589,6 +5590,9 @@ case EFFECT_GUARD_SPLIT:
|
|||||||
}
|
}
|
||||||
else // consider move effects that hinder the target
|
else // consider move effects that hinder the target
|
||||||
{
|
{
|
||||||
|
if (IsAdditionalEffectBlocked(battlerAtk, aiData->abilities[battlerAtk], battlerDef, aiData->abilities[battlerDef]))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (additionalEffect->moveEffect)
|
switch (additionalEffect->moveEffect)
|
||||||
{
|
{
|
||||||
case MOVE_EFFECT_FLINCH:
|
case MOVE_EFFECT_FLINCH:
|
||||||
|
|||||||
@ -1124,7 +1124,7 @@ bool32 ShouldSwitch(u32 battler)
|
|||||||
|
|
||||||
if (IsDoubleBattle())
|
if (IsDoubleBattle())
|
||||||
{
|
{
|
||||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
u32 partner = BATTLE_PARTNER(battler);
|
||||||
battlerIn1 = battler;
|
battlerIn1 = battler;
|
||||||
if (gAbsentBattlerFlags & (1u << partner))
|
if (gAbsentBattlerFlags & (1u << partner))
|
||||||
battlerIn2 = battler;
|
battlerIn2 = battler;
|
||||||
@ -1275,7 +1275,7 @@ void ModifySwitchAfterMoveScoring(u32 battler)
|
|||||||
|
|
||||||
if (IsDoubleBattle())
|
if (IsDoubleBattle())
|
||||||
{
|
{
|
||||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
u32 partner = BATTLE_PARTNER(battler);
|
||||||
battlerIn1 = battler;
|
battlerIn1 = battler;
|
||||||
if (gAbsentBattlerFlags & (1u << partner))
|
if (gAbsentBattlerFlags & (1u << partner))
|
||||||
battlerIn2 = battler;
|
battlerIn2 = battler;
|
||||||
@ -1323,7 +1323,7 @@ bool32 IsSwitchinValid(u32 battler)
|
|||||||
// Edge case: See if partner already chose to switch into the same mon
|
// Edge case: See if partner already chose to switch into the same mon
|
||||||
if (IsDoubleBattle())
|
if (IsDoubleBattle())
|
||||||
{
|
{
|
||||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
u32 partner = BATTLE_PARTNER(battler);
|
||||||
if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE) // Generic switch
|
if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE) // Generic switch
|
||||||
{
|
{
|
||||||
if ((gAiLogicData->shouldSwitch & (1u << partner)) && gAiLogicData->monToSwitchInId[partner] == gAiLogicData->mostSuitableMonId[battler])
|
if ((gAiLogicData->shouldSwitch & (1u << partner)) && gAiLogicData->monToSwitchInId[partner] == gAiLogicData->mostSuitableMonId[battler])
|
||||||
|
|||||||
@ -701,6 +701,17 @@ bool32 IsDamageMoveUnusable(struct DamageContext *ctx)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 IsAdditionalEffectBlocked(u32 battlerAtk, u32 abilityAtk, u32 battlerDef, u32 abilityDef)
|
||||||
|
{
|
||||||
|
if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (abilityDef == ABILITY_SHIELD_DUST && !IsMoldBreakerTypeAbility(battlerAtk, abilityAtk))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType)
|
static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType)
|
||||||
{
|
{
|
||||||
if (rollType == DMG_ROLL_LOWEST)
|
if (rollType == DMG_ROLL_LOWEST)
|
||||||
@ -897,7 +908,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
|
|||||||
gBattleStruct->magnitudeBasePower = 70;
|
gBattleStruct->magnitudeBasePower = 70;
|
||||||
gBattleStruct->presentBasePower = 80;
|
gBattleStruct->presentBasePower = 80;
|
||||||
|
|
||||||
struct DamageContext ctx;
|
struct DamageContext ctx = {0};
|
||||||
ctx.battlerAtk = battlerAtk;
|
ctx.battlerAtk = battlerAtk;
|
||||||
ctx.battlerDef = battlerDef;
|
ctx.battlerDef = battlerDef;
|
||||||
ctx.move = move;
|
ctx.move = move;
|
||||||
@ -1030,6 +1041,49 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
|||||||
{
|
{
|
||||||
switch (additionalEffect->moveEffect)
|
switch (additionalEffect->moveEffect)
|
||||||
{
|
{
|
||||||
|
case MOVE_EFFECT_ATK_MINUS_1:
|
||||||
|
case MOVE_EFFECT_ATK_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_DEF_MINUS_1:
|
||||||
|
case MOVE_EFFECT_DEF_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_SPD_MINUS_1:
|
||||||
|
case MOVE_EFFECT_SPD_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_DEF))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_SP_ATK_MINUS_1:
|
||||||
|
case MOVE_EFFECT_SP_ATK_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPATK))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||||
|
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPDEF))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_EVS_MINUS_1:
|
||||||
|
case MOVE_EFFECT_EVS_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_EVASION))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_ACC_MINUS_1:
|
||||||
|
case MOVE_EFFECT_ACC_MINUS_2:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ACC))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK) || BattlerStatCanRise(battlerAtk, abilityAtk, STAT_DEF)))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||||
|
if (abilityAtk == ABILITY_CONTRARY && (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_DEF) || BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPDEF)))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
case MOVE_EFFECT_ATK_PLUS_1:
|
case MOVE_EFFECT_ATK_PLUS_1:
|
||||||
case MOVE_EFFECT_ATK_PLUS_2:
|
case MOVE_EFFECT_ATK_PLUS_2:
|
||||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
||||||
@ -1073,6 +1127,9 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
|||||||
}
|
}
|
||||||
else // consider move effects that hinder the target
|
else // consider move effects that hinder the target
|
||||||
{
|
{
|
||||||
|
if (IsAdditionalEffectBlocked(battlerAtk, abilityAtk, battlerDef, abilityDef))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (additionalEffect->moveEffect)
|
switch (additionalEffect->moveEffect)
|
||||||
{
|
{
|
||||||
case MOVE_EFFECT_POISON:
|
case MOVE_EFFECT_POISON:
|
||||||
@ -1107,7 +1164,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
|||||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||||
case MOVE_EFFECT_ACC_MINUS_1:
|
case MOVE_EFFECT_ACC_MINUS_1:
|
||||||
case MOVE_EFFECT_EVS_MINUS_1:
|
case MOVE_EFFECT_EVS_MINUS_1:
|
||||||
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo > 1)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
case MOVE_EFFECT_ATK_MINUS_2:
|
case MOVE_EFFECT_ATK_MINUS_2:
|
||||||
@ -1117,7 +1174,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
|||||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||||
case MOVE_EFFECT_ACC_MINUS_2:
|
case MOVE_EFFECT_ACC_MINUS_2:
|
||||||
case MOVE_EFFECT_EVS_MINUS_2:
|
case MOVE_EFFECT_EVS_MINUS_2:
|
||||||
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
if (CanLowerStat(battlerAtk, battlerDef, gAiLogicData, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo > 1)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1174,7 +1231,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
|||||||
case MOVE_EFFECT_ATK_DEF_DOWN:
|
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||||
if ((additionalEffect->self && abilityAtk != ABILITY_CONTRARY)
|
if ((additionalEffect->self && abilityAtk != ABILITY_CONTRARY)
|
||||||
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move)))
|
|| (noOfHitsToKo > 1 && !additionalEffect->self && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
case MOVE_EFFECT_RECHARGE:
|
case MOVE_EFFECT_RECHARGE:
|
||||||
@ -1195,7 +1252,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
|||||||
case MOVE_EFFECT_ACC_PLUS_2:
|
case MOVE_EFFECT_ACC_PLUS_2:
|
||||||
case MOVE_EFFECT_ALL_STATS_UP:
|
case MOVE_EFFECT_ALL_STATS_UP:
|
||||||
if ((additionalEffect->self && abilityAtk == ABILITY_CONTRARY)
|
if ((additionalEffect->self && abilityAtk == ABILITY_CONTRARY)
|
||||||
|| (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move))))
|
|| (noOfHitsToKo > 1 && !additionalEffect->self && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(battlerAtk, abilityAtk, move))))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3378,7 +3435,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
|
|||||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !HasMoveWithEffect(battler, EFFECT_SLEEP_TALK))
|
if (gBattleMons[battler].status1 & STATUS1_SLEEP && !HasMoveWithEffect(battler, EFFECT_SLEEP_TALK))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (gBattleMons[battler].volatiles.recharge || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0))
|
if (gDisableStructs[battler].rechargeTimer > 0 || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@ -2484,11 +2484,10 @@ void AnimTask_HideSwapSprite(u8 taskId)
|
|||||||
case 0:
|
case 0:
|
||||||
gTasks[taskId].data[11] = gSprites[spriteId].x; // Save battler position
|
gTasks[taskId].data[11] = gSprites[spriteId].x; // Save battler position
|
||||||
gSprites[spriteId].x = -64; // hide it from screen to avoid the blip/glitch effect when swapping the sprite.
|
gSprites[spriteId].x = -64; // hide it from screen to avoid the blip/glitch effect when swapping the sprite.
|
||||||
gTasks[taskId].data[10] = gBattleAnimArgs[0];
|
|
||||||
gTasks[taskId].data[0]++;
|
gTasks[taskId].data[0]++;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10], gBattleAnimArgs[1]);
|
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, SPECIES_GFX_CHANGE_FORM_CHANGE);
|
||||||
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
|
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
|
||||||
|
|
||||||
if (IsContest())
|
if (IsContest())
|
||||||
@ -2536,14 +2535,6 @@ void AnimTask_HideSwapSprite(u8 taskId)
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
gSprites[spriteId].x = gTasks[taskId].data[11]; // restores battler position
|
gSprites[spriteId].x = gTasks[taskId].data[11]; // restores battler position
|
||||||
if (!IsContest())
|
|
||||||
{
|
|
||||||
if (!IsOnPlayerSide(gBattleAnimAttacker))
|
|
||||||
{
|
|
||||||
if (gTasks[taskId].data[10] == 0)
|
|
||||||
SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DestroyAnimVisualTask(taskId);
|
DestroyAnimVisualTask(taskId);
|
||||||
break;
|
break;
|
||||||
@ -2596,7 +2587,6 @@ void AnimTask_TransformMon(u8 taskId)
|
|||||||
SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 1);
|
SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 1);
|
||||||
|
|
||||||
gTasks[taskId].data[10] = gBattleAnimArgs[0];
|
gTasks[taskId].data[10] = gBattleAnimArgs[0];
|
||||||
gTasks[taskId].data[11] = gBattleAnimArgs[1];
|
|
||||||
gTasks[taskId].data[0]++;
|
gTasks[taskId].data[0]++;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -2611,7 +2601,7 @@ void AnimTask_TransformMon(u8 taskId)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10], gTasks[taskId].data[11]);
|
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]);
|
||||||
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
|
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
|
||||||
|
|
||||||
if (IsContest())
|
if (IsContest())
|
||||||
@ -2680,7 +2670,7 @@ void AnimTask_TransformMon(u8 taskId)
|
|||||||
{
|
{
|
||||||
if (!IsOnPlayerSide(gBattleAnimAttacker))
|
if (!IsOnPlayerSide(gBattleAnimAttacker))
|
||||||
{
|
{
|
||||||
if (gTasks[taskId].data[10] == 0)
|
if (gTasks[taskId].data[10] == SPECIES_GFX_CHANGE_TRANSFORM)
|
||||||
SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies);
|
SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -454,6 +454,13 @@ void HandleInputChooseTarget(u32 battler)
|
|||||||
PlaySE(SE_SELECT);
|
PlaySE(SE_SELECT);
|
||||||
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget;
|
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget;
|
||||||
gBattlerControllerFuncs[battler] = HandleInputChooseMove;
|
gBattlerControllerFuncs[battler] = HandleInputChooseMove;
|
||||||
|
if (gBattleStruct->gimmick.playerSelect == 1 && gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE)
|
||||||
|
{
|
||||||
|
gBattleStruct->gimmick.playerSelect = 0;
|
||||||
|
gBattleStruct->zmove.viewing = TRUE;
|
||||||
|
ReloadMoveNames(battler);
|
||||||
|
}
|
||||||
|
TryToAddMoveInfoWindow();
|
||||||
DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1);
|
DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1);
|
||||||
DoBounceEffect(battler, BOUNCE_MON, 7, 1);
|
DoBounceEffect(battler, BOUNCE_MON, 7, 1);
|
||||||
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
|
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
|
||||||
@ -1725,6 +1732,14 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
|
|||||||
u16 move = moveInfo->moves[gMoveSelectionCursor[battler]];
|
u16 move = moveInfo->moves[gMoveSelectionCursor[battler]];
|
||||||
u16 pwr = GetMovePower(move);
|
u16 pwr = GetMovePower(move);
|
||||||
u16 acc = GetMoveAccuracy(move);
|
u16 acc = GetMoveAccuracy(move);
|
||||||
|
enum DamageCategory cat = GetBattleMoveCategory(move);
|
||||||
|
|
||||||
|
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))
|
||||||
|
{
|
||||||
|
pwr = GetMaxMovePower(move);
|
||||||
|
move = GetMaxMove(battler, move);
|
||||||
|
acc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
u8 pwr_num[3], acc_num[3];
|
u8 pwr_num[3], acc_num[3];
|
||||||
u8 cat_desc[] = _("分类:");
|
u8 cat_desc[] = _("分类:");
|
||||||
@ -1760,7 +1775,7 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
|
|||||||
if (gCategoryIconSpriteId == 0xFF)
|
if (gCategoryIconSpriteId == 0xFF)
|
||||||
gCategoryIconSpriteId = CreateSprite(&gSpriteTemplate_CategoryIcons, 43, 64, 1);
|
gCategoryIconSpriteId = CreateSprite(&gSpriteTemplate_CategoryIcons, 43, 64, 1);
|
||||||
|
|
||||||
StartSpriteAnim(&gSprites[gCategoryIconSpriteId], GetBattleMoveCategory(move));
|
StartSpriteAnim(&gSprites[gCategoryIconSpriteId], cat);
|
||||||
|
|
||||||
CopyWindowToVram(B_WIN_MOVE_DESCRIPTION, COPYWIN_FULL);
|
CopyWindowToVram(B_WIN_MOVE_DESCRIPTION, COPYWIN_FULL);
|
||||||
}
|
}
|
||||||
@ -2084,6 +2099,8 @@ void PlayerHandleChooseMove(u32 battler)
|
|||||||
|
|
||||||
if (!IsGimmickTriggerSpriteActive())
|
if (!IsGimmickTriggerSpriteActive())
|
||||||
gBattleStruct->gimmick.triggerSpriteId = 0xFF;
|
gBattleStruct->gimmick.triggerSpriteId = 0xFF;
|
||||||
|
else if (!IsGimmickTriggerSpriteMatchingBattler(battler))
|
||||||
|
DestroyGimmickTriggerSprite();
|
||||||
if (!(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE && !gBattleStruct->zmove.viable))
|
if (!(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE && !gBattleStruct->zmove.viable))
|
||||||
CreateGimmickTriggerSprite(battler);
|
CreateGimmickTriggerSprite(battler);
|
||||||
|
|
||||||
|
|||||||
@ -361,7 +361,6 @@ static const struct ListMenuItem sVolatileStatusListItems[] =
|
|||||||
{COMPOUND_STRING("无理取闹"), VOLATILE_TORMENT},
|
{COMPOUND_STRING("无理取闹"), VOLATILE_TORMENT},
|
||||||
{COMPOUND_STRING("粉尘"), VOLATILE_POWDER},
|
{COMPOUND_STRING("粉尘"), VOLATILE_POWDER},
|
||||||
{COMPOUND_STRING("变圆"), VOLATILE_DEFENSE_CURL},
|
{COMPOUND_STRING("变圆"), VOLATILE_DEFENSE_CURL},
|
||||||
{COMPOUND_STRING("无法动弹"), VOLATILE_RECHARGE},
|
|
||||||
{COMPOUND_STRING("愤怒"), VOLATILE_RAGE},
|
{COMPOUND_STRING("愤怒"), VOLATILE_RAGE},
|
||||||
{COMPOUND_STRING("同命"), VOLATILE_DESTINY_BOND},
|
{COMPOUND_STRING("同命"), VOLATILE_DESTINY_BOND},
|
||||||
{COMPOUND_STRING("无法逃脱"), VOLATILE_ESCAPE_PREVENTION},
|
{COMPOUND_STRING("无法逃脱"), VOLATILE_ESCAPE_PREVENTION},
|
||||||
|
|||||||
@ -168,6 +168,17 @@ static bool32 HandleEndTurnVarious(u32 battler)
|
|||||||
gBattleStruct->hpBefore[i] = gBattleMons[i].hp;
|
gBattleStruct->hpBefore[i] = gBattleMons[i].hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gBattleStruct->incrementEchoedVoice)
|
||||||
|
{
|
||||||
|
if (gBattleStruct->echoedVoiceCounter < 4)
|
||||||
|
gBattleStruct->echoedVoiceCounter++;
|
||||||
|
gBattleStruct->incrementEchoedVoice = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gBattleStruct->echoedVoiceCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return effect;
|
return effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,13 +311,12 @@ static bool32 HandleEndTurnEmergencyExit(u32 battler)
|
|||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||||
&& CountUsablePartyMons(battler) > 0
|
|
||||||
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) // Not currently held by Sky Drop
|
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) // Not currently held by Sky Drop
|
||||||
{
|
{
|
||||||
gBattlerAbility = battler;
|
gBattlerAbility = battler;
|
||||||
gLastUsedAbility = ability;
|
gLastUsedAbility = ability;
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || IsOnPlayerSide(battler))
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||||
BattleScriptExecute(BattleScript_EmergencyExitEnd2);
|
BattleScriptExecute(BattleScript_EmergencyExitEnd2);
|
||||||
else
|
else
|
||||||
BattleScriptExecute(BattleScript_EmergencyExitWildEnd2);
|
BattleScriptExecute(BattleScript_EmergencyExitWildEnd2);
|
||||||
@ -797,9 +807,9 @@ static bool32 HandleEndTurnSaltCure(u32 battler)
|
|||||||
&& !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
|
&& !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
|
||||||
{
|
{
|
||||||
if (IS_BATTLER_ANY_TYPE(battler, TYPE_STEEL, TYPE_WATER))
|
if (IS_BATTLER_ANY_TYPE(battler, TYPE_STEEL, TYPE_WATER))
|
||||||
gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 4;
|
gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4;
|
||||||
else
|
else
|
||||||
gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 8;
|
gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
|
||||||
if (gBattleStruct->moveDamage[battler] == 0)
|
if (gBattleStruct->moveDamage[battler] == 0)
|
||||||
gBattleStruct->moveDamage[battler] = 1;
|
gBattleStruct->moveDamage[battler] = 1;
|
||||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SALT_CURE);
|
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SALT_CURE);
|
||||||
|
|||||||
@ -125,7 +125,7 @@ struct FactorySelectScreen
|
|||||||
struct SwapScreenAction
|
struct SwapScreenAction
|
||||||
{
|
{
|
||||||
u8 id;
|
u8 id;
|
||||||
void (*func)(u8 taskId);
|
TaskFunc func;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FactorySwapScreen
|
struct FactorySwapScreen
|
||||||
@ -253,7 +253,7 @@ static EWRAM_DATA u8 *sSwapMenuTilemapBuffer = NULL;
|
|||||||
static EWRAM_DATA u8 *sSwapMonPicBgTilemapBuffer = NULL;
|
static EWRAM_DATA u8 *sSwapMonPicBgTilemapBuffer = NULL;
|
||||||
|
|
||||||
static struct FactorySelectScreen *sFactorySelectScreen;
|
static struct FactorySelectScreen *sFactorySelectScreen;
|
||||||
static void (*sSwap_CurrentOptionFunc)(u8 taskId);
|
static TaskFunc sSwap_CurrentOptionFunc;
|
||||||
static struct FactorySwapScreen *sFactorySwapScreen;
|
static struct FactorySwapScreen *sFactorySwapScreen;
|
||||||
|
|
||||||
COMMON_DATA u8 (*gFactorySelect_CurrentOptionFunc)(void) = NULL;
|
COMMON_DATA u8 (*gFactorySelect_CurrentOptionFunc)(void) = NULL;
|
||||||
@ -886,7 +886,7 @@ static const struct SpriteTemplate sSpriteTemplate_Swap_MonPicBgAnim =
|
|||||||
.callback = SpriteCallbackDummy
|
.callback = SpriteCallbackDummy
|
||||||
};
|
};
|
||||||
|
|
||||||
void static (*const sSwap_MenuOptionFuncs[])(u8 taskId) =
|
static const TaskFunc sSwap_MenuOptionFuncs[] =
|
||||||
{
|
{
|
||||||
Swap_OptionSummary,
|
Swap_OptionSummary,
|
||||||
Swap_OptionSwap,
|
Swap_OptionSwap,
|
||||||
|
|||||||
@ -633,15 +633,8 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
|
|||||||
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
||||||
gBattleSpritesDataPtr->battlerData[battler].transformSpecies = species = GetGMaxTargetSpecies(species);
|
gBattleSpritesDataPtr->battlerData[battler].transformSpecies = species = GetGMaxTargetSpecies(species);
|
||||||
|
|
||||||
if (B_TRANSFORM_SHINY >= GEN_4)
|
personalityValue = gTransformedPersonalities[battler];
|
||||||
{
|
isShiny = gTransformedShininess[battler];
|
||||||
personalityValue = gTransformedPersonalities[battler];
|
|
||||||
isShiny = gTransformedShininess[battler];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
personalityValue = GetMonData(mon, MON_DATA_PERSONALITY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
position = GetBattlerPosition(battler);
|
position = GetBattlerPosition(battler);
|
||||||
@ -913,7 +906,7 @@ void CopyBattleSpriteInvisibility(u8 battler)
|
|||||||
gBattleSpritesDataPtr->battlerData[battler].invisible = gSprites[gBattlerSpriteIds[battler]].invisible;
|
gBattleSpritesDataPtr->battlerData[battler].invisible = gSprites[gBattlerSpriteIds[battler]].invisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool8 trackEnemyPersonality)
|
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, u8 changeType)
|
||||||
{
|
{
|
||||||
u32 personalityValue, position, paletteOffset, targetSpecies;
|
u32 personalityValue, position, paletteOffset, targetSpecies;
|
||||||
bool32 isShiny;
|
bool32 isShiny;
|
||||||
@ -947,24 +940,23 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
|||||||
targetSpecies = GetIllusionMonSpecies(battlerDef);
|
targetSpecies = GetIllusionMonSpecies(battlerDef);
|
||||||
else
|
else
|
||||||
targetSpecies = GetMonData(monDef, MON_DATA_SPECIES);
|
targetSpecies = GetMonData(monDef, MON_DATA_SPECIES);
|
||||||
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
|
gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies = targetSpecies;
|
||||||
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
targetSpecies = gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies;
|
targetSpecies = gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies;
|
||||||
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality && !megaEvo)
|
|
||||||
{
|
|
||||||
personalityValue = GetMonData(monDef, MON_DATA_PERSONALITY);
|
|
||||||
isShiny = GetMonData(monDef, MON_DATA_IS_SHINY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
|
|
||||||
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changeType == SPECIES_GFX_CHANGE_TRANSFORM)
|
||||||
|
{
|
||||||
|
personalityValue = gDisableStructs[battlerAtk].transformedMonPersonality;
|
||||||
|
isShiny = gDisableStructs[battlerAtk].transformedMonShininess;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
|
||||||
|
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
|
||||||
|
}
|
||||||
HandleLoadSpecialPokePic(!IsOnPlayerSide(battlerAtk),
|
HandleLoadSpecialPokePic(!IsOnPlayerSide(battlerAtk),
|
||||||
gMonSpritesGfxPtr->spritesGfx[position],
|
gMonSpritesGfxPtr->spritesGfx[position],
|
||||||
targetSpecies,
|
targetSpecies,
|
||||||
@ -977,14 +969,10 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
|||||||
paletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue);
|
paletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue);
|
||||||
LoadPalette(paletteData, paletteOffset, PLTT_SIZE_4BPP);
|
LoadPalette(paletteData, paletteOffset, PLTT_SIZE_4BPP);
|
||||||
|
|
||||||
if (!megaEvo)
|
if (changeType == SPECIES_GFX_CHANGE_TRANSFORM)
|
||||||
{
|
{
|
||||||
BlendPalette(paletteOffset, 16, 6, RGB_WHITE);
|
BlendPalette(paletteOffset, 16, 6, RGB_WHITE);
|
||||||
CpuCopy32(&gPlttBufferFaded[paletteOffset], &gPlttBufferUnfaded[paletteOffset], PLTT_SIZEOF(16));
|
CpuCopy32(&gPlttBufferFaded[paletteOffset], &gPlttBufferUnfaded[paletteOffset], PLTT_SIZEOF(16));
|
||||||
if (!IsContest())
|
|
||||||
{
|
|
||||||
gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies = targetSpecies;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamax tint
|
// dynamax tint
|
||||||
@ -998,6 +986,13 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
|||||||
CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, PLTT_SIZEOF(16));
|
CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, PLTT_SIZEOF(16));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Terastallization's tint
|
||||||
|
if (changeType != SPECIES_GFX_CHANGE_ILLUSION_OFF && GetActiveGimmick(battlerAtk) == GIMMICK_TERA)
|
||||||
|
{
|
||||||
|
BlendPalette(paletteOffset, 16, 8, GetTeraTypeRGB(GetBattlerTeraType(battlerAtk)));
|
||||||
|
CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, PLTT_SIZEOF(16));
|
||||||
|
}
|
||||||
|
|
||||||
gSprites[gBattlerSpriteIds[battlerAtk]].y = GetBattlerSpriteDefault_Y(battlerAtk);
|
gSprites[gBattlerSpriteIds[battlerAtk]].y = GetBattlerSpriteDefault_Y(battlerAtk);
|
||||||
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], 0);
|
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,6 +178,13 @@ bool32 IsGimmickTriggerSpriteActive(void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler)
|
||||||
|
{
|
||||||
|
if (battler == gSprites[gBattleStruct->gimmick.triggerSpriteId].tBattler)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void HideGimmickTriggerSprite(void)
|
void HideGimmickTriggerSprite(void)
|
||||||
{
|
{
|
||||||
if (gBattleStruct->gimmick.triggerSpriteId != 0xFF)
|
if (gBattleStruct->gimmick.triggerSpriteId != 0xFF)
|
||||||
|
|||||||
@ -2258,10 +2258,11 @@ static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32
|
|||||||
for (i = 0; i < scale; i++)
|
for (i = 0; i < scale; i++)
|
||||||
pixelsArray[i] = 0;
|
pixelsArray[i] = 0;
|
||||||
|
|
||||||
|
// Safe Div, because 2vs1 battles can have maxValue 0.
|
||||||
if (maxValue < totalPixels)
|
if (maxValue < totalPixels)
|
||||||
pixels = (*currValue * totalPixels / maxValue) >> 8;
|
pixels = SAFE_DIV(*currValue * totalPixels, maxValue) >> 8;
|
||||||
else
|
else
|
||||||
pixels = *currValue * totalPixels / maxValue;
|
pixels = SAFE_DIV(*currValue * totalPixels, maxValue);
|
||||||
|
|
||||||
filledPixels = pixels;
|
filledPixels = pixels;
|
||||||
|
|
||||||
|
|||||||
@ -244,7 +244,7 @@ EWRAM_DATA u8 gPartyCriticalHits[PARTY_SIZE] = {0};
|
|||||||
EWRAM_DATA static u8 sTriedEvolving = 0;
|
EWRAM_DATA static u8 sTriedEvolving = 0;
|
||||||
EWRAM_DATA u8 gCategoryIconSpriteId = 0;
|
EWRAM_DATA u8 gCategoryIconSpriteId = 0;
|
||||||
|
|
||||||
COMMON_DATA void (*gPreBattleCallback1)(void) = NULL;
|
COMMON_DATA MainCallback gPreBattleCallback1 = NULL;
|
||||||
COMMON_DATA void (*gBattleMainFunc)(void) = NULL;
|
COMMON_DATA void (*gBattleMainFunc)(void) = NULL;
|
||||||
COMMON_DATA struct BattleResults gBattleResults = {0};
|
COMMON_DATA struct BattleResults gBattleResults = {0};
|
||||||
COMMON_DATA u8 gLeveledUpInBattle = 0;
|
COMMON_DATA u8 gLeveledUpInBattle = 0;
|
||||||
@ -3002,7 +3002,10 @@ static void ClearSetBScriptingStruct(void)
|
|||||||
memset(&gBattleScripting, 0, sizeof(gBattleScripting));
|
memset(&gBattleScripting, 0, sizeof(gBattleScripting));
|
||||||
|
|
||||||
gBattleScripting.windowsType = temp;
|
gBattleScripting.windowsType = temp;
|
||||||
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
if (TESTING)
|
||||||
|
gBattleScripting.battleStyle = OPTIONS_BATTLE_STYLE_SET;
|
||||||
|
else
|
||||||
|
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
||||||
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
|
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
|
||||||
gBattleScripting.specialTrainerBattleType = specialBattleType;
|
gBattleScripting.specialTrainerBattleType = specialBattleType;
|
||||||
}
|
}
|
||||||
@ -3227,7 +3230,7 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy)
|
|||||||
gLastHitBy[battler] = 0xFF;
|
gLastHitBy[battler] = 0xFF;
|
||||||
|
|
||||||
gBattleStruct->lastTakenMove[battler] = 0;
|
gBattleStruct->lastTakenMove[battler] = 0;
|
||||||
gBattleStruct->sameMoveTurns[battler] = 0;
|
gBattleStruct->metronomeItemCounter[battler] = 0;
|
||||||
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
||||||
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
||||||
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
|
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
|
||||||
@ -3235,6 +3238,9 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy)
|
|||||||
gBattleStruct->battlerState[battler].stompingTantrumTimer = 0;
|
gBattleStruct->battlerState[battler].stompingTantrumTimer = 0;
|
||||||
gBattleStruct->palaceFlags &= ~(1u << battler);
|
gBattleStruct->palaceFlags &= ~(1u << battler);
|
||||||
gBattleStruct->battlerState[battler].canPickupItem = FALSE;
|
gBattleStruct->battlerState[battler].canPickupItem = FALSE;
|
||||||
|
gBattleStruct->hazardsCounter = 0;
|
||||||
|
gDisableStructs[battler].hazardsDone = FALSE;
|
||||||
|
gSpecialStatuses[battler].switchInItemDone = FALSE;
|
||||||
|
|
||||||
ClearPursuitValuesIfSet(battler);
|
ClearPursuitValuesIfSet(battler);
|
||||||
|
|
||||||
@ -3348,7 +3354,7 @@ const u8* FaintClearSetData(u32 battler)
|
|||||||
gLastHitBy[battler] = 0xFF;
|
gLastHitBy[battler] = 0xFF;
|
||||||
|
|
||||||
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
||||||
gBattleStruct->sameMoveTurns[battler] = 0;
|
gBattleStruct->metronomeItemCounter[battler] = 0;
|
||||||
gBattleStruct->lastTakenMove[battler] = MOVE_NONE;
|
gBattleStruct->lastTakenMove[battler] = MOVE_NONE;
|
||||||
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
||||||
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
||||||
@ -4207,7 +4213,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gBattleMons[battler].volatiles.multipleTurns
|
if (gBattleMons[battler].volatiles.multipleTurns
|
||||||
|| gBattleMons[battler].volatiles.recharge)
|
|| gDisableStructs[battler].rechargeTimer > 0)
|
||||||
{
|
{
|
||||||
gChosenActionByBattler[battler] = B_ACTION_USE_MOVE;
|
gChosenActionByBattler[battler] = B_ACTION_USE_MOVE;
|
||||||
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
||||||
@ -4362,7 +4368,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
gBattleCommunication[GetPartnerBattler(battler)] = STATE_BEFORE_ACTION_CHOSEN;
|
gBattleCommunication[GetPartnerBattler(battler)] = STATE_BEFORE_ACTION_CHOSEN;
|
||||||
RecordedBattle_ClearBattlerAction(battler, 1);
|
RecordedBattle_ClearBattlerAction(battler, 1);
|
||||||
if (gBattleMons[GetPartnerBattler(battler)].volatiles.multipleTurns
|
if (gBattleMons[GetPartnerBattler(battler)].volatiles.multipleTurns
|
||||||
|| gBattleMons[GetPartnerBattler(battler)].volatiles.recharge)
|
|| gDisableStructs[GetPartnerBattler(battler)].rechargeTimer > 0)
|
||||||
{
|
{
|
||||||
BtlController_EmitEndBounceEffect(battler, B_COMM_TO_CONTROLLER);
|
BtlController_EmitEndBounceEffect(battler, B_COMM_TO_CONTROLLER);
|
||||||
MarkBattlerForControllerExec(battler);
|
MarkBattlerForControllerExec(battler);
|
||||||
@ -4770,7 +4776,7 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
|||||||
&& ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPEED, battler)
|
&& ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPEED, battler)
|
||||||
&& IsOnPlayerSide(battler))
|
&& IsOnPlayerSide(battler))
|
||||||
{
|
{
|
||||||
speed = (speed * 110) / 100;
|
speed = uq4_12_multiply_by_int_half_down(GetBadgeBoostModifier(), speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// item effects
|
// item effects
|
||||||
@ -5126,11 +5132,8 @@ static void TurnValuesCleanUp(bool8 var0)
|
|||||||
gDisableStructs[i].isFirstTurn--;
|
gDisableStructs[i].isFirstTurn--;
|
||||||
|
|
||||||
if (gDisableStructs[i].rechargeTimer)
|
if (gDisableStructs[i].rechargeTimer)
|
||||||
{
|
|
||||||
gDisableStructs[i].rechargeTimer--;
|
gDisableStructs[i].rechargeTimer--;
|
||||||
if (gDisableStructs[i].rechargeTimer == 0)
|
|
||||||
gBattleMons[i].volatiles.recharge = FALSE;
|
|
||||||
}
|
|
||||||
gBattleStruct->battlerState[i].canPickupItem = FALSE;
|
gBattleStruct->battlerState[i].canPickupItem = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5624,17 +5627,7 @@ static void HandleEndTurn_FinishBattle(void)
|
|||||||
|
|
||||||
for (i = 0; i < PARTY_SIZE; i++)
|
for (i = 0; i < PARTY_SIZE; i++)
|
||||||
{
|
{
|
||||||
bool8 changedForm = FALSE;
|
bool8 changedForm = TryRevertPartyMonFormChange(i);
|
||||||
|
|
||||||
// Appeared in battle and didn't faint
|
|
||||||
if ((gBattleStruct->appearedInBattle & (1u << i)) && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0)
|
|
||||||
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE_ENVIRONMENT);
|
|
||||||
|
|
||||||
if (!changedForm)
|
|
||||||
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE);
|
|
||||||
|
|
||||||
// Clear original species field
|
|
||||||
gBattleStruct->partyState[B_SIDE_PLAYER][i].changedSpecies = SPECIES_NONE;
|
|
||||||
gBattleStruct->partyState[B_SIDE_OPPONENT][i].changedSpecies = SPECIES_NONE;
|
gBattleStruct->partyState[B_SIDE_OPPONENT][i].changedSpecies = SPECIES_NONE;
|
||||||
|
|
||||||
// Recalculate the stats of every party member before the end
|
// Recalculate the stats of every party member before the end
|
||||||
@ -5672,6 +5665,7 @@ static void FreeResetData_ReturnToOvOrDoEvolutions(void)
|
|||||||
else
|
else
|
||||||
gSaveBlock3Ptr->dexNavChain = 0;
|
gSaveBlock3Ptr->dexNavChain = 0;
|
||||||
|
|
||||||
|
ClearCurrentTrainerWantRematchVsSeeker();
|
||||||
gDexNavSpecies = SPECIES_NONE;
|
gDexNavSpecies = SPECIES_NONE;
|
||||||
ResetSpriteData();
|
ResetSpriteData();
|
||||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
||||||
|
|||||||
@ -303,7 +303,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
|||||||
[STRINGID_PKMNTRYINGTOTAKEFOE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n想和对手同归于尽!"),
|
[STRINGID_PKMNTRYINGTOTAKEFOE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n想和对手同归于尽!"),
|
||||||
[STRINGID_PKMNTOOKFOE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n和对手同归于尽了!"),
|
[STRINGID_PKMNTOOKFOE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n和对手同归于尽了!"),
|
||||||
[STRINGID_PKMNREDUCEDPP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}的PP减少了!"),
|
[STRINGID_PKMNREDUCEDPP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}的PP减少了!"),
|
||||||
[STRINGID_PKMNSTOLEITEM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n从{B_DEF_NAME_WITH_PREFIX2}那里\l夺取了{B_LAST_ITEM}!"),
|
[STRINGID_PKMNSTOLEITEM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n从{B_EFF_NAME_WITH_PREFIX2}那里\l夺取了{B_LAST_ITEM}!"),
|
||||||
[STRINGID_TARGETCANTESCAPENOW] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n无法逃走了!"),
|
[STRINGID_TARGETCANTESCAPENOW] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n无法逃走了!"),
|
||||||
[STRINGID_PKMNFELLINTONIGHTMARE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n开始做恶梦了!"),
|
[STRINGID_PKMNFELLINTONIGHTMARE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}\n开始做恶梦了!"),
|
||||||
[STRINGID_PKMNLOCKEDINNIGHTMARE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n正被恶梦缠身!"),
|
[STRINGID_PKMNLOCKEDINNIGHTMARE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n正被恶梦缠身!"),
|
||||||
@ -705,7 +705,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
|||||||
[STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("继承了{B_SCR_NAME_WITH_PREFIX}的\n{B_SCR_ABILITY}!"),
|
[STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("继承了{B_SCR_NAME_WITH_PREFIX}的\n{B_SCR_ABILITY}!"),
|
||||||
[STRINGID_PKNMABSORBINGPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n正在积蓄力量!"),
|
[STRINGID_PKNMABSORBINGPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n正在积蓄力量!"),
|
||||||
[STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("下回合无法逃走!"),
|
[STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("下回合无法逃走!"),
|
||||||
[STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_LAST_ITEM}让{B_SCR_NAME_WITH_PREFIX}\n着迷了!"),
|
[STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_LAST_ITEM}让{B_DEF_NAME_WITH_PREFIX}\n着迷了!"),
|
||||||
[STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n被冷光包围了!"),
|
[STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}\n被冷光包围了!"),
|
||||||
[STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX2}的\n能力因{B_LAST_ITEM}不会降低!"),
|
[STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX2}的\n能力因{B_LAST_ITEM}不会降低!"),
|
||||||
[STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}衷心的祈愿\n传递到了{B_ATK_NAME_WITH_PREFIX2}那里!"),
|
[STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}衷心的祈愿\n传递到了{B_ATK_NAME_WITH_PREFIX2}那里!"),
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
#include "item_use.h"
|
#include "item_use.h"
|
||||||
#include "list_menu.h"
|
#include "list_menu.h"
|
||||||
#include "mail.h"
|
#include "mail.h"
|
||||||
#include "main.h"
|
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "menu_helpers.h"
|
#include "menu_helpers.h"
|
||||||
@ -414,7 +413,7 @@ void CB2_ReturnToPyramidBagMenu(void)
|
|||||||
GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_PREV, gPyramidBagMenuState.exitCallback);
|
GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_PREV, gPyramidBagMenuState.exitCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GoToBattlePyramidBagMenu(u8 location, void (*exitCallback)(void))
|
void GoToBattlePyramidBagMenu(u8 location, MainCallback exitCallback)
|
||||||
{
|
{
|
||||||
gPyramidBagMenu = AllocZeroed(sizeof(*gPyramidBagMenu));
|
gPyramidBagMenu = AllocZeroed(sizeof(*gPyramidBagMenu));
|
||||||
|
|
||||||
@ -1526,7 +1525,7 @@ static void CreatePyramidBagYesNo(u8 taskId, const struct YesNoFuncTable *yesNoT
|
|||||||
CreateYesNoMenuWithCallbacks(taskId, &sWindowTemplates_MenuActions[MENU_WIN_YESNO], 1, 0, 2, 1, 0xE, yesNoTable);
|
CreateYesNoMenuWithCallbacks(taskId, &sWindowTemplates_MenuActions[MENU_WIN_YESNO], 1, 0, 2, 1, 0xE, yesNoTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayItemMessageInBattlePyramid(u8 taskId, const u8 *str, void (*callback)(u8 taskId))
|
void DisplayItemMessageInBattlePyramid(u8 taskId, const u8 *str, TaskFunc callback)
|
||||||
{
|
{
|
||||||
FillWindowPixelBuffer(WIN_MSG, PIXEL_FILL(1));
|
FillWindowPixelBuffer(WIN_MSG, PIXEL_FILL(1));
|
||||||
DisplayMessageAndContinueTask(taskId, WIN_MSG, 0xA, 0xD, FONT_NORMAL, GetPlayerTextSpeedDelay(), str, callback);
|
DisplayMessageAndContinueTask(taskId, WIN_MSG, 0xA, 0xD, FONT_NORMAL, GetPlayerTextSpeedDelay(), str, callback);
|
||||||
|
|||||||
@ -370,7 +370,7 @@ static void Cmd_jumpifvolatile(void);
|
|||||||
static void Cmd_jumpifability(void);
|
static void Cmd_jumpifability(void);
|
||||||
static void Cmd_jumpifsideaffecting(void);
|
static void Cmd_jumpifsideaffecting(void);
|
||||||
static void Cmd_jumpifstat(void);
|
static void Cmd_jumpifstat(void);
|
||||||
static void Cmd_unused_0x21(void);
|
static void Cmd_jumpifstatignorecontrary(void);
|
||||||
static void Cmd_jumpbasedontype(void);
|
static void Cmd_jumpbasedontype(void);
|
||||||
static void Cmd_getexp(void);
|
static void Cmd_getexp(void);
|
||||||
static void Cmd_checkteamslost(void);
|
static void Cmd_checkteamslost(void);
|
||||||
@ -629,7 +629,7 @@ void (*const gBattleScriptingCommandsTable[])(void) =
|
|||||||
Cmd_jumpifability, //0x1E
|
Cmd_jumpifability, //0x1E
|
||||||
Cmd_jumpifsideaffecting, //0x1F
|
Cmd_jumpifsideaffecting, //0x1F
|
||||||
Cmd_jumpifstat, //0x20
|
Cmd_jumpifstat, //0x20
|
||||||
Cmd_unused_0x21, //0x21
|
Cmd_jumpifstatignorecontrary, //0x21
|
||||||
Cmd_jumpbasedontype, //0x22
|
Cmd_jumpbasedontype, //0x22
|
||||||
Cmd_getexp, //0x23
|
Cmd_getexp, //0x23
|
||||||
Cmd_checkteamslost, //0x24
|
Cmd_checkteamslost, //0x24
|
||||||
@ -1079,7 +1079,6 @@ bool32 EmergencyExitCanBeTriggered(u32 battler)
|
|||||||
&& HadMoreThanHalfHpNowDoesnt(battler)
|
&& HadMoreThanHalfHpNowDoesnt(battler)
|
||||||
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||||
&& CountUsablePartyMons(battler) > 0
|
|
||||||
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP)
|
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -1541,7 +1540,7 @@ static void Cmd_ppreduce(void)
|
|||||||
|
|
||||||
// For item Metronome, echoed voice
|
// For item Metronome, echoed voice
|
||||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || WasUnableToUseMove(gBattlerAttacker))
|
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || WasUnableToUseMove(gBattlerAttacker))
|
||||||
gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0;
|
gBattleStruct->metronomeItemCounter[gBattlerAttacker] = 0;
|
||||||
|
|
||||||
if (gBattleMons[gBattlerAttacker].pp[gCurrMovePos] > ppToDeduct)
|
if (gBattleMons[gBattlerAttacker].pp[gCurrMovePos] > ppToDeduct)
|
||||||
gBattleMons[gBattlerAttacker].pp[gCurrMovePos] -= ppToDeduct;
|
gBattleMons[gBattlerAttacker].pp[gCurrMovePos] -= ppToDeduct;
|
||||||
@ -1807,7 +1806,7 @@ static void Cmd_damagecalc(void)
|
|||||||
|
|
||||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||||
|
|
||||||
struct DamageContext ctx;
|
struct DamageContext ctx = {0};
|
||||||
ctx.battlerAtk = gBattlerAttacker;
|
ctx.battlerAtk = gBattlerAttacker;
|
||||||
ctx.move = gCurrentMove;
|
ctx.move = gCurrentMove;
|
||||||
ctx.moveType = GetBattleMoveType(gCurrentMove);
|
ctx.moveType = GetBattleMoveType(gCurrentMove);
|
||||||
@ -2832,11 +2831,11 @@ static void CheckSetUnburden(u8 battler)
|
|||||||
gDisableStructs[battler].unburdenActive = TRUE;
|
gDisableStructs[battler].unburdenActive = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// battlerStealer steals the item of battlerItem
|
// battlerStealer steals the item of itemBattler
|
||||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
void StealTargetItem(u8 battlerStealer, u8 itemBattler)
|
||||||
{
|
{
|
||||||
gLastUsedItem = gBattleMons[battlerItem].item;
|
gLastUsedItem = gBattleMons[itemBattler].item;
|
||||||
gBattleMons[battlerItem].item = ITEM_NONE;
|
gBattleMons[itemBattler].item = ITEM_NONE;
|
||||||
|
|
||||||
if (GetGenConfig(GEN_STEAL_WILD_ITEMS) >= GEN_9
|
if (GetGenConfig(GEN_STEAL_WILD_ITEMS) >= GEN_9
|
||||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
|
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
|
||||||
@ -2855,16 +2854,16 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
|||||||
MarkBattlerForControllerExec(battlerStealer);
|
MarkBattlerForControllerExec(battlerStealer);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordItemEffectBattle(battlerItem, ITEM_NONE);
|
RecordItemEffectBattle(itemBattler, ITEM_NONE);
|
||||||
CheckSetUnburden(battlerItem);
|
CheckSetUnburden(itemBattler);
|
||||||
|
|
||||||
BtlController_EmitSetMonData(battlerItem, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[battlerItem].item); // remove target item
|
BtlController_EmitSetMonData(itemBattler, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[itemBattler].item), &gBattleMons[itemBattler].item); // remove target item
|
||||||
MarkBattlerForControllerExec(battlerItem);
|
MarkBattlerForControllerExec(itemBattler);
|
||||||
|
|
||||||
if (GetBattlerAbility(gBattlerTarget) != ABILITY_GORILLA_TACTICS)
|
if (GetBattlerAbility(itemBattler) != ABILITY_GORILLA_TACTICS)
|
||||||
gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE;
|
gBattleStruct->choicedMove[itemBattler] = MOVE_NONE;
|
||||||
|
|
||||||
TrySaveExchangedItem(battlerItem, gLastUsedItem);
|
TrySaveExchangedItem(itemBattler, gLastUsedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool32 TrySetReflect(u32 battler)
|
static inline bool32 TrySetReflect(u32 battler)
|
||||||
@ -3315,7 +3314,6 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||||||
if (B_SKIP_RECHARGE == GEN_1 && !IsBattlerAlive(gBattlerTarget)) // Skip recharge if gen 1 and foe is KO'd
|
if (B_SKIP_RECHARGE == GEN_1 && !IsBattlerAlive(gBattlerTarget)) // Skip recharge if gen 1 and foe is KO'd
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gBattleMons[gEffectBattler].volatiles.recharge = TRUE;
|
|
||||||
gDisableStructs[gEffectBattler].rechargeTimer = 2;
|
gDisableStructs[gEffectBattler].rechargeTimer = 2;
|
||||||
gLockedMoves[gEffectBattler] = gCurrentMove;
|
gLockedMoves[gEffectBattler] = gCurrentMove;
|
||||||
gBattlescriptCurrInstr++;
|
gBattlescriptCurrInstr++;
|
||||||
@ -3831,7 +3829,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (TryChangeBattleWeather(gBattlerAttacker, weather, FALSE))
|
if (TryChangeBattleWeather(gBattlerAttacker, weather, ABILITY_NONE))
|
||||||
{
|
{
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = msg;
|
gBattleCommunication[MULTISTRING_CHOOSER] = msg;
|
||||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||||
@ -4433,7 +4431,7 @@ static void Cmd_jumpifstat(void)
|
|||||||
u8 value = cmd->value;
|
u8 value = cmd->value;
|
||||||
u8 comparison = cmd->comparison;
|
u8 comparison = cmd->comparison;
|
||||||
|
|
||||||
ret = CompareStat(battler, stat, value, comparison);
|
ret = CompareStat(battler, stat, value, comparison, GetBattlerAbility(battler));
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
@ -4441,8 +4439,22 @@ static void Cmd_jumpifstat(void)
|
|||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Cmd_unused_0x21(void)
|
static void Cmd_jumpifstatignorecontrary(void)
|
||||||
{
|
{
|
||||||
|
CMD_ARGS(u8 battler, u8 comparison, u8 stat, u8 value, const u8 *jumpInstr);
|
||||||
|
|
||||||
|
bool32 ret = 0;
|
||||||
|
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||||
|
u8 stat = cmd->stat;
|
||||||
|
u8 value = cmd->value;
|
||||||
|
u8 comparison = cmd->comparison;
|
||||||
|
|
||||||
|
ret = CompareStat(battler, stat, value, comparison, ABILITY_NONE);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
|
else
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Cmd_jumpbasedontype(void)
|
static void Cmd_jumpbasedontype(void)
|
||||||
@ -4773,7 +4785,15 @@ static void Cmd_getexp(void)
|
|||||||
|
|
||||||
if (battler != 0xFF)
|
if (battler != 0xFF)
|
||||||
{
|
{
|
||||||
CopyMonLevelAndBaseStatsToBattleMon(battler, &gPlayerParty[*expMonId]);
|
if (gBattleMons[battler].volatiles.transformed)
|
||||||
|
{
|
||||||
|
gBattleMons[battler].level = GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL);
|
||||||
|
gBattleMons[battler].hp = GetMonData(&gPlayerParty[*expMonId], MON_DATA_HP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopyMonLevelAndBaseStatsToBattleMon(battler, &gPlayerParty[*expMonId]);
|
||||||
|
}
|
||||||
if (gBattleMons[battler].volatiles.powerTrick)
|
if (gBattleMons[battler].volatiles.powerTrick)
|
||||||
SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, temp);
|
SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, temp);
|
||||||
}
|
}
|
||||||
@ -5577,22 +5597,54 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
|
|||||||
switch (abilityAtk)
|
switch (abilityAtk)
|
||||||
{
|
{
|
||||||
case ABILITY_MAGICIAN:
|
case ABILITY_MAGICIAN:
|
||||||
if (move != MOVE_FLING && move != MOVE_NATURAL_GIFT
|
if (GetMoveEffect(move) != EFFECT_FLING
|
||||||
|
&& GetMoveEffect(move) != EFFECT_NATURAL_GIFT
|
||||||
&& gBattleMons[battlerAtk].item == ITEM_NONE
|
&& gBattleMons[battlerAtk].item == ITEM_NONE
|
||||||
&& gBattleMons[battlerDef].item != ITEM_NONE
|
|
||||||
&& IsBattlerAlive(battlerAtk)
|
&& IsBattlerAlive(battlerAtk)
|
||||||
&& IsBattlerTurnDamaged(battlerDef)
|
&& !gSpecialStatuses[battlerAtk].gemBoost) // In base game, gems are consumed after magician would activate.
|
||||||
&& CanStealItem(battlerAtk, battlerDef, gBattleMons[battlerDef].item)
|
|
||||||
&& !gSpecialStatuses[battlerAtk].gemBoost // In base game, gems are consumed after magician would activate.
|
|
||||||
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(battlerDef)] & (1u << gBattlerPartyIndexes[battlerDef]))
|
|
||||||
&& !DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
|
||||||
&& (GetBattlerAbility(battlerDef) != ABILITY_STICKY_HOLD || !IsBattlerAlive(battlerDef)))
|
|
||||||
{
|
{
|
||||||
StealTargetItem(battlerAtk, battlerDef);
|
u32 numMagicianTargets = 0;
|
||||||
gBattleScripting.battler = gBattlerAbility = battlerAtk;
|
u32 magicianTargets = 0;
|
||||||
gEffectBattler = battlerDef;
|
|
||||||
BattleScriptCall(BattleScript_MagicianActivates);
|
for (u32 i = 0; i < gBattlersCount; i++)
|
||||||
effect = TRUE;
|
{
|
||||||
|
if (gBattleMons[i].item != ITEM_NONE
|
||||||
|
&& i != battlerAtk
|
||||||
|
&& IsBattlerTurnDamaged(i)
|
||||||
|
&& CanStealItem(battlerAtk, i, gBattleMons[i].item)
|
||||||
|
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(i)] & (1u << gBattlerPartyIndexes[i]))
|
||||||
|
&& !DoesSubstituteBlockMove(battlerAtk, i, move)
|
||||||
|
&& (GetBattlerAbility(i) != ABILITY_STICKY_HOLD || !IsBattlerAlive(i)))
|
||||||
|
{
|
||||||
|
magicianTargets |= 1u << i;
|
||||||
|
numMagicianTargets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numMagicianTargets == 0)
|
||||||
|
{
|
||||||
|
effect = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 battlers[4] = {0, 1, 2, 3};
|
||||||
|
if (numMagicianTargets > 1)
|
||||||
|
SortBattlersBySpeed(battlers, FALSE);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < gBattlersCount; i++)
|
||||||
|
{
|
||||||
|
u32 battler = battlers[i];
|
||||||
|
|
||||||
|
if (!(magicianTargets & 1u << battler))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
StealTargetItem(battlerAtk, battler);
|
||||||
|
gBattlerAbility = battlerAtk;
|
||||||
|
gEffectBattler = battler;
|
||||||
|
BattleScriptCall(BattleScript_MagicianActivates);
|
||||||
|
effect = TRUE;
|
||||||
|
break; // found target to steal from
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_MOXIE:
|
case ABILITY_MOXIE:
|
||||||
@ -5613,7 +5665,7 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
|
|||||||
else if (abilityAtk == ABILITY_GRIM_NEIGH || abilityAtk == ABILITY_AS_ONE_SHADOW_RIDER)
|
else if (abilityAtk == ABILITY_GRIM_NEIGH || abilityAtk == ABILITY_AS_ONE_SHADOW_RIDER)
|
||||||
stat = STAT_SPATK;
|
stat = STAT_SPATK;
|
||||||
|
|
||||||
if (numMonsFainted && CompareStat(battlerAtk, stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (numMonsFainted && CompareStat(battlerAtk, stat, MAX_STAT_STAGE, CMP_LESS_THAN, abilityAtk))
|
||||||
{
|
{
|
||||||
gLastUsedAbility = abilityAtk;
|
gLastUsedAbility = abilityAtk;
|
||||||
if (abilityAtk == ABILITY_AS_ONE_ICE_RIDER)
|
if (abilityAtk == ABILITY_AS_ONE_ICE_RIDER)
|
||||||
@ -5653,17 +5705,17 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 numStatBuffs = 0;
|
u32 numStatBuffs = 0;
|
||||||
if (CompareStat(battlerAtk, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battlerAtk, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, abilityAtk))
|
||||||
{
|
{
|
||||||
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_ATK) + STAT_ANIM_PLUS1;
|
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_ATK) + STAT_ANIM_PLUS1;
|
||||||
numStatBuffs++;
|
numStatBuffs++;
|
||||||
}
|
}
|
||||||
if (CompareStat(battlerAtk, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battlerAtk, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN, abilityAtk))
|
||||||
{
|
{
|
||||||
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_SPATK) + STAT_ANIM_PLUS1;
|
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_SPATK) + STAT_ANIM_PLUS1;
|
||||||
numStatBuffs++;
|
numStatBuffs++;
|
||||||
}
|
}
|
||||||
if (CompareStat(battlerAtk, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battlerAtk, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, abilityAtk))
|
||||||
{
|
{
|
||||||
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_SPEED) + STAT_ANIM_PLUS1;
|
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(STAT_SPEED) + STAT_ANIM_PLUS1;
|
||||||
numStatBuffs++;
|
numStatBuffs++;
|
||||||
@ -5694,26 +5746,29 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
u32 effect = FALSE;
|
u32 effect = FALSE;
|
||||||
|
u32 side = GetBattlerSide(gBattlerTarget);
|
||||||
switch (moveEffect)
|
switch (moveEffect)
|
||||||
{
|
{
|
||||||
case EFFECT_KNOCK_OFF:
|
case EFFECT_KNOCK_OFF:
|
||||||
if (gBattleStruct->battlerState[gBattlerTarget].itemCanBeKnockedOff
|
if (gBattleStruct->battlerState[gBattlerTarget].itemCanBeKnockedOff
|
||||||
&& gBattleMons[gBattlerTarget].item != ITEM_NONE
|
&& gBattleMons[gBattlerTarget].item != ITEM_NONE
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(gBattlerAttacker))
|
&& IsBattlerAlive(gBattlerAttacker)
|
||||||
|
&& !(B_KNOCK_OFF_REMOVAL >= GEN_5 && side == B_SIDE_PLAYER && !(gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
|
||||||
{
|
{
|
||||||
u32 side = GetBattlerSide(gBattlerTarget);
|
|
||||||
gLastUsedItem = gBattleMons[gBattlerTarget].item;
|
gLastUsedItem = gBattleMons[gBattlerTarget].item;
|
||||||
gBattleMons[gBattlerTarget].item = 0;
|
gBattleMons[gBattlerTarget].item = 0;
|
||||||
if (gBattleMons[gBattlerTarget].ability != ABILITY_GORILLA_TACTICS)
|
if (gBattleMons[gBattlerTarget].ability != ABILITY_GORILLA_TACTICS)
|
||||||
gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE;
|
gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE;
|
||||||
CheckSetUnburden(gBattlerTarget);
|
CheckSetUnburden(gBattlerTarget);
|
||||||
|
|
||||||
// In Gen 5+, Knock Off removes the target's item rather than rendering it unusable.
|
// In Gen 5+, Knock Off removes the target's item rather than rendering it unusable
|
||||||
if (B_KNOCK_OFF_REMOVAL >= GEN_5)
|
if (B_KNOCK_OFF_REMOVAL >= GEN_5)
|
||||||
{
|
{
|
||||||
BtlController_EmitSetMonData(gBattlerTarget, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[gBattlerTarget].item);
|
BtlController_EmitSetMonData(gBattlerTarget, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[gBattlerTarget].item);
|
||||||
MarkBattlerForControllerExec(gBattlerTarget);
|
MarkBattlerForControllerExec(gBattlerTarget);
|
||||||
|
// Mark item as stolen so it will be restored after battle
|
||||||
|
gBattleStruct->itemLost[side][gBattlerPartyIndexes[gBattlerTarget]].stolen = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5752,6 +5807,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
|
gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
|
||||||
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
|
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
|
||||||
}
|
}
|
||||||
|
gEffectBattler = gBattlerTarget;
|
||||||
BattleScriptCall(BattleScript_ItemSteal);
|
BattleScriptCall(BattleScript_ItemSteal);
|
||||||
effect = TRUE;
|
effect = TRUE;
|
||||||
}
|
}
|
||||||
@ -5828,6 +5884,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_EXPLOSION:
|
case EFFECT_EXPLOSION:
|
||||||
|
case EFFECT_MISTY_EXPLOSION:
|
||||||
if (!IsAbilityOnField(ABILITY_DAMP))
|
if (!IsAbilityOnField(ABILITY_DAMP))
|
||||||
{
|
{
|
||||||
gBattleStruct->moveDamage[gBattlerAttacker] = 0;
|
gBattleStruct->moveDamage[gBattlerAttacker] = 0;
|
||||||
@ -5854,7 +5911,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_RAPID_SPIN:
|
case EFFECT_RAPID_SPIN:
|
||||||
if (IsBattlerTurnDamaged(gBattlerTarget))
|
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker))
|
||||||
{
|
{
|
||||||
BattleScriptCall(BattleScript_RapidSpinAway);
|
BattleScriptCall(BattleScript_RapidSpinAway);
|
||||||
effect = TRUE;
|
effect = TRUE;
|
||||||
@ -5865,7 +5922,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
&& !IsBattlerAlive(gBattlerTarget)
|
&& !IsBattlerAlive(gBattlerTarget)
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& !NoAliveMonsForEitherParty()
|
&& !NoAliveMonsForEitherParty()
|
||||||
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerAttacker)))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_ATK, GetGenConfig(GEN_CONFIG_FELL_STINGER_STAT_RAISE) >= GEN_7 ? 3 : 2, FALSE);
|
SET_STATCHANGER(STAT_ATK, GetGenConfig(GEN_CONFIG_FELL_STINGER_STAT_RAISE) >= GEN_7 ? 3 : 2, FALSE);
|
||||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
|
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
|
||||||
@ -5875,7 +5932,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_STONE_AXE:
|
case EFFECT_STONE_AXE:
|
||||||
if (!IsHazardOnSide(GetBattlerSide(gBattlerTarget), HAZARDS_STEALTH_ROCK)
|
if (!IsHazardOnSide(side, HAZARDS_STEALTH_ROCK)
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(gBattlerAttacker))
|
&& IsBattlerAlive(gBattlerAttacker))
|
||||||
{
|
{
|
||||||
@ -5886,7 +5943,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_CEASELESS_EDGE:
|
case EFFECT_CEASELESS_EDGE:
|
||||||
if (gSideTimers[GetBattlerSide(gBattlerTarget)].spikesAmount < 3
|
if (gSideTimers[side].spikesAmount < 3
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(gBattlerAttacker))
|
&& IsBattlerAlive(gBattlerAttacker))
|
||||||
{
|
{
|
||||||
@ -6095,7 +6152,7 @@ static void Cmd_moveend(void)
|
|||||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& !IsBattleMoveStatus(gCurrentMove)
|
&& !IsBattleMoveStatus(gCurrentMove)
|
||||||
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerTarget)))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||||
BattleScriptCall(BattleScript_RageIsBuilding);
|
BattleScriptCall(BattleScript_RageIsBuilding);
|
||||||
@ -6511,7 +6568,7 @@ static void Cmd_moveend(void)
|
|||||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_THROAT_SPRAY
|
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_THROAT_SPRAY
|
||||||
&& IsBattlerAlive(gBattlerAttacker)
|
&& IsBattlerAlive(gBattlerAttacker)
|
||||||
&& IsAnyTargetAffected(gBattlerAttacker)
|
&& IsAnyTargetAffected(gBattlerAttacker)
|
||||||
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerAttacker))
|
||||||
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
|
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
|
||||||
{
|
{
|
||||||
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
|
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
|
||||||
@ -6684,7 +6741,7 @@ static void Cmd_moveend(void)
|
|||||||
effect = TRUE;
|
effect = TRUE;
|
||||||
gBattleScripting.battler = battler;
|
gBattleScripting.battler = battler;
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || IsOnPlayerSide(battler))
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||||
BattleScriptCall(BattleScript_EmergencyExit);
|
BattleScriptCall(BattleScript_EmergencyExit);
|
||||||
else
|
else
|
||||||
BattleScriptCall(BattleScript_EmergencyExitWild);
|
BattleScriptCall(BattleScript_EmergencyExitWild);
|
||||||
@ -6882,9 +6939,9 @@ static void Cmd_moveend(void)
|
|||||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker]
|
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker]
|
||||||
|| gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT
|
|| gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT
|
||||||
|| gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
|| gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||||
gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0;
|
gBattleStruct->metronomeItemCounter[gBattlerAttacker] = 0;
|
||||||
else if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
|
else if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
|
||||||
gBattleStruct->sameMoveTurns[gBattlerAttacker]++;
|
gBattleStruct->metronomeItemCounter[gBattlerAttacker]++;
|
||||||
gBattleScripting.moveendState++;
|
gBattleScripting.moveendState++;
|
||||||
break;
|
break;
|
||||||
case MOVEEND_CLEAR_BITS: // Clear/Set bits for things like using a move for all targets and all hits.
|
case MOVEEND_CLEAR_BITS: // Clear/Set bits for things like using a move for all targets and all hits.
|
||||||
@ -6938,6 +6995,8 @@ 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))
|
||||||
gBattleMons[gBattlerAttacker].volatiles.charge = FALSE;
|
gBattleMons[gBattlerAttacker].volatiles.charge = FALSE;
|
||||||
|
if (moveEffect == EFFECT_ECHOED_VOICE && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE))
|
||||||
|
gBattleStruct->incrementEchoedVoice = TRUE;
|
||||||
// check if Stellar type boost should be used up
|
// check if Stellar type boost should be used up
|
||||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA
|
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA
|
||||||
&& GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR
|
&& GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR
|
||||||
@ -7878,7 +7937,6 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
|||||||
gBattleStruct->hpOnSwitchout[GetBattlerSide(i)] = gBattleMons[i].hp;
|
gBattleStruct->hpOnSwitchout[GetBattlerSide(i)] = gBattleMons[i].hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
gDisableStructs[battler].hazardsDone = FALSE;
|
|
||||||
gBattleStruct->battlerState[battler].forcedSwitch = FALSE;
|
gBattleStruct->battlerState[battler].forcedSwitch = FALSE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -9562,7 +9620,7 @@ static void Cmd_setprotectlike(void)
|
|||||||
if (gCurrentTurnActionNumber == (gBattlersCount - 1))
|
if (gCurrentTurnActionNumber == (gBattlersCount - 1))
|
||||||
notLastTurn = FALSE;
|
notLastTurn = FALSE;
|
||||||
|
|
||||||
if ((sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= Random() && notLastTurn)
|
if ((sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= RandomUniform(RNG_PROTECT_FAIL, 0, USHRT_MAX) && notLastTurn)
|
||||||
|| (protectMethod == PROTECT_WIDE_GUARD && B_WIDE_GUARD != GEN_5)
|
|| (protectMethod == PROTECT_WIDE_GUARD && B_WIDE_GUARD != GEN_5)
|
||||||
|| (protectMethod == PROTECT_QUICK_GUARD && B_QUICK_GUARD != GEN_5))
|
|| (protectMethod == PROTECT_QUICK_GUARD && B_QUICK_GUARD != GEN_5))
|
||||||
{
|
{
|
||||||
@ -9591,6 +9649,7 @@ static void Cmd_setprotectlike(void)
|
|||||||
gDisableStructs[gBattlerAttacker].protectUses = 0;
|
gDisableStructs[gBattlerAttacker].protectUses = 0;
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECT_FAILED;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECT_FAILED;
|
||||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
||||||
|
gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
@ -9729,7 +9788,7 @@ static void Cmd_setfieldweather(void)
|
|||||||
|
|
||||||
u8 battleWeatherId = cmd->weather;
|
u8 battleWeatherId = cmd->weather;
|
||||||
|
|
||||||
if (!TryChangeBattleWeather(gBattlerAttacker, battleWeatherId, FALSE))
|
if (!TryChangeBattleWeather(gBattlerAttacker, battleWeatherId, ABILITY_NONE))
|
||||||
{
|
{
|
||||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_FAILED;
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_FAILED;
|
||||||
@ -11158,7 +11217,8 @@ static void Cmd_setfocusenergy(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetGenConfig(GEN_CONFIG_FOCUS_ENERGY_CRIT_RATIO) >= GEN_3)
|
if (GetGenConfig(GEN_CONFIG_FOCUS_ENERGY_CRIT_RATIO) >= GEN_3
|
||||||
|
|| GetGenConfig(GEN_CONFIG_CRIT_CHANCE) == GEN_1)
|
||||||
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
gBattleMons[battler].volatiles.focusEnergy = TRUE;
|
||||||
else
|
else
|
||||||
gBattleMons[battler].volatiles.dragonCheer = TRUE;
|
gBattleMons[battler].volatiles.dragonCheer = TRUE;
|
||||||
@ -11190,7 +11250,10 @@ static void Cmd_transformdataexecution(void)
|
|||||||
gDisableStructs[gBattlerAttacker].disabledMove = MOVE_NONE;
|
gDisableStructs[gBattlerAttacker].disabledMove = MOVE_NONE;
|
||||||
gDisableStructs[gBattlerAttacker].disableTimer = 0;
|
gDisableStructs[gBattlerAttacker].disableTimer = 0;
|
||||||
gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality;
|
gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality;
|
||||||
gDisableStructs[gBattlerAttacker].transformedMonShininess = gBattleMons[gBattlerTarget].isShiny;
|
if (B_TRANSFORM_SHINY >= GEN_4)
|
||||||
|
gDisableStructs[gBattlerAttacker].transformedMonShininess = gBattleMons[gBattlerTarget].isShiny;
|
||||||
|
else
|
||||||
|
gDisableStructs[gBattlerAttacker].transformedMonShininess = gBattleMons[gBattlerAttacker].isShiny;
|
||||||
gDisableStructs[gBattlerAttacker].mimickedMoves = 0;
|
gDisableStructs[gBattlerAttacker].mimickedMoves = 0;
|
||||||
gDisableStructs[gBattlerAttacker].usedMoves = 0;
|
gDisableStructs[gBattlerAttacker].usedMoves = 0;
|
||||||
|
|
||||||
@ -12075,7 +12138,7 @@ static void Cmd_jumpifconfusedandstatmaxed(void)
|
|||||||
CMD_ARGS(u8 stat, const u8 *jumpInstr);
|
CMD_ARGS(u8 stat, const u8 *jumpInstr);
|
||||||
|
|
||||||
if (gBattleMons[gBattlerTarget].volatiles.confusionTurns > 0
|
if (gBattleMons[gBattlerTarget].volatiles.confusionTurns > 0
|
||||||
&& !CompareStat(gBattlerTarget, cmd->stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& !CompareStat(gBattlerTarget, cmd->stat, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerTarget)))
|
||||||
gBattlescriptCurrInstr = cmd->jumpInstr; // Fails if we're confused AND stat cannot be raised
|
gBattlescriptCurrInstr = cmd->jumpInstr; // Fails if we're confused AND stat cannot be raised
|
||||||
else
|
else
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
@ -14127,6 +14190,8 @@ static void Cmd_givecaughtmon(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//Before sending to PC, we revert battle form
|
||||||
|
TryRevertPartyMonFormChange(gSelectedMonPartyId);
|
||||||
// Mon chosen, try to put it in the PC
|
// Mon chosen, try to put it in the PC
|
||||||
if (CopyMonToPC(&gPlayerParty[gSelectedMonPartyId]) == MON_GIVEN_TO_PC)
|
if (CopyMonToPC(&gPlayerParty[gSelectedMonPartyId]) == MON_GIVEN_TO_PC)
|
||||||
{
|
{
|
||||||
@ -15285,34 +15350,56 @@ void BS_SetTerrain(void)
|
|||||||
switch (GetMoveEffect(gCurrentMove))
|
switch (GetMoveEffect(gCurrentMove))
|
||||||
{
|
{
|
||||||
case EFFECT_MISTY_TERRAIN:
|
case EFFECT_MISTY_TERRAIN:
|
||||||
statusFlag = STATUS_FIELD_MISTY_TERRAIN;
|
if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
|
{
|
||||||
|
statusFlag = STATUS_FIELD_MISTY_TERRAIN;
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_GRASSY_TERRAIN:
|
case EFFECT_GRASSY_TERRAIN:
|
||||||
statusFlag = STATUS_FIELD_GRASSY_TERRAIN;
|
if (!(gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN))
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY;
|
{
|
||||||
|
statusFlag = STATUS_FIELD_GRASSY_TERRAIN;
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_ELECTRIC_TERRAIN:
|
case EFFECT_ELECTRIC_TERRAIN:
|
||||||
statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN;
|
if (!(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN))
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
|
{
|
||||||
|
statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN;
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_PSYCHIC_TERRAIN:
|
case EFFECT_PSYCHIC_TERRAIN:
|
||||||
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN;
|
if (!(gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN))
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
|
{
|
||||||
|
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN;
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_HIT_SET_TERRAIN:
|
case EFFECT_HIT_SET_TERRAIN:
|
||||||
statusFlag = GetMoveTerrainFlag(gCurrentMove);
|
if (!(gFieldStatuses & GetMoveTerrainFlag(gCurrentMove)))
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
|
{
|
||||||
|
statusFlag = GetMoveTerrainFlag(gCurrentMove);
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
enum ItemHoldEffect atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
|
if (gBattleStruct->isSkyBattle)
|
||||||
|
{
|
||||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
gFieldStatuses |= statusFlag;
|
}
|
||||||
gFieldTimers.terrainTimer = gBattleTurnCounter + (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5;
|
else if (statusFlag)
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
{
|
||||||
|
TryChangeBattleTerrain(gBattlerAttacker, statusFlag);
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_JumpIfTerrainAffected(void)
|
void BS_JumpIfTerrainAffected(void)
|
||||||
@ -15674,9 +15761,7 @@ void BS_TryAllySwitch(void)
|
|||||||
{
|
{
|
||||||
NATIVE_ARGS(const u8 *failInstr);
|
NATIVE_ARGS(const u8 *failInstr);
|
||||||
|
|
||||||
if (!IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))
|
if (!IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)) || HasPartnerTrainer(gBattlerAttacker))
|
||||||
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
|
||||||
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
|
||||||
{
|
{
|
||||||
gBattlescriptCurrInstr = cmd->failInstr;
|
gBattlescriptCurrInstr = cmd->failInstr;
|
||||||
}
|
}
|
||||||
@ -15980,7 +16065,7 @@ 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 or if 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, GetBattlerAbility(gBattlerTarget)))
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
else
|
else
|
||||||
gBattlescriptCurrInstr = cmd->failInstr;
|
gBattlescriptCurrInstr = cmd->failInstr;
|
||||||
@ -16795,15 +16880,6 @@ void BS_JumpIfNoAlly(void)
|
|||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_InfatuateWithBattler(void)
|
|
||||||
{
|
|
||||||
NATIVE_ARGS(u8 battler, u8 infatuateWith);
|
|
||||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
|
||||||
gBattleScripting.battler = battler;
|
|
||||||
gBattleMons[battler].volatiles.infatuation = INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith));
|
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BS_SetLastUsedItem(void)
|
void BS_SetLastUsedItem(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS(u8 battler);
|
NATIVE_ARGS(u8 battler);
|
||||||
@ -16934,7 +17010,7 @@ void BS_TryAcupressure(void)
|
|||||||
u32 bits = 0;
|
u32 bits = 0;
|
||||||
for (u32 stat = STAT_ATK; stat < NUM_BATTLE_STATS; stat++)
|
for (u32 stat = STAT_ATK; stat < NUM_BATTLE_STATS; stat++)
|
||||||
{
|
{
|
||||||
if (CompareStat(gBattlerTarget, stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(gBattlerTarget, stat, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerTarget)))
|
||||||
bits |= 1u << stat;
|
bits |= 1u << stat;
|
||||||
}
|
}
|
||||||
if (bits)
|
if (bits)
|
||||||
@ -17064,11 +17140,14 @@ void BS_ArenaJudgmentWindow(void)
|
|||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetArenMonLostValues(u32 battler)
|
static void SetArenMonLostValues(u32 battler, u32 side)
|
||||||
{
|
{
|
||||||
gBattleMons[battler].hp = 0;
|
gBattleMons[battler].hp = 0;
|
||||||
gHitMarker |= HITMARKER_FAINTED(battler);
|
gHitMarker |= HITMARKER_FAINTED(battler);
|
||||||
gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[battler];
|
if (side == B_SIDE_PLAYER)
|
||||||
|
gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[battler];
|
||||||
|
else
|
||||||
|
gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[battler];
|
||||||
gDisableStructs[battler].truantSwitchInHack = TRUE;
|
gDisableStructs[battler].truantSwitchInHack = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17077,22 +17156,22 @@ static void SetArenMonLostValues(u32 battler)
|
|||||||
void BS_ArenaOpponentMonLost(void)
|
void BS_ArenaOpponentMonLost(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS();
|
NATIVE_ARGS();
|
||||||
SetArenMonLostValues(opponentMon);
|
SetArenMonLostValues(opponentMon, B_SIDE_OPPONENT);
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_ArenaPlayerMonLost(void)
|
void BS_ArenaPlayerMonLost(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS();
|
NATIVE_ARGS();
|
||||||
SetArenMonLostValues(playerMon);
|
SetArenMonLostValues(playerMon, B_SIDE_PLAYER);
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_ArenaBothMonsLost(void)
|
void BS_ArenaBothMonsLost(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS();
|
NATIVE_ARGS();
|
||||||
SetArenMonLostValues(playerMon);
|
SetArenMonLostValues(playerMon, B_SIDE_PLAYER);
|
||||||
SetArenMonLostValues(opponentMon);
|
SetArenMonLostValues(opponentMon, B_SIDE_OPPONENT);
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
#undef playerMon
|
#undef playerMon
|
||||||
@ -17122,13 +17201,12 @@ void BS_EraseArenaRefTextBox(void)
|
|||||||
|
|
||||||
void BS_ArenaJudgmentString(void)
|
void BS_ArenaJudgmentString(void)
|
||||||
{
|
{
|
||||||
CMD_ARGS(u8 id);
|
NATIVE_ARGS(u8 id);
|
||||||
BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[cmd->id]);
|
BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[cmd->id]);
|
||||||
BattlePutTextOnWindow(gDisplayedStringBattle, ARENA_WIN_JUDGMENT_TEXT);
|
BattlePutTextOnWindow(gDisplayedStringBattle, ARENA_WIN_JUDGMENT_TEXT);
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Argument passed but no use
|
|
||||||
void BS_ArenaWaitMessage(void)
|
void BS_ArenaWaitMessage(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS();
|
NATIVE_ARGS();
|
||||||
@ -17331,10 +17409,11 @@ void BS_TryActivateSoulheart(void)
|
|||||||
while (gBattleStruct->soulheartBattlerId < gBattlersCount)
|
while (gBattleStruct->soulheartBattlerId < gBattlersCount)
|
||||||
{
|
{
|
||||||
gBattleScripting.battler = gBattleStruct->soulheartBattlerId++;
|
gBattleScripting.battler = gBattleStruct->soulheartBattlerId++;
|
||||||
if (GetBattlerAbility(gBattleScripting.battler) == ABILITY_SOUL_HEART
|
u32 ability = GetBattlerAbility(gBattleScripting.battler);
|
||||||
|
if (ability == ABILITY_SOUL_HEART
|
||||||
&& IsBattlerAlive(gBattleScripting.battler)
|
&& IsBattlerAlive(gBattleScripting.battler)
|
||||||
&& !NoAliveMonsForEitherParty()
|
&& !NoAliveMonsForEitherParty()
|
||||||
&& CompareStat(gBattleScripting.battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattleScripting.battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN, ability))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
|
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
|
||||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK);
|
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK);
|
||||||
@ -18211,19 +18290,17 @@ void BS_JumpIfSpecies(void)
|
|||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_JumpIfLeafGuardProtected(void)
|
void BS_JumpIfAbilityPreventsRest(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||||
if (IsLeafGuardProtected(battler, GetBattlerAbility(battler)))
|
u32 ability = GetBattlerAbility(battler);
|
||||||
{
|
if (B_LEAF_GUARD_PREVENTS_REST >= GEN_5 && IsLeafGuardProtected(battler, ability))
|
||||||
gBattlerAbility = battler;
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
|
else if (IsShieldsDownProtected(battler, ability))
|
||||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS_SetAttackerToStickyWebUser(void)
|
void BS_SetAttackerToStickyWebUser(void)
|
||||||
@ -18244,10 +18321,11 @@ void BS_CutOneThirdHpAndRaiseStats(void)
|
|||||||
|
|
||||||
bool8 atLeastOneStatBoosted = FALSE;
|
bool8 atLeastOneStatBoosted = FALSE;
|
||||||
u16 hpFraction = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 3);
|
u16 hpFraction = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 3);
|
||||||
|
u32 ability = GetBattlerAbility(gBattlerAttacker);
|
||||||
|
|
||||||
for (u32 stat = 1; stat < NUM_STATS; stat++)
|
for (u32 stat = 1; stat < NUM_STATS; stat++)
|
||||||
{
|
{
|
||||||
if (CompareStat(gBattlerAttacker, stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(gBattlerAttacker, stat, MAX_STAT_STAGE, CMP_LESS_THAN, ability))
|
||||||
{
|
{
|
||||||
atLeastOneStatBoosted = TRUE;
|
atLeastOneStatBoosted = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1125,6 +1125,17 @@ bool32 GetTrainerFlagFromScriptPointer(const u8 *data)
|
|||||||
TrainerBattleParameter *temp = (TrainerBattleParameter*)(data + OPCODE_OFFSET);
|
TrainerBattleParameter *temp = (TrainerBattleParameter*)(data + OPCODE_OFFSET);
|
||||||
return FlagGet(TRAINER_FLAGS_START + temp->params.opponentA);
|
return FlagGet(TRAINER_FLAGS_START + temp->params.opponentA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 GetRematchFromScriptPointer(const u8 *data)
|
||||||
|
{
|
||||||
|
#if FREE_MATCH_CALL
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
TrainerBattleParameter *temp = (TrainerBattleParameter*)(data + OPCODE_OFFSET);
|
||||||
|
return ShouldTryRematchBattleForTrainerId(temp->params.opponentA);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#undef OPCODE_OFFSET
|
#undef OPCODE_OFFSET
|
||||||
|
|
||||||
// Set trainer's movement type so they stop and remain facing that direction
|
// Set trainer's movement type so they stop and remain facing that direction
|
||||||
@ -1741,6 +1752,20 @@ static void ClearTrainerWantRematchState(const struct RematchTrainer *table, u16
|
|||||||
#endif //FREE_MATCH_CALL
|
#endif //FREE_MATCH_CALL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearCurrentTrainerWantRematchVsSeeker(void)
|
||||||
|
{
|
||||||
|
#if FREE_MATCH_CALL == FALSE
|
||||||
|
if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) && FlagGet(I_VS_SEEKER_CHARGING) && (I_VS_SEEKER_CHARGING != 0))
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < REMATCH_TABLE_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
if (gSaveBlock1Ptr->trainerRematches[i] == TRAINER_BATTLE_PARAM.opponentA)
|
||||||
|
gSaveBlock1Ptr->trainerRematches[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //FREE_MATCH_CALL
|
||||||
|
}
|
||||||
|
|
||||||
static u32 GetTrainerMatchCallFlag(u32 trainerId)
|
static u32 GetTrainerMatchCallFlag(u32 trainerId)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
@ -1772,12 +1797,18 @@ static bool8 WasSecondRematchWon(const struct RematchTrainer *table, u16 firstBa
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (!HasTrainerBeenFought(table[tableId].trainerIds[1]))
|
if (!HasTrainerBeenFought(table[tableId].trainerIds[1]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
#if FREE_MATCH_CALL == FALSE
|
||||||
|
if (I_VS_SEEKER_CHARGING)
|
||||||
|
{
|
||||||
|
if (gSaveBlock1Ptr->trainerRematches[tableId] == 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FREE_MATCH_CALL == FALSE
|
#if FREE_MATCH_CALL == FALSE
|
||||||
static bool32 HasAtLeastFiveBadges(void)
|
static bool32 HasEnoughBadgesForRematch(void)
|
||||||
{
|
{
|
||||||
s32 i, count;
|
s32 i, count;
|
||||||
|
|
||||||
@ -1785,7 +1816,7 @@ static bool32 HasAtLeastFiveBadges(void)
|
|||||||
{
|
{
|
||||||
if (FlagGet(gBadgeFlags[i]) == TRUE)
|
if (FlagGet(gBadgeFlags[i]) == TRUE)
|
||||||
{
|
{
|
||||||
if (++count >= 5)
|
if (++count >= OW_REMATCH_BADGE_COUNT)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1799,7 +1830,7 @@ static bool32 HasAtLeastFiveBadges(void)
|
|||||||
void IncrementRematchStepCounter(void)
|
void IncrementRematchStepCounter(void)
|
||||||
{
|
{
|
||||||
#if FREE_MATCH_CALL == FALSE
|
#if FREE_MATCH_CALL == FALSE
|
||||||
if (!HasAtLeastFiveBadges())
|
if (!HasEnoughBadgesForRematch())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsVsSeekerEnabled())
|
if (IsVsSeekerEnabled())
|
||||||
@ -1815,7 +1846,7 @@ void IncrementRematchStepCounter(void)
|
|||||||
#if FREE_MATCH_CALL == FALSE
|
#if FREE_MATCH_CALL == FALSE
|
||||||
static bool32 IsRematchStepCounterMaxed(void)
|
static bool32 IsRematchStepCounterMaxed(void)
|
||||||
{
|
{
|
||||||
if (HasAtLeastFiveBadges() && gSaveBlock1Ptr->trainerRematchStepCounter >= STEP_COUNTER_MAX)
|
if (HasEnoughBadgesForRematch() && gSaveBlock1Ptr->trainerRematchStepCounter >= STEP_COUNTER_MAX)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1855,10 +1886,15 @@ u16 GetLastBeatenRematchTrainerId(u16 trainerId)
|
|||||||
|
|
||||||
bool8 ShouldTryRematchBattle(void)
|
bool8 ShouldTryRematchBattle(void)
|
||||||
{
|
{
|
||||||
if (IsFirstTrainerIdReadyForRematch(gRematchTable, TRAINER_BATTLE_PARAM.opponentA))
|
return ShouldTryRematchBattleForTrainerId(TRAINER_BATTLE_PARAM.opponentA);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 ShouldTryRematchBattleForTrainerId(u16 trainerId)
|
||||||
|
{
|
||||||
|
if (IsFirstTrainerIdReadyForRematch(gRematchTable, trainerId))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return WasSecondRematchWon(gRematchTable, TRAINER_BATTLE_PARAM.opponentA);
|
return WasSecondRematchWon(gRematchTable, trainerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 IsTrainerReadyForRematch(void)
|
bool8 IsTrainerReadyForRematch(void)
|
||||||
|
|||||||
@ -1987,7 +1987,7 @@ void DoSpecialTrainerBattle(void)
|
|||||||
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
|
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
|
||||||
break;
|
break;
|
||||||
case FRONTIER_MODE_LINK_MULTIS:
|
case FRONTIER_MODE_LINK_MULTIS:
|
||||||
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_TOWER_LINK_MULTI;
|
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_TOWER_LINK_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
|
||||||
FillFrontierTrainersParties(FRONTIER_MULTI_PARTY_SIZE);
|
FillFrontierTrainersParties(FRONTIER_MULTI_PARTY_SIZE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,7 @@ static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item);
|
|||||||
static bool32 CanBeInfinitelyConfused(u32 battler);
|
static bool32 CanBeInfinitelyConfused(u32 battler);
|
||||||
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum FunctionCallOption option);
|
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum FunctionCallOption option);
|
||||||
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum FunctionCallOption option);
|
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum FunctionCallOption option);
|
||||||
|
static bool32 IsOpposingSideEmpty(u32 battler);
|
||||||
|
|
||||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
|
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
|
||||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
|
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
|
||||||
@ -405,7 +406,7 @@ void HandleAction_UseMove(void)
|
|||||||
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
||||||
gBattleStruct->moveTarget[gBattlerAttacker] = GetBattleMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE);
|
gBattleStruct->moveTarget[gBattlerAttacker] = GetBattleMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE);
|
||||||
}
|
}
|
||||||
else if (gBattleMons[gBattlerAttacker].volatiles.multipleTurns || gBattleMons[gBattlerAttacker].volatiles.recharge)
|
else if (gBattleMons[gBattlerAttacker].volatiles.multipleTurns || gDisableStructs[gBattlerAttacker].rechargeTimer > 0)
|
||||||
{
|
{
|
||||||
gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker];
|
gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker];
|
||||||
}
|
}
|
||||||
@ -1196,7 +1197,7 @@ void PrepareStringBattle(enum StringID stringId, u32 battler)
|
|||||||
else if (GetGenConfig(GEN_CONFIG_UPDATED_INTIMIDATE) >= GEN_8
|
else if (GetGenConfig(GEN_CONFIG_UPDATED_INTIMIDATE) >= GEN_8
|
||||||
&& stringId == STRINGID_PKMNCUTSATTACKWITH
|
&& stringId == STRINGID_PKMNCUTSATTACKWITH
|
||||||
&& targetAbility == ABILITY_RATTLED
|
&& targetAbility == ABILITY_RATTLED
|
||||||
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, targetAbility))
|
||||||
{
|
{
|
||||||
gBattlerAbility = gBattlerTarget;
|
gBattlerAbility = gBattlerTarget;
|
||||||
BattleScriptCall(BattleScript_AbilityRaisesDefenderStat);
|
BattleScriptCall(BattleScript_AbilityRaisesDefenderStat);
|
||||||
@ -1702,13 +1703,13 @@ u32 GetBattlerAffectionHearts(u32 battler)
|
|||||||
// gBattlerAttacker is the battler that's trying to raise their stats and due to limitations of RandomUniformExcept, cannot be an argument
|
// gBattlerAttacker is the battler that's trying to raise their stats and due to limitations of RandomUniformExcept, cannot be an argument
|
||||||
bool32 MoodyCantRaiseStat(u32 stat)
|
bool32 MoodyCantRaiseStat(u32 stat)
|
||||||
{
|
{
|
||||||
return CompareStat(gBattlerAttacker, stat, MAX_STAT_STAGE, CMP_EQUAL);
|
return CompareStat(gBattlerAttacker, stat, MAX_STAT_STAGE, CMP_EQUAL, GetBattlerAbility(gBattlerAttacker));
|
||||||
}
|
}
|
||||||
|
|
||||||
// gBattlerAttacker is the battler that's trying to lower their stats and due to limitations of RandomUniformExcept, cannot be an argument
|
// gBattlerAttacker is the battler that's trying to lower their stats and due to limitations of RandomUniformExcept, cannot be an argument
|
||||||
bool32 MoodyCantLowerStat(u32 stat)
|
bool32 MoodyCantLowerStat(u32 stat)
|
||||||
{
|
{
|
||||||
return stat == GET_STAT_BUFF_ID(gBattleScripting.statChanger) || CompareStat(gBattlerAttacker, stat, MIN_STAT_STAGE, CMP_EQUAL);
|
return stat == GET_STAT_BUFF_ID(gBattleScripting.statChanger) || CompareStat(gBattlerAttacker, stat, MIN_STAT_STAGE, CMP_EQUAL, GetBattlerAbility(gBattlerAttacker));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryToRevertMimicryAndFlags(void)
|
void TryToRevertMimicryAndFlags(void)
|
||||||
@ -1927,10 +1928,8 @@ static enum MoveCanceller CancellerSkyDrop(void)
|
|||||||
|
|
||||||
static enum MoveCanceller CancellerRecharge(void)
|
static enum MoveCanceller CancellerRecharge(void)
|
||||||
{
|
{
|
||||||
if (gBattleMons[gBattlerAttacker].volatiles.recharge)
|
if (gDisableStructs[gBattlerAttacker].rechargeTimer > 0)
|
||||||
{
|
{
|
||||||
gBattleMons[gBattlerAttacker].volatiles.recharge = FALSE;
|
|
||||||
gDisableStructs[gBattlerAttacker].rechargeTimer = 0;
|
|
||||||
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
|
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
|
||||||
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
|
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
|
||||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||||
@ -2403,8 +2402,7 @@ static enum MoveCanceller CancellerProtean(void)
|
|||||||
|
|
||||||
static enum MoveCanceller CancellerPsychicTerrain(void)
|
static enum MoveCanceller CancellerPsychicTerrain(void)
|
||||||
{
|
{
|
||||||
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
|
if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_PSYCHIC_TERRAIN)
|
||||||
&& IsBattlerGrounded(gBattlerTarget)
|
|
||||||
&& GetChosenMovePriority(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)) > 0
|
&& GetChosenMovePriority(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)) > 0
|
||||||
&& GetMoveTarget(gCurrentMove) != MOVE_TARGET_ALL_BATTLERS
|
&& GetMoveTarget(gCurrentMove) != MOVE_TARGET_ALL_BATTLERS
|
||||||
&& GetMoveTarget(gCurrentMove) != MOVE_TARGET_OPPONENTS_FIELD
|
&& GetMoveTarget(gCurrentMove) != MOVE_TARGET_OPPONENTS_FIELD
|
||||||
@ -2792,24 +2790,24 @@ bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility)
|
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability)
|
||||||
{
|
{
|
||||||
u16 battlerAbility = GetBattlerAbility(battler);
|
|
||||||
|
|
||||||
if (gBattleWeather & sBattleWeatherInfo[battleWeatherId].flag)
|
if (gBattleWeather & sBattleWeatherInfo[battleWeatherId].flag)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (gBattleWeather & B_WEATHER_PRIMAL_ANY
|
else if (gBattleWeather & B_WEATHER_PRIMAL_ANY
|
||||||
&& battlerAbility != ABILITY_DESOLATE_LAND
|
&& ability != ABILITY_DESOLATE_LAND
|
||||||
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
|
&& ability != ABILITY_PRIMORDIAL_SEA
|
||||||
&& battlerAbility != ABILITY_DELTA_STREAM)
|
&& ability != ABILITY_DELTA_STREAM)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (GetGenConfig(GEN_CONFIG_ABILITY_WEATHER) < GEN_6 && viaAbility)
|
else if (GetGenConfig(GEN_CONFIG_ABILITY_WEATHER) < GEN_6 && ability != ABILITY_NONE)
|
||||||
{
|
{
|
||||||
gBattleWeather = sBattleWeatherInfo[battleWeatherId].flag;
|
gBattleWeather = sBattleWeatherInfo[battleWeatherId].flag;
|
||||||
|
for (u32 i = 0; i < gBattlersCount; i++)
|
||||||
|
gDisableStructs[i].weatherAbilityDone = FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2822,25 +2820,29 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbilit
|
|||||||
gWishFutureKnock.weatherDuration = 8;
|
gWishFutureKnock.weatherDuration = 8;
|
||||||
else
|
else
|
||||||
gWishFutureKnock.weatherDuration = 5;
|
gWishFutureKnock.weatherDuration = 5;
|
||||||
|
for (u32 i = 0; i < gBattlersCount; i++)
|
||||||
|
gDisableStructs[i].weatherAbilityDone = FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u16 *timer)
|
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag)
|
||||||
{
|
{
|
||||||
if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
|
if (gBattleStruct->isSkyBattle)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(gFieldStatuses & statusFlag))
|
||||||
{
|
{
|
||||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
|
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
|
||||||
gFieldStatuses |= statusFlag;
|
gFieldStatuses |= statusFlag;
|
||||||
gDisableStructs[battler].terrainAbilityDone = FALSE;
|
for (u32 i = 0; i < gBattlersCount; i++)
|
||||||
|
gDisableStructs[i].terrainAbilityDone = FALSE;
|
||||||
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
|
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
|
||||||
*timer = gBattleTurnCounter + 8;
|
gFieldTimers.terrainTimer = gBattleTurnCounter + 8;
|
||||||
else
|
else
|
||||||
*timer = gBattleTurnCounter + 5;
|
gFieldTimers.terrainTimer = gBattleTurnCounter + 5;
|
||||||
|
|
||||||
gBattleScripting.battler = battler;
|
gBattleScripting.battler = battler;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -3210,7 +3212,7 @@ bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32
|
|||||||
break;
|
break;
|
||||||
case MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY:
|
case MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY:
|
||||||
gBattleStruct->pledgeMove = FALSE;
|
gBattleStruct->pledgeMove = FALSE;
|
||||||
if (!CompareStat(battlerDef, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (!CompareStat(battlerDef, statId, MAX_STAT_STAGE, CMP_LESS_THAN, abilityDef))
|
||||||
{
|
{
|
||||||
if ((gProtectStructs[battlerAtk].notFirstStrike))
|
if ((gProtectStructs[battlerAtk].notFirstStrike))
|
||||||
battleScript = BattleScript_MonMadeMoveUseless;
|
battleScript = BattleScript_MonMadeMoveUseless;
|
||||||
@ -3690,8 +3692,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
case ABILITY_ANTICIPATION:
|
case ABILITY_ANTICIPATION:
|
||||||
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
||||||
{
|
{
|
||||||
u32 types[3];
|
struct DamageContext ctx = {0};
|
||||||
GetBattlerTypes(battler, FALSE, types);
|
uq4_12_t modifier = UQ_4_12(1.0);
|
||||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (IsBattlerAlive(i) && !IsBattlerAlly(i, battler))
|
if (IsBattlerAlive(i) && !IsBattlerAlly(i, battler))
|
||||||
@ -3702,9 +3704,14 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
|
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
|
||||||
moveType = GetBattleMoveType(move);
|
moveType = GetBattleMoveType(move);
|
||||||
|
|
||||||
if (GetTypeModifier(moveType, types[0]) >= UQ_4_12(2.0)
|
ctx.battlerAtk = i;
|
||||||
|| (types[0] != types[1] && GetTypeModifier(moveType, types[1]) >= UQ_4_12(2.0))
|
ctx.battlerDef = battler;
|
||||||
|| (types[2] != TYPE_MYSTERY && GetTypeModifier(moveType, types[2]) >= UQ_4_12(2.0))
|
ctx.move = move;
|
||||||
|
ctx.moveType = moveType;
|
||||||
|
ctx.isAnticipation = TRUE;
|
||||||
|
modifier = CalcTypeEffectivenessMultiplier(&ctx);
|
||||||
|
|
||||||
|
if (modifier >= UQ_4_12(2.0)
|
||||||
|| moveEffect == EFFECT_OHKO
|
|| moveEffect == EFFECT_OHKO
|
||||||
|| moveEffect == EFFECT_SHEER_COLD)
|
|| moveEffect == EFFECT_SHEER_COLD)
|
||||||
{
|
{
|
||||||
@ -3768,7 +3775,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
|
|
||||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||||
|
|
||||||
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(statId, 1, FALSE);
|
SET_STATCHANGER(statId, 1, FALSE);
|
||||||
SaveBattlerAttacker(gBattlerAttacker);
|
SaveBattlerAttacker(gBattlerAttacker);
|
||||||
@ -3834,7 +3841,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_DRIZZLE:
|
case ABILITY_DRIZZLE:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
|
||||||
effect++;
|
effect++;
|
||||||
@ -3847,7 +3854,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_SAND_STREAM:
|
case ABILITY_SAND_STREAM:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
|
||||||
effect++;
|
effect++;
|
||||||
@ -3859,8 +3866,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ABILITY_ORICHALCUM_PULSE:
|
||||||
case ABILITY_DROUGHT:
|
case ABILITY_DROUGHT:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
|
||||||
effect++;
|
effect++;
|
||||||
@ -3873,12 +3881,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_SNOW_WARNING:
|
case ABILITY_SNOW_WARNING:
|
||||||
if (GetGenConfig(GEN_SNOW_WARNING) >= GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_SNOW, TRUE))
|
if (GetGenConfig(GEN_SNOW_WARNING) >= GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_SNOW, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesSnow);
|
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesSnow);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
else if (GetGenConfig(GEN_SNOW_WARNING) < GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_HAIL, TRUE))
|
else if (GetGenConfig(GEN_SNOW_WARNING) < GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_HAIL, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesHail);
|
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesHail);
|
||||||
effect++;
|
effect++;
|
||||||
@ -3892,35 +3900,35 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
break;
|
break;
|
||||||
case ABILITY_ELECTRIC_SURGE:
|
case ABILITY_ELECTRIC_SURGE:
|
||||||
case ABILITY_HADRON_ENGINE:
|
case ABILITY_HADRON_ENGINE:
|
||||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.terrainTimer))
|
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_GRASSY_SURGE:
|
case ABILITY_GRASSY_SURGE:
|
||||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
|
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_GrassySurgeActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_GrassySurgeActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_MISTY_SURGE:
|
case ABILITY_MISTY_SURGE:
|
||||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.terrainTimer))
|
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_MistySurgeActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_MistySurgeActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_PSYCHIC_SURGE:
|
case ABILITY_PSYCHIC_SURGE:
|
||||||
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.terrainTimer))
|
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_PsychicSurgeActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_PsychicSurgeActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_INTIMIDATE:
|
case ABILITY_INTIMIDATE:
|
||||||
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
if (!gSpecialStatuses[battler].switchInAbilityDone && !IsOpposingSideEmpty(battler))
|
||||||
{
|
{
|
||||||
SaveBattlerAttacker(gBattlerAttacker);
|
SaveBattlerAttacker(gBattlerAttacker);
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
@ -3932,7 +3940,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
break;
|
break;
|
||||||
case ABILITY_SUPERSWEET_SYRUP:
|
case ABILITY_SUPERSWEET_SYRUP:
|
||||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||||
&& !GetBattlerPartyState(battler)->supersweetSyrup)
|
&& !GetBattlerPartyState(battler)->supersweetSyrup
|
||||||
|
&& !IsOpposingSideEmpty(battler))
|
||||||
{
|
{
|
||||||
SaveBattlerAttacker(gBattlerAttacker);
|
SaveBattlerAttacker(gBattlerAttacker);
|
||||||
gBattlerAttacker = battler;
|
gBattlerAttacker = battler;
|
||||||
@ -3979,7 +3988,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (GetGenConfig(GEN_INTREPID_SWORD) == GEN_9)
|
if (GetGenConfig(GEN_INTREPID_SWORD) == GEN_9)
|
||||||
GetBattlerPartyState(battler)->intrepidSwordBoost = TRUE;
|
GetBattlerPartyState(battler)->intrepidSwordBoost = TRUE;
|
||||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||||
if (CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
||||||
@ -3994,7 +4003,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (GetGenConfig(GEN_DAUNTLESS_SHIELD) == GEN_9)
|
if (GetGenConfig(GEN_DAUNTLESS_SHIELD) == GEN_9)
|
||||||
GetBattlerPartyState(battler)->dauntlessShieldBoost = TRUE;
|
GetBattlerPartyState(battler)->dauntlessShieldBoost = TRUE;
|
||||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||||
if (CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_DEF, 1, FALSE);
|
SET_STATCHANGER(STAT_DEF, 1, FALSE);
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
|
||||||
@ -4004,7 +4013,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
break;
|
break;
|
||||||
case ABILITY_WIND_RIDER:
|
case ABILITY_WIND_RIDER:
|
||||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||||
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility)
|
||||||
&& gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND)
|
&& gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND)
|
||||||
{
|
{
|
||||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||||
@ -4014,21 +4023,21 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_DESOLATE_LAND:
|
case ABILITY_DESOLATE_LAND:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN_PRIMAL, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN_PRIMAL, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_DesolateLandActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_DesolateLandActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_PRIMORDIAL_SEA:
|
case ABILITY_PRIMORDIAL_SEA:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN_PRIMAL, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN_PRIMAL, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_PrimordialSeaActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_PrimordialSeaActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_DELTA_STREAM:
|
case ABILITY_DELTA_STREAM:
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_STRONG_WINDS, TRUE))
|
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_STRONG_WINDS, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_DeltaStreamActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_DeltaStreamActivates);
|
||||||
effect++;
|
effect++;
|
||||||
@ -4070,13 +4079,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_ORICHALCUM_PULSE:
|
|
||||||
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, TRUE))
|
|
||||||
{
|
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
|
|
||||||
effect++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ABILITY_SUPREME_OVERLORD:
|
case ABILITY_SUPREME_OVERLORD:
|
||||||
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
||||||
{
|
{
|
||||||
@ -4147,7 +4149,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
else //ABILITY_EMBODY_ASPECT_TEAL_MASK
|
else //ABILITY_EMBODY_ASPECT_TEAL_MASK
|
||||||
stat = STAT_SPEED;
|
stat = STAT_SPEED;
|
||||||
|
|
||||||
if (CompareStat(battler, stat, MAX_STAT_STAGE, CMP_EQUAL))
|
if (CompareStat(battler, stat, MAX_STAT_STAGE, CMP_EQUAL, gLastUsedAbility))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||||
@ -4300,7 +4302,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABILITY_SPEED_BOOST:
|
case ABILITY_SPEED_BOOST:
|
||||||
if (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN) && gDisableStructs[battler].isFirstTurn != 2)
|
if (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility) && gDisableStructs[battler].isFirstTurn != 2)
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_SPEED, 1, FALSE);
|
SET_STATCHANGER(STAT_SPEED, 1, FALSE);
|
||||||
BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates);
|
BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates);
|
||||||
@ -4316,9 +4318,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
|
|
||||||
for (i = STAT_ATK; i < statsNum; i++)
|
for (i = STAT_ATK; i < statsNum; i++)
|
||||||
{
|
{
|
||||||
if (CompareStat(battler, i, MIN_STAT_STAGE, CMP_GREATER_THAN))
|
if (CompareStat(battler, i, MIN_STAT_STAGE, CMP_GREATER_THAN, gLastUsedAbility))
|
||||||
validToLower |= 1u << i;
|
validToLower |= 1u << i;
|
||||||
if (CompareStat(battler, i, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battler, i, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
validToRaise |= 1u << i;
|
validToRaise |= 1u << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4455,7 +4457,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (IsBattlerTurnDamaged(battler)
|
if (IsBattlerTurnDamaged(battler)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& moveType == TYPE_DARK
|
&& moveType == TYPE_DARK
|
||||||
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||||
@ -4467,7 +4469,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (IsBattlerTurnDamaged(battler)
|
if (IsBattlerTurnDamaged(battler)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& (moveType == TYPE_DARK || moveType == TYPE_BUG || moveType == TYPE_GHOST)
|
&& (moveType == TYPE_DARK || moveType == TYPE_BUG || moveType == TYPE_GHOST)
|
||||||
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
SET_STATCHANGER(STAT_SPEED, 1, FALSE);
|
SET_STATCHANGER(STAT_SPEED, 1, FALSE);
|
||||||
@ -4479,7 +4481,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (IsBattlerTurnDamaged(battler)
|
if (IsBattlerTurnDamaged(battler)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& moveType == TYPE_WATER
|
&& moveType == TYPE_WATER
|
||||||
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
SET_STATCHANGER(STAT_DEF, 2, FALSE);
|
SET_STATCHANGER(STAT_DEF, 2, FALSE);
|
||||||
@ -4491,7 +4493,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (gBattlerAttacker != gBattlerTarget
|
if (gBattlerAttacker != gBattlerTarget
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
SET_STATCHANGER(STAT_DEF, 1, FALSE);
|
SET_STATCHANGER(STAT_DEF, 1, FALSE);
|
||||||
@ -4505,7 +4507,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
&& HadMoreThanHalfHpNowDoesnt(battler)
|
&& HadMoreThanHalfHpNowDoesnt(battler)
|
||||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
|
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
|
||||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||||
&& CompareStat(battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
|
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
|
||||||
@ -4517,8 +4519,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (IsBattlerTurnDamaged(battler)
|
if (IsBattlerTurnDamaged(battler)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& IsBattleMovePhysical(gCurrentMove)
|
&& IsBattleMovePhysical(gCurrentMove)
|
||||||
&& (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN) // Don't activate if both Speed and Defense cannot be raised.
|
&& (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility) // Don't activate if both Speed and Defense cannot be raised.
|
||||||
|| CompareStat(battler, STAT_DEF, MIN_STAT_STAGE, CMP_GREATER_THAN)))
|
|| CompareStat(battler, STAT_DEF, MIN_STAT_STAGE, CMP_GREATER_THAN, gLastUsedAbility)))
|
||||||
{
|
{
|
||||||
if (GetMoveEffect(gCurrentMove) == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker))
|
if (GetMoveEffect(gCurrentMove) == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker))
|
||||||
gProtectStructs[battler].disableEjectPack = TRUE; // Set flag for target
|
gProtectStructs[battler].disableEjectPack = TRUE; // Set flag for target
|
||||||
@ -4532,8 +4534,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
&& gDisableStructs[gBattlerAttacker].disabledMove == MOVE_NONE
|
&& gDisableStructs[gBattlerAttacker].disabledMove == MOVE_NONE
|
||||||
&& IsBattlerAlive(gBattlerAttacker)
|
&& IsBattlerAlive(gBattlerAttacker)
|
||||||
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
|
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
|
||||||
&& gBattleMons[gBattlerAttacker].pp[gChosenMovePos] != 0
|
&& gChosenMove != MOVE_STRUGGLE
|
||||||
&& !(GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX) // TODO: Max Moves don't make contact, useless?
|
|
||||||
&& RandomPercentage(RNG_CURSED_BODY, 30))
|
&& RandomPercentage(RNG_CURSED_BODY, 30))
|
||||||
{
|
{
|
||||||
gDisableStructs[gBattlerAttacker].disabledMove = gChosenMove;
|
gDisableStructs[gBattlerAttacker].disabledMove = gChosenMove;
|
||||||
@ -4596,7 +4597,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (gSpecialStatuses[battler].criticalHit
|
if (gSpecialStatuses[battler].criticalHit
|
||||||
&& IsBattlerTurnDamaged(battler)
|
&& IsBattlerTurnDamaged(battler)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
SET_STATCHANGER(STAT_ATK, MAX_STAT_STAGE - gBattleMons[battler].statStages[STAT_ATK], FALSE);
|
SET_STATCHANGER(STAT_ATK, MAX_STAT_STAGE - gBattleMons[battler].statStages[STAT_ATK], FALSE);
|
||||||
BattleScriptCall(BattleScript_TargetsStatWasMaxedOut);
|
BattleScriptCall(BattleScript_TargetsStatWasMaxedOut);
|
||||||
@ -4621,7 +4622,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
case ABILITY_GOOEY:
|
case ABILITY_GOOEY:
|
||||||
case ABILITY_TANGLING_HAIR:
|
case ABILITY_TANGLING_HAIR:
|
||||||
if (IsBattlerAlive(gBattlerAttacker)
|
if (IsBattlerAlive(gBattlerAttacker)
|
||||||
&& (CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN) || GetBattlerAbility(gBattlerAttacker) == ABILITY_MIRROR_ARMOR)
|
&& (CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN, gLastUsedAbility) || GetBattlerAbility(gBattlerAttacker) == ABILITY_MIRROR_ARMOR)
|
||||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move))
|
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move))
|
||||||
@ -4829,7 +4830,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
case ABILITY_STEAM_ENGINE:
|
case ABILITY_STEAM_ENGINE:
|
||||||
if (IsBattlerTurnDamaged(gBattlerTarget)
|
if (IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(battler)
|
&& IsBattlerAlive(battler)
|
||||||
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility)
|
||||||
&& (moveType == TYPE_FIRE || moveType == TYPE_WATER))
|
&& (moveType == TYPE_FIRE || moveType == TYPE_WATER))
|
||||||
{
|
{
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
@ -4848,7 +4849,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
BattleScriptCall(BattleScript_BlockedByPrimalWeatherRet);
|
BattleScriptCall(BattleScript_BlockedByPrimalWeatherRet);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
else if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, TRUE))
|
else if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, gLastUsedAbility))
|
||||||
{
|
{
|
||||||
gBattleScripting.battler = battler;
|
gBattleScripting.battler = battler;
|
||||||
BattleScriptCall(BattleScript_SandSpitActivates);
|
BattleScriptCall(BattleScript_SandSpitActivates);
|
||||||
@ -4906,7 +4907,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
if (!gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
if (!gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(gBattlerTarget)
|
&& IsBattlerAlive(gBattlerTarget)
|
||||||
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
|
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN))
|
||||||
{
|
{
|
||||||
BattleScriptCall(BattleScript_SeedSowerActivates);
|
BattleScriptCall(BattleScript_SeedSowerActivates);
|
||||||
effect++;
|
effect++;
|
||||||
@ -4915,7 +4916,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
case ABILITY_THERMAL_EXCHANGE:
|
case ABILITY_THERMAL_EXCHANGE:
|
||||||
if (IsBattlerTurnDamaged(gBattlerTarget)
|
if (IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& IsBattlerAlive(gBattlerTarget)
|
&& IsBattlerAlive(gBattlerTarget)
|
||||||
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN, gLastUsedAbility)
|
||||||
&& moveType == TYPE_FIRE)
|
&& moveType == TYPE_FIRE)
|
||||||
{
|
{
|
||||||
gEffectBattler = gBattlerTarget;
|
gEffectBattler = gBattlerTarget;
|
||||||
@ -4956,7 +4957,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||||
&& (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2))
|
&& (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2))
|
||||||
{
|
{
|
||||||
SWAP(gBattlerAttacker, gBattlerTarget, i);
|
SaveBattlerTarget(gBattlerTarget);
|
||||||
|
SaveBattlerAttacker(gBattlerAttacker);
|
||||||
|
gBattlerAttacker = gBattlerTarget;
|
||||||
|
gBattlerTarget = BATTLE_OPPOSITE(gBattlerAttacker);
|
||||||
BattleScriptCall(BattleScript_ToxicDebrisActivates);
|
BattleScriptCall(BattleScript_ToxicDebrisActivates);
|
||||||
effect++;
|
effect++;
|
||||||
}
|
}
|
||||||
@ -5522,7 +5526,6 @@ bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 ability
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check order of battlerAtk and battlerDef
|
|
||||||
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||||
{
|
{
|
||||||
if (CanSetNonVolatileStatus(
|
if (CanSetNonVolatileStatus(
|
||||||
@ -5709,7 +5712,6 @@ bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u
|
|||||||
|
|
||||||
// Checks that apply to all non volatile statuses
|
// Checks that apply to all non volatile statuses
|
||||||
if (abilityDef == ABILITY_COMATOSE
|
if (abilityDef == ABILITY_COMATOSE
|
||||||
|| abilityDef == ABILITY_SHIELDS_DOWN
|
|
||||||
|| abilityDef == ABILITY_PURIFYING_SALT)
|
|| abilityDef == ABILITY_PURIFYING_SALT)
|
||||||
{
|
{
|
||||||
abilityAffected = TRUE;
|
abilityAffected = TRUE;
|
||||||
@ -5724,6 +5726,11 @@ bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u
|
|||||||
abilityAffected = TRUE;
|
abilityAffected = TRUE;
|
||||||
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
||||||
}
|
}
|
||||||
|
else if (IsShieldsDownProtected(battlerDef, abilityDef))
|
||||||
|
{
|
||||||
|
abilityAffected = TRUE;
|
||||||
|
battleScript = BattleScript_AbilityProtectsDoesntAffect;
|
||||||
|
}
|
||||||
else if ((sideBattler = IsFlowerVeilProtected(battlerDef)))
|
else if ((sideBattler = IsFlowerVeilProtected(battlerDef)))
|
||||||
{
|
{
|
||||||
abilityAffected = TRUE;
|
abilityAffected = TRUE;
|
||||||
@ -5862,11 +5869,12 @@ static enum ItemEffect HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, e
|
|||||||
|
|
||||||
static enum ItemEffect StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemCaseId caseID)
|
static enum ItemEffect StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemCaseId caseID)
|
||||||
{
|
{
|
||||||
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
|
u32 ability = GetBattlerAbility(battler);
|
||||||
|
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN, ability) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
|
||||||
{
|
{
|
||||||
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
||||||
gEffectBattler = gBattleScripting.battler = battler;
|
gEffectBattler = gBattleScripting.battler = battler;
|
||||||
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
|
if (ability == ABILITY_RIPEN)
|
||||||
SET_STATCHANGER(statId, 2, FALSE);
|
SET_STATCHANGER(statId, 2, FALSE);
|
||||||
else
|
else
|
||||||
SET_STATCHANGER(statId, 1, FALSE);
|
SET_STATCHANGER(statId, 1, FALSE);
|
||||||
@ -5887,15 +5895,15 @@ static enum ItemEffect RandomStatRaiseBerry(u32 battler, u32 itemId, enum ItemCa
|
|||||||
{
|
{
|
||||||
s32 stat;
|
s32 stat;
|
||||||
enum StringID stringId;
|
enum StringID stringId;
|
||||||
|
u32 battlerAbility = GetBattlerAbility(battler);
|
||||||
|
|
||||||
for (stat = STAT_ATK; stat < NUM_STATS; stat++)
|
for (stat = STAT_ATK; stat < NUM_STATS; stat++)
|
||||||
{
|
{
|
||||||
if (CompareStat(battler, stat, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (CompareStat(battler, stat, MAX_STAT_STAGE, CMP_LESS_THAN, battlerAbility))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (stat != NUM_STATS && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
|
if (stat != NUM_STATS && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
|
||||||
{
|
{
|
||||||
u16 battlerAbility = GetBattlerAbility(battler);
|
|
||||||
u32 savedAttacker = gBattlerAttacker;
|
u32 savedAttacker = gBattlerAttacker;
|
||||||
// MoodyCantRaiseStat requires that the battler is set to gBattlerAttacker
|
// MoodyCantRaiseStat requires that the battler is set to gBattlerAttacker
|
||||||
gBattlerAttacker = gBattleScripting.battler = battler;
|
gBattlerAttacker = gBattleScripting.battler = battler;
|
||||||
@ -5968,8 +5976,9 @@ static enum ItemEffect TrySetEnigmaBerry(u32 battler)
|
|||||||
|
|
||||||
static enum ItemEffect DamagedStatBoostBerryEffect(u32 battler, u8 statId, enum DamageCategory category)
|
static enum ItemEffect DamagedStatBoostBerryEffect(u32 battler, u8 statId, enum DamageCategory category)
|
||||||
{
|
{
|
||||||
|
u32 ability = GetBattlerAbility(battler);
|
||||||
if (IsBattlerAlive(battler)
|
if (IsBattlerAlive(battler)
|
||||||
&& CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN, ability)
|
||||||
&& (gBattleScripting.overrideBerryRequirements
|
&& (gBattleScripting.overrideBerryRequirements
|
||||||
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
||||||
&& GetBattleMoveCategory(gCurrentMove) == category
|
&& GetBattleMoveCategory(gCurrentMove) == category
|
||||||
@ -5980,7 +5989,7 @@ static enum ItemEffect DamagedStatBoostBerryEffect(u32 battler, u8 statId, enum
|
|||||||
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
||||||
|
|
||||||
gEffectBattler = battler;
|
gEffectBattler = battler;
|
||||||
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
|
if (ability == ABILITY_RIPEN)
|
||||||
SET_STATCHANGER(statId, 2, FALSE);
|
SET_STATCHANGER(statId, 2, FALSE);
|
||||||
else
|
else
|
||||||
SET_STATCHANGER(statId, 1, FALSE);
|
SET_STATCHANGER(statId, 1, FALSE);
|
||||||
@ -5996,7 +6005,7 @@ static enum ItemEffect DamagedStatBoostBerryEffect(u32 battler, u8 statId, enum
|
|||||||
|
|
||||||
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID)
|
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID)
|
||||||
{
|
{
|
||||||
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
|
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(battler)))
|
||||||
{
|
{
|
||||||
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
||||||
gLastUsedItem = itemId; // For surge abilities
|
gLastUsedItem = itemId; // For surge abilities
|
||||||
@ -6953,7 +6962,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler)
|
|||||||
case HOLD_EFFECT_BLUNDER_POLICY:
|
case HOLD_EFFECT_BLUNDER_POLICY:
|
||||||
if (gBattleStruct->blunderPolicy
|
if (gBattleStruct->blunderPolicy
|
||||||
&& IsBattlerAlive(gBattlerAttacker)
|
&& IsBattlerAlive(gBattlerAttacker)
|
||||||
&& CompareStat(gBattlerAttacker, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
|
&& CompareStat(gBattlerAttacker, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerAttacker)))
|
||||||
{
|
{
|
||||||
gBattleStruct->blunderPolicy = FALSE;
|
gBattleStruct->blunderPolicy = FALSE;
|
||||||
gLastUsedItem = atkItem;
|
gLastUsedItem = atkItem;
|
||||||
@ -7640,13 +7649,13 @@ enum IronBallCheck
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Only called directly when calculating damage type effectiveness, and Iron Ball's type effectiveness mechanics
|
// Only called directly when calculating damage type effectiveness, and Iron Ball's type effectiveness mechanics
|
||||||
static bool32 IsBattlerGroundedInverseCheck(u32 battler, u32 ability, enum InverseBattleCheck checkInverse, enum IronBallCheck checkIronBall)
|
static bool32 IsBattlerGroundedInverseCheck(u32 battler, u32 ability, enum InverseBattleCheck checkInverse, enum IronBallCheck checkIronBall, bool32 isAnticipation)
|
||||||
{
|
{
|
||||||
enum ItemHoldEffect holdEffect = GetBattlerHoldEffect(battler, TRUE);
|
enum ItemHoldEffect holdEffect = GetBattlerHoldEffect(battler, TRUE);
|
||||||
|
|
||||||
if (!(checkIronBall == IGNORE_IRON_BALL) && holdEffect == HOLD_EFFECT_IRON_BALL)
|
if (!(checkIronBall == IGNORE_IRON_BALL) && holdEffect == HOLD_EFFECT_IRON_BALL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
|
if (gFieldStatuses & STATUS_FIELD_GRAVITY && isAnticipation == FALSE)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (B_ROOTED_GROUNDING >= GEN_4 && gBattleMons[battler].volatiles.root)
|
if (B_ROOTED_GROUNDING >= GEN_4 && gBattleMons[battler].volatiles.root)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -7667,7 +7676,7 @@ static bool32 IsBattlerGroundedInverseCheck(u32 battler, u32 ability, enum Inver
|
|||||||
|
|
||||||
bool32 IsBattlerGrounded(u32 battler)
|
bool32 IsBattlerGrounded(u32 battler)
|
||||||
{
|
{
|
||||||
return IsBattlerGroundedInverseCheck(battler, GetBattlerAbility(battler), NOT_INVERSE_BATTLE, CHECK_IRON_BALL);
|
return IsBattlerGroundedInverseCheck(battler, GetBattlerAbility(battler), NOT_INVERSE_BATTLE, CHECK_IRON_BALL, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetMoveSlot(u16 *moves, u32 move)
|
u32 GetMoveSlot(u16 *moves, u32 move)
|
||||||
@ -8067,10 +8076,10 @@ static inline u32 CalcMoveBasePower(struct DamageContext *ctx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EFFECT_ECHOED_VOICE:
|
case EFFECT_ECHOED_VOICE:
|
||||||
// gBattleStruct->sameMoveTurns incremented in ppreduce
|
// gBattleStruct->echoedVoiceCounter incremented in EndTurnVarious called by DoEndTurnEffects
|
||||||
if (gBattleStruct->sameMoveTurns[battlerAtk] != 0 && GetMoveEffect(gLastResultingMoves[battlerAtk]) == EFFECT_ECHOED_VOICE)
|
if (gBattleStruct->echoedVoiceCounter != 0)
|
||||||
{
|
{
|
||||||
basePower += (basePower * gBattleStruct->sameMoveTurns[battlerAtk]);
|
basePower += (basePower * gBattleStruct->echoedVoiceCounter);
|
||||||
if (basePower > 200)
|
if (basePower > 200)
|
||||||
basePower = 200;
|
basePower = 200;
|
||||||
}
|
}
|
||||||
@ -8759,9 +8768,9 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
|||||||
|
|
||||||
// The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
|
// The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
|
||||||
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battlerAtk) && IsBattleMovePhysical(move))
|
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battlerAtk) && IsBattleMovePhysical(move))
|
||||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
|
modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
|
||||||
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battlerAtk) && IsBattleMoveSpecial(move))
|
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battlerAtk) && IsBattleMoveSpecial(move))
|
||||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
|
modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
|
||||||
|
|
||||||
return uq4_12_multiply_by_int_half_down(modifier, atkStat);
|
return uq4_12_multiply_by_int_half_down(modifier, atkStat);
|
||||||
}
|
}
|
||||||
@ -8935,11 +8944,11 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
|
|||||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SNOW) && usesDefStat)
|
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SNOW) && usesDefStat)
|
||||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||||
|
|
||||||
// The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
|
// The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges)
|
||||||
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battlerDef) && IsBattleMovePhysical(move))
|
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battlerDef) && IsBattleMovePhysical(move))
|
||||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
|
modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
|
||||||
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battlerDef) && IsBattleMoveSpecial(move))
|
if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battlerDef) && IsBattleMoveSpecial(move))
|
||||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
|
modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier());
|
||||||
|
|
||||||
return uq4_12_multiply_by_int_half_down(modifier, defStat);
|
return uq4_12_multiply_by_int_half_down(modifier, defStat);
|
||||||
}
|
}
|
||||||
@ -9200,7 +9209,7 @@ static inline uq4_12_t GetAttackerItemsModifier(u32 battlerAtk, uq4_12_t typeEff
|
|||||||
{
|
{
|
||||||
case HOLD_EFFECT_METRONOME:
|
case HOLD_EFFECT_METRONOME:
|
||||||
metronomeBoostBase = PercentToUQ4_12(GetBattlerHoldEffectParam(battlerAtk));
|
metronomeBoostBase = PercentToUQ4_12(GetBattlerHoldEffectParam(battlerAtk));
|
||||||
metronomeTurns = min(gBattleStruct->sameMoveTurns[battlerAtk], 5);
|
metronomeTurns = min(gBattleStruct->metronomeItemCounter[battlerAtk], 5);
|
||||||
// according to bulbapedia this is the "correct" way to calculate the metronome boost
|
// according to bulbapedia this is the "correct" way to calculate the metronome boost
|
||||||
// due to the limited domain of damage numbers it will never really matter whether this is off by one
|
// due to the limited domain of damage numbers it will never really matter whether this is off by one
|
||||||
return uq4_12_add(UQ_4_12(1.0), metronomeBoostBase * metronomeTurns);
|
return uq4_12_add(UQ_4_12(1.0), metronomeBoostBase * metronomeTurns);
|
||||||
@ -9523,7 +9532,7 @@ static inline void MulByTypeEffectiveness(struct DamageContext *ctx, uq4_12_t *m
|
|||||||
|
|
||||||
if (ctx->moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gBattleMons[ctx->battlerDef].volatiles.miracleEye && mod == UQ_4_12(0.0))
|
if (ctx->moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gBattleMons[ctx->battlerDef].volatiles.miracleEye && mod == UQ_4_12(0.0))
|
||||||
mod = UQ_4_12(1.0);
|
mod = UQ_4_12(1.0);
|
||||||
if (GetMoveEffect(ctx->move) == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == GetMoveArgType(ctx->move))
|
if (GetMoveEffect(ctx->move) == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == GetMoveArgType(ctx->move) && !ctx->isAnticipation)
|
||||||
mod = UQ_4_12(2.0);
|
mod = UQ_4_12(2.0);
|
||||||
if (ctx->moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(ctx->battlerDef) && mod == UQ_4_12(0.0))
|
if (ctx->moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(ctx->battlerDef) && mod == UQ_4_12(0.0))
|
||||||
mod = UQ_4_12(1.0);
|
mod = UQ_4_12(1.0);
|
||||||
@ -9531,7 +9540,7 @@ static inline void MulByTypeEffectiveness(struct DamageContext *ctx, uq4_12_t *m
|
|||||||
mod = UQ_4_12(2.0);
|
mod = UQ_4_12(2.0);
|
||||||
|
|
||||||
// B_WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
|
// B_WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
|
||||||
if (gBattleWeather & B_WEATHER_STRONG_WINDS && HasWeatherEffect())
|
if (gBattleWeather & B_WEATHER_STRONG_WINDS && HasWeatherEffect() && !ctx->isAnticipation)
|
||||||
{
|
{
|
||||||
if (defType == TYPE_FLYING && mod >= UQ_4_12(2.0))
|
if (defType == TYPE_FLYING && mod >= UQ_4_12(2.0))
|
||||||
mod = UQ_4_12(1.0);
|
mod = UQ_4_12(1.0);
|
||||||
@ -9622,7 +9631,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(struct DamageCont
|
|||||||
if (B_GLARE_GHOST < GEN_4 && ctx->move == MOVE_GLARE && IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_GHOST))
|
if (B_GLARE_GHOST < GEN_4 && ctx->move == MOVE_GLARE && IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_GHOST))
|
||||||
modifier = UQ_4_12(0.0);
|
modifier = UQ_4_12(0.0);
|
||||||
}
|
}
|
||||||
else if (ctx->moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(ctx->battlerDef, ctx->abilityDef, INVERSE_BATTLE, CHECK_IRON_BALL) && !(MoveIgnoresTypeIfFlyingAndUngrounded(ctx->move)))
|
else if (ctx->moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(ctx->battlerDef, ctx->abilityDef, INVERSE_BATTLE, CHECK_IRON_BALL, ctx->isAnticipation) && !(MoveIgnoresTypeIfFlyingAndUngrounded(ctx->move)))
|
||||||
{
|
{
|
||||||
modifier = UQ_4_12(0.0);
|
modifier = UQ_4_12(0.0);
|
||||||
if (ctx->updateFlags && ctx->abilityDef == ABILITY_LEVITATE)
|
if (ctx->updateFlags && ctx->abilityDef == ABILITY_LEVITATE)
|
||||||
@ -9652,7 +9661,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(struct DamageCont
|
|||||||
&& ctx->moveType == TYPE_GROUND
|
&& ctx->moveType == TYPE_GROUND
|
||||||
&& IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_FLYING)
|
&& IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_FLYING)
|
||||||
&& GetBattlerHoldEffect(ctx->battlerDef, TRUE) == HOLD_EFFECT_IRON_BALL
|
&& GetBattlerHoldEffect(ctx->battlerDef, TRUE) == HOLD_EFFECT_IRON_BALL
|
||||||
&& !IsBattlerGroundedInverseCheck(ctx->battlerDef, ctx->abilityDef, NOT_INVERSE_BATTLE, IGNORE_IRON_BALL)
|
&& !IsBattlerGroundedInverseCheck(ctx->battlerDef, ctx->abilityDef, NOT_INVERSE_BATTLE, IGNORE_IRON_BALL, FALSE)
|
||||||
&& !FlagGet(B_FLAG_INVERSE_BATTLE))
|
&& !FlagGet(B_FLAG_INVERSE_BATTLE))
|
||||||
{
|
{
|
||||||
modifier = UQ_4_12(1.0);
|
modifier = UQ_4_12(1.0);
|
||||||
@ -9686,7 +9695,7 @@ uq4_12_t CalcTypeEffectivenessMultiplier(struct DamageContext *ctx)
|
|||||||
if (ctx->move != MOVE_STRUGGLE && ctx->moveType != TYPE_MYSTERY)
|
if (ctx->move != MOVE_STRUGGLE && ctx->moveType != TYPE_MYSTERY)
|
||||||
{
|
{
|
||||||
modifier = CalcTypeEffectivenessMultiplierInternal(ctx, modifier);
|
modifier = CalcTypeEffectivenessMultiplierInternal(ctx, modifier);
|
||||||
if (GetMoveEffect(ctx->move) == EFFECT_TWO_TYPED_MOVE)
|
if (GetMoveEffect(ctx->move) == EFFECT_TWO_TYPED_MOVE && !ctx->isAnticipation)
|
||||||
{
|
{
|
||||||
ctx->moveType = GetMoveArgType(ctx->move);
|
ctx->moveType = GetMoveArgType(ctx->move);
|
||||||
modifier = CalcTypeEffectivenessMultiplierInternal(ctx, modifier);
|
modifier = CalcTypeEffectivenessMultiplierInternal(ctx, modifier);
|
||||||
@ -10096,17 +10105,46 @@ bool32 CanBattlerFormChange(u32 battler, enum FormChanges method)
|
|||||||
if (gBattleMons[battler].volatiles.transformed
|
if (gBattleMons[battler].volatiles.transformed
|
||||||
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
|
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
// Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle.
|
|
||||||
if ((IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler)) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
|
switch (method)
|
||||||
return TRUE;
|
{
|
||||||
else if (IsBattlerPrimalReverted(battler) && (method == FORM_CHANGE_END_BATTLE))
|
case FORM_CHANGE_END_BATTLE:
|
||||||
return TRUE;
|
if (IsBattlerPrimalReverted(battler))
|
||||||
// Gigantamaxed Pokemon should revert upon fainting, switching, or ending the battle.
|
return TRUE;
|
||||||
else if (IsGigantamaxed(battler) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
|
// Fallthrough
|
||||||
return TRUE;
|
case FORM_CHANGE_FAINT:
|
||||||
|
if (IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler) || IsGigantamaxed(battler))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case FORM_CHANGE_BATTLE_SWITCH:
|
||||||
|
if (IsGigantamaxed(battler))
|
||||||
|
return TRUE;
|
||||||
|
else if (GetActiveGimmick(battler) == GIMMICK_TERA && GetBattlerAbility(battler) == ABILITY_HUNGER_SWITCH)
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battler].species, method);
|
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battler].species, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 TryRevertPartyMonFormChange(u32 partyIndex)
|
||||||
|
{
|
||||||
|
bool32 changedForm = FALSE;
|
||||||
|
|
||||||
|
// Appeared in battle and didn't faint
|
||||||
|
if ((gBattleStruct->appearedInBattle & (1u << partyIndex)) && GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL) != 0)
|
||||||
|
changedForm = TryFormChange(partyIndex, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE_ENVIRONMENT);
|
||||||
|
|
||||||
|
if (!changedForm)
|
||||||
|
changedForm = TryFormChange(partyIndex, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE);
|
||||||
|
|
||||||
|
// Clear original species field
|
||||||
|
gBattleStruct->partyState[B_SIDE_PLAYER][partyIndex].changedSpecies = SPECIES_NONE;
|
||||||
|
|
||||||
|
return changedForm;
|
||||||
|
}
|
||||||
|
|
||||||
bool32 TryBattleFormChange(u32 battler, enum FormChanges method)
|
bool32 TryBattleFormChange(u32 battler, enum FormChanges method)
|
||||||
{
|
{
|
||||||
u32 monId = gBattlerPartyIndexes[battler];
|
u32 monId = gBattlerPartyIndexes[battler];
|
||||||
@ -10120,7 +10158,7 @@ bool32 TryBattleFormChange(u32 battler, enum FormChanges method)
|
|||||||
targetSpecies = GetBattleFormChangeTargetSpecies(battler, method);
|
targetSpecies = GetBattleFormChangeTargetSpecies(battler, method);
|
||||||
if (targetSpecies == currentSpecies)
|
if (targetSpecies == currentSpecies)
|
||||||
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
|
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
|
||||||
if (targetSpecies != currentSpecies)
|
if (targetSpecies != currentSpecies && targetSpecies != SPECIES_NONE)
|
||||||
{
|
{
|
||||||
// Saves the original species on the first form change.
|
// Saves the original species on the first form change.
|
||||||
|
|
||||||
@ -10137,17 +10175,22 @@ bool32 TryBattleFormChange(u32 battler, enum FormChanges method)
|
|||||||
{
|
{
|
||||||
bool32 restoreSpecies = FALSE;
|
bool32 restoreSpecies = FALSE;
|
||||||
|
|
||||||
// Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle, so no need to add it to the form change tables.
|
switch (method)
|
||||||
if ((IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler)) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
|
{
|
||||||
restoreSpecies = TRUE;
|
case FORM_CHANGE_END_BATTLE:
|
||||||
|
|
||||||
// Unlike Megas, Primal Reversion isn't canceled on fainting.
|
|
||||||
else if (IsBattlerPrimalReverted(battler) && (method == FORM_CHANGE_END_BATTLE))
|
|
||||||
restoreSpecies = TRUE;
|
|
||||||
|
|
||||||
// Gigantamax Pokemon have their forms reverted after fainting, switching, or ending the battle.
|
|
||||||
else if (IsGigantamaxed(battler) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
|
|
||||||
restoreSpecies = TRUE;
|
restoreSpecies = TRUE;
|
||||||
|
break;
|
||||||
|
case FORM_CHANGE_FAINT:
|
||||||
|
if (IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler) || IsGigantamaxed(battler))
|
||||||
|
restoreSpecies = TRUE;
|
||||||
|
break;
|
||||||
|
case FORM_CHANGE_BATTLE_SWITCH:
|
||||||
|
if (IsGigantamaxed(battler))
|
||||||
|
restoreSpecies = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (restoreSpecies)
|
if (restoreSpecies)
|
||||||
{
|
{
|
||||||
@ -10425,9 +10468,17 @@ u32 TryImmunityAbilityHealStatus(u32 battler, u32 caseID)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uq4_12_t GetBadgeBoostModifier(void)
|
||||||
|
{
|
||||||
|
if (GetGenConfig(GEN_CONFIG_BADGE_BOOST) < GEN_3)
|
||||||
|
return UQ_4_12(1.125);
|
||||||
|
else
|
||||||
|
return UQ_4_12(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, u32 battler)
|
bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, u32 battler)
|
||||||
{
|
{
|
||||||
if (B_BADGE_BOOST == GEN_3 && badgeFlag != 0)
|
if (GetGenConfig(GEN_CONFIG_BADGE_BOOST) <= GEN_3 && badgeFlag != 0)
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
|
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_FRONTIER))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -10729,15 +10780,15 @@ bool32 TestIfSheerForceAffected(u32 battler, u16 move)
|
|||||||
return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
|
return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is the body of "jumpifstat", but can be used dynamically in a function
|
// This function is the body of "jumpifstat", but can be used dynamically in a function. It considers Contrary.
|
||||||
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind)
|
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind, u32 ability)
|
||||||
{
|
{
|
||||||
bool32 ret = FALSE;
|
bool32 ret = FALSE;
|
||||||
u8 statValue = gBattleMons[battler].statStages[statId];
|
u8 statValue = gBattleMons[battler].statStages[statId];
|
||||||
|
|
||||||
// Because this command is used as a way of checking if a stat can be lowered/raised,
|
// Because this command is used as a way of checking if a stat can be lowered/raised,
|
||||||
// we need to do some modification at run-time.
|
// we need to do some modification at run-time.
|
||||||
if (GetBattlerAbility(battler) == ABILITY_CONTRARY)
|
if (ability == ABILITY_CONTRARY)
|
||||||
{
|
{
|
||||||
if (cmpKind == CMP_GREATER_THAN)
|
if (cmpKind == CMP_GREATER_THAN)
|
||||||
cmpKind = CMP_LESS_THAN;
|
cmpKind = CMP_LESS_THAN;
|
||||||
@ -10808,7 +10859,7 @@ void BufferStatChange(u32 battler, u8 statId, enum StringID stringId)
|
|||||||
|
|
||||||
bool32 TryRoomService(u32 battler)
|
bool32 TryRoomService(u32 battler)
|
||||||
{
|
{
|
||||||
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && CompareStat(battler, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN))
|
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && CompareStat(battler, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN, GetBattlerAbility(battler)))
|
||||||
{
|
{
|
||||||
BufferStatChange(battler, STAT_SPEED, STRINGID_STATFELL);
|
BufferStatChange(battler, STAT_SPEED, STRINGID_STATFELL);
|
||||||
gEffectBattler = gBattleScripting.battler = battler;
|
gEffectBattler = gBattleScripting.battler = battler;
|
||||||
@ -10866,7 +10917,6 @@ bool32 PickupHasValidTarget(u32 battler)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Pass down weather as an arg
|
|
||||||
bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags)
|
bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags)
|
||||||
{
|
{
|
||||||
if (gBattleWeather & weatherFlags && HasWeatherEffect())
|
if (gBattleWeather & weatherFlags && HasWeatherEffect())
|
||||||
@ -11240,6 +11290,8 @@ void SetShellSideArmCategory(void)
|
|||||||
statStage = gBattleMons[battlerDef].statStages[STAT_DEF];
|
statStage = gBattleMons[battlerDef].statStages[STAT_DEF];
|
||||||
targetDefStat *= gStatStageRatios[statStage][0];
|
targetDefStat *= gStatStageRatios[statStage][0];
|
||||||
targetDefStat /= gStatStageRatios[statStage][1];
|
targetDefStat /= gStatStageRatios[statStage][1];
|
||||||
|
if (targetDefStat == 0)
|
||||||
|
targetDefStat = 1;
|
||||||
|
|
||||||
physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerAtkStat) / targetDefStat) / 50);
|
physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerAtkStat) / targetDefStat) / 50);
|
||||||
|
|
||||||
@ -11247,6 +11299,8 @@ void SetShellSideArmCategory(void)
|
|||||||
statStage = gBattleMons[battlerDef].statStages[STAT_SPDEF];
|
statStage = gBattleMons[battlerDef].statStages[STAT_SPDEF];
|
||||||
targetSpDefStat *= gStatStageRatios[statStage][0];
|
targetSpDefStat *= gStatStageRatios[statStage][0];
|
||||||
targetSpDefStat /= gStatStageRatios[statStage][1];
|
targetSpDefStat /= gStatStageRatios[statStage][1];
|
||||||
|
if (targetSpDefStat == 0)
|
||||||
|
targetSpDefStat = 1;
|
||||||
|
|
||||||
special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerSpAtkStat) / targetSpDefStat) / 50);
|
special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerSpAtkStat) / targetSpDefStat) / 50);
|
||||||
|
|
||||||
@ -11887,3 +11941,27 @@ bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 HasPartnerTrainer(u32 battler)
|
||||||
|
{
|
||||||
|
if ((GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_PLAYER_HAS_PARTNER)
|
||||||
|
|| (GetBattlerSide(battler) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 IsOpposingSideEmpty(u32 battler)
|
||||||
|
{
|
||||||
|
u32 oppositeBattler = BATTLE_OPPOSITE(battler);
|
||||||
|
|
||||||
|
if (IsBattlerAlive(oppositeBattler))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!IsDoubleBattle())
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (IsBattlerAlive(BATTLE_PARTNER(oppositeBattler)))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|||||||
@ -2432,6 +2432,7 @@ static void CalculatePokeblock(struct BlenderBerry *berries, struct Pokeblock *p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Factor in max RPM and round
|
// Factor in max RPM and round
|
||||||
|
multiuseVar = maxRPM / 333 + 100;
|
||||||
for (i = 0; i < FLAVOR_COUNT; i++)
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
||||||
{
|
{
|
||||||
s32 remainder;
|
s32 remainder;
|
||||||
|
|||||||
@ -9110,7 +9110,7 @@ const struct Item gItemsInfo[] =
|
|||||||
"携带后,可以治愈\n"
|
"携带后,可以治愈\n"
|
||||||
"混乱。"),
|
"混乱。"),
|
||||||
.pocket = POCKET_BERRIES,
|
.pocket = POCKET_BERRIES,
|
||||||
.type = ITEM_USE_BAG_MENU,
|
.type = ITEM_USE_PARTY_MENU,
|
||||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||||
.effect = gItemEffect_PersimBerry,
|
.effect = gItemEffect_PersimBerry,
|
||||||
|
|||||||
@ -8964,7 +8964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
|||||||
.description = COMPOUND_STRING(
|
.description = COMPOUND_STRING(
|
||||||
"让电流覆盖全身猛撞。自己也\n"
|
"让电流覆盖全身猛撞。自己也\n"
|
||||||
"会受伤。有时会让对手麻痹。"),
|
"会受伤。有时会让对手麻痹。"),
|
||||||
.effect = EFFECT_HIT,
|
.effect = EFFECT_RECOIL,
|
||||||
.power = 120,
|
.power = 120,
|
||||||
.type = TYPE_ELECTRIC,
|
.type = TYPE_ELECTRIC,
|
||||||
.accuracy = 100,
|
.accuracy = 100,
|
||||||
@ -16964,6 +16964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
|||||||
.target = MOVE_TARGET_SELECTED,
|
.target = MOVE_TARGET_SELECTED,
|
||||||
.priority = 0,
|
.priority = 0,
|
||||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||||
|
.argument = { .damagePercentage = 50 },
|
||||||
.metronomeBanned = B_UPDATED_MOVE_FLAGS >= GEN_8,
|
.metronomeBanned = B_UPDATED_MOVE_FLAGS >= GEN_8,
|
||||||
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_MONS_WITH_GOOD_APPEALS,
|
.contestEffect = CONTEST_EFFECT_BADLY_STARTLE_MONS_WITH_GOOD_APPEALS,
|
||||||
.contestCategory = CONTEST_CATEGORY_CUTE,
|
.contestCategory = CONTEST_CATEGORY_CUTE,
|
||||||
@ -20024,6 +20025,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
|
|||||||
.target = MOVE_TARGET_SELECTED,
|
.target = MOVE_TARGET_SELECTED,
|
||||||
.priority = 0,
|
.priority = 0,
|
||||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||||
|
.argument = { .damagePercentage = 50 },
|
||||||
.metronomeBanned = TRUE,
|
.metronomeBanned = TRUE,
|
||||||
.battleAnimScript = gBattleAnimMove_Ruination,
|
.battleAnimScript = gBattleAnimMove_Ruination,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -38,14 +38,14 @@ const struct Fusion *const gFusionTablePointers[NUM_SPECIES] =
|
|||||||
#if P_FUSION_FORMS
|
#if P_FUSION_FORMS
|
||||||
#if P_FAMILY_KYUREM
|
#if P_FAMILY_KYUREM
|
||||||
#if P_FAMILY_RESHIRAM
|
#if P_FAMILY_RESHIRAM
|
||||||
const u16 gKyurenWhiteSwapMoveTable[][2] =
|
const u16 gKyuremWhiteSwapMoveTable[][2] =
|
||||||
{
|
{
|
||||||
{MOVE_SCARY_FACE, MOVE_FUSION_FLARE},
|
{MOVE_SCARY_FACE, MOVE_FUSION_FLARE},
|
||||||
{MOVE_GLACIATE, MOVE_ICE_BURN},
|
{MOVE_GLACIATE, MOVE_ICE_BURN},
|
||||||
};
|
};
|
||||||
#endif //P_FAMILY_RESHIRAM
|
#endif //P_FAMILY_RESHIRAM
|
||||||
#if P_FAMILY_ZEKROM
|
#if P_FAMILY_ZEKROM
|
||||||
const u16 gKyurenBlackSwapMoveTable[][2] =
|
const u16 gKyuremBlackSwapMoveTable[][2] =
|
||||||
{
|
{
|
||||||
{MOVE_SCARY_FACE, MOVE_FUSION_BOLT},
|
{MOVE_SCARY_FACE, MOVE_FUSION_BOLT},
|
||||||
{MOVE_GLACIATE, MOVE_FREEZE_SHOCK},
|
{MOVE_GLACIATE, MOVE_FREEZE_SHOCK},
|
||||||
|
|||||||